[vlc-commits] [Git][videolan/vlc][master] vout: apple: add a property to observe picture in picture state change

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Thu Jan 9 21:17:15 UTC 2025



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
ba880a0b by Maxime Chapelet at 2025-01-09T21:04:01+00:00
vout: apple: add a property to observe picture in picture state change

libvlc client can set a block that will be called each time picture in picture is
started or closed.

`VLCPictureInPictureWindowControlling` implementation is also moved from the display
module to the picture in picture module

- - - - -


4 changed files:

- modules/video_output/apple/VLCDrawable.h
- modules/video_output/apple/VLCPictureInPictureController.m
- modules/video_output/apple/VLCSampleBufferDisplay.m
- modules/video_output/apple/vlc_pip_controller.h


Changes:

=====================================
modules/video_output/apple/VLCDrawable.h
=====================================
@@ -71,6 +71,10 @@
  */
 @protocol VLCPictureInPictureWindowControlling <NSObject>
 
+/// Property to set the event handler block that will notify when the picture
+/// in picture is started or stopped
+ at property (nonatomic) void(^stateChangeEventHandler)(BOOL isStarted);
+
 /// Call to present the display in picture in picture mode
 - (void)startPictureInPicture;
 


=====================================
modules/video_output/apple/VLCPictureInPictureController.m
=====================================
@@ -41,11 +41,13 @@
 API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
 @interface VLCPictureInPictureController: NSObject
     <AVPictureInPictureSampleBufferPlaybackDelegate, 
-     AVPictureInPictureControllerDelegate>
+     AVPictureInPictureControllerDelegate,
+     VLCPictureInPictureWindowControlling>
 
 @property (nonatomic, readonly) NSObject *avPipController;
 @property (nonatomic, readonly) pip_controller_t *pipcontroller;
 @property (nonatomic, readonly, weak) id<VLCPictureInPictureDrawable> drawable;
+ at property (nonatomic) void(^stateChangeEventHandler)(BOOL isStarted);
 
 - (instancetype)initWithPipController:(pip_controller_t *)pipcontroller;
 - (void)invalidatePlaybackState;
@@ -89,7 +91,7 @@ API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
     ];
     void *mediaController = (__bridge void*)_drawable.mediaController;
     BOOL isMediaSeekable = (BOOL)_pipcontroller->media_cbs->is_media_seekable(mediaController);
-              avPipController.requiresLinearPlayback = !isMediaSeekable;
+    avPipController.requiresLinearPlayback = !isMediaSeekable;
     avPipController.delegate = self;
 #if TARGET_OS_IOS
     // Not sure if it's mandatory, its usefulness isn't obvious and 
@@ -103,24 +105,8 @@ API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
                        forKeyPath:@"isPictureInPicturePossible"
                           options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew
                           context:NULL];
-}
-
-- (void)startPictureInPicture {
-    AVPictureInPictureController *avPipController =
-        (AVPictureInPictureController *)_avPipController;
-    [avPipController startPictureInPicture];
-}
 
-- (void)stopPictureInPicture {
-    AVPictureInPictureController *avPipController =
-        (AVPictureInPictureController *)_avPipController;
-    [avPipController stopPictureInPicture];
-}
-
-- (void)invalidatePlaybackState {
-    AVPictureInPictureController *avPipController =
-        (AVPictureInPictureController *)_avPipController;
-    [avPipController invalidatePlaybackState];
+    _drawable.pictureInPictureReady(self);
 }
 
 - (void)close {
@@ -215,44 +201,47 @@ API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
     [self invalidatePlaybackState];
 }
 
- at end
+- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
+    if (_stateChangeEventHandler)
+        _stateChangeEventHandler(YES);
+}
 
-static void SetDisplayLayer( pip_controller_t *pipcontroller, void *layer) {
-    if (@available(macOS 12.0, iOS 15.0, tvos 15.0, *)) {
-        VLCPictureInPictureController *sys = 
-            (__bridge VLCPictureInPictureController*)pipcontroller->p_sys;
-        
-        AVSampleBufferDisplayLayer *displayLayer =
-            (__bridge AVSampleBufferDisplayLayer *)layer;
-        
-        [sys prepare:displayLayer];
-    }
+- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
+    if(_stateChangeEventHandler)
+        _stateChangeEventHandler(NO);
 }
 
-static void StartPictureInPicture( pip_controller_t *pipcontroller) {
-    if (@available(macOS 12.0, iOS 15.0, tvos 15.0, *)) {
-        VLCPictureInPictureController *sys = 
-            (__bridge VLCPictureInPictureController*)pipcontroller->p_sys;
-        
-        [sys startPictureInPicture];
-    }
+#pragma mark - VLCDisplayPictureInPictureControlling
+
+- (void)startPictureInPicture {
+    AVPictureInPictureController *avPipController =
+        (AVPictureInPictureController *)_avPipController;
+    [avPipController startPictureInPicture];
 }
 
-static void StopPictureInPicture( pip_controller_t *pipcontroller) {
-    if (@available(macOS 12.0, iOS 15.0, tvos 15.0, *)) {
-        VLCPictureInPictureController *sys = 
-            (__bridge VLCPictureInPictureController*)pipcontroller->p_sys;
+- (void)stopPictureInPicture {
+    AVPictureInPictureController *avPipController =
+        (AVPictureInPictureController *)_avPipController;
+    [avPipController stopPictureInPicture];
+}
 
-        [sys stopPictureInPicture];
-    }
+- (void)invalidatePlaybackState {
+    AVPictureInPictureController *avPipController =
+        (AVPictureInPictureController *)_avPipController;
+    [avPipController invalidatePlaybackState];
 }
 
-static void InvalidatePictureInPicture( pip_controller_t *pipcontroller) {
+ at end
+
+static void SetDisplayLayer( pip_controller_t *pipcontroller, void *layer) {
     if (@available(macOS 12.0, iOS 15.0, tvos 15.0, *)) {
         VLCPictureInPictureController *sys = 
             (__bridge VLCPictureInPictureController*)pipcontroller->p_sys;
         
-        [sys invalidatePlaybackState];
+        AVSampleBufferDisplayLayer *displayLayer =
+            (__bridge AVSampleBufferDisplayLayer *)layer;
+        
+        [sys prepare:displayLayer];
     }
 }
 
@@ -314,9 +303,6 @@ static int OpenController( pip_controller_t *pipcontroller )
 {
     static const struct pip_controller_operations ops = {
         SetDisplayLayer, 
-        StartPictureInPicture, 
-        StopPictureInPicture, 
-        InvalidatePictureInPicture, 
         CloseController
     };
 


=====================================
modules/video_output/apple/VLCSampleBufferDisplay.m
=====================================
@@ -639,14 +639,13 @@ shouldInheritContentsScale:(CGFloat)newScale
 
 #pragma mark -
 
- at interface VLCSampleBufferDisplay: NSObject <VLCPictureInPictureWindowControlling>
+ at interface VLCSampleBufferDisplay: NSObject
 {
     @public
     vout_display_place_t place;
     filter_t *converter;
 }
     @property (nonatomic, readonly, weak) VLCView *window;
-    @property (nonatomic, readonly, weak) id drawable;
     @property (nonatomic, readonly) vout_display_t *vd;
     @property (nonatomic) VLCSampleBufferDisplayView *displayView;
     @property (nonatomic) AVSampleBufferDisplayLayer *displayLayer;
@@ -694,8 +693,6 @@ shouldInheritContentsScale:(CGFloat)newScale
 
     _window = window;
 
-    _drawable = (__bridge id)var_InheritAddress (vd, "drawable-nsobject");
-
     _pipcontroller = CreatePipController(vd, (__bridge void *)self);
 
     _vd = vd;
@@ -713,13 +710,6 @@ shouldInheritContentsScale:(CGFloat)newScale
             (__bridge void*)_displayView.displayLayer
         );
     }
-    
-    if ( ![_drawable conformsToProtocol:@protocol(VLCPictureInPictureDrawable)] )
-        return;
-    
-    id<VLCPictureInPictureDrawable> drawable = (id<VLCPictureInPictureDrawable>)_drawable;
-    
-    drawable.pictureInPictureReady(self);
 }
 
 - (void)prepareDisplay {
@@ -766,35 +756,6 @@ shouldInheritContentsScale:(CGFloat)newScale
     _pipcontroller = NULL;
 }
 
-#pragma mark - VLCDisplayPictureInPictureControlling
-
-- (void)startPictureInPicture {
-    if ( _pipcontroller
-            && _pipcontroller->ops->start_pip ) {
-        _pipcontroller->ops->start_pip(
-            _pipcontroller
-        );
-    }
-}
-
-- (void)stopPictureInPicture {
-    if ( _pipcontroller
-            && _pipcontroller->ops->stop_pip ) {
-        _pipcontroller->ops->stop_pip(
-            _pipcontroller
-        );
-    }
-}
-
-- (void)invalidatePlaybackState {
-    if ( _pipcontroller
-            && _pipcontroller->ops->invalidate_pip ) {
-        _pipcontroller->ops->invalidate_pip(
-            _pipcontroller
-        );
-    }
-}
-
 @end
 
 #pragma mark -


=====================================
modules/video_output/apple/vlc_pip_controller.h
=====================================
@@ -33,9 +33,6 @@ typedef struct pip_controller_t pip_controller_t;
 
 struct pip_controller_operations {
     void (*set_display_layer)(pip_controller_t *, void *);
-    void (*start_pip)(pip_controller_t *);
-    void (*stop_pip)(pip_controller_t *);
-    void (*invalidate_pip)(pip_controller_t *);
     int (*close)(pip_controller_t *);
 };
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ba880a0b86650534deed0d5fd24282e9c3cdb1a2

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ba880a0b86650534deed0d5fd24282e9c3cdb1a2
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list