| 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 |