Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: Source/core/html/HTMLMediaElement.cpp

Issue 913133003: Move text track active list management to CueTimeline (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rename to CueTimeline. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "core/html/HTMLSourceElement.h" 46 #include "core/html/HTMLSourceElement.h"
47 #include "core/html/HTMLTrackElement.h" 47 #include "core/html/HTMLTrackElement.h"
48 #include "core/html/MediaController.h" 48 #include "core/html/MediaController.h"
49 #include "core/html/MediaError.h" 49 #include "core/html/MediaError.h"
50 #include "core/html/MediaFragmentURIParser.h" 50 #include "core/html/MediaFragmentURIParser.h"
51 #include "core/html/TimeRanges.h" 51 #include "core/html/TimeRanges.h"
52 #include "core/html/shadow/MediaControls.h" 52 #include "core/html/shadow/MediaControls.h"
53 #include "core/html/track/AudioTrack.h" 53 #include "core/html/track/AudioTrack.h"
54 #include "core/html/track/AudioTrackList.h" 54 #include "core/html/track/AudioTrackList.h"
55 #include "core/html/track/AutomaticTrackSelection.h" 55 #include "core/html/track/AutomaticTrackSelection.h"
56 #include "core/html/track/CueTimeline.h"
56 #include "core/html/track/InbandTextTrack.h" 57 #include "core/html/track/InbandTextTrack.h"
57 #include "core/html/track/TextTrackCueList.h"
58 #include "core/html/track/TextTrackList.h" 58 #include "core/html/track/TextTrackList.h"
59 #include "core/html/track/VideoTrack.h" 59 #include "core/html/track/VideoTrack.h"
60 #include "core/html/track/VideoTrackList.h" 60 #include "core/html/track/VideoTrackList.h"
61 #include "core/layout/compositing/LayerCompositor.h" 61 #include "core/layout/compositing/LayerCompositor.h"
62 #include "core/loader/FrameLoader.h" 62 #include "core/loader/FrameLoader.h"
63 #include "core/rendering/RenderVideo.h" 63 #include "core/rendering/RenderVideo.h"
64 #include "core/rendering/RenderView.h" 64 #include "core/rendering/RenderView.h"
65 #include "platform/ContentType.h" 65 #include "platform/ContentType.h"
66 #include "platform/Logging.h" 66 #include "platform/Logging.h"
67 #include "platform/MIMETypeFromURL.h" 67 #include "platform/MIMETypeFromURL.h"
68 #include "platform/MIMETypeRegistry.h" 68 #include "platform/MIMETypeRegistry.h"
69 #include "platform/RuntimeEnabledFeatures.h" 69 #include "platform/RuntimeEnabledFeatures.h"
70 #include "platform/UserGestureIndicator.h" 70 #include "platform/UserGestureIndicator.h"
71 #include "platform/graphics/GraphicsLayer.h" 71 #include "platform/graphics/GraphicsLayer.h"
72 #include "platform/weborigin/SecurityOrigin.h" 72 #include "platform/weborigin/SecurityOrigin.h"
73 #include "public/platform/Platform.h" 73 #include "public/platform/Platform.h"
74 #include "public/platform/WebContentDecryptionModule.h" 74 #include "public/platform/WebContentDecryptionModule.h"
75 #include "public/platform/WebInbandTextTrack.h" 75 #include "public/platform/WebInbandTextTrack.h"
76 #include "wtf/CurrentTime.h" 76 #include "wtf/CurrentTime.h"
77 #include "wtf/MathExtras.h" 77 #include "wtf/MathExtras.h"
78 #include "wtf/NonCopyingSort.h"
79 #include "wtf/text/CString.h" 78 #include "wtf/text/CString.h"
80 #include <limits> 79 #include <limits>
81 80
82 #if ENABLE(WEB_AUDIO) 81 #if ENABLE(WEB_AUDIO)
83 #include "platform/audio/AudioSourceProvider.h" 82 #include "platform/audio/AudioSourceProvider.h"
84 #include "platform/audio/AudioSourceProviderClient.h" 83 #include "platform/audio/AudioSourceProviderClient.h"
85 #endif 84 #endif
86 85
87 using blink::WebInbandTextTrack; 86 using blink::WebInbandTextTrack;
88 using blink::WebMediaPlayer; 87 using blink::WebMediaPlayer;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 141
143 static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* do cument) 142 static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* do cument)
144 { 143 {
145 DocumentElementSetMap& map = documentToElementSetMap(); 144 DocumentElementSetMap& map = documentToElementSetMap();
146 WeakMediaElementSet set = map.take(document); 145 WeakMediaElementSet set = map.take(document);
147 set.remove(element); 146 set.remove(element);
148 if (!set.isEmpty()) 147 if (!set.isEmpty())
149 map.add(document, set); 148 map.add(document, set);
150 } 149 }
151 150
152 class TrackDisplayUpdateScope {
153 STACK_ALLOCATED();
154 public:
155 TrackDisplayUpdateScope(HTMLMediaElement* mediaElement)
156 {
157 m_mediaElement = mediaElement;
158 m_mediaElement->beginIgnoringTrackDisplayUpdateRequests();
159 }
160 ~TrackDisplayUpdateScope()
161 {
162 ASSERT(m_mediaElement);
163 m_mediaElement->endIgnoringTrackDisplayUpdateRequests();
164 }
165
166 private:
167 RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
168 };
169
170 class AudioSourceProviderClientLockScope { 151 class AudioSourceProviderClientLockScope {
171 STACK_ALLOCATED(); 152 STACK_ALLOCATED();
172 public: 153 public:
173 #if ENABLE(WEB_AUDIO) 154 #if ENABLE(WEB_AUDIO)
174 AudioSourceProviderClientLockScope(HTMLMediaElement& element) 155 AudioSourceProviderClientLockScope(HTMLMediaElement& element)
175 : m_client(element.audioSourceNode()) 156 : m_client(element.audioSourceNode())
176 { 157 {
177 if (m_client) 158 if (m_client)
178 m_client->lock(); 159 m_client->lock();
179 } 160 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 , m_havePreparedToPlay(false) 349 , m_havePreparedToPlay(false)
369 , m_tracksAreReady(true) 350 , m_tracksAreReady(true)
370 , m_haveVisibleTextTrack(false) 351 , m_haveVisibleTextTrack(false)
371 , m_processingPreferenceChange(false) 352 , m_processingPreferenceChange(false)
372 , m_remoteRoutesAvailable(false) 353 , m_remoteRoutesAvailable(false)
373 , m_playingRemotely(false) 354 , m_playingRemotely(false)
374 #if ENABLE(OILPAN) 355 #if ENABLE(OILPAN)
375 , m_isFinalizing(false) 356 , m_isFinalizing(false)
376 , m_closeMediaSourceWhenFinalizing(false) 357 , m_closeMediaSourceWhenFinalizing(false)
377 #endif 358 #endif
378 , m_lastTextTrackUpdateTime(-1)
379 , m_initialPlayWithoutUserGestures(false) 359 , m_initialPlayWithoutUserGestures(false)
380 , m_autoplayMediaCounted(false) 360 , m_autoplayMediaCounted(false)
381 , m_audioTracks(AudioTrackList::create(*this)) 361 , m_audioTracks(AudioTrackList::create(*this))
382 , m_videoTracks(VideoTrackList::create(*this)) 362 , m_videoTracks(VideoTrackList::create(*this))
383 , m_textTracks(nullptr) 363 , m_textTracks(nullptr)
384 , m_ignoreTrackDisplayUpdate(0)
385 #if ENABLE(WEB_AUDIO) 364 #if ENABLE(WEB_AUDIO)
386 , m_audioSourceNode(nullptr) 365 , m_audioSourceNode(nullptr)
387 #endif 366 #endif
388 { 367 {
389 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 368 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
390 369
391 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); 370 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
392 371
393 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) 372 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture())
394 m_userGestureRequiredForPlay = true; 373 m_userGestureRequiredForPlay = true;
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 790
812 // 4.8 - Set the initial playback position to 0. 791 // 4.8 - Set the initial playback position to 0.
813 // FIXME: Make this less subtle. The position only becomes 0 because the ready state is HAVE_NOTHING. 792 // FIXME: Make this less subtle. The position only becomes 0 because the ready state is HAVE_NOTHING.
814 invalidateCachedTime(); 793 invalidateCachedTime();
815 794
816 // 4.9 - Set the timeline offset to Not-a-Number (NaN). 795 // 4.9 - Set the timeline offset to Not-a-Number (NaN).
817 // 4.10 - Update the duration attribute to Not-a-Number (NaN). 796 // 4.10 - Update the duration attribute to Not-a-Number (NaN).
818 797
819 798
820 updateMediaController(); 799 updateMediaController();
821 updateActiveTextTrackCues(0); 800 cueTimeline().updateActiveCues(0);
822 } 801 }
823 802
824 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. 803 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute.
825 setPlaybackRate(defaultPlaybackRate()); 804 setPlaybackRate(defaultPlaybackRate());
826 805
827 // 6 - Set the error attribute to null and the autoplaying flag to true. 806 // 6 - Set the error attribute to null and the autoplaying flag to true.
828 m_error = nullptr; 807 m_error = nullptr;
829 m_autoplaying = true; 808 m_autoplaying = true;
830 809
831 // 7 - Invoke the media element's resource selection algorithm. 810 // 7 - Invoke the media element's resource selection algorithm.
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 { 1112 {
1134 if (m_mediaSource) 1113 if (m_mediaSource)
1135 return WebMediaPlayer::LoadTypeMediaSource; 1114 return WebMediaPlayer::LoadTypeMediaSource;
1136 1115
1137 if (isMediaStreamURL(m_currentSrc.string())) 1116 if (isMediaStreamURL(m_currentSrc.string()))
1138 return WebMediaPlayer::LoadTypeMediaStream; 1117 return WebMediaPlayer::LoadTypeMediaStream;
1139 1118
1140 return WebMediaPlayer::LoadTypeURL; 1119 return WebMediaPlayer::LoadTypeURL;
1141 } 1120 }
1142 1121
1143 static bool trackIndexCompare(TextTrack* a,
1144 TextTrack* b)
1145 {
1146 return a->trackIndex() - b->trackIndex() < 0;
1147 }
1148
1149 static bool eventTimeCueCompare(const std::pair<double, TextTrackCue*>& a,
1150 const std::pair<double, TextTrackCue*>& b)
1151 {
1152 // 12 - Sort the tasks in events in ascending time order (tasks with earlier
1153 // times first).
1154 if (a.first != b.first)
1155 return a.first - b.first < 0;
1156
1157 // If the cues belong to different text tracks, it doesn't make sense to
1158 // compare the two tracks by the relative cue order, so return the relative
1159 // track order.
1160 if (a.second->track() != b.second->track())
1161 return trackIndexCompare(a.second->track(), b.second->track());
1162
1163 // 12 - Further sort tasks in events that have the same time by the
1164 // relative text track cue order of the text track cues associated
1165 // with these tasks.
1166 return a.second->cueIndex() - b.second->cueIndex() < 0;
1167 }
1168
1169
1170 void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
1171 {
1172 // 4.8.10.8 Playing the media resource
1173
1174 // If the current playback position changes while the steps are running,
1175 // then the user agent must wait for the steps to complete, and then must
1176 // immediately rerun the steps.
1177 if (ignoreTrackDisplayUpdateRequests())
1178 return;
1179
1180 // 1 - Let current cues be a list of cues, initialized to contain all the
1181 // cues of all the hidden, showing, or showing by default text tracks of the
1182 // media element (not the disabled ones) whose start times are less than or
1183 // equal to the current playback position and whose end times are greater
1184 // than the current playback position.
1185 CueList currentCues;
1186
1187 // The user agent must synchronously unset [the text track cue active] flag
1188 // whenever ... the media element's readyState is changed back to HAVE_NOTHI NG.
1189 if (m_readyState != HAVE_NOTHING && m_player)
1190 currentCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime));
1191
1192 CueList previousCues;
1193 CueList missedCues;
1194
1195 // 2 - Let other cues be a list of cues, initialized to contain all the cues
1196 // of hidden, showing, and showing by default text tracks of the media
1197 // element that are not present in current cues.
1198 previousCues = m_currentlyActiveCues;
1199
1200 // 3 - Let last time be the current playback position at the time this
1201 // algorithm was last run for this media element, if this is not the first
1202 // time it has run.
1203 double lastTime = m_lastTextTrackUpdateTime;
1204
1205 // 4 - If the current playback position has, since the last time this
1206 // algorithm was run, only changed through its usual monotonic increase
1207 // during normal playback, then let missed cues be the list of cues in other
1208 // cues whose start times are greater than or equal to last time and whose
1209 // end times are less than or equal to the current playback position.
1210 // Otherwise, let missed cues be an empty list.
1211 if (lastTime >= 0 && m_lastSeekTime < movieTime) {
1212 CueList potentiallySkippedCues =
1213 m_cueTree.allOverlaps(m_cueTree.createInterval(lastTime, movieTime)) ;
1214
1215 for (CueInterval cue : potentiallySkippedCues) {
1216 // Consider cues that may have been missed since the last seek time.
1217 if (cue.low() > std::max(m_lastSeekTime, lastTime) && cue.high() < m ovieTime)
1218 missedCues.append(cue);
1219 }
1220 }
1221
1222 m_lastTextTrackUpdateTime = movieTime;
1223
1224 // 5 - If the time was reached through the usual monotonic increase of the
1225 // current playback position during normal playback, and if the user agent
1226 // has not fired a timeupdate event at the element in the past 15 to 250ms
1227 // and is not still running event handlers for such an event, then the user
1228 // agent must queue a task to fire a simple event named timeupdate at the
1229 // element. (In the other cases, such as explicit seeks, relevant events get
1230 // fired as part of the overall process of changing the current playback
1231 // position.)
1232 if (!m_seeking && m_lastSeekTime < lastTime)
1233 scheduleTimeupdateEvent(true);
1234
1235 // Explicitly cache vector sizes, as their content is constant from here.
1236 size_t currentCuesSize = currentCues.size();
1237 size_t missedCuesSize = missedCues.size();
1238 size_t previousCuesSize = previousCues.size();
1239
1240 // 6 - If all of the cues in current cues have their text track cue active
1241 // flag set, none of the cues in other cues have their text track cue active
1242 // flag set, and missed cues is empty, then abort these steps.
1243 bool activeSetChanged = missedCuesSize;
1244
1245 for (size_t i = 0; !activeSetChanged && i < previousCuesSize; ++i) {
1246 if (!currentCues.contains(previousCues[i]) && previousCues[i].data()->is Active())
1247 activeSetChanged = true;
1248 }
1249
1250 for (CueInterval currentCue : currentCues) {
1251 currentCue.data()->updateDisplayTree(movieTime);
1252
1253 if (!currentCue.data()->isActive())
1254 activeSetChanged = true;
1255 }
1256
1257 if (!activeSetChanged)
1258 return;
1259
1260 // 7 - If the time was reached through the usual monotonic increase of the
1261 // current playback position during normal playback, and there are cues in
1262 // other cues that have their text track cue pause-on-exi flag set and that
1263 // either have their text track cue active flag set or are also in missed
1264 // cues, then immediately pause the media element.
1265 for (size_t i = 0; !m_paused && i < previousCuesSize; ++i) {
1266 if (previousCues[i].data()->pauseOnExit()
1267 && previousCues[i].data()->isActive()
1268 && !currentCues.contains(previousCues[i]))
1269 pause();
1270 }
1271
1272 for (size_t i = 0; !m_paused && i < missedCuesSize; ++i) {
1273 if (missedCues[i].data()->pauseOnExit())
1274 pause();
1275 }
1276
1277 // 8 - Let events be a list of tasks, initially empty. Each task in this
1278 // list will be associated with a text track, a text track cue, and a time,
1279 // which are used to sort the list before the tasks are queued.
1280 WillBeHeapVector<std::pair<double, RawPtrWillBeMember<TextTrackCue>>> eventT asks;
1281
1282 // 8 - Let affected tracks be a list of text tracks, initially empty.
1283 WillBeHeapVector<RawPtrWillBeMember<TextTrack>> affectedTracks;
1284
1285 for (size_t i = 0; i < missedCuesSize; ++i) {
1286 // 9 - For each text track cue in missed cues, prepare an event named en ter
1287 // for the TextTrackCue object with the text track cue start time.
1288 eventTasks.append(std::make_pair(missedCues[i].data()->startTime(),
1289 missedCues[i].data()));
1290
1291 // 10 - For each text track [...] in missed cues, prepare an event
1292 // named exit for the TextTrackCue object with the with the later of
1293 // the text track cue end time and the text track cue start time.
1294
1295 // Note: An explicit task is added only if the cue is NOT a zero or
1296 // negative length cue. Otherwise, the need for an exit event is
1297 // checked when these tasks are actually queued below. This doesn't
1298 // affect sorting events before dispatch either, because the exit
1299 // event has the same time as the enter event.
1300 if (missedCues[i].data()->startTime() < missedCues[i].data()->endTime())
1301 eventTasks.append(std::make_pair(missedCues[i].data()->endTime(),
1302 missedCues[i].data()));
1303 }
1304
1305 for (size_t i = 0; i < previousCuesSize; ++i) {
1306 // 10 - For each text track cue in other cues that has its text
1307 // track cue active flag set prepare an event named exit for the
1308 // TextTrackCue object with the text track cue end time.
1309 if (!currentCues.contains(previousCues[i]))
1310 eventTasks.append(std::make_pair(previousCues[i].data()->endTime(),
1311 previousCues[i].data()));
1312 }
1313
1314 for (size_t i = 0; i < currentCuesSize; ++i) {
1315 // 11 - For each text track cue in current cues that does not have its
1316 // text track cue active flag set, prepare an event named enter for the
1317 // TextTrackCue object with the text track cue start time.
1318 if (!previousCues.contains(currentCues[i]))
1319 eventTasks.append(std::make_pair(currentCues[i].data()->startTime(),
1320 currentCues[i].data()));
1321 }
1322
1323 // 12 - Sort the tasks in events in ascending time order (tasks with earlier
1324 // times first).
1325 nonCopyingSort(eventTasks.begin(), eventTasks.end(), eventTimeCueCompare);
1326
1327 for (size_t i = 0; i < eventTasks.size(); ++i) {
1328 if (!affectedTracks.contains(eventTasks[i].second->track()))
1329 affectedTracks.append(eventTasks[i].second->track());
1330
1331 // 13 - Queue each task in events, in list order.
1332 RefPtrWillBeRawPtr<Event> event = nullptr;
1333
1334 // Each event in eventTasks may be either an enterEvent or an exitEvent,
1335 // depending on the time that is associated with the event. This
1336 // correctly identifies the type of the event, if the startTime is
1337 // less than the endTime in the cue.
1338 if (eventTasks[i].second->startTime() >= eventTasks[i].second->endTime() ) {
1339 event = Event::create(EventTypeNames::enter);
1340 event->setTarget(eventTasks[i].second);
1341 m_asyncEventQueue->enqueueEvent(event.release());
1342
1343 event = Event::create(EventTypeNames::exit);
1344 event->setTarget(eventTasks[i].second);
1345 m_asyncEventQueue->enqueueEvent(event.release());
1346 } else {
1347 if (eventTasks[i].first == eventTasks[i].second->startTime())
1348 event = Event::create(EventTypeNames::enter);
1349 else
1350 event = Event::create(EventTypeNames::exit);
1351
1352 event->setTarget(eventTasks[i].second);
1353 m_asyncEventQueue->enqueueEvent(event.release());
1354 }
1355 }
1356
1357 // 14 - Sort affected tracks in the same order as the text tracks appear in
1358 // the media element's list of text tracks, and remove duplicates.
1359 nonCopyingSort(affectedTracks.begin(), affectedTracks.end(), trackIndexCompa re);
1360
1361 // 15 - For each text track in affected tracks, in the list order, queue a
1362 // task to fire a simple event named cuechange at the TextTrack object, and, ...
1363 for (size_t i = 0; i < affectedTracks.size(); ++i) {
1364 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechang e);
1365 event->setTarget(affectedTracks[i]);
1366
1367 m_asyncEventQueue->enqueueEvent(event.release());
1368
1369 // ... if the text track has a corresponding track element, to then fire a
1370 // simple event named cuechange at the track element as well.
1371 if (affectedTracks[i]->trackType() == TextTrack::TrackElement) {
1372 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuec hange);
1373 HTMLTrackElement* trackElement = static_cast<LoadableTextTrack*>(aff ectedTracks[i].get())->trackElement();
1374 ASSERT(trackElement);
1375 event->setTarget(trackElement);
1376
1377 m_asyncEventQueue->enqueueEvent(event.release());
1378 }
1379 }
1380
1381 // 16 - Set the text track cue active flag of all the cues in the current
1382 // cues, and unset the text track cue active flag of all the cues in the
1383 // other cues.
1384 for (size_t i = 0; i < currentCuesSize; ++i)
1385 currentCues[i].data()->setIsActive(true);
1386
1387 for (size_t i = 0; i < previousCuesSize; ++i) {
1388 if (!currentCues.contains(previousCues[i]))
1389 previousCues[i].data()->setIsActive(false);
1390 }
1391
1392 // Update the current active cues.
1393 m_currentlyActiveCues = currentCues;
1394
1395 if (activeSetChanged)
1396 updateTextTrackDisplay();
1397 }
1398
1399 bool HTMLMediaElement::textTracksAreReady() const 1122 bool HTMLMediaElement::textTracksAreReady() const
1400 { 1123 {
1401 // 4.8.10.12.1 Text track model 1124 // 4.8.10.12.1 Text track model
1402 // ... 1125 // ...
1403 // The text tracks of a media element are ready if all the text tracks whose mode was not 1126 // The text tracks of a media element are ready if all the text tracks whose mode was not
1404 // in the disabled state when the element's resource selection algorithm las t started now 1127 // in the disabled state when the element's resource selection algorithm las t started now
1405 // have a text track readiness state of loaded or failed to load. 1128 // have a text track readiness state of loaded or failed to load.
1406 for (unsigned i = 0; i < m_textTracksWhenResourceSelectionBegan.size(); ++i) { 1129 for (unsigned i = 0; i < m_textTracksWhenResourceSelectionBegan.size(); ++i) {
1407 if (m_textTracksWhenResourceSelectionBegan[i]->readinessState() == TextT rack::Loading 1130 if (m_textTracksWhenResourceSelectionBegan[i]->readinessState() == TextT rack::Loading
1408 || m_textTracksWhenResourceSelectionBegan[i]->readinessState() == Te xtTrack::NotLoaded) 1131 || m_textTracksWhenResourceSelectionBegan[i]->readinessState() == Te xtTrack::NotLoaded)
(...skipping 27 matching lines...) Expand all
1436 // run the following algorithm ... 1159 // run the following algorithm ...
1437 1160
1438 for (HTMLTrackElement* trackElement = Traversal<HTMLTrackElement>::first Child(*this); trackElement; trackElement = Traversal<HTMLTrackElement>::nextSibl ing(*trackElement)) { 1161 for (HTMLTrackElement* trackElement = Traversal<HTMLTrackElement>::first Child(*this); trackElement; trackElement = Traversal<HTMLTrackElement>::nextSibl ing(*trackElement)) {
1439 if (trackElement->track() != track) 1162 if (trackElement->track() != track)
1440 continue; 1163 continue;
1441 1164
1442 // Mark this track as "configured" so configureTextTracks won't chan ge the mode again. 1165 // Mark this track as "configured" so configureTextTracks won't chan ge the mode again.
1443 track->setHasBeenConfigured(true); 1166 track->setHasBeenConfigured(true);
1444 if (track->mode() != TextTrack::disabledKeyword()) { 1167 if (track->mode() != TextTrack::disabledKeyword()) {
1445 if (trackElement->readyState() == HTMLTrackElement::LOADED) 1168 if (trackElement->readyState() == HTMLTrackElement::LOADED)
1446 textTrackAddCues(track, track->cues()); 1169 cueTimeline().addCues(track, track->cues());
1447 1170
1448 // If this is the first added track, create the list of text tra cks. 1171 // If this is the first added track, create the list of text tra cks.
1449 if (!m_textTracks) 1172 if (!m_textTracks)
1450 m_textTracks = TextTrackList::create(this); 1173 m_textTracks = TextTrackList::create(this);
1451 } 1174 }
1452 break; 1175 break;
1453 } 1176 }
1454 } else if (track->trackType() == TextTrack::AddTrack && track->mode() != Tex tTrack::disabledKeyword()) { 1177 } else if (track->trackType() == TextTrack::AddTrack && track->mode() != Tex tTrack::disabledKeyword()) {
1455 textTrackAddCues(track, track->cues()); 1178 cueTimeline().addCues(track, track->cues());
1456 } 1179 }
1457 1180
1458 configureTextTrackDisplay(AssumeVisibleChange); 1181 configureTextTrackDisplay(AssumeVisibleChange);
1459 1182
1460 ASSERT(textTracks()->contains(track)); 1183 ASSERT(textTracks()->contains(track));
1461 textTracks()->scheduleChangeEvent(); 1184 textTracks()->scheduleChangeEvent();
1462 } 1185 }
1463 1186
1464 void HTMLMediaElement::textTrackKindChanged(TextTrack* track) 1187 void HTMLMediaElement::textTrackKindChanged(TextTrack* track)
1465 { 1188 {
1466 if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTr ack::subtitlesKeyword() && track->mode() == TextTrack::showingKeyword()) 1189 if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTr ack::subtitlesKeyword() && track->mode() == TextTrack::showingKeyword())
1467 track->setMode(TextTrack::hiddenKeyword()); 1190 track->setMode(TextTrack::hiddenKeyword());
1468 } 1191 }
1469 1192
1470 void HTMLMediaElement::beginIgnoringTrackDisplayUpdateRequests()
1471 {
1472 ++m_ignoreTrackDisplayUpdate;
1473 }
1474
1475 void HTMLMediaElement::endIgnoringTrackDisplayUpdateRequests()
1476 {
1477 ASSERT(m_ignoreTrackDisplayUpdate);
1478 --m_ignoreTrackDisplayUpdate;
1479 if (!m_ignoreTrackDisplayUpdate && inActiveDocument())
1480 updateActiveTextTrackCues(currentTime());
1481 }
1482
1483 void HTMLMediaElement::textTrackAddCues(TextTrack* track, const TextTrackCueList * cues)
1484 {
1485 WTF_LOG(Media, "HTMLMediaElement::textTrackAddCues(%p)", this);
1486 ASSERT(track->mode() != TextTrack::disabledKeyword());
1487
1488 TrackDisplayUpdateScope scope(this);
1489 for (size_t i = 0; i < cues->length(); ++i)
1490 textTrackAddCue(cues->item(i)->track(), cues->item(i));
1491 }
1492
1493 void HTMLMediaElement::textTrackRemoveCues(TextTrack*, const TextTrackCueList* c ues)
1494 {
1495 WTF_LOG(Media, "HTMLMediaElement::textTrackRemoveCues(%p)", this);
1496
1497 TrackDisplayUpdateScope scope(this);
1498 for (size_t i = 0; i < cues->length(); ++i)
1499 textTrackRemoveCue(cues->item(i)->track(), cues->item(i));
1500 }
1501
1502 void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtrWillBeRawPtr< TextTrackCue> cue)
1503 {
1504 ASSERT(track->mode() != TextTrack::disabledKeyword());
1505
1506 // Negative duration cues need be treated in the interval tree as
1507 // zero-length cues.
1508 double endTime = std::max(cue->startTime(), cue->endTime());
1509
1510 CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, c ue.get());
1511 if (!m_cueTree.contains(interval))
1512 m_cueTree.add(interval);
1513 updateActiveTextTrackCues(currentTime());
1514 }
1515
1516 void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<Tex tTrackCue> cue)
1517 {
1518 // Negative duration cues need to be treated in the interval tree as
1519 // zero-length cues.
1520 double endTime = std::max(cue->startTime(), cue->endTime());
1521
1522 CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, c ue.get());
1523 m_cueTree.remove(interval);
1524
1525 // Since the cue will be removed from the media element and likely the
1526 // TextTrack might also be destructed, notifying the region of the cue
1527 // removal shouldn't be done.
1528 cue->notifyRegionWhenRemovingDisplayTree(false);
1529
1530 size_t index = m_currentlyActiveCues.find(interval);
1531 if (index != kNotFound) {
1532 m_currentlyActiveCues.remove(index);
1533 cue->setIsActive(false);
1534 }
1535 cue->removeDisplayTree();
1536 updateActiveTextTrackCues(currentTime());
1537
1538 cue->notifyRegionWhenRemovingDisplayTree(true);
1539 }
1540
1541
1542 bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidURLAction actionI fInvalid) 1193 bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidURLAction actionI fInvalid)
1543 { 1194 {
1544 if (!url.isValid()) { 1195 if (!url.isValid()) {
1545 WTF_LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%p, %s) -> FALSE becau se url is invalid", this, urlForLoggingMedia(url).utf8().data()); 1196 WTF_LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%p, %s) -> FALSE becau se url is invalid", this, urlForLoggingMedia(url).utf8().data());
1546 return false; 1197 return false;
1547 } 1198 }
1548 1199
1549 LocalFrame* frame = document().frame(); 1200 LocalFrame* frame = document().frame();
1550 if (!frame || !document().securityOrigin()->canDisplay(url)) { 1201 if (!frame || !document().securityOrigin()->canDisplay(url)) {
1551 if (actionIfInvalid == Complain) 1202 if (actionIfInvalid == Complain)
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 } 1573 }
1923 1574
1924 if (shouldUpdateDisplayState) { 1575 if (shouldUpdateDisplayState) {
1925 updateDisplayState(); 1576 updateDisplayState();
1926 if (hasMediaControls()) 1577 if (hasMediaControls())
1927 mediaControls()->refreshClosedCaptionsButtonVisibility(); 1578 mediaControls()->refreshClosedCaptionsButtonVisibility();
1928 } 1579 }
1929 1580
1930 updatePlayState(); 1581 updatePlayState();
1931 updateMediaController(); 1582 updateMediaController();
1932 updateActiveTextTrackCues(currentTime()); 1583 cueTimeline().updateActiveCues(currentTime());
1933 } 1584 }
1934 1585
1935 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) 1586 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
1936 { 1587 {
1937 ASSERT(m_player); 1588 ASSERT(m_player);
1938 if (m_networkState != NETWORK_LOADING) 1589 if (m_networkState != NETWORK_LOADING)
1939 return; 1590 return;
1940 1591
1941 double time = WTF::currentTime(); 1592 double time = WTF::currentTime();
1942 double timedelta = time - m_previousProgressTime; 1593 double timedelta = time - m_previousProgressTime;
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 2162
2512 if (!m_seeking) 2163 if (!m_seeking)
2513 scheduleTimeupdateEvent(true); 2164 scheduleTimeupdateEvent(true);
2514 2165
2515 if (!effectivePlaybackRate()) 2166 if (!effectivePlaybackRate())
2516 return; 2167 return;
2517 2168
2518 if (!m_paused && hasMediaControls()) 2169 if (!m_paused && hasMediaControls())
2519 mediaControls()->playbackProgressed(); 2170 mediaControls()->playbackProgressed();
2520 2171
2521 updateActiveTextTrackCues(currentTime()); 2172 cueTimeline().updateActiveCues(currentTime());
2522 } 2173 }
2523 2174
2524 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) 2175 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
2525 { 2176 {
2526 double now = WTF::currentTime(); 2177 double now = WTF::currentTime();
2527 double movieTime = currentTime(); 2178 double movieTime = currentTime();
2528 2179
2529 bool haveNotRecentlyFiredTimeupdate = (now - m_lastTimeUpdateEventWallTime) >= maxTimeupdateEventFrequency; 2180 bool haveNotRecentlyFiredTimeupdate = (now - m_lastTimeUpdateEventWallTime) >= maxTimeupdateEventFrequency;
2530 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime; 2181 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime;
2531 2182
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 2372
2722 void HTMLMediaElement::addTextTrack(TextTrack* track) 2373 void HTMLMediaElement::addTextTrack(TextTrack* track)
2723 { 2374 {
2724 textTracks()->append(track); 2375 textTracks()->append(track);
2725 2376
2726 textTracksChanged(); 2377 textTracksChanged();
2727 } 2378 }
2728 2379
2729 void HTMLMediaElement::removeTextTrack(TextTrack* track) 2380 void HTMLMediaElement::removeTextTrack(TextTrack* track)
2730 { 2381 {
2731 TrackDisplayUpdateScope scope(this); 2382 TrackDisplayUpdateScope scope(this->cueTimeline());
2732 m_textTracks->remove(track); 2383 m_textTracks->remove(track);
2733 2384
2734 textTracksChanged(); 2385 textTracksChanged();
2735 } 2386 }
2736 2387
2737 void HTMLMediaElement::forgetResourceSpecificTracks() 2388 void HTMLMediaElement::forgetResourceSpecificTracks()
2738 { 2389 {
2739 // Implements the "forget the media element's media-resource-specific tracks " algorithm. 2390 // Implements the "forget the media element's media-resource-specific tracks " algorithm.
2740 // The order is explicitly specified as text, then audio, and finally video. Also 2391 // The order is explicitly specified as text, then audio, and finally video. Also
2741 // 'removetrack' events should not be fired. 2392 // 'removetrack' events should not be fired.
2742 if (m_textTracks) { 2393 if (m_textTracks) {
2743 TrackDisplayUpdateScope scope(this); 2394 TrackDisplayUpdateScope scope(this->cueTimeline());
2744 m_textTracks->removeAllInbandTracks(); 2395 m_textTracks->removeAllInbandTracks();
2745 textTracksChanged(); 2396 textTracksChanged();
2746 } 2397 }
2747 2398
2748 m_audioTracks->removeAll(); 2399 m_audioTracks->removeAll();
2749 m_videoTracks->removeAll(); 2400 m_videoTracks->removeAll();
2750 2401
2751 m_audioTracksTimer.stop(); 2402 m_audioTracksTimer.stop();
2752 } 2403 }
2753 2404
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
3038 // inserted in a video or audio element will have no effect. 2689 // inserted in a video or audio element will have no effect.
3039 m_currentSourceNode = nullptr; 2690 m_currentSourceNode = nullptr;
3040 WTF_LOG(Media, "HTMLMediaElement::sourceRemoved(%p) - m_currentSourceNod e set to 0", this); 2691 WTF_LOG(Media, "HTMLMediaElement::sourceRemoved(%p) - m_currentSourceNod e set to 0", this);
3041 } 2692 }
3042 } 2693 }
3043 2694
3044 void HTMLMediaElement::mediaPlayerTimeChanged() 2695 void HTMLMediaElement::mediaPlayerTimeChanged()
3045 { 2696 {
3046 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged(%p)", this); 2697 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged(%p)", this);
3047 2698
3048 updateActiveTextTrackCues(currentTime()); 2699 cueTimeline().updateActiveCues(currentTime());
3049 2700
3050 invalidateCachedTime(); 2701 invalidateCachedTime();
3051 2702
3052 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with t he seek. 2703 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with t he seek.
3053 if (m_seeking && m_readyState >= HAVE_CURRENT_DATA && !webMediaPlayer()->see king()) 2704 if (m_seeking && m_readyState >= HAVE_CURRENT_DATA && !webMediaPlayer()->see king())
3054 finishSeek(); 2705 finishSeek();
3055 2706
3056 // Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity, 2707 // Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity,
3057 // it will only queue a 'timeupdate' event if we haven't already posted one at the current 2708 // it will only queue a 'timeupdate' event if we haven't already posted one at the current
3058 // movie time. 2709 // movie time.
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 // 5 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. 3033 // 5 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event.
3383 setShouldDelayLoadEvent(false); 3034 setShouldDelayLoadEvent(false);
3384 3035
3385 // 6 - Abort the overall resource selection algorithm. 3036 // 6 - Abort the overall resource selection algorithm.
3386 m_currentSourceNode = nullptr; 3037 m_currentSourceNode = nullptr;
3387 3038
3388 // Reset m_readyState since m_player is gone. 3039 // Reset m_readyState since m_player is gone.
3389 m_readyState = HAVE_NOTHING; 3040 m_readyState = HAVE_NOTHING;
3390 invalidateCachedTime(); 3041 invalidateCachedTime();
3391 updateMediaController(); 3042 updateMediaController();
3392 updateActiveTextTrackCues(0); 3043 cueTimeline().updateActiveCues(0);
3393 } 3044 }
3394 3045
3395 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() 3046 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g()
3396 { 3047 {
3397 #if ENABLE(WEB_AUDIO) 3048 #if ENABLE(WEB_AUDIO)
3398 if (audioSourceProvider()) 3049 if (audioSourceProvider())
3399 audioSourceProvider()->setClient(0); 3050 audioSourceProvider()->setClient(0);
3400 #endif 3051 #endif
3401 m_player.clear(); 3052 m_player.clear();
3402 } 3053 }
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
3681 } 3332 }
3682 3333
3683 ensureMediaControls(); 3334 ensureMediaControls();
3684 mediaControls()->reset(); 3335 mediaControls()->reset();
3685 if (shouldShowControls()) 3336 if (shouldShowControls())
3686 mediaControls()->show(); 3337 mediaControls()->show();
3687 else 3338 else
3688 mediaControls()->hide(); 3339 mediaControls()->hide();
3689 } 3340 }
3690 3341
3342 CueTimeline& HTMLMediaElement::cueTimeline()
3343 {
3344 if (!m_cueTimeline)
3345 m_cueTimeline = adoptPtrWillBeNoop(new CueTimeline(*this));
3346 return *m_cueTimeline;
3347 }
3348
3691 void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu mption) 3349 void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu mption)
3692 { 3350 {
3693 ASSERT(m_textTracks); 3351 ASSERT(m_textTracks);
3694 WTF_LOG(Media, "HTMLMediaElement::configureTextTrackDisplay(%p)", this); 3352 WTF_LOG(Media, "HTMLMediaElement::configureTextTrackDisplay(%p)", this);
3695 3353
3696 if (m_processingPreferenceChange) 3354 if (m_processingPreferenceChange)
3697 return; 3355 return;
3698 3356
3699 bool haveVisibleTextTrack = false; 3357 bool haveVisibleTextTrack = false;
3700 for (unsigned i = 0; i < m_textTracks->length(); ++i) { 3358 for (unsigned i = 0; i < m_textTracks->length(); ++i) {
3701 if (m_textTracks->item(i)->mode() == TextTrack::showingKeyword()) { 3359 if (m_textTracks->item(i)->mode() == TextTrack::showingKeyword()) {
3702 haveVisibleTextTrack = true; 3360 haveVisibleTextTrack = true;
3703 break; 3361 break;
3704 } 3362 }
3705 } 3363 }
3706 3364
3707 if (assumption == AssumeNoVisibleChange 3365 if (assumption == AssumeNoVisibleChange
3708 && m_haveVisibleTextTrack == haveVisibleTextTrack) { 3366 && m_haveVisibleTextTrack == haveVisibleTextTrack) {
3709 updateActiveTextTrackCues(currentTime()); 3367 cueTimeline().updateActiveCues(currentTime());
3710 return; 3368 return;
3711 } 3369 }
3712 m_haveVisibleTextTrack = haveVisibleTextTrack; 3370 m_haveVisibleTextTrack = haveVisibleTextTrack;
3713 m_closedCaptionsVisible = m_haveVisibleTextTrack; 3371 m_closedCaptionsVisible = m_haveVisibleTextTrack;
3714 3372
3715 if (!m_haveVisibleTextTrack && !hasMediaControls()) 3373 if (!m_haveVisibleTextTrack && !hasMediaControls())
3716 return; 3374 return;
3717 3375
3718 ensureMediaControls(); 3376 ensureMediaControls();
3719 mediaControls()->changedClosedCaptionsVisibility(); 3377 mediaControls()->changedClosedCaptionsVisibility();
3720 3378
3721 updateActiveTextTrackCues(currentTime()); 3379 cueTimeline().updateActiveCues(currentTime());
3722 updateTextTrackDisplay(); 3380 updateTextTrackDisplay();
3723 } 3381 }
3724 3382
3725 void* HTMLMediaElement::preDispatchEventHandler(Event* event) 3383 void* HTMLMediaElement::preDispatchEventHandler(Event* event)
3726 { 3384 {
3727 if (event && event->type() == EventTypeNames::webkitfullscreenchange) 3385 if (event && event->type() == EventTypeNames::webkitfullscreenchange)
3728 configureMediaControls(); 3386 configureMediaControls();
3729 3387
3730 return nullptr; 3388 return nullptr;
3731 } 3389 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3921 { 3579 {
3922 #if ENABLE(OILPAN) 3580 #if ENABLE(OILPAN)
3923 visitor->trace(m_playedTimeRanges); 3581 visitor->trace(m_playedTimeRanges);
3924 visitor->trace(m_asyncEventQueue); 3582 visitor->trace(m_asyncEventQueue);
3925 visitor->trace(m_error); 3583 visitor->trace(m_error);
3926 visitor->trace(m_currentSourceNode); 3584 visitor->trace(m_currentSourceNode);
3927 visitor->trace(m_nextChildNodeToConsider); 3585 visitor->trace(m_nextChildNodeToConsider);
3928 visitor->trace(m_mediaSource); 3586 visitor->trace(m_mediaSource);
3929 visitor->trace(m_audioTracks); 3587 visitor->trace(m_audioTracks);
3930 visitor->trace(m_videoTracks); 3588 visitor->trace(m_videoTracks);
3589 visitor->trace(m_cueTimeline);
3931 visitor->trace(m_textTracks); 3590 visitor->trace(m_textTracks);
3932 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3591 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3933 visitor->trace(m_mediaController); 3592 visitor->trace(m_mediaController);
3934 #if ENABLE(WEB_AUDIO) 3593 #if ENABLE(WEB_AUDIO)
3935 visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakM embers>(this); 3594 visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakM embers>(this);
3936 #endif 3595 #endif
3937 HeapSupplementable<HTMLMediaElement>::trace(visitor); 3596 HeapSupplementable<HTMLMediaElement>::trace(visitor);
3938 #endif 3597 #endif
3939 HTMLElement::trace(visitor); 3598 HTMLElement::trace(visitor);
3940 ActiveDOMObject::trace(visitor); 3599 ActiveDOMObject::trace(visitor);
(...skipping 29 matching lines...) Expand all
3970 3629
3971 #if ENABLE(WEB_AUDIO) 3630 #if ENABLE(WEB_AUDIO)
3972 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3631 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3973 { 3632 {
3974 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) 3633 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider())
3975 audioSourceProvider()->setClient(nullptr); 3634 audioSourceProvider()->setClient(nullptr);
3976 } 3635 }
3977 #endif 3636 #endif
3978 3637
3979 } 3638 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698