Changeset 237378 in webkit
- Timestamp:
- Oct 24, 2018 3:03:31 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r237376 r237378 1 2018-10-22 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-23 Jer Noble <jer.noble@apple.com> 2 44 -
trunk/Source/WebCore/platform/GenericTaskQueue.cpp
r237364 r237378 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 { 55 72 ASSERT(!sharedTimer().isActive()); 56 ASSERT(!pendingDispatchers().isEmpty());57 73 58 74 // Copy the pending events first because we don't want to process synchronously the new events 59 75 // queued by the JS events handlers that are executed in the loop below. 60 Deque<WeakPtr<TaskDispatcher<Timer>>> queuedDispatchers = WTFMove(pendingDispatchers()); 76 Deque<WeakPtr<TaskDispatcher<Timer>>> queuedDispatchers; 77 { 78 auto locker = holdLock(sharedLock()); 79 queuedDispatchers = WTFMove(pendingDispatchers()); 80 } 61 81 while (!queuedDispatchers.isEmpty()) { 62 82 WeakPtr<TaskDispatcher<Timer>> dispatcher = queuedDispatchers.takeFirst(); … … 67 87 } 68 88 89 69 90 Deque<WeakPtr<TaskDispatcher<Timer>>>& TaskDispatcher<Timer>::pendingDispatchers() 70 91 { 71 ASSERT(isMainThread()); 72 static NeverDestroyed<Deque<WeakPtr<TaskDispatcher<Timer>>>> dispatchers; 92 static LazyNeverDestroyed<Deque<WeakPtr<TaskDispatcher<Timer>>>> dispatchers; 93 94 static std::once_flag onceFlag; 95 std::call_once(onceFlag, [] { 96 dispatchers.construct(); 97 }); 98 73 99 return dispatchers.get(); 74 100 } … … 76 102 void TaskDispatcher<Timer>::dispatchOneTask() 77 103 { 78 ASSERT(!m_pendingTasks.isEmpty()); 79 auto task = m_pendingTasks.takeFirst(); 104 WTF::Function<void()> task; 105 { 106 auto locker = holdLock(sharedLock()); 107 ASSERT(!m_pendingTasks.isEmpty()); 108 task = m_pendingTasks.takeFirst(); 109 } 80 110 task(); 81 111 } -
trunk/Source/WebCore/platform/GenericTaskQueue.h
r237364 r237378 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
r237376 r237378 333 333 bool performTaskAtMediaTime(WTF::Function<void()>&&, MediaTime) final; 334 334 335 WeakPtrFactory<MediaPlayerPrivateAVFoundationObjC> m_weakPtrFactory; 335 336 RetainPtr<AVURLAsset> m_avAsset; 336 337 RetainPtr<AVPlayer> m_avPlayer; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r237376 r237378 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 … … 3363 3363 @implementation WebCoreAVFMovieObserver 3364 3364 3365 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC*)callback3365 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3366 3366 { 3367 3367 self = [super init]; 3368 3368 if (!self) 3369 3369 return nil; 3370 m_ callback = callback;3370 m_player = WTFMove(player); 3371 3371 return self; 3372 3372 } … … 3374 3374 - (void)disconnect 3375 3375 { 3376 [NSObject cancelPreviousPerformRequestsWithTarget:self]; 3377 m_callback = nil; 3376 m_player = nullptr; 3378 3377 } 3379 3378 3380 3379 - (void)metadataLoaded 3381 3380 { 3382 if (!m_callback) 3383 return; 3384 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::AssetMetadataLoaded); 3381 m_taskQueue.enqueueTask([player = m_player] { 3382 if (player) 3383 player->metadataLoaded(); 3384 }); 3385 3385 } 3386 3386 … … 3388 3388 { 3389 3389 UNUSED_PARAM(unusedNotification); 3390 if (!m_callback) 3391 return; 3392 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemDidPlayToEndTime); 3390 m_taskQueue.enqueueTask([player = m_player] { 3391 if (player) 3392 player->didEnd(); 3393 }); 3393 3394 } 3394 3395 3395 3396 - (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context 3396 3397 { 3397 UNUSED_PARAM(object); 3398 id newValue = [change valueForKey:NSKeyValueChangeNewKey]; 3399 3400 if (!m_callback) 3401 return; 3402 3403 bool willChange = [[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue]; 3404 bool shouldLogValue = !willChange; 3405 WTF::Function<void ()> function; 3406 3407 if (context == MediaPlayerAVFoundationObservationContextAVPlayerLayer) { 3408 if ([keyPath isEqualToString:@"readyForDisplay"]) 3409 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::firstFrameAvailableDidChange, m_callback, [newValue boolValue]); 3410 } 3411 3412 if (context == MediaPlayerAVFoundationObservationContextPlayerItemTrack) { 3413 if ([keyPath isEqualToString:@"enabled"]) 3414 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::trackEnabledDidChange, m_callback, [newValue boolValue]); 3415 } 3416 3417 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && willChange) { 3418 if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3419 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackLikelyToKeepUpWillChange, m_callback); 3420 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3421 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferEmptyWillChange, m_callback); 3422 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3423 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferFullWillChange, m_callback); 3424 } 3425 3426 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && !willChange) { 3427 // A value changed for an AVPlayerItem 3428 if ([keyPath isEqualToString:@"status"]) 3429 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playerItemStatusDidChange, m_callback, [newValue intValue]); 3430 else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3431 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackLikelyToKeepUpDidChange, m_callback, [newValue boolValue]); 3432 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3433 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferEmptyDidChange, m_callback, [newValue boolValue]); 3434 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3435 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackBufferFullDidChange, m_callback, [newValue boolValue]); 3436 else if ([keyPath isEqualToString:@"asset"]) { 3437 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::setAsset, m_callback, RetainPtr<id>(newValue)); 3438 shouldLogValue = false; 3439 } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) 3440 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::loadedTimeRangesDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3441 else if ([keyPath isEqualToString:@"seekableTimeRanges"]) 3442 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::seekableTimeRangesDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3443 else if ([keyPath isEqualToString:@"tracks"]) { 3444 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::tracksDidChange, m_callback, RetainPtr<NSArray>(newValue)); 3445 shouldLogValue = false; 3446 } else if ([keyPath isEqualToString:@"hasEnabledAudio"]) 3447 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::hasEnabledAudioDidChange, m_callback, [newValue boolValue]); 3448 else if ([keyPath isEqualToString:@"presentationSize"]) 3449 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::presentationSizeDidChange, m_callback, FloatSize([newValue sizeValue])); 3450 else if ([keyPath isEqualToString:@"duration"]) 3451 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::durationDidChange, m_callback, PAL::toMediaTime([newValue CMTimeValue])); 3452 else if ([keyPath isEqualToString:@"timedMetadata"] && newValue) { 3453 MediaTime now; 3454 CMTime itemTime = [(AVPlayerItemType *)object currentTime]; 3455 if (CMTIME_IS_NUMERIC(itemTime)) 3456 now = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3457 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::metadataDidArrive, m_callback, RetainPtr<NSArray>(newValue), now); 3458 shouldLogValue = false; 3459 } else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3460 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::canPlayFastReverseDidChange, m_callback, [newValue boolValue]); 3461 else if ([keyPath isEqualToString:@"canPlayFastForward"]) 3462 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::canPlayFastForwardDidChange, m_callback, [newValue boolValue]); 3463 } 3464 3465 if (context == MediaPlayerAVFoundationObservationContextPlayer && !willChange) { 3466 // A value changed for an AVPlayer. 3467 if ([keyPath isEqualToString:@"rate"]) 3468 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]); 3398 m_taskQueue.enqueueTask([player = m_player, keyPath = retainPtr(keyPath), change = retainPtr(change), object = retainPtr(object), context] { 3399 if (!player) 3400 return; 3401 id newValue = [change valueForKey:NSKeyValueChangeNewKey]; 3402 bool willChange = [[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue]; 3403 bool shouldLogValue = !willChange; 3404 3405 if (context == MediaPlayerAVFoundationObservationContextAVPlayerLayer) { 3406 if ([keyPath isEqualToString:@"readyForDisplay"]) 3407 player->firstFrameAvailableDidChange([newValue boolValue]); 3408 } 3409 3410 if (context == MediaPlayerAVFoundationObservationContextPlayerItemTrack) { 3411 if ([keyPath isEqualToString:@"enabled"]) 3412 player->trackEnabledDidChange([newValue boolValue]); 3413 } 3414 3415 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && willChange) { 3416 if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3417 player->playbackLikelyToKeepUpWillChange(); 3418 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3419 player->playbackBufferEmptyWillChange(); 3420 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3421 player->playbackBufferFullWillChange(); 3422 } 3423 3424 if (context == MediaPlayerAVFoundationObservationContextPlayerItem && !willChange) { 3425 // A value changed for an AVPlayerItem 3426 if ([keyPath isEqualToString:@"status"]) 3427 player->playerItemStatusDidChange([newValue intValue]); 3428 else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 3429 player->playbackLikelyToKeepUpDidChange([newValue boolValue]); 3430 else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) 3431 player->playbackBufferEmptyDidChange([newValue boolValue]); 3432 else if ([keyPath isEqualToString:@"playbackBufferFull"]) 3433 player->playbackBufferFullDidChange([newValue boolValue]); 3434 else if ([keyPath isEqualToString:@"asset"]) { 3435 player->setAsset(RetainPtr<id>(newValue)); 3436 shouldLogValue = false; 3437 } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) 3438 player->loadedTimeRangesDidChange(RetainPtr<NSArray>(newValue)); 3439 else if ([keyPath isEqualToString:@"seekableTimeRanges"]) 3440 player->seekableTimeRangesDidChange(RetainPtr<NSArray>(newValue)); 3441 else if ([keyPath isEqualToString:@"tracks"]) { 3442 player->tracksDidChange(RetainPtr<NSArray>(newValue)); 3443 shouldLogValue = false; 3444 } else if ([keyPath isEqualToString:@"hasEnabledAudio"]) 3445 player->hasEnabledAudioDidChange([newValue boolValue]); 3446 else if ([keyPath isEqualToString:@"presentationSize"]) 3447 player->presentationSizeDidChange(FloatSize([newValue sizeValue])); 3448 else if ([keyPath isEqualToString:@"duration"]) 3449 player->durationDidChange(PAL::toMediaTime([newValue CMTimeValue])); 3450 else if ([keyPath isEqualToString:@"timedMetadata"] && newValue) { 3451 MediaTime now; 3452 CMTime itemTime = [(AVPlayerItemType *)object.get() currentTime]; 3453 if (CMTIME_IS_NUMERIC(itemTime)) 3454 now = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3455 player->metadataDidArrive(RetainPtr<NSArray>(newValue), now); 3456 shouldLogValue = false; 3457 } else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3458 player->canPlayFastReverseDidChange([newValue boolValue]); 3459 else if ([keyPath isEqualToString:@"canPlayFastForward"]) 3460 player->canPlayFastForwardDidChange([newValue boolValue]); 3461 } 3462 3463 if (context == MediaPlayerAVFoundationObservationContextPlayer && !willChange) { 3464 // A value changed for an AVPlayer. 3465 if ([keyPath isEqualToString:@"rate"]) 3466 player->rateDidChange([newValue doubleValue]); 3469 3467 #if ENABLE(WIRELESS_PLAYBACK_TARGET) 3470 else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"])3471 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);3468 else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"]) 3469 player->playbackTargetIsWirelessDidChange(); 3472 3470 #endif 3473 3471 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA) 3474 else if ([keyPath isEqualToString:@"outputObscuredDueToInsufficientExternalProtection"])3475 function = std::bind(&MediaPlayerPrivateAVFoundationObjC::outputObscuredDueToInsufficientExternalProtectionChanged, m_callback,[newValue boolValue]);3476 #endif 3477 }3472 else if ([keyPath isEqualToString:@"outputObscuredDueToInsufficientExternalProtection"]) 3473 player->outputObscuredDueToInsufficientExternalProtectionChanged([newValue boolValue]); 3474 #endif 3475 } 3478 3476 3479 3477 #if !RELEASE_LOG_DISABLED 3480 if (m_callback->logger().willLog(m_callback->logChannel(), WTFLogLevelDebug) && !([keyPath isEqualToString:@"loadedTimeRanges"] || [keyPath isEqualToString:@"seekableTimeRanges"])) { 3481 auto identifier = Logger::LogSiteIdentifier("MediaPlayerPrivateAVFoundation", "observeValueForKeyPath", m_callback->logIdentifier()); 3482 3483 if (shouldLogValue) { 3484 if ([keyPath isEqualToString:@"duration"]) 3485 m_callback->logger().debug(m_callback->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", PAL::toMediaTime([newValue CMTimeValue])); 3486 else { 3487 RetainPtr<NSString> valueString = adoptNS([[NSString alloc] initWithFormat:@"%@", newValue]); 3488 m_callback->logger().debug(m_callback->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", [valueString.get() UTF8String]); 3489 } 3490 } else 3491 m_callback->logger().debug(m_callback->logChannel(), identifier, willChange ? "will" : "did", " change '", [keyPath UTF8String], "'"); 3492 } 3493 #endif 3494 3495 if (!function) 3496 return; 3497 3498 auto weakThis = makeWeakPtr(*m_callback); 3499 m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification([weakThis, function = WTFMove(function)]{ 3500 // weakThis and function both refer to the same MediaPlayerPrivateAVFoundationObjC instance. If the WeakPtr has 3501 // been cleared, the underlying object has been destroyed, and it is unsafe to call function(). 3502 if (!weakThis) 3503 return; 3504 function(); 3505 })); 3478 if (player->logger().willLog(player->logChannel(), WTFLogLevelDebug) && !([keyPath isEqualToString:@"loadedTimeRanges"] || [keyPath isEqualToString:@"seekableTimeRanges"])) { 3479 auto identifier = Logger::LogSiteIdentifier("MediaPlayerPrivateAVFoundation", "observeValueForKeyPath", player->logIdentifier()); 3480 3481 if (shouldLogValue) { 3482 if ([keyPath isEqualToString:@"duration"]) 3483 player->logger().debug(player->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", PAL::toMediaTime([newValue CMTimeValue])); 3484 else { 3485 RetainPtr<NSString> valueString = adoptNS([[NSString alloc] initWithFormat:@"%@", newValue]); 3486 player->logger().debug(player->logChannel(), identifier, "did change '", [keyPath UTF8String], "' to ", [valueString.get() UTF8String]); 3487 } 3488 } else 3489 player->logger().debug(player->logChannel(), identifier, willChange ? "will" : "did", " change '", [keyPath UTF8String], "'"); 3490 } 3491 #endif 3492 }); 3506 3493 } 3507 3494 … … 3511 3498 { 3512 3499 UNUSED_PARAM(output); 3513 UNUSED_PARAM(nativeSamples); 3514 3515 if (!m_callback) 3516 return; 3517 3518 RetainPtr<WebCoreAVFMovieObserver> protectedSelf = self; 3519 RetainPtr<NSArray> protectedStrings = strings; 3520 RetainPtr<NSArray> protectedNativeSamples = nativeSamples; 3521 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedStrings = WTFMove(protectedStrings), protectedNativeSamples = WTFMove(protectedNativeSamples), itemTime] { 3522 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3523 if (!callback) 3500 3501 m_taskQueue.enqueueTask([player = m_player, strings = retainPtr(strings), nativeSamples = retainPtr(nativeSamples), itemTime] { 3502 if (!player) 3524 3503 return; 3525 3504 MediaTime time = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3526 callback->processCue(protectedStrings.get(), protectedNativeSamples.get(), time);3505 player->processCue(strings.get(), nativeSamples.get(), time); 3527 3506 }); 3528 3507 } … … 3532 3511 UNUSED_PARAM(output); 3533 3512 3534 if (!m_callback) 3535 return; 3536 3537 callOnMainThread([protectedSelf = RetainPtr<WebCoreAVFMovieObserver>(self)] { 3538 if (MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback) 3539 callback->flushCues(); 3513 m_taskQueue.enqueueTask([player = m_player] { 3514 if (player) 3515 player->flushCues(); 3540 3516 }); 3541 3517 } … … 3549 3525 @implementation WebCoreAVFLoaderDelegate 3550 3526 3551 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC*)callback3527 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3552 3528 { 3553 3529 self = [super init]; 3554 3530 if (!self) 3555 3531 return nil; 3556 m_ callback = callback;3532 m_player = WTFMove(player); 3557 3533 return self; 3558 3534 } … … 3561 3537 { 3562 3538 UNUSED_PARAM(resourceLoader); 3563 if (!m_ callback)3539 if (!m_player) 3564 3540 return NO; 3565 3541 3566 RetainPtr<WebCoreAVFLoaderDelegate> protectedSelf = self; 3567 RetainPtr<AVAssetResourceLoadingRequest> protectedLoadingRequest = loadingRequest; 3568 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedLoadingRequest = WTFMove(protectedLoadingRequest)] { 3569 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3570 if (!callback) { 3571 [protectedLoadingRequest finishLoadingWithError:nil]; 3542 m_taskQueue.enqueueTask([player = m_player, loadingRequest = retainPtr(loadingRequest)] { 3543 if (!player) { 3544 [loadingRequest finishLoadingWithError:nil]; 3572 3545 return; 3573 3546 } 3574 3547 3575 if (! callback->shouldWaitForLoadingOfResource(protectedLoadingRequest.get()))3576 [ protectedLoadingRequest finishLoadingWithError:nil];3548 if (!player->shouldWaitForLoadingOfResource(loadingRequest.get())) 3549 [loadingRequest finishLoadingWithError:nil]; 3577 3550 }); 3578 3551 … … 3591 3564 { 3592 3565 UNUSED_PARAM(resourceLoader); 3593 if (!m_callback) 3594 return; 3595 3596 RetainPtr<WebCoreAVFLoaderDelegate> protectedSelf = self; 3597 RetainPtr<AVAssetResourceLoadingRequest> protectedLoadingRequest = loadingRequest; 3598 callOnMainThread([protectedSelf = WTFMove(protectedSelf), protectedLoadingRequest = WTFMove(protectedLoadingRequest)] { 3599 MediaPlayerPrivateAVFoundationObjC* callback = protectedSelf->m_callback; 3600 if (callback) 3601 callback->didCancelLoadingRequest(protectedLoadingRequest.get()); 3566 m_taskQueue.enqueueTask([player = m_player, loadingRequest = retainPtr(loadingRequest)] { 3567 if (player) 3568 player->didCancelLoadingRequest(loadingRequest.get()); 3602 3569 }); 3603 3570 } 3604 3571 3605 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC*)callback3606 {3607 m_callback = callback;3608 }3609 3572 @end 3610 3573 … … 3615 3578 @implementation WebCoreAVFPullDelegate 3616 3579 3617 - (id)initWith Callback:(MediaPlayerPrivateAVFoundationObjC *)callback3580 - (id)initWithPlayer:(WeakPtr<MediaPlayerPrivateAVFoundationObjC>&&)player 3618 3581 { 3619 3582 self = [super init]; 3620 3583 if (self) 3621 m_ callback = callback;3584 m_player = WTFMove(player); 3622 3585 return self; 3623 3586 } 3624 3587 3625 - (void)setCallback:(MediaPlayerPrivateAVFoundationObjC *)callback3626 {3627 m_callback = callback;3628 }3629 3630 3588 - (void)outputMediaDataWillChange:(AVPlayerItemVideoOutputType *)output 3631 3589 { 3632 if (m_ callback)3633 m_ callback->outputMediaDataWillChange(output);3590 if (m_player) 3591 m_player->outputMediaDataWillChange(output); 3634 3592 } 3635 3593
Note: See TracChangeset
for help on using the changeset viewer.