Changeset 237350 in webkit
- Timestamp:
- Oct 23, 2018 7:40:58 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r237347 r237350 1 2018-10-23 Jer Noble <jer.noble@apple.com> 2 3 Use WeakPtr and GenericTaskQueue within ObjC classes used by MediaPlayerPrivateAVFoundationObjC 4 https://bugs.webkit.org/show_bug.cgi?id=190790 5 6 Reviewed by Alex Christensen. 7 8 Move towards using WeakPtr callbacks instead of raw pointers within the utility objects used by 9 MediaPlayerPrivateAVFoundationObjC. Additionally, accessing WeakPtr off the thread which created 10 the pointer is not allowed, so use a GenericTaskQueue to schedule callbacks instead. Make 11 GenericTaskQueue<Timer> thread-safe by locking around access to m_pendingTasks, and by making 12 incrementing the pending task count atomic. 13 14 * platform/GenericTaskQueue.cpp: 15 (WebCore::TaskDispatcher<Timer>::postTask): 16 (WebCore::TaskDispatcher<Timer>::sharedLock): 17 (WebCore::TaskDispatcher<Timer>::sharedTimerFired): 18 (WebCore::TaskDispatcher<Timer>::dispatchOneTask): 19 (WebCore::TaskDispatcher<Timer>::pendingDispatchers): 20 * platform/GenericTaskQueue.h: 21 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: 22 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: 23 (WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC): 24 (WebCore::MediaPlayerPrivateAVFoundationObjC::~MediaPlayerPrivateAVFoundationObjC): 25 (-[WebCoreAVFMovieObserver initWithPlayer:]): 26 (-[WebCoreAVFMovieObserver disconnect]): 27 (-[WebCoreAVFMovieObserver metadataLoaded]): 28 (-[WebCoreAVFMovieObserver didEnd:]): 29 (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]): 30 (-[WebCoreAVFMovieObserver legibleOutput:didOutputAttributedStrings:nativeSampleBuffers:forItemTime:]): 31 (-[WebCoreAVFMovieObserver outputSequenceWasFlushed:]): 32 (-[WebCoreAVFLoaderDelegate initWithPlayer:]): 33 (-[WebCoreAVFLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): 34 (-[WebCoreAVFLoaderDelegate resourceLoader:didCancelLoadingRequest:]): 35 (-[WebCoreAVFPullDelegate initWithPlayer:]): 36 (-[WebCoreAVFPullDelegate outputMediaDataWillChange:]): 37 (-[WebCoreAVFMovieObserver initWithCallback:]): Deleted. 38 (-[WebCoreAVFLoaderDelegate initWithCallback:]): Deleted. 39 (-[WebCoreAVFLoaderDelegate setCallback:]): Deleted. 40 (-[WebCoreAVFPullDelegate initWithCallback:]): Deleted. 41 (-[WebCoreAVFPullDelegate setCallback:]): Deleted. 42 1 43 2018-10-22 Justin Michaud <justin_michaud@apple.com> 2 44 -
trunk/Source/WebCore/platform/GenericTaskQueue.cpp
r232613 r237350 27 27 #include "GenericTaskQueue.h" 28 28 29 #include <wtf/Lock.h> 29 30 #include <wtf/MainThread.h> 30 31 #include <wtf/NeverDestroyed.h> … … 38 39 void TaskDispatcher<Timer>::postTask(Function<void()>&& function) 39 40 { 40 m_pendingTasks.append(WTFMove(function)); 41 pendingDispatchers().append(makeWeakPtr(*this)); 42 if (!sharedTimer().isActive()) 43 sharedTimer().startOneShot(0_s); 41 { 42 auto locker = holdLock(sharedLock()); 43 m_pendingTasks.append(WTFMove(function)); 44 pendingDispatchers().append(makeWeakPtr(*this)); 45 } 46 47 auto startTimer = [] { 48 if (!sharedTimer().isActive()) 49 sharedTimer().startOneShot(0_s); 50 }; 51 if (isMainThread()) 52 startTimer(); 53 else 54 callOnMainThread(WTFMove(startTimer)); 44 55 } 45 56 … … 51 62 } 52 63 64 Lock& TaskDispatcher<Timer>::sharedLock() 65 { 66 static NeverDestroyed<Lock> lock; 67 return lock; 68 } 69 53 70 void TaskDispatcher<Timer>::sharedTimerFired() 54 71 { … … 58 75 // Copy the pending events first because we don't want to process synchronously the new events 59 76 // queued by the JS events handlers that are executed in the loop below. 60 Deque<WeakPtr<TaskDispatcher<Timer>>> queuedDispatchers = WTFMove(pendingDispatchers()); 77 Deque<WeakPtr<TaskDispatcher<Timer>>> queuedDispatchers; 78 { 79 auto locker = holdLock(sharedLock()); 80 queuedDispatchers = WTFMove(pendingDispatchers()); 81 } 61 82 while (!queuedDispatchers.isEmpty()) { 62 83 WeakPtr<TaskDispatcher<Timer>> dispatcher = queuedDispatchers.takeFirst(); … … 67 88 } 68 89 90 69 91 Deque<WeakPtr<TaskDispatcher<Timer>>>& TaskDispatcher<Timer>::pendingDispatchers() 70 92 { 71 ASSERT(isMainThread()); 72 static NeverDestroyed<Deque<WeakPtr<TaskDispatcher<Timer>>>> dispatchers; 93 static LazyNeverDestroyed<Deque<WeakPtr<TaskDispatcher<Timer>>>> dispatchers; 94 95 static std::once_flag onceFlag; 96 std::call_once(onceFlag, [] { 97 dispatchers.construct(); 98 }); 99 73 100 return dispatchers.get(); 74 101 } … … 76 103 void TaskDispatcher<Timer>::dispatchOneTask() 77 104 { 78 ASSERT(!m_pendingTasks.isEmpty()); 79 auto task = m_pendingTasks.takeFirst(); 105 WTF::Function<void()> task; 106 { 107 auto locker = holdLock(sharedLock()); 108 ASSERT(!m_pendingTasks.isEmpty()); 109 task = m_pendingTasks.takeFirst(); 110 } 80 111 task(); 81 112 } -
trunk/Source/WebCore/platform/GenericTaskQueue.h
r237209 r237350 31 31 #include <wtf/WeakPtr.h> 32 32 33 namespace WTF { 34 class Lock; 35 }; 36 33 37 namespace WebCore { 34 38 … … 59 63 private: 60 64 static Timer& sharedTimer(); 65 static WTF::Lock& sharedLock(); 61 66 static void sharedTimerFired(); 62 67 static Deque<WeakPtr<TaskDispatcher<Timer>>>& pendingDispatchers(); … … 67 72 }; 68 73 69 template <typename T >70 class GenericTaskQueue : public CanMakeWeakPtr<GenericTaskQueue<T >> {74 template <typename T, typename C = unsigned> 75 class GenericTaskQueue : public CanMakeWeakPtr<GenericTaskQueue<T, C>> { 71 76 public: 72 77 GenericTaskQueue() … … 120 125 private: 121 126 TaskDispatcher<T> m_dispatcher; 122 unsignedm_pendingTasks { 0 };127 C m_pendingTasks { 0 }; 123 128 bool m_isClosed { false }; 124 129 }; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
r237266 r237350 331 331 AVPlayer *objCAVFoundationAVPlayer() const final { return m_avPlayer.get(); } 332 332 333 WeakPtrFactory<MediaPlayerPrivateAVFoundationObjC> m_weakPtrFactory; 333 334 RetainPtr<AVURLAsset> m_avAsset; 334 335 RetainPtr<AVPlayer> m_avPlayer; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r237266 r237350 337 337 #endif 338 338 { 339 MediaPlayerPrivateAVFoundationObjC* m_callback; 339 WeakPtr<MediaPlayerPrivateAVFoundationObjC> m_player; 340 GenericTaskQueue<Timer, std::atomic<unsigned>> m_taskQueue; 340 341 int m_delayCallbacks; 341 342 } 342 -(id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC*)callback;343 -(id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)callback; 343 344 -(void)disconnect; 344 345 -(void)metadataLoaded; … … 353 354 #if HAVE(AVFOUNDATION_LOADER_DELEGATE) 354 355 @interface WebCoreAVFLoaderDelegate : NSObject<AVAssetResourceLoaderDelegate> { 355 MediaPlayerPrivateAVFoundationObjC* m_callback; 356 } 357 - (id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC*)callback; 356 WeakPtr<MediaPlayerPrivateAVFoundationObjC> m_player; 357 GenericTaskQueue<Timer, std::atomic<unsigned>> m_taskQueue; 358 } 359 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player; 358 360 - (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest; 359 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC*)callback;360 361 @end 361 362 #endif … … 363 364 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) 364 365 @interface WebCoreAVFPullDelegate : NSObject<AVPlayerItemOutputPullDelegate> { 365 MediaPlayerPrivateAVFoundationObjC *m_callback; 366 } 367 - (id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC *)callback; 368 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC*)callback; 366 WeakPtr<MediaPlayerPrivateAVFoundationObjC> m_player; 367 } 368 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player; 369 369 - (void)outputMediaDataWillChange:(AVPlayerItemOutput *)sender; 370 370 - (void)outputSequenceWasFlushed:(AVPlayerItemOutput *)output; … … 502 502 , m_videoFullscreenLayerManager(std::make_unique<VideoFullscreenLayerManagerObjC>()) 503 503 , m_videoFullscreenGravity(MediaPlayer::VideoGravityResizeAspect) 504 , m_objcObserver(adoptNS([[WebCoreAVFMovieObserver alloc] initWith Callback:this]))504 , m_objcObserver(adoptNS([[WebCoreAVFMovieObserver alloc] initWithPlayer:m_weakPtrFactory.createWeakPtr(*this)])) 505 505 , m_videoFrameHasDrawn(false) 506 506 , m_haveCheckedPlayability(false) 507 507 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) 508 , m_videoOutputDelegate(adoptNS([[WebCoreAVFPullDelegate alloc] initWith Callback:this]))508 , m_videoOutputDelegate(adoptNS([[WebCoreAVFPullDelegate alloc] initWithPlayer:m_weakPtrFactory.createWeakPtr(*this)])) 509 509 #endif 510 510 #if HAVE(AVFOUNDATION_LOADER_DELEGATE) 511 , m_loaderDelegate(adoptNS([[WebCoreAVFLoaderDelegate alloc] initWith Callback:this]))511 , m_loaderDelegate(adoptNS([[WebCoreAVFLoaderDelegate alloc] initWithPlayer:m_weakPtrFactory.createWeakPtr(*this)])) 512 512 #endif 513 513 , m_currentTextTrack(0) … … 531 531 MediaPlayerPrivateAVFoundationObjC::~MediaPlayerPrivateAVFoundationObjC() 532 532 { 533 m_weakPtrFactory.revokeAll(); 534 533 535 #if HAVE(AVFOUNDATION_LOADER_DELEGATE) 534 [m_loaderDelegate.get() setCallback:0];535 536 [[m_avAsset.get() resourceLoader] setDelegate:nil queue:0]; 536 537 … … 539 540 #endif 540 541 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) 541 [m_videoOutputDelegate setCallback:0];542 542 [m_videoOutput setDelegate:nil queue:0]; 543 543 #endif … … 3350 3350 @implementation WebCoreAVFMovieObserver 3351 3351 3352 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC*)callback3352 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3353 3353 { 3354 3354 self = [super init]; 3355 3355 if (!self) 3356 3356 return nil; 3357 m_ callback = callback;3357 m_player = WTFMove(player); 3358 3358 return self; 3359 3359 } … … 3361 3361 - (void)disconnect 3362 3362 { 3363 [NSObject cancelPreviousPerformRequestsWithTarget:self]; 3364 m_callback = nil; 3363 m_player = nullptr; 3365 3364 } 3366 3365 3367 3366 - (void)metadataLoaded 3368 3367 { 3369 if (!m_callback) 3370 return; 3371 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::AssetMetadataLoaded); 3368 m_taskQueue.enqueueTask([player = m_player] { 3369 if (player) 3370 player->metadataLoaded(); 3371 }); 3372 3372 } 3373 3373 … … 3375 3375 { 3376 3376 UNUSED_PARAM(unusedNotification); 3377 if (!m_callback) 3378 return; 3379 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemDidPlayToEndTime); 3377 m_taskQueue.enqueueTask([player = m_player] { 3378 if (player) 3379 player->didEnd(); 3380 }); 3380 3381 } 3381 3382 3382 3383 - (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context 3383 3384 { 3384 UNUSED_PARAM(object); 3385 id newValue = [change valueForKey:NSKeyValueChangeNewKey]; 3386 3387 if (!m_callback) 3388 return; 3389 3390 bool willChange = [[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue]; 3391 bool shouldLogValue = !willChange; 3392 WTF::Function<void ()> function; 3393 3394 if (context == MediaPlayerAVFoundationObservationContextAVPlayerLayer) { 3395 if ([keyPath isEqualToString:@"readyForDisplay"]) 3396 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::firstFrameAvailableDidChange, m_callback, [newValue boolValue]); 3397 } 3398 3399 if (context == MediaPlayerAVFoundationObservationContextPlayerItemTrack) { 3400 if ([keyPath isEqualToString:@"enabled"]) 3401 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::trackEnabledDidChange, m_callback, [newValue boolValue]); 3402 } 3403 3404 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && willChange) { 3405 if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3406 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackLikelyToKeepUpWillChange, m_callback); 3407 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3408 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferEmptyWillChange, m_callback); 3409 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3410 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferFullWillChange, m_callback); 3411 } 3412 3413 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && !willChange) { 3414 // A value changed for an AVPlayerItem 3415 if ([keyPath isEqualToString:@"status"]) 3416 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playerItemStatusDidChange, m_callback, [newValue intValue]); 3417 else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3418 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackLikelyToKeepUpDidChange, m_callback, [newValue boolValue]); 3419 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3420 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferEmptyDidChange, m_callback, [newValue boolValue]); 3421 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3422 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferFullDidChange, m_callback, [newValue boolValue]); 3423 else if ([keyPath isEqualToString:@"asset"]) { 3424 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::setAsset, m_callback, RetainPtr<id>(newValue)); 3425 shouldLogValue = false; 3426 } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) 3427 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::loadedTimeRangesDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3428 else if ([keyPath isEqualToString:@"seekableTimeRanges"]) 3429 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::seekableTimeRangesDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3430 else if ([keyPath isEqualToString:@"tracks"]) { 3431 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::tracksDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3432 shouldLogValue = false; 3433 } else if ([keyPath isEqualToString:@"hasEnabledAudio"]) 3434 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::hasEnabledAudioDidChange, m_callback, [newValue boolValue]); 3435 else if ([keyPath isEqualToString:@"presentationSize"]) 3436 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::presentationSizeDidChange, m_callback, FloatSize([newValue sizeValue])); 3437 else if ([keyPath isEqualToString:@"duration"]) 3438 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::durationDidChange, m_callback, PAL::toMediaTime([newValue CMTimeValue])); 3439 else if ([keyPath isEqualToString:@"timedMetadata"] && newValue) { 3440 MediaTime now; 3441 CMTime itemTime = [(AVPlayerItemType *)object currentTime]; 3442 if (CMTIME_IS_NUMERIC(itemTime)) 3443 now = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3444 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::metadataDidArrive, m_callback, RetainPtr<NSArray>(newValue), now); 3445 shouldLogValue = false; 3446 } else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3447 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::canPlayFastReverseDidChange, m_callback, [newValue boolValue]); 3448 else if ([keyPath isEqualToString:@"canPlayFastForward"]) 3449 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::canPlayFastForwardDidChange, m_callback, [newValue boolValue]); 3450 } 3451 3452 if (context == MediaPlayerAVFoundationObservationContextPlayer && !willChange) { 3453 // A value changed for an AVPlayer. 3454 if ([keyPath isEqualToString:@"rate"]) 3455 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]); 3385 m_taskQueue.enqueueTask([player = m_player, keyPath = retainPtr(keyPath), change = retainPtr(change), object = retainPtr(object), context] { 3386 if (!player) 3387 return; 3388 id newValue = [change valueForKey:NSKeyValueChangeNewKey]; 3389 bool willChange = [[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue]; 3390 bool shouldLogValue = !willChange; 3391 3392 if (context == MediaPlayerAVFoundationObservationContextAVPlayerLayer) { 3393 if ([keyPath isEqualToString:@"readyForDisplay"]) 3394 player->firstFrameAvailableDidChange([newValue boolValue]); 3395 } 3396 3397 if (context == MediaPlayerAVFoundationObservationContextPlayerItemTrack) { 3398 if ([keyPath isEqualToString:@"enabled"]) 3399 player->trackEnabledDidChange([newValue boolValue]); 3400 } 3401 3402 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && willChange) { 3403 if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3404 player->playbackLikelyToKeepUpWillChange(); 3405 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3406 player->playbackBufferEmptyWillChange(); 3407 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3408 player->playbackBufferFullWillChange(); 3409 } 3410 3411 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && !willChange) { 3412 // A value changed for an AVPlayerItem 3413 if ([keyPath isEqualToString:@"status"]) 3414 player->playerItemStatusDidChange([newValue intValue]); 3415 else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3416 player->playbackLikelyToKeepUpDidChange([newValue boolValue]); 3417 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3418 player->playbackBufferEmptyDidChange([newValue boolValue]); 3419 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3420 player->playbackBufferFullDidChange([newValue boolValue]); 3421 else if ([keyPath isEqualToString:@"asset"]) { 3422 player->setAsset(RetainPtr<id>(newValue)); 3423 shouldLogValue = false; 3424 } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) 3425 player->loadedTimeRangesDidChange(RetainPtr<NSArray>(newValue)); 3426 else if ([keyPath isEqualToString:@"seekableTimeRanges"]) 3427 player->seekableTimeRangesDidChange(RetainPtr<NSArray>(newValue)); 3428 else if ([keyPath isEqualToString:@"tracks"]) { 3429 player->tracksDidChange(RetainPtr<NSArray>(newValue)); 3430 shouldLogValue = false; 3431 } else if ([keyPath isEqualToString:@"hasEnabledAudio"]) 3432 player->hasEnabledAudioDidChange([newValue boolValue]); 3433 else if ([keyPath isEqualToString:@"presentationSize"]) 3434 player->presentationSizeDidChange(FloatSize([newValue sizeValue])); 3435 else if ([keyPath isEqualToString:@"duration"]) 3436 player->durationDidChange(PAL::toMediaTime([newValue CMTimeValue])); 3437 else if ([keyPath isEqualToString:@"timedMetadata"] && newValue) { 3438 MediaTime now; 3439 CMTime itemTime = [(AVPlayerItemType *)object.get() currentTime]; 3440 if (CMTIME_IS_NUMERIC(itemTime)) 3441 now = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3442 player->metadataDidArrive(RetainPtr<NSArray>(newValue), now); 3443 shouldLogValue = false; 3444 } else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3445 player->canPlayFastReverseDidChange([newValue boolValue]); 3446 else if ([keyPath isEqualToString:@"canPlayFastForward"]) 3447 player->canPlayFastForwardDidChange([newValue boolValue]); 3448 } 3449 3450 if (context == MediaPlayerAVFoundationObservationContextPlayer && !willChange) { 3451 // A value changed for an AVPlayer. 3452 if ([keyPath isEqualToString:@"rate"]) 3453 player->rateDidChange([newValue doubleValue]); 3456 3454 #if ENABLE(WIRELESS_PLAYBACK_TARGET) 3457 else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"])3458 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);3455 else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"]) 3456 player->playbackTargetIsWirelessDidChange(); 3459 3457 #endif 3460 3458 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA) 3461 else if ([keyPath isEqualToString:@"outputObscuredDueToInsufficientExternalProtection"])3462 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::outputObscuredDueToInsufficientExternalProtectionChanged, m_callback,[newValue boolValue]);3463 #endif 3464 }3459 else if ([keyPath isEqualToString:@"outputObscuredDueToInsufficientExternalProtection"]) 3460 player->outputObscuredDueToInsufficientExternalProtectionChanged([newValue boolValue]); 3461 #endif 3462 } 3465 3463 3466 3464 #if !RELEASE_LOG_DISABLED 3467 if (m_callback->logger().willLog(m_callback->logChannel(), WTFLogLevelDebug) && !([keyPath isEqualToString:@"loadedTimeRanges"] || [keyPath isEqualToString:@"seekableTimeRanges"])) { 3468 auto identifier = Logger::LogSiteIdentifier("MediaPlayerPrivateAVFoundation", "observeValueForKeyPath", m_callback->logIdentifier()); 3469 3470 if (shouldLogValue) { 3471 if ([keyPath isEqualToString:@"duration"]) 3472 m_callback->logger().debug(m_callback->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", PAL::toMediaTime([newValue CMTimeValue])); 3473 else { 3474 RetainPtr<NSString> valueString = adoptNS([[NSString alloc] initWithFormat:@"%@", newValue]); 3475 m_callback->logger().debug(m_callback->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", [valueString.get() UTF8String]); 3476 } 3477 } else 3478 m_callback->logger().debug(m_callback->logChannel(), identifier, willChange ? "will" : "did", " change '", [keyPath UTF8String], "'"); 3479 } 3480 #endif 3481 3482 if (!function) 3483 return; 3484 3485 auto weakThis = makeWeakPtr(*m_callback); 3486 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification([weakThis, function = WTFMove(function)]{ 3487 // weakThis and function both refer to the same MediaPlayerPrivateAVFoundationObjC instance. If the WeakPtr has 3488 // been cleared, the underlying object has been destroyed, and it is unsafe to call function(). 3489 if (!weakThis) 3490 return; 3491 function(); 3492 })); 3465 if (player->logger().willLog(player->logChannel(), WTFLogLevelDebug) && !([keyPath isEqualToString:@"loadedTimeRanges"] || [keyPath isEqualToString:@"seekableTimeRanges"])) { 3466 auto identifier = Logger::LogSiteIdentifier("MediaPlayerPrivateAVFoundation", "observeValueForKeyPath", player->logIdentifier()); 3467 3468 if (shouldLogValue) { 3469 if ([keyPath isEqualToString:@"duration"]) 3470 player->logger().debug(player->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", PAL::toMediaTime([newValue CMTimeValue])); 3471 else { 3472 RetainPtr<NSString> valueString = adoptNS([[NSString alloc] initWithFormat:@"%@", newValue]); 3473 player->logger().debug(player->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", [valueString.get() UTF8String]); 3474 } 3475 } else 3476 player->logger().debug(player->logChannel(), identifier, willChange ? "will" : "did", " change '", [keyPath UTF8String], "'"); 3477 } 3478 #endif 3479 }); 3493 3480 } 3494 3481 … … 3498 3485 { 3499 3486 UNUSED_PARAM(output); 3500 UNUSED_PARAM(nativeSamples); 3501 3502 if (!m_callback) 3503 return; 3504 3505 RetainPtr<WebCoreAVFMovieObserver> protectedSelf = self; 3506 RetainPtr<NSArray> protectedStrings = strings; 3507 RetainPtr<NSArray> protectedNativeSamples = nativeSamples; 3508 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedStrings = WTFMove(protectedStrings), protectedNativeSamples = WTFMove(protectedNativeSamples), itemTime] { 3509 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3510 if (!callback) 3487 3488 m_taskQueue.enqueueTask([player = m_player, strings = retainPtr(strings), nativeSamples = retainPtr(nativeSamples), itemTime] { 3489 if (!player) 3511 3490 return; 3512 3491 MediaTime time = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3513 callback->processCue(protectedStrings.get(), protectedNativeSamples.get(), time);3492 player->processCue(strings.get(), nativeSamples.get(), time); 3514 3493 }); 3515 3494 } … … 3519 3498 UNUSED_PARAM(output); 3520 3499 3521 if (!m_callback) 3522 return; 3523 3524 callOnMainThread([protectedSelf = RetainPtr<WebCoreAVFMovieObserver>(self)] { 3525 if (MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback) 3526 callback->flushCues(); 3500 m_taskQueue.enqueueTask([player = m_player] { 3501 if (player) 3502 player->flushCues(); 3527 3503 }); 3528 3504 } … … 3536 3512 @implementation WebCoreAVFLoaderDelegate 3537 3513 3538 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC*)callback3514 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3539 3515 { 3540 3516 self = [super init]; 3541 3517 if (!self) 3542 3518 return nil; 3543 m_ callback = callback;3519 m_player = WTFMove(player); 3544 3520 return self; 3545 3521 } … … 3548 3524 { 3549 3525 UNUSED_PARAM(resourceLoader); 3550 if (!m_ callback)3526 if (!m_player) 3551 3527 return NO; 3552 3528 3553 RetainPtr<WebCoreAVFLoaderDelegate> protectedSelf = self; 3554 RetainPtr<AVAssetResourceLoadingRequest> protectedLoadingRequest = loadingRequest; 3555 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedLoadingRequest = WTFMove(protectedLoadingRequest)] { 3556 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3557 if (!callback) { 3558 [protectedLoadingRequest finishLoadingWithError:nil]; 3529 m_taskQueue.enqueueTask([player = m_player, loadingRequest = retainPtr(loadingRequest)] { 3530 if (!player) { 3531 [loadingRequest finishLoadingWithError:nil]; 3559 3532 return; 3560 3533 } 3561 3534 3562 if (! callback->shouldWaitForLoadingOfResource(protectedLoadingRequest.get()))3563 [ protectedLoadingRequest finishLoadingWithError:nil];3535 if (!player->shouldWaitForLoadingOfResource(loadingRequest.get())) 3536 [loadingRequest finishLoadingWithError:nil]; 3564 3537 }); 3565 3538 … … 3578 3551 { 3579 3552 UNUSED_PARAM(resourceLoader); 3580 if (!m_callback) 3581 return; 3582 3583 RetainPtr<WebCoreAVFLoaderDelegate> protectedSelf = self; 3584 RetainPtr<AVAssetResourceLoadingRequest> protectedLoadingRequest = loadingRequest; 3585 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedLoadingRequest = WTFMove(protectedLoadingRequest)] { 3586 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3587 if (callback) 3588 callback->didCancelLoadingRequest(protectedLoadingRequest.get()); 3553 m_taskQueue.enqueueTask([player = m_player, loadingRequest = retainPtr(loadingRequest)] { 3554 if (player) 3555 player->didCancelLoadingRequest(loadingRequest.get()); 3589 3556 }); 3590 3557 } 3591 3558 3592 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC*)callback3593 {3594 m_callback = callback;3595 }3596 3559 @end 3597 3560 … … 3602 3565 @implementation WebCoreAVFPullDelegate 3603 3566 3604 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC *)callback3567 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3605 3568 { 3606 3569 self = [super init]; 3607 3570 if (self) 3608 m_ callback = callback;3571 m_player = WTFMove(player); 3609 3572 return self; 3610 3573 } 3611 3574 3612 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC *)callback3613 {3614 m_callback = callback;3615 }3616 3617 3575 - (void)outputMediaDataWillChange:(AVPlayerItemVideoOutputType *)output 3618 3576 { 3619 if (m_ callback)3620 m_ callback->outputMediaDataWillChange(output);3577 if (m_player) 3578 m_player->outputMediaDataWillChange(output); 3621 3579 } 3622 3580
Note: See TracChangeset
for help on using the changeset viewer.