mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
30cae3d32d
1. If mHasUserInteraction MediaElement is false, don't run the TimeMarchesOn because the element is not played. 2. Update the activeCueList only in TimeMarchesOn(). 3. Run TimeMarchesOn() at the beginning of play. r=rillian MozReview-Commit-ID: BhwsIfRm3B2 --HG-- extra : rebase_source : 9713d4f467f1d708f65a25e54435d0c6e8ff1816
304 lines
7.8 KiB
C++
304 lines
7.8 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 et tw=78: */
|
|
/* 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/AsyncEventDispatcher.h"
|
|
#include "mozilla/dom/TextTrack.h"
|
|
#include "mozilla/dom/TextTrackBinding.h"
|
|
#include "mozilla/dom/TextTrackList.h"
|
|
#include "mozilla/dom/TextTrackCue.h"
|
|
#include "mozilla/dom/TextTrackCueList.h"
|
|
#include "mozilla/dom/TextTrackRegion.h"
|
|
#include "mozilla/dom/HTMLMediaElement.h"
|
|
#include "mozilla/dom/HTMLTrackElement.h"
|
|
|
|
namespace mozilla {
|
|
namespace 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_INHERITED(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()
|
|
{
|
|
}
|
|
|
|
void
|
|
TextTrack::SetDefaultSettings()
|
|
{
|
|
nsPIDOMWindowInner* ownerWindow = GetOwner();
|
|
mCueList = new TextTrackCueList(ownerWindow);
|
|
mActiveCueList = new TextTrackCueList(ownerWindow);
|
|
mCuePos = 0;
|
|
mDirty = false;
|
|
}
|
|
|
|
JSObject*
|
|
TextTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return TextTrackBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
void
|
|
TextTrack::SetMode(TextTrackMode aValue)
|
|
{
|
|
if (mMode != aValue) {
|
|
mMode = aValue;
|
|
if (aValue == TextTrackMode::Disabled) {
|
|
SetCuesInactive();
|
|
// Remove all the cues in MediaElement.
|
|
if (mTextTrackList) {
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement) {
|
|
for (size_t i = 0; i < mCueList->Length(); ++i) {
|
|
mediaElement->NotifyCueRemoved(*(*mCueList)[i]);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Add all the cues into MediaElement.
|
|
if (mTextTrackList) {
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement) {
|
|
for (size_t i = 0; i < mCueList->Length(); ++i) {
|
|
mediaElement->NotifyCueAdded(*(*mCueList)[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (mTextTrackList) {
|
|
mTextTrackList->CreateAndDispatchChangeEvent();
|
|
}
|
|
// 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->GetAttribute(NS_LITERAL_STRING("id"), aId);
|
|
}
|
|
}
|
|
|
|
void
|
|
TextTrack::AddCue(TextTrackCue& aCue)
|
|
{
|
|
mCueList->AddCue(aCue);
|
|
aCue.SetTrack(this);
|
|
if (mTextTrackList) {
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement && (mMode != TextTrackMode::Disabled)) {
|
|
mediaElement->NotifyCueAdded(aCue);
|
|
}
|
|
}
|
|
SetDirty();
|
|
}
|
|
|
|
void
|
|
TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
|
|
{
|
|
aCue.SetActive(false);
|
|
|
|
mCueList->RemoveCue(aCue, aRv);
|
|
aCue.SetTrack(nullptr);
|
|
if (mTextTrackList) {
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement) {
|
|
mediaElement->NotifyCueRemoved(aCue);
|
|
}
|
|
}
|
|
SetDirty();
|
|
}
|
|
|
|
void
|
|
TextTrack::SetCuesDirty()
|
|
{
|
|
for (uint32_t i = 0; i < mCueList->Length(); i++) {
|
|
((*mCueList)[i])->Reset();
|
|
}
|
|
}
|
|
|
|
void
|
|
TextTrack::UpdateActiveCueList()
|
|
{
|
|
if (!mTextTrackList) {
|
|
return;
|
|
}
|
|
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (!mediaElement) {
|
|
return;
|
|
}
|
|
|
|
// If we are dirty, i.e. an event happened that may cause the sorted mCueList
|
|
// to have changed like a seek or an insert for a cue, than we need to rebuild
|
|
// the active cue list from scratch.
|
|
if (mDirty) {
|
|
mCuePos = 0;
|
|
mDirty = false;
|
|
mActiveCueList->RemoveAll();
|
|
}
|
|
|
|
double playbackTime = mediaElement->CurrentTime();
|
|
// Remove all the cues from the active cue list whose end times now occur
|
|
// earlier then the current playback time.
|
|
for (uint32_t i = mActiveCueList->Length(); i > 0; i--) {
|
|
if ((*mActiveCueList)[i - 1]->EndTime() < playbackTime) {
|
|
mActiveCueList->RemoveCueAt(i - 1);
|
|
}
|
|
}
|
|
// Add all the cues, starting from the position of the last cue that was
|
|
// added, that have valid start and end times for the current playback time.
|
|
// We can stop iterating safely once we encounter a cue that does not have
|
|
// a valid start time as the cue list is sorted.
|
|
for (; mCuePos < mCueList->Length() &&
|
|
(*mCueList)[mCuePos]->StartTime() <= playbackTime; mCuePos++) {
|
|
if ((*mCueList)[mCuePos]->EndTime() >= playbackTime) {
|
|
mActiveCueList->AddCue(*(*mCueList)[mCuePos]);
|
|
}
|
|
}
|
|
}
|
|
|
|
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(uint32_t aReadyState)
|
|
{
|
|
if (aReadyState <= TextTrackReadyState::FailedToLoad) {
|
|
SetReadyState(static_cast<TextTrackReadyState>(aReadyState));
|
|
}
|
|
}
|
|
|
|
void
|
|
TextTrack::SetReadyState(TextTrackReadyState aState)
|
|
{
|
|
mReadyState = aState;
|
|
|
|
if (!mTextTrackList) {
|
|
return;
|
|
}
|
|
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement && (mReadyState == TextTrackReadyState::Loaded||
|
|
mReadyState == TextTrackReadyState::FailedToLoad)) {
|
|
mediaElement->RemoveTextTrack(this, true);
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
mCueList->SetCuesInactive();
|
|
}
|
|
|
|
void
|
|
TextTrack::NotifyCueUpdated(TextTrackCue *aCue)
|
|
{
|
|
mCueList->NotifyCueUpdated(aCue);
|
|
if (mTextTrackList) {
|
|
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
|
if (mediaElement) {
|
|
mediaElement->NotifyCueUpdated(aCue);
|
|
}
|
|
}
|
|
SetDirty();
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|