Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 et tw=78: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "MediaTrack.h"
8 : #include "MediaTrackList.h"
9 : #include "mozilla/AsyncEventDispatcher.h"
10 : #include "mozilla/dom/HTMLMediaElement.h"
11 : #include "mozilla/dom/AudioTrack.h"
12 : #include "mozilla/dom/VideoStreamTrack.h"
13 : #include "mozilla/dom/VideoTrack.h"
14 : #include "mozilla/dom/TrackEvent.h"
15 : #include "nsThreadUtils.h"
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 0 : MediaTrackList::MediaTrackList(nsPIDOMWindowInner* aOwnerWindow,
21 0 : HTMLMediaElement* aMediaElement)
22 : : DOMEventTargetHelper(aOwnerWindow)
23 0 : , mMediaElement(aMediaElement)
24 : {
25 0 : }
26 :
27 0 : MediaTrackList::~MediaTrackList()
28 : {
29 0 : }
30 :
31 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaTrackList,
32 : DOMEventTargetHelper,
33 : mTracks,
34 : mMediaElement)
35 :
36 0 : NS_IMPL_ADDREF_INHERITED(MediaTrackList, DOMEventTargetHelper)
37 0 : NS_IMPL_RELEASE_INHERITED(MediaTrackList, DOMEventTargetHelper)
38 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaTrackList)
39 0 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
40 :
41 : MediaTrack*
42 0 : MediaTrackList::operator[](uint32_t aIndex)
43 : {
44 0 : return mTracks.ElementAt(aIndex);
45 : }
46 :
47 : MediaTrack*
48 0 : MediaTrackList::IndexedGetter(uint32_t aIndex, bool& aFound)
49 : {
50 0 : aFound = aIndex < mTracks.Length();
51 0 : if (!aFound) {
52 0 : return nullptr;
53 : }
54 0 : return mTracks[aIndex];
55 : }
56 :
57 : MediaTrack*
58 0 : MediaTrackList::GetTrackById(const nsAString& aId)
59 : {
60 0 : for (uint32_t i = 0; i < mTracks.Length(); ++i) {
61 0 : if (aId.Equals(mTracks[i]->GetId())) {
62 0 : return mTracks[i];
63 : }
64 : }
65 0 : return nullptr;
66 : }
67 :
68 : void
69 0 : MediaTrackList::AddTrack(MediaTrack* aTrack)
70 : {
71 0 : mTracks.AppendElement(aTrack);
72 0 : aTrack->Init(GetOwner());
73 0 : aTrack->SetTrackList(this);
74 0 : CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("addtrack"));
75 :
76 0 : if ((!aTrack->AsAudioTrack() || !aTrack->AsAudioTrack()->Enabled()) &&
77 0 : (!aTrack->AsVideoTrack() || !aTrack->AsVideoTrack()->Selected())) {
78 : // Track not enabled, no need to notify media element.
79 0 : return;
80 : }
81 :
82 0 : if (HTMLMediaElement* element = GetMediaElement()) {
83 0 : element->NotifyMediaTrackEnabled(aTrack);
84 : }
85 : }
86 :
87 : void
88 0 : MediaTrackList::RemoveTrack(const RefPtr<MediaTrack>& aTrack)
89 : {
90 0 : mTracks.RemoveElement(aTrack);
91 0 : aTrack->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
92 0 : aTrack->SetTrackList(nullptr);
93 0 : CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("removetrack"));
94 0 : }
95 :
96 : void
97 0 : MediaTrackList::RemoveTracks()
98 : {
99 0 : while (!mTracks.IsEmpty()) {
100 0 : RefPtr<MediaTrack> track = mTracks.LastElement();
101 0 : RemoveTrack(track);
102 : }
103 0 : }
104 :
105 : already_AddRefed<AudioTrack>
106 0 : MediaTrackList::CreateAudioTrack(const nsAString& aId,
107 : const nsAString& aKind,
108 : const nsAString& aLabel,
109 : const nsAString& aLanguage,
110 : bool aEnabled)
111 : {
112 : RefPtr<AudioTrack> track = new AudioTrack(aId, aKind, aLabel, aLanguage,
113 0 : aEnabled);
114 0 : return track.forget();
115 : }
116 :
117 : already_AddRefed<VideoTrack>
118 0 : MediaTrackList::CreateVideoTrack(const nsAString& aId,
119 : const nsAString& aKind,
120 : const nsAString& aLabel,
121 : const nsAString& aLanguage,
122 : VideoStreamTrack* aVideoTrack)
123 : {
124 0 : RefPtr<VideoTrack> track = new VideoTrack(aId, aKind, aLabel, aLanguage, aVideoTrack);
125 0 : return track.forget();
126 : }
127 :
128 : void
129 0 : MediaTrackList::EmptyTracks()
130 : {
131 0 : for (uint32_t i = 0; i < mTracks.Length(); ++i) {
132 0 : mTracks[i]->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
133 0 : mTracks[i]->SetTrackList(nullptr);
134 : }
135 0 : mTracks.Clear();
136 0 : }
137 :
138 : void
139 0 : MediaTrackList::CreateAndDispatchChangeEvent()
140 : {
141 : RefPtr<AsyncEventDispatcher> asyncDispatcher =
142 0 : new AsyncEventDispatcher(this, NS_LITERAL_STRING("change"), false);
143 0 : asyncDispatcher->PostDOMEvent();
144 0 : }
145 :
146 : void
147 0 : MediaTrackList::CreateAndDispatchTrackEventRunner(MediaTrack* aTrack,
148 : const nsAString& aEventName)
149 : {
150 0 : TrackEventInit eventInit;
151 :
152 0 : if (aTrack->AsAudioTrack()) {
153 0 : eventInit.mTrack.SetValue().SetAsAudioTrack() = aTrack->AsAudioTrack();
154 0 : } else if (aTrack->AsVideoTrack()) {
155 0 : eventInit.mTrack.SetValue().SetAsVideoTrack() = aTrack->AsVideoTrack();
156 : }
157 :
158 : RefPtr<TrackEvent> event =
159 0 : TrackEvent::Constructor(this, aEventName, eventInit);
160 :
161 : RefPtr<AsyncEventDispatcher> asyncDispatcher =
162 0 : new AsyncEventDispatcher(this, event);
163 0 : asyncDispatcher->PostDOMEvent();
164 0 : }
165 :
166 : } // namespace dom
167 : } // namespace mozilla
|