Bug 1259788 - Multi-track support for MediaTrackList. r?jesup
MozReview-Commit-ID: 1av5uvyCMYv
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1234,36 +1234,71 @@ void HTMLMediaElement::NotifyLoadError()
QueueLoadFromSourceTask();
} else {
NS_WARNING("Should know the source we were loading from!");
}
}
void HTMLMediaElement::NotifyMediaTrackEnabled(MediaTrack* aTrack)
{
+ MOZ_ASSERT(aTrack);
if (!aTrack) {
return;
}
#ifdef DEBUG
nsString id;
aTrack->GetId(id);
- LOG(LogLevel::Debug, ("MediaElement %p MediaStreamTrack enabled with id %s",
+ LOG(LogLevel::Debug, ("MediaElement %p MediaTrack with id %s enabled",
this, NS_ConvertUTF16toUTF8(id).get()));
#endif
- // TODO: We are dealing with single audio track and video track for now.
- if (AudioTrack* track = aTrack->AsAudioTrack()) {
- if (!track->Enabled()) {
+ MOZ_ASSERT((aTrack->AsAudioTrack() && aTrack->AsAudioTrack()->Enabled()) ||
+ (aTrack->AsVideoTrack() && aTrack->AsVideoTrack()->Selected()));
+
+ if (aTrack->AsAudioTrack()) {
+ SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_TRACK);
+ } else if (aTrack->AsVideoTrack()) {
+ mDisableVideo = false;
+ }
+}
+
+void HTMLMediaElement::NotifyMediaTrackDisabled(MediaTrack* aTrack)
+{
+ MOZ_ASSERT(aTrack);
+ if (!aTrack) {
+ return;
+ }
+#ifdef DEBUG
+ nsString id;
+ aTrack->GetId(id);
+
+ LOG(LogLevel::Debug, ("MediaElement %p MediaTrack with id %s disabled",
+ this, NS_ConvertUTF16toUTF8(id).get()));
+#endif
+
+ MOZ_ASSERT((!aTrack->AsAudioTrack() || !aTrack->AsAudioTrack()->Enabled()) &&
+ (!aTrack->AsVideoTrack() || !aTrack->AsVideoTrack()->Selected()));
+
+
+ if (aTrack->AsAudioTrack()) {
+ bool shouldMute = true;
+ for (uint32_t i = 0; i < AudioTracks()->Length(); ++i) {
+ if ((*AudioTracks())[i]->Enabled()) {
+ shouldMute = false;
+ break;
+ }
+ }
+ if (shouldMute) {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_TRACK);
- } else {
- SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_TRACK);
}
- } else if (VideoTrack* track = aTrack->AsVideoTrack()) {
- mDisableVideo = !track->Selected();
+ } else if (aTrack->AsVideoTrack()) {
+ if (VideoTracks()->SelectedIndex() == -1) {
+ mDisableVideo = false;
+ }
}
}
void HTMLMediaElement::NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream)
{
if (!mSrcStream || mSrcStream != aStream) {
return;
}
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -338,19 +338,29 @@ public:
void NotifyAddedSource();
/**
* Called when there's been an error fetching the resource. This decides
* whether it's appropriate to fire an error event.
*/
void NotifyLoadError();
+ /**
+ * Called by one of our associated MediaTrackLists (audio/video) when an
+ * AudioTrack is enabled or a VideoTrack is selected.
+ */
void NotifyMediaTrackEnabled(MediaTrack* aTrack);
/**
+ * Called by one of our associated MediaTrackLists (audio/video) when an
+ * AudioTrack is disabled or a VideoTrack is unselected.
+ */
+ void NotifyMediaTrackDisabled(MediaTrack* aTrack);
+
+ /**
* Called when tracks become available to the source media stream.
*/
void NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream);
virtual bool IsNodeOfType(uint32_t aFlags) const override;
/**
* Returns the current load ID. Asynchronous events store the ID that was
--- a/dom/media/AudioTrack.cpp
+++ b/dom/media/AudioTrack.cpp
@@ -43,20 +43,27 @@ AudioTrack::SetEnabledInternal(bool aEna
mEnabled = aEnabled;
// If this AudioTrack is no longer in its original AudioTrackList, then
// whether it is enabled or not has no effect on its original list.
if (!mList) {
return;
}
- if (!(aFlags & MediaTrack::FIRE_NO_EVENTS)) {
- mList->CreateAndDispatchChangeEvent();
-
+ if (mEnabled) {
HTMLMediaElement* element = mList->GetMediaElement();
if (element) {
element->NotifyMediaTrackEnabled(this);
}
+ } else {
+ HTMLMediaElement* element = mList->GetMediaElement();
+ if (element) {
+ element->NotifyMediaTrackDisabled(this);
+ }
+ }
+
+ if (!(aFlags & MediaTrack::FIRE_NO_EVENTS)) {
+ mList->CreateAndDispatchChangeEvent();
}
}
} // namespace dom
} //namespace mozilla
--- a/dom/media/MediaTrack.cpp
+++ b/dom/media/MediaTrack.cpp
@@ -1,16 +1,18 @@
/* -*- 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 "MediaTrack.h"
+#include "AudioTrack.h"
#include "MediaTrackList.h"
+#include "VideoTrack.h"
namespace mozilla {
namespace dom {
MediaTrack::MediaTrack(const nsAString& aId,
const nsAString& aKind,
const nsAString& aLabel,
const nsAString& aLanguage)
--- a/dom/media/MediaTrackList.cpp
+++ b/dom/media/MediaTrackList.cpp
@@ -67,22 +67,33 @@ MediaTrackList::GetTrackById(const nsASt
void
MediaTrackList::AddTrack(MediaTrack* aTrack)
{
mTracks.AppendElement(aTrack);
aTrack->Init(GetOwner());
aTrack->SetTrackList(this);
CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("addtrack"));
+
+ if ((!aTrack->AsAudioTrack() || !aTrack->AsAudioTrack()->Enabled()) &&
+ (!aTrack->AsVideoTrack() || !aTrack->AsVideoTrack()->Selected())) {
+ // Track not enabled, no need to notify media element.
+ return;
+ }
+
+ if (HTMLMediaElement* element = GetMediaElement()) {
+ element->NotifyMediaTrackEnabled(aTrack);
+ }
}
void
MediaTrackList::RemoveTrack(const RefPtr<MediaTrack>& aTrack)
{
mTracks.RemoveElement(aTrack);
+ aTrack->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
aTrack->SetTrackList(nullptr);
CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("removetrack"));
}
void
MediaTrackList::RemoveTracks()
{
while (!mTracks.IsEmpty()) {
@@ -113,16 +124,17 @@ MediaTrackList::CreateVideoTrack(const n
RefPtr<VideoTrack> track = new VideoTrack(aId, aKind, aLabel, aLanguage, aVideoTrack);
return track.forget();
}
void
MediaTrackList::EmptyTracks()
{
for (uint32_t i = 0; i < mTracks.Length(); ++i) {
+ mTracks[i]->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
mTracks[i]->SetTrackList(nullptr);
}
mTracks.Clear();
}
void
MediaTrackList::CreateAndDispatchChangeEvent()
{
--- a/dom/media/VideoTrack.cpp
+++ b/dom/media/VideoTrack.cpp
@@ -73,26 +73,31 @@ VideoTrack::SetEnabledInternal(bool aEna
}
VideoTrack* track = list[i];
track->SetSelected(false);
}
// Set the index of selected video track to the current's index.
list.mSelectedIndex = curIndex;
+
+ HTMLMediaElement* element = mList->GetMediaElement();
+ if (element) {
+ element->NotifyMediaTrackEnabled(this);
+ }
} else {
list.mSelectedIndex = -1;
+
+ HTMLMediaElement* element = mList->GetMediaElement();
+ if (element) {
+ element->NotifyMediaTrackDisabled(this);
+ }
}
// Fire the change event at selection changes on this video track, shall
// propose a spec change later.
if (!(aFlags & MediaTrack::FIRE_NO_EVENTS)) {
list.CreateAndDispatchChangeEvent();
-
- HTMLMediaElement* element = mList->GetMediaElement();
- if (element) {
- element->NotifyMediaTrackEnabled(this);
- }
}
}
} // namespace dom
} //namespace mozilla