OLD | NEW |
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 // Default to not logging warnings about excessive drift in the cached media tim
e because it adds a | 118 // Default to not logging warnings about excessive drift in the cached media tim
e because it adds a |
119 // fair amount of overhead and logging. | 119 // fair amount of overhead and logging. |
120 #define LOG_CACHED_TIME_WARNINGS 0 | 120 #define LOG_CACHED_TIME_WARNINGS 0 |
121 #endif | 121 #endif |
122 | 122 |
123 // URL protocol used to signal that the media source API is being used. | 123 // URL protocol used to signal that the media source API is being used. |
124 static const char mediaSourceBlobProtocol[] = "blob"; | 124 static const char mediaSourceBlobProtocol[] = "blob"; |
125 | 125 |
126 using namespace HTMLNames; | 126 using namespace HTMLNames; |
127 | 127 |
128 typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<HTMLMediaElement> > WeakMediaEl
ementSet; | 128 typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<HTMLMediaElement>> WeakMediaEle
mentSet; |
129 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Document>, WeakMediaElementSet>
DocumentElementSetMap; | 129 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Document>, WeakMediaElementSet>
DocumentElementSetMap; |
130 static DocumentElementSetMap& documentToElementSetMap() | 130 static DocumentElementSetMap& documentToElementSetMap() |
131 { | 131 { |
132 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<DocumentElementSetMap>, map, (ado
ptPtrWillBeNoop(new DocumentElementSetMap()))); | 132 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<DocumentElementSetMap>, map, (ado
ptPtrWillBeNoop(new DocumentElementSetMap()))); |
133 return *map; | 133 return *map; |
134 } | 134 } |
135 | 135 |
136 static void addElementToDocumentMap(HTMLMediaElement* element, Document* documen
t) | 136 static void addElementToDocumentMap(HTMLMediaElement* element, Document* documen
t) |
137 { | 137 { |
138 DocumentElementSetMap& map = documentToElementSetMap(); | 138 DocumentElementSetMap& map = documentToElementSetMap(); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 , m_volume(1.0f) | 320 , m_volume(1.0f) |
321 , m_lastSeekTime(0) | 321 , m_lastSeekTime(0) |
322 , m_previousProgressTime(std::numeric_limits<double>::max()) | 322 , m_previousProgressTime(std::numeric_limits<double>::max()) |
323 , m_duration(std::numeric_limits<double>::quiet_NaN()) | 323 , m_duration(std::numeric_limits<double>::quiet_NaN()) |
324 , m_lastTimeUpdateEventWallTime(0) | 324 , m_lastTimeUpdateEventWallTime(0) |
325 , m_lastTimeUpdateEventMovieTime(0) | 325 , m_lastTimeUpdateEventMovieTime(0) |
326 , m_defaultPlaybackStartPosition(0) | 326 , m_defaultPlaybackStartPosition(0) |
327 , m_loadState(WaitingForSource) | 327 , m_loadState(WaitingForSource) |
328 , m_deferredLoadState(NotDeferred) | 328 , m_deferredLoadState(NotDeferred) |
329 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) | 329 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) |
330 , m_webLayer(0) | 330 , m_webLayer(nullptr) |
331 , m_preload(MediaPlayer::Auto) | 331 , m_preload(MediaPlayer::Auto) |
332 , m_displayMode(Unknown) | 332 , m_displayMode(Unknown) |
333 , m_cachedTime(MediaPlayer::invalidTime()) | 333 , m_cachedTime(MediaPlayer::invalidTime()) |
334 , m_fragmentEndTime(MediaPlayer::invalidTime()) | 334 , m_fragmentEndTime(MediaPlayer::invalidTime()) |
335 , m_pendingActionFlags(0) | 335 , m_pendingActionFlags(0) |
336 , m_userGestureRequiredForPlay(false) | 336 , m_userGestureRequiredForPlay(false) |
337 , m_playing(false) | 337 , m_playing(false) |
338 , m_shouldDelayLoadEvent(false) | 338 , m_shouldDelayLoadEvent(false) |
339 , m_haveFiredLoadedData(false) | 339 , m_haveFiredLoadedData(false) |
340 , m_active(true) | 340 , m_active(true) |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 // 4 - If the current playback position has, since the last time this | 1181 // 4 - If the current playback position has, since the last time this |
1182 // algorithm was run, only changed through its usual monotonic increase | 1182 // algorithm was run, only changed through its usual monotonic increase |
1183 // during normal playback, then let missed cues be the list of cues in other | 1183 // during normal playback, then let missed cues be the list of cues in other |
1184 // cues whose start times are greater than or equal to last time and whose | 1184 // cues whose start times are greater than or equal to last time and whose |
1185 // end times are less than or equal to the current playback position. | 1185 // end times are less than or equal to the current playback position. |
1186 // Otherwise, let missed cues be an empty list. | 1186 // Otherwise, let missed cues be an empty list. |
1187 if (lastTime >= 0 && m_lastSeekTime < movieTime) { | 1187 if (lastTime >= 0 && m_lastSeekTime < movieTime) { |
1188 CueList potentiallySkippedCues = | 1188 CueList potentiallySkippedCues = |
1189 m_cueTree.allOverlaps(m_cueTree.createInterval(lastTime, movieTime))
; | 1189 m_cueTree.allOverlaps(m_cueTree.createInterval(lastTime, movieTime))
; |
1190 | 1190 |
1191 for (size_t i = 0; i < potentiallySkippedCues.size(); ++i) { | 1191 for (CueInterval cue : potentiallySkippedCues) { |
1192 double cueStartTime = potentiallySkippedCues[i].low(); | |
1193 double cueEndTime = potentiallySkippedCues[i].high(); | |
1194 | |
1195 // Consider cues that may have been missed since the last seek time. | 1192 // Consider cues that may have been missed since the last seek time. |
1196 if (cueStartTime > std::max(m_lastSeekTime, lastTime) && cueEndTime
< movieTime) | 1193 if (cue.low() > std::max(m_lastSeekTime, lastTime) && cue.high() < m
ovieTime) |
1197 missedCues.append(potentiallySkippedCues[i]); | 1194 missedCues.append(cue); |
1198 } | 1195 } |
1199 } | 1196 } |
1200 | 1197 |
1201 m_lastTextTrackUpdateTime = movieTime; | 1198 m_lastTextTrackUpdateTime = movieTime; |
1202 | 1199 |
1203 // 5 - If the time was reached through the usual monotonic increase of the | 1200 // 5 - If the time was reached through the usual monotonic increase of the |
1204 // current playback position during normal playback, and if the user agent | 1201 // current playback position during normal playback, and if the user agent |
1205 // has not fired a timeupdate event at the element in the past 15 to 250ms | 1202 // has not fired a timeupdate event at the element in the past 15 to 250ms |
1206 // and is not still running event handlers for such an event, then the user | 1203 // and is not still running event handlers for such an event, then the user |
1207 // agent must queue a task to fire a simple event named timeupdate at the | 1204 // agent must queue a task to fire a simple event named timeupdate at the |
(...skipping 11 matching lines...) Expand all Loading... |
1219 // 6 - If all of the cues in current cues have their text track cue active | 1216 // 6 - If all of the cues in current cues have their text track cue active |
1220 // flag set, none of the cues in other cues have their text track cue active | 1217 // flag set, none of the cues in other cues have their text track cue active |
1221 // flag set, and missed cues is empty, then abort these steps. | 1218 // flag set, and missed cues is empty, then abort these steps. |
1222 bool activeSetChanged = missedCuesSize; | 1219 bool activeSetChanged = missedCuesSize; |
1223 | 1220 |
1224 for (size_t i = 0; !activeSetChanged && i < previousCuesSize; ++i) { | 1221 for (size_t i = 0; !activeSetChanged && i < previousCuesSize; ++i) { |
1225 if (!currentCues.contains(previousCues[i]) && previousCues[i].data()->is
Active()) | 1222 if (!currentCues.contains(previousCues[i]) && previousCues[i].data()->is
Active()) |
1226 activeSetChanged = true; | 1223 activeSetChanged = true; |
1227 } | 1224 } |
1228 | 1225 |
1229 for (size_t i = 0; i < currentCuesSize; ++i) { | 1226 for (CueInterval currentCue : currentCues) { |
1230 currentCues[i].data()->updateDisplayTree(movieTime); | 1227 currentCue.data()->updateDisplayTree(movieTime); |
1231 | 1228 |
1232 if (!currentCues[i].data()->isActive()) | 1229 if (!currentCue.data()->isActive()) |
1233 activeSetChanged = true; | 1230 activeSetChanged = true; |
1234 } | 1231 } |
1235 | 1232 |
1236 if (!activeSetChanged) | 1233 if (!activeSetChanged) |
1237 return; | 1234 return; |
1238 | 1235 |
1239 // 7 - If the time was reached through the usual monotonic increase of the | 1236 // 7 - If the time was reached through the usual monotonic increase of the |
1240 // current playback position during normal playback, and there are cues in | 1237 // current playback position during normal playback, and there are cues in |
1241 // other cues that have their text track cue pause-on-exi flag set and that | 1238 // other cues that have their text track cue pause-on-exi flag set and that |
1242 // either have their text track cue active flag set or are also in missed | 1239 // either have their text track cue active flag set or are also in missed |
1243 // cues, then immediately pause the media element. | 1240 // cues, then immediately pause the media element. |
1244 for (size_t i = 0; !m_paused && i < previousCuesSize; ++i) { | 1241 for (size_t i = 0; !m_paused && i < previousCuesSize; ++i) { |
1245 if (previousCues[i].data()->pauseOnExit() | 1242 if (previousCues[i].data()->pauseOnExit() |
1246 && previousCues[i].data()->isActive() | 1243 && previousCues[i].data()->isActive() |
1247 && !currentCues.contains(previousCues[i])) | 1244 && !currentCues.contains(previousCues[i])) |
1248 pause(); | 1245 pause(); |
1249 } | 1246 } |
1250 | 1247 |
1251 for (size_t i = 0; !m_paused && i < missedCuesSize; ++i) { | 1248 for (size_t i = 0; !m_paused && i < missedCuesSize; ++i) { |
1252 if (missedCues[i].data()->pauseOnExit()) | 1249 if (missedCues[i].data()->pauseOnExit()) |
1253 pause(); | 1250 pause(); |
1254 } | 1251 } |
1255 | 1252 |
1256 // 8 - Let events be a list of tasks, initially empty. Each task in this | 1253 // 8 - Let events be a list of tasks, initially empty. Each task in this |
1257 // list will be associated with a text track, a text track cue, and a time, | 1254 // list will be associated with a text track, a text track cue, and a time, |
1258 // which are used to sort the list before the tasks are queued. | 1255 // which are used to sort the list before the tasks are queued. |
1259 WillBeHeapVector<std::pair<double, RawPtrWillBeMember<TextTrackCue> > > even
tTasks; | 1256 WillBeHeapVector<std::pair<double, RawPtrWillBeMember<TextTrackCue>>> eventT
asks; |
1260 | 1257 |
1261 // 8 - Let affected tracks be a list of text tracks, initially empty. | 1258 // 8 - Let affected tracks be a list of text tracks, initially empty. |
1262 WillBeHeapVector<RawPtrWillBeMember<TextTrack> > affectedTracks; | 1259 WillBeHeapVector<RawPtrWillBeMember<TextTrack>> affectedTracks; |
1263 | 1260 |
1264 for (size_t i = 0; i < missedCuesSize; ++i) { | 1261 for (size_t i = 0; i < missedCuesSize; ++i) { |
1265 // 9 - For each text track cue in missed cues, prepare an event named en
ter | 1262 // 9 - For each text track cue in missed cues, prepare an event named en
ter |
1266 // for the TextTrackCue object with the text track cue start time. | 1263 // for the TextTrackCue object with the text track cue start time. |
1267 eventTasks.append(std::make_pair(missedCues[i].data()->startTime(), | 1264 eventTasks.append(std::make_pair(missedCues[i].data()->startTime(), |
1268 missedCues[i].data())); | 1265 missedCues[i].data())); |
1269 | 1266 |
1270 // 10 - For each text track [...] in missed cues, prepare an event | 1267 // 10 - For each text track [...] in missed cues, prepare an event |
1271 // named exit for the TextTrackCue object with the with the later of | 1268 // named exit for the TextTrackCue object with the with the later of |
1272 // the text track cue end time and the text track cue start time. | 1269 // the text track cue end time and the text track cue start time. |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2787 return textTrackLanguageSelectionScore(track); | 2784 return textTrackLanguageSelectionScore(track); |
2788 } | 2785 } |
2789 | 2786 |
2790 void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) | 2787 void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) |
2791 { | 2788 { |
2792 ASSERT(group.tracks.size()); | 2789 ASSERT(group.tracks.size()); |
2793 | 2790 |
2794 WTF_LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%p, %d)", this, gr
oup.kind); | 2791 WTF_LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%p, %d)", this, gr
oup.kind); |
2795 | 2792 |
2796 // First, find the track in the group that should be enabled (if any). | 2793 // First, find the track in the group that should be enabled (if any). |
2797 WillBeHeapVector<RefPtrWillBeMember<TextTrack> > currentlyEnabledTracks; | 2794 WillBeHeapVector<RefPtrWillBeMember<TextTrack>> currentlyEnabledTracks; |
2798 RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr; | 2795 RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr; |
2799 RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr; | 2796 RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr; |
2800 RefPtrWillBeRawPtr<TextTrack> fallbackTrack = nullptr; | 2797 RefPtrWillBeRawPtr<TextTrack> fallbackTrack = nullptr; |
2801 int highestTrackScore = 0; | 2798 int highestTrackScore = 0; |
2802 for (size_t i = 0; i < group.tracks.size(); ++i) { | 2799 for (size_t i = 0; i < group.tracks.size(); ++i) { |
2803 RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i]; | 2800 RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i]; |
2804 | 2801 |
2805 if (m_processingPreferenceChange && textTrack->mode() == TextTrack::show
ingKeyword()) | 2802 if (m_processingPreferenceChange && textTrack->mode() == TextTrack::show
ingKeyword()) |
2806 currentlyEnabledTracks.append(textTrack); | 2803 currentlyEnabledTracks.append(textTrack); |
2807 | 2804 |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3783 if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captions
Keyword()) | 3780 if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captions
Keyword()) |
3784 textTrack->setHasBeenConfigured(false); | 3781 textTrack->setHasBeenConfigured(false); |
3785 } | 3782 } |
3786 } | 3783 } |
3787 | 3784 |
3788 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3785 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
3789 { | 3786 { |
3790 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3787 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
3791 configureMediaControls(); | 3788 configureMediaControls(); |
3792 | 3789 |
3793 return 0; | 3790 return nullptr; |
3794 } | 3791 } |
3795 | 3792 |
3796 void HTMLMediaElement::createMediaPlayer() | 3793 void HTMLMediaElement::createMediaPlayer() |
3797 { | 3794 { |
3798 AudioSourceProviderClientLockScope scope(*this); | 3795 AudioSourceProviderClientLockScope scope(*this); |
3799 | 3796 |
3800 closeMediaSource(); | 3797 closeMediaSource(); |
3801 | 3798 |
3802 m_player = MediaPlayer::create(this); | 3799 m_player = MediaPlayer::create(this); |
3803 | 3800 |
(...skipping 17 matching lines...) Expand all Loading... |
3821 AudioSourceProviderClientLockScope scope(*this); | 3818 AudioSourceProviderClientLockScope scope(*this); |
3822 if (audioSourceProvider()) | 3819 if (audioSourceProvider()) |
3823 audioSourceProvider()->setClient(m_audioSourceNode); | 3820 audioSourceProvider()->setClient(m_audioSourceNode); |
3824 } | 3821 } |
3825 | 3822 |
3826 AudioSourceProvider* HTMLMediaElement::audioSourceProvider() | 3823 AudioSourceProvider* HTMLMediaElement::audioSourceProvider() |
3827 { | 3824 { |
3828 if (m_player) | 3825 if (m_player) |
3829 return m_player->audioSourceProvider(); | 3826 return m_player->audioSourceProvider(); |
3830 | 3827 |
3831 return 0; | 3828 return nullptr; |
3832 } | 3829 } |
3833 #endif | 3830 #endif |
3834 | 3831 |
3835 const AtomicString& HTMLMediaElement::mediaGroup() const | 3832 const AtomicString& HTMLMediaElement::mediaGroup() const |
3836 { | 3833 { |
3837 return fastGetAttribute(mediagroupAttr); | 3834 return fastGetAttribute(mediagroupAttr); |
3838 } | 3835 } |
3839 | 3836 |
3840 void HTMLMediaElement::setMediaGroup(const AtomicString& group) | 3837 void HTMLMediaElement::setMediaGroup(const AtomicString& group) |
3841 { | 3838 { |
3842 // When a media element is created with a mediagroup attribute, and when a m
edia element's mediagroup | 3839 // When a media element is created with a mediagroup attribute, and when a m
edia element's mediagroup |
3843 // attribute is set, changed, or removed, the user agent must run the follow
ing steps: | 3840 // attribute is set, changed, or removed, the user agent must run the follow
ing steps: |
3844 // 1. Let _R [this] be the media element in question. | 3841 // 1. Let _R [this] be the media element in question. |
3845 // 2. Let m have no current media controller, if it currently has one. | 3842 // 2. Let m have no current media controller, if it currently has one. |
3846 setControllerInternal(nullptr); | 3843 setControllerInternal(nullptr); |
3847 | 3844 |
3848 // 3. If m's mediagroup attribute is being removed, then abort these steps. | 3845 // 3. If m's mediagroup attribute is being removed, then abort these steps. |
3849 if (group.isNull() || group.isEmpty()) | 3846 if (group.isNull() || group.isEmpty()) |
3850 return; | 3847 return; |
3851 | 3848 |
3852 // 4. If there is another media element whose Document is the same as m's Do
cument (even if one or both | 3849 // 4. If there is another media element whose Document is the same as m's Do
cument (even if one or both |
3853 // of these elements are not actually in the Document), | 3850 // of these elements are not actually in the Document), |
3854 WeakMediaElementSet elements = documentToElementSetMap().get(&document()); | 3851 WeakMediaElementSet elements = documentToElementSetMap().get(&document()); |
3855 for (WeakMediaElementSet::iterator i = elements.begin(); i != elements.end()
; ++i) { | 3852 for (const auto& element : elements) { |
3856 if (*i == this) | 3853 if (element == this) |
3857 continue; | 3854 continue; |
3858 | 3855 |
3859 // and which also has a mediagroup attribute, and whose mediagroup attri
bute has the same value as | 3856 // and which also has a mediagroup attribute, and whose mediagroup attri
bute has the same value as |
3860 // the new value of m's mediagroup attribute, | 3857 // the new value of m's mediagroup attribute, |
3861 if ((*i)->mediaGroup() == group) { | 3858 if (element->mediaGroup() == group) { |
3862 // then let controller be that media element's current media contro
ller. | 3859 // then let controller be that media element's current media contro
ller. |
3863 setControllerInternal((*i)->controller()); | 3860 setControllerInternal(element->controller()); |
3864 return; | 3861 return; |
3865 } | 3862 } |
3866 } | 3863 } |
3867 | 3864 |
3868 // Otherwise, let controller be a newly created MediaController. | 3865 // Otherwise, let controller be a newly created MediaController. |
3869 setControllerInternal(MediaController::create(Node::executionContext())); | 3866 setControllerInternal(MediaController::create(Node::executionContext())); |
3870 } | 3867 } |
3871 | 3868 |
3872 MediaController* HTMLMediaElement::controller() const | 3869 MediaController* HTMLMediaElement::controller() const |
3873 { | 3870 { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4027 | 4024 |
4028 // Select the first video track if a video track hasn't been selected yet. | 4025 // Select the first video track if a video track hasn't been selected yet. |
4029 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 4026 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
4030 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | 4027 videoTracks().anonymousIndexedGetter(0)->setSelected(true); |
4031 } | 4028 } |
4032 | 4029 |
4033 #if ENABLE(WEB_AUDIO) | 4030 #if ENABLE(WEB_AUDIO) |
4034 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 4031 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
4035 { | 4032 { |
4036 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) | 4033 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) |
4037 audioSourceProvider()->setClient(0); | 4034 audioSourceProvider()->setClient(nullptr); |
4038 } | 4035 } |
4039 #endif | 4036 #endif |
4040 | 4037 |
4041 } | 4038 } |
OLD | NEW |