Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  TextTrack.cpp

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "mozilla/dom/TextTrack.h"

#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "mozilla/dom/TextTrackBinding.h"
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/TextTrackCueList.h"
#include "mozilla/dom/TextTrackList.h"
#include "mozilla/dom/TextTrackRegion.h"
#include "nsGlobalWindowInner.h"

extern mozilla::LazyLogModule gTextTrackLog;

#define WEBVTT_LOG(msg, ...)                                        \
  MOZ_LOG_FMT(gTextTrackLog, LogLevel::Debug, "TextTrack={}, " msg, \
              fmt::ptr(this), ##__VA_ARGS__)
#define WEBVTT_LOGV(msg, ...)                                         \
  MOZ_LOG_FMT(gTextTrackLog, LogLevel::Verbose, "TextTrack={}, " msg, \
              fmt::ptr(this), ##__VA_ARGS__)

namespace mozilla::dom {

NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrack, DOMEventTargetHelper, mCueList,
                                   mActiveCueList, mTextTrackList,
                                   mTrackElement)

NS_IMPL_ADDREF_INHERITED(TextTrack, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(TextTrack, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextTrack)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)

TextTrack::TextTrack(nsPIDOMWindowInner* aOwnerWindow, TextTrackKind aKind,
                     const nsAString& aLabel, const nsAString& aLanguage,
                     TextTrackMode aMode, TextTrackReadyState aReadyState,
                     TextTrackSource aTextTrackSource)
    : DOMEventTargetHelper(aOwnerWindow),
      mKind(aKind),
      mLabel(aLabel),
      mLanguage(aLanguage),
      mMode(aMode),
      mReadyState(aReadyState),
      mTextTrackSource(aTextTrackSource) {
  SetDefaultSettings();
}

TextTrack::TextTrack(nsPIDOMWindowInner* aOwnerWindow,
                     TextTrackList* aTextTrackList, TextTrackKind aKind,
                     const nsAString& aLabel, const nsAString& aLanguage,
                     TextTrackMode aMode, TextTrackReadyState aReadyState,
                     TextTrackSource aTextTrackSource)
    : DOMEventTargetHelper(aOwnerWindow),
      mTextTrackList(aTextTrackList),
      mKind(aKind),
      mLabel(aLabel),
      mLanguage(aLanguage),
      mMode(aMode),
      mReadyState(aReadyState),
      mTextTrackSource(aTextTrackSource) {
  SetDefaultSettings();
}

TextTrack::~TextTrack() = default;

void TextTrack::SetDefaultSettings() {
  nsPIDOMWindowInner* ownerWindow = GetOwnerWindow();
  mCueList = new TextTrackCueList(ownerWindow);
  mActiveCueList = new TextTrackCueList(ownerWindow);
  mCuePos = 0;
  mDirty = false;
}

JSObject* TextTrack::WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) {
  return TextTrack_Binding::Wrap(aCx, this, aGivenProto);
}

void TextTrack::SetMode(TextTrackMode aValue) {
  RefPtr<TextTrack> kungFuDeathGrip = this;
  if (mMode == aValue) {
    return;
  }
  WEBVTT_LOG("Set mode={} for track kind {}", GetEnumString(aValue).get(),
             GetEnumString(mKind).get());
  mMode = aValue;

  HTMLMediaElement* mediaElement = GetMediaElement();
  if (aValue == TextTrackMode::Disabled) {
    for (size_t i = 0; i < mCueList->Length() && mediaElement; ++i) {
      mediaElement->NotifyCueRemoved(*(*mCueList)[i]);
    }
    SetCuesInactive();
  } else {
    for (size_t i = 0; i < mCueList->Length() && mediaElement; ++i) {
      mediaElement->NotifyCueAdded(*(*mCueList)[i]);
    }
  }
  if (mediaElement) {
    mediaElement->NotifyTextTrackModeChanged();
  }
  // https://html.spec.whatwg.org/multipage/media.html#sourcing-out-of-band-text-tracks:start-the-track-processing-model
  // Run the `start-the-track-processing-model` to track's corresponding track
  // element whenever track's mode changes.
  if (mTrackElement) {
    mTrackElement->MaybeDispatchLoadResource();
  }
  // Ensure the TimeMarchesOn is called in case that the mCueList
  // is empty.
  NotifyCueUpdated(nullptr);
}

void TextTrack::GetId(nsAString& aId) const {
  // If the track has a track element then its id should be the same as the
  // track element's id.
  if (mTrackElement) {
    mTrackElement->GetAttr(nsGkAtoms::id, aId);
  }
}

void TextTrack::AddCue(TextTrackCue& aCue) {
  WEBVTT_LOG("AddCue {} [{}:{}]", fmt::ptr(&aCue), aCue.StartTime(),
             aCue.EndTime());
  TextTrack* oldTextTrack = aCue.GetTrack();
  if (oldTextTrack) {
    ErrorResult dummy;
    oldTextTrack->RemoveCue(aCue, dummy);
  }
  mCueList->AddCue(aCue);
  aCue.SetTrack(this);
  HTMLMediaElement* mediaElement = GetMediaElement();
  if (mediaElement && (mMode != TextTrackMode::Disabled)) {
    mediaElement->NotifyCueAdded(aCue);
  }
}

void TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv) {
  WEBVTT_LOG("RemoveCue {}", fmt::ptr(&aCue));
  // Bug1304948, check the aCue belongs to the TextTrack.
  mCueList->RemoveCue(aCue, aRv);
  if (aRv.Failed()) {
    return;
  }
  aCue.SetActive(false);
  aCue.SetTrack(nullptr);
  HTMLMediaElement* mediaElement = GetMediaElement();
  if (mediaElement) {
    mediaElement->NotifyCueRemoved(aCue);
  }
}

void TextTrack::ClearAllCues() {
  WEBVTT_LOG("ClearAllCues");
  ErrorResult dummy;
  while (!mCueList->IsEmpty()) {
    RemoveCue(*(*mCueList)[0], dummy);
  }
}

void TextTrack::SetCuesDirty() {
  for (uint32_t i = 0; i < mCueList->Length(); i++) {
    ((*mCueList)[i])->Reset();
  }
}

TextTrackCueList* TextTrack::GetActiveCues() {
  if (mMode != TextTrackMode::Disabled) {
    return mActiveCueList;
  }
  return nullptr;
}

void TextTrack::GetActiveCueArray(nsTArray<RefPtr<TextTrackCue>>& aCues) {
  if (mMode != TextTrackMode::Disabled) {
    mActiveCueList->GetArray(aCues);
  }
}

TextTrackReadyState TextTrack::ReadyState() const { return mReadyState; }

void TextTrack::SetReadyState(TextTrackReadyState aState) {
  WEBVTT_LOG("SetReadyState={}", EnumValueToString(aState));
  mReadyState = aState;
  HTMLMediaElement* mediaElement = GetMediaElement();
  if (mediaElement && (mReadyState == TextTrackReadyState::Loaded ||
                       mReadyState == TextTrackReadyState::FailedToLoad)) {
    mediaElement->RemoveTextTrack(this, true);
    mediaElement->UpdateReadyState();
  }
}

TextTrackList* TextTrack::GetTextTrackList() { return mTextTrackList; }

void TextTrack::SetTextTrackList(TextTrackList* aTextTrackList) {
  mTextTrackList = aTextTrackList;
}

HTMLTrackElement* TextTrack::GetTrackElement() { return mTrackElement; }

void TextTrack::SetTrackElement(HTMLTrackElement* aTrackElement) {
  mTrackElement = aTrackElement;
}

void TextTrack::SetCuesInactive() {
  WEBVTT_LOG("SetCuesInactive");
  mCueList->SetCuesInactive();
}

void TextTrack::NotifyCueUpdated(TextTrackCue* aCue) {
  WEBVTT_LOG("NotifyCueUpdated, cue={}", fmt::ptr(aCue));
  mCueList->NotifyCueUpdated(aCue);
  HTMLMediaElement* mediaElement = GetMediaElement();
  if (mediaElement) {
    mediaElement->NotifyCueUpdated(aCue);
  }
}

void TextTrack::GetLabel(nsAString& aLabel) const {
  if (mTrackElement) {
    mTrackElement->GetLabel(aLabel);
  } else {
    aLabel = mLabel;
  }
}
void TextTrack::GetLanguage(nsAString& aLanguage) const {
  if (mTrackElement) {
    mTrackElement->GetSrclang(aLanguage);
  } else {
    aLanguage = mLanguage;
  }
}

void TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName) {
  nsGlobalWindowInner* win = GetOwnerWindow();
  if (!win) {
    return;
  }
  win->Dispatch(
      NS_NewRunnableFunction("dom::TextTrack::DispatchAsyncTrustedEvent",
                             [self = RefPtr{this}, aEventName]() {
                               self->DispatchTrustedEvent(aEventName);
                             }));
}

bool TextTrack::IsLoaded() {
  if (mMode == TextTrackMode::Disabled) {
    return true;
  }
  // If the TrackElement's src is null, we can not block the
  // MediaElement.
  if (mTrackElement) {
    nsAutoString src;
    if (!(mTrackElement->GetAttr(nsGkAtoms::src, src))) {
      return true;
    }
  }
  return mReadyState >= TextTrackReadyState::Loaded;
}

void TextTrack::NotifyCueActiveStateChanged(TextTrackCue* aCue) {
  MOZ_ASSERT(aCue);
  if (aCue->GetActive()) {
    MOZ_ASSERT(!mActiveCueList->IsCueExist(aCue));
    WEBVTT_LOG("NotifyCueActiveStateChanged, add cue {} to the active list",
               fmt::ptr(aCue));
    mActiveCueList->AddCue(*aCue);
  } else {
    MOZ_ASSERT(mActiveCueList->IsCueExist(aCue));
    WEBVTT_LOG(
        "NotifyCueActiveStateChanged, remove cue {} from the active list",
        fmt::ptr(aCue));
    mActiveCueList->RemoveCue(*aCue);
  }
}

void TextTrack::GetOverlappingCurrentOtherAndMissCues(
    CueBuckets* aCurrentCues, CueBuckets* aOtherCues, CueBuckets* aMissCues,
    const media::TimeInterval& aInterval,
    const Maybe<double>& aLastTime) const {
  const HTMLMediaElement* mediaElement = GetMediaElement();
  if (!mediaElement || Mode() == TextTrackMode::Disabled ||
      mCueList->IsEmpty()) {
    return;
  }

  // According to `time marches on` step1, current cue list contains the cues
  // whose start times are less than or equal to the current playback position
  // and whose end times are greater than the current playback position.
  // https://html.spec.whatwg.org/multipage/media.html#time-marches-on
  MOZ_ASSERT(aCurrentCues && aOtherCues);
  const double playbackTime = mediaElement->CurrentTime();
  const double intervalStart = aInterval.mStart.ToSeconds();
  const double intervalEnd = aInterval.mEnd.ToSeconds();

  if (intervalEnd < (*mCueList)[0]->StartTime()) {
    WEBVTT_LOGV("Abort : interval ends before the first cue starts");
    return;
  }
  // Optimize the loop range by identifying the first cue that starts after the
  // interval.
  size_t lastIdx = 0;
  struct LastIdxComparator {
    const double mIntervalEnd;
    explicit LastIdxComparator(double aIntervalEnd)
        : mIntervalEnd(aIntervalEnd) {}
    int operator()(const TextTrackCue* aCue) const {
      return aCue->StartTime() > mIntervalEnd ? 0 : -1;
    }
  } compLast(intervalEnd);
  if (!BinarySearchIf(mCueList->GetCuesArray(), 0, mCueList->Length(), compLast,
                      &lastIdx)) {
    // Failed to find the match, set it to the last idx.
    lastIdx = mCueList->Length() - 1;
  }

  // Search cues in the partial range.
  for (size_t idx = 0; idx <= lastIdx; ++idx) {
    TextTrackCue* cue = (*mCueList)[idx];
    double cueStart = cue->StartTime();
    double cueEnd = cue->EndTime();
    if (cueStart <= playbackTime && cueEnd > playbackTime) {
      WEBVTT_LOG("Add cue {} [{}:{}] to current cue list", fmt::ptr(cue),
                 cueStart, cueEnd);
      aCurrentCues->AddCue(cue);
    } else {
      // As the spec doesn't have a restriction for the negative duration, it
      // does happen sometime if user sets it explicitly. It will be treated as
      // a `missing cue` (a subset of the `other cues`) and it won't be
      // displayed.
      if (cueEnd < cueStart) {
        // Add cue into `otherCue` only when its start time is contained by the
        // current time interval.
        if (intervalStart <= cueStart && cueStart < intervalEnd) {
          WEBVTT_LOG(
              "[Negative duration] Add cue {} [{}:{}] to other cues and "
              "missing cues list",
              fmt::ptr(cue), cueStart, cueEnd);
          aOtherCues->AddCue(cue);
          aMissCues->AddCue(cue);
        }
        continue;
      }
      // Cues are completely outside the time interval.
      if (cueEnd < intervalStart || cueStart > intervalEnd) {
        continue;
      }
      WEBVTT_LOG("Add cue {} [{}:{}] to other cue list", fmt::ptr(cue),
                 cueStart, cueEnd);
      aOtherCues->AddCue(cue);
      if (aLastTime && cueStart >= *aLastTime && cueEnd <= playbackTime) {
        WEBVTT_LOG("Add cue {} [{}:{}] to missing cues list", fmt::ptr(cue),
                   cueStart, cueEnd);
        aMissCues->AddCue(cue);
      }
    }
  }
}

HTMLMediaElement* TextTrack::GetMediaElement() const {
  return mTextTrackList ? mTextTrackList->GetMediaElement() : nullptr;
}

void TextTrack::CueBuckets::AddCue(TextTrackCue* aCue) {
  if (aCue->GetActive()) {
    ActiveCues().AppendElement(aCue);
    if (aCue->PauseOnExit()) {
      mHasPauseOnExist[static_cast<uint8_t>(CueActivityState::Active)] = true;
    }
  } else {
    InactiveCues().AppendElement(aCue);
    if (aCue->PauseOnExit()) {
      mHasPauseOnExist[static_cast<uint8_t>(CueActivityState::Inactive)] = true;
    }
  }
  AllCues().AppendElement(aCue);
  if (aCue->PauseOnExit()) {
    mHasPauseOnExist[static_cast<uint8_t>(CueActivityState::All)] = true;
  }
}

}  // namespace mozilla::dom

#undef WEBVTT_LOG
#undef WEBVTT_LOGV

Messung V0.5 in Prozent
C=92 H=98 G=94

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002