1 | /* |
2 | * Copyright (C) 2011 Google Inc. All rights reserved. |
3 | * Copyright (C) 2011-2017 Apple Inc. All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are |
7 | * met: |
8 | * |
9 | * * Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * * Redistributions in binary form must reproduce the above |
12 | * copyright notice, this list of conditions and the following disclaimer |
13 | * in the documentation and/or other materials provided with the |
14 | * distribution. |
15 | * * Neither the name of Google Inc. nor the names of its |
16 | * contributors may be used to endorse or promote products derived from |
17 | * this software without specific prior written permission. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include "config.h" |
33 | #include "VideoTrack.h" |
34 | |
35 | #if ENABLE(VIDEO_TRACK) |
36 | |
37 | #include "HTMLMediaElement.h" |
38 | #include "VideoTrackList.h" |
39 | #include <wtf/NeverDestroyed.h> |
40 | |
41 | #if ENABLE(MEDIA_SOURCE) |
42 | #include "SourceBuffer.h" |
43 | #endif |
44 | |
45 | namespace WebCore { |
46 | |
47 | const AtomicString& VideoTrack::alternativeKeyword() |
48 | { |
49 | static NeverDestroyed<const AtomicString> alternative("alternative" , AtomicString::ConstructFromLiteral); |
50 | return alternative; |
51 | } |
52 | |
53 | const AtomicString& VideoTrack::captionsKeyword() |
54 | { |
55 | static NeverDestroyed<const AtomicString> captions("captions" , AtomicString::ConstructFromLiteral); |
56 | return captions; |
57 | } |
58 | |
59 | const AtomicString& VideoTrack::mainKeyword() |
60 | { |
61 | static NeverDestroyed<const AtomicString> captions("main" , AtomicString::ConstructFromLiteral); |
62 | return captions; |
63 | } |
64 | |
65 | const AtomicString& VideoTrack::signKeyword() |
66 | { |
67 | static NeverDestroyed<const AtomicString> sign("sign" , AtomicString::ConstructFromLiteral); |
68 | return sign; |
69 | } |
70 | |
71 | const AtomicString& VideoTrack::subtitlesKeyword() |
72 | { |
73 | static NeverDestroyed<const AtomicString> subtitles("subtitles" , AtomicString::ConstructFromLiteral); |
74 | return subtitles; |
75 | } |
76 | |
77 | const AtomicString& VideoTrack::() |
78 | { |
79 | static NeverDestroyed<const AtomicString> ("commentary" , AtomicString::ConstructFromLiteral); |
80 | return commentary; |
81 | } |
82 | |
83 | VideoTrack::VideoTrack(VideoTrackClient& client, VideoTrackPrivate& trackPrivate) |
84 | : MediaTrackBase(MediaTrackBase::VideoTrack, trackPrivate.id(), trackPrivate.label(), trackPrivate.language()) |
85 | , m_client(&client) |
86 | , m_private(trackPrivate) |
87 | , m_selected(trackPrivate.selected()) |
88 | { |
89 | #if !RELEASE_LOG_DISABLED |
90 | m_private->setLogger(logger(), logIdentifier()); |
91 | #endif |
92 | m_private->setClient(this); |
93 | updateKindFromPrivate(); |
94 | } |
95 | |
96 | VideoTrack::~VideoTrack() |
97 | { |
98 | m_private->setClient(nullptr); |
99 | } |
100 | |
101 | void VideoTrack::setPrivate(VideoTrackPrivate& trackPrivate) |
102 | { |
103 | if (m_private.ptr() == &trackPrivate) |
104 | return; |
105 | |
106 | m_private->setClient(nullptr); |
107 | m_private = trackPrivate; |
108 | m_private->setClient(this); |
109 | #if !RELEASE_LOG_DISABLED |
110 | m_private->setLogger(logger(), logIdentifier()); |
111 | #endif |
112 | |
113 | m_private->setSelected(m_selected); |
114 | updateKindFromPrivate(); |
115 | } |
116 | |
117 | bool VideoTrack::isValidKind(const AtomicString& value) const |
118 | { |
119 | return value == alternativeKeyword() |
120 | || value == commentaryKeyword() |
121 | || value == captionsKeyword() |
122 | || value == mainKeyword() |
123 | || value == signKeyword() |
124 | || value == subtitlesKeyword(); |
125 | } |
126 | |
127 | void VideoTrack::setSelected(const bool selected) |
128 | { |
129 | if (m_selected == selected) |
130 | return; |
131 | |
132 | m_selected = selected; |
133 | m_private->setSelected(selected); |
134 | |
135 | if (m_client) |
136 | m_client->videoTrackSelectedChanged(*this); |
137 | } |
138 | |
139 | size_t VideoTrack::inbandTrackIndex() |
140 | { |
141 | return m_private->trackIndex(); |
142 | } |
143 | |
144 | void VideoTrack::selectedChanged(bool selected) |
145 | { |
146 | setSelected(selected); |
147 | } |
148 | |
149 | void VideoTrack::idChanged(const AtomicString& id) |
150 | { |
151 | setId(id); |
152 | } |
153 | |
154 | void VideoTrack::labelChanged(const AtomicString& label) |
155 | { |
156 | setLabel(label); |
157 | } |
158 | |
159 | void VideoTrack::languageChanged(const AtomicString& language) |
160 | { |
161 | setLanguage(language); |
162 | } |
163 | |
164 | void VideoTrack::willRemove() |
165 | { |
166 | auto element = makeRefPtr(mediaElement()); |
167 | if (!element) |
168 | return; |
169 | element->removeVideoTrack(*this); |
170 | } |
171 | |
172 | #if ENABLE(MEDIA_SOURCE) |
173 | |
174 | void VideoTrack::setKind(const AtomicString& kind) |
175 | { |
176 | // 10.1 kind, on setting: |
177 | // 1. If the value being assigned to this attribute does not match one of the video track kinds, |
178 | // then abort these steps. |
179 | if (!isValidKind(kind)) |
180 | return; |
181 | |
182 | // 2. Update this attribute to the new value. |
183 | setKindInternal(kind); |
184 | |
185 | // 3. If the sourceBuffer attribute on this track is not null, then queue a task to fire a simple |
186 | // event named change at sourceBuffer.videoTracks. |
187 | if (m_sourceBuffer) |
188 | m_sourceBuffer->videoTracks().scheduleChangeEvent(); |
189 | |
190 | // 4. Queue a task to fire a simple event named change at the VideoTrackList object referenced by |
191 | // the videoTracks attribute on the HTMLMediaElement. |
192 | mediaElement()->ensureVideoTracks().scheduleChangeEvent(); |
193 | } |
194 | |
195 | void VideoTrack::setLanguage(const AtomicString& language) |
196 | { |
197 | // 10.1 language, on setting: |
198 | // 1. If the value being assigned to this attribute is not an empty string or a BCP 47 language |
199 | // tag[BCP47], then abort these steps. |
200 | // BCP 47 validation is done in TrackBase::setLanguage() which is |
201 | // shared between all tracks that support setting language. |
202 | |
203 | // 2. Update this attribute to the new value. |
204 | MediaTrackBase::setLanguage(language); |
205 | |
206 | // 3. If the sourceBuffer attribute on this track is not null, then queue a task to fire a simple |
207 | // event named change at sourceBuffer.videoTracks. |
208 | if (m_sourceBuffer) |
209 | m_sourceBuffer->videoTracks().scheduleChangeEvent(); |
210 | |
211 | // 4. Queue a task to fire a simple event named change at the VideoTrackList object referenced by |
212 | // the videoTracks attribute on the HTMLMediaElement. |
213 | if (mediaElement()) |
214 | mediaElement()->ensureVideoTracks().scheduleChangeEvent(); |
215 | } |
216 | |
217 | #endif |
218 | |
219 | void VideoTrack::updateKindFromPrivate() |
220 | { |
221 | switch (m_private->kind()) { |
222 | case VideoTrackPrivate::Alternative: |
223 | setKindInternal(VideoTrack::alternativeKeyword()); |
224 | return; |
225 | case VideoTrackPrivate::Captions: |
226 | setKindInternal(VideoTrack::captionsKeyword()); |
227 | return; |
228 | case VideoTrackPrivate::Main: |
229 | setKindInternal(VideoTrack::mainKeyword()); |
230 | return; |
231 | case VideoTrackPrivate::Sign: |
232 | setKindInternal(VideoTrack::signKeyword()); |
233 | return; |
234 | case VideoTrackPrivate::Subtitles: |
235 | setKindInternal(VideoTrack::subtitlesKeyword()); |
236 | return; |
237 | case VideoTrackPrivate::Commentary: |
238 | setKindInternal(VideoTrack::commentaryKeyword()); |
239 | return; |
240 | case VideoTrackPrivate::None: |
241 | setKindInternal(emptyString()); |
242 | return; |
243 | } |
244 | ASSERT_NOT_REACHED(); |
245 | } |
246 | |
247 | void VideoTrack::setMediaElement(HTMLMediaElement* element) |
248 | { |
249 | TrackBase::setMediaElement(element); |
250 | #if !RELEASE_LOG_DISABLED |
251 | m_private->setLogger(logger(), logIdentifier()); |
252 | #endif |
253 | } |
254 | |
255 | } // namespace WebCore |
256 | |
257 | #endif |
258 | |