[vlc-commits] [Git][videolan/vlc][master] 10 commits: avcapture: setup framerate correctly

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Thu Sep 23 09:32:26 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
84a51793 by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: setup framerate correctly

Set the framerate to 1 / framerate_base, avoiding the following warning
for a 30fps capture stream:

    rawvideo decoder warning: invalid frame rate 0/30000, using 25 fps
    instead

- - - - -
34111f32 by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: fix typo

- - - - -
de133912 by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: remove trailing characters

- - - - -
d105cfe4 by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: improve the es_format_t exposed

- - - - -
3e9507cd by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: use video_format_Print

...instead of using custom debug strings

- - - - -
27489f99 by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: fix locking for pts

- - - - -
3571e7ed by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: use a separate class for ARC

ARC is not supported when storing NSObject in a structure. But it is
well-supported when storing a NSObject as (__bridge_retained void*) into
the p_sys until (__bridge_tranfer) releases it.

It highly simplify the whole handling of ARC objects and avoid using
CFRelease/CFRetain in the code, unifying with other Objective-C modules
like VLCVideoUIView or VLCOpenGLES2VideoView.

- - - - -
2a3074cc by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: signal missing protocol implemented

AVCaptureVideoDataOutputSampleBufferDelegate is implemented by
VLCAVDecompressedVideoOutput but wasn't signalled, leading to warnings
when compiling.

- - - - -
ca04b74f by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: fix PTS conversion and usage

CMTime is **not** equivalent to vlc_tick_t. In particular, the timescale
doesn't match. So it should be converted before usage.

In addition, GET_TIME is supposed to return where the access is
currently reading, which should also match the timestamps of the output
frames from the access.

Fixes #26101

- - - - -
48d50cdf by Alexandre Janniaux at 2021-09-23T09:10:09+00:00
avcapture: fix output format to BGRA

We request kCVPixelFormatType_32BGRA which is BGRA, not RGB32.

- - - - -


1 changed file:

- modules/access/avcapture.m


Changes:

=====================================
modules/access/avcapture.m
=====================================
@@ -72,11 +72,20 @@ vlc_module_begin ()
    set_callbacks(Open, Close)
 vlc_module_end ()
 
+static vlc_tick_t vlc_CMTime_to_tick(CMTime timestamp)
+{
+    CMTime scaled = CMTimeConvertScale(
+            timestamp, CLOCK_FREQ,
+            kCMTimeRoundingMethod_Default);
+
+    return VLC_TICK_0 + scaled.value;
+}
 
 /*****************************************************************************
 * AVFoundation Bridge
 *****************************************************************************/
- at interface VLCAVDecompressedVideoOutput : AVCaptureVideoDataOutput
+ at interface VLCAVDecompressedVideoOutput :
+    AVCaptureVideoDataOutput <AVCaptureVideoDataOutputSampleBufferDelegate>
 {
     demux_t             *p_avcapture;
 
@@ -157,23 +166,22 @@ vlc_module_end ()
         self.videoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
         bytesPerRow = CVPixelBufferGetBytesPerRow(CMSampleBufferGetImageBuffer(sampleBuffer));
         videoDimensionsReady = YES;
-        msg_Dbg(p_avcapture, "Dimensionns obtained height:%i width:%i bytesPerRow:%lu", [self height], [self width], bytesPerRow);
+        msg_Dbg(p_avcapture, "Dimensions obtained height:%i width:%i bytesPerRow:%lu", [self height], [self width], bytesPerRow);
     }
 }
 
--(vlc_tick_t)currentPts
+- (vlc_tick_t)currentPts
 {
     vlc_tick_t pts;
 
-    if ( !currentImageBuffer || currentPts == previousPts )
-        return 0;
-
     @synchronized (self)
     {
+       if ( !currentImageBuffer || currentPts == previousPts )
+           return VLC_TICK_INVALID;
         pts = previousPts = currentPts;
     }
 
-    return currentPts;
+    return pts;
 }
 
 - (void)captureOutput:(AVCaptureOutput *)captureOutput
@@ -187,13 +195,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
         CVBufferRetain(videoFrame);
         [self getVideoDimensions:sampleBuffer];
 
+
         @synchronized (self) {
             imageBufferToRelease = currentImageBuffer;
             currentImageBuffer = videoFrame;
-            currentPts = (vlc_tick_t)presentationtimestamp.value;
+            currentPts = vlc_CMTime_to_tick(presentationtimestamp);
             timeScale = (long)presentationtimestamp.timescale;
         }
-        
+
         CVBufferRelease(imageBufferToRelease);
     }
 }
@@ -237,16 +246,21 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
 * Struct
 *****************************************************************************/
 
-typedef struct demux_sys_t
-{
-    CFTypeRef _Nullable             session;       // AVCaptureSession
-    CFTypeRef _Nullable             device;        // AVCaptureDevice
-    CFTypeRef _Nullable             output;        // VLCAVDecompressedVideoOutput
-    es_out_id_t                     *p_es_video;
-    es_format_t                     fmt;
-    int                             height, width;
-    BOOL                            b_es_setup;
-} demux_sys_t;
+ at interface VLCAVCaptureDemux : NSObject {
+    demux_t                         *_demux;
+    AVCaptureSession                *_session;
+    AVCaptureDevice                 *_device;
+    VLCAVDecompressedVideoOutput    *_output;
+    es_out_id_t                     *_es_video;
+    es_format_t                     _fmt;
+    int                             _height, _width;
+}
+
+- (VLCAVCaptureDemux*)init:(demux_t *)demux;
+- (int)demux;
+- (vlc_tick_t)pts;
+- (void)dealloc;
+ at end
 
 /*****************************************************************************
 * Open:
@@ -254,8 +268,82 @@ typedef struct demux_sys_t
 static int Open(vlc_object_t *p_this)
 {
     demux_t                 *p_demux = (demux_t*)p_this;
-    demux_sys_t             *p_sys = NULL;
 
+    if (p_demux->out == NULL)
+        return VLC_EGENERIC;
+
+    @autoreleasepool {
+        VLCAVCaptureDemux *demux = [[VLCAVCaptureDemux alloc] init:p_demux];
+        if (demux == nil)
+            return VLC_EGENERIC;
+        p_demux->p_sys = (__bridge_retained void*)demux;
+    }
+    p_demux->pf_demux = Demux;
+    p_demux->pf_control = Control;
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+* Close:
+*****************************************************************************/
+static void Close(vlc_object_t *p_this)
+{
+    demux_t *p_demux = (demux_t*)p_this;
+    VLCAVCaptureDemux *demux =
+        (__bridge_transfer VLCAVCaptureDemux*)p_demux->p_sys;
+
+    /* Signal ARC we won't use those references anymore. */
+    p_demux->p_sys = nil;
+    demux = nil;
+}
+
+/*****************************************************************************
+* Demux:
+*****************************************************************************/
+static int Demux(demux_t *p_demux)
+{
+    VLCAVCaptureDemux *demux = (__bridge VLCAVCaptureDemux *)p_demux->p_sys;
+    return [demux demux];
+}
+
+/*****************************************************************************
+* Control:
+*****************************************************************************/
+static int Control(demux_t *p_demux, int i_query, va_list args)
+{
+    VLCAVCaptureDemux *demux = (__bridge VLCAVCaptureDemux *)p_demux->p_sys;
+    bool        *pb;
+
+    switch( i_query )
+    {
+        /* Special for access_demux */
+        case DEMUX_CAN_PAUSE:
+        case DEMUX_CAN_SEEK:
+        case DEMUX_SET_PAUSE_STATE:
+        case DEMUX_CAN_CONTROL_PACE:
+           pb = va_arg(args, bool *);
+           *pb = false;
+           return VLC_SUCCESS;
+
+        case DEMUX_GET_PTS_DELAY:
+           *va_arg(args, vlc_tick_t *) =
+               VLC_TICK_FROM_MS(var_InheritInteger(p_demux, "live-caching"));
+           return VLC_SUCCESS;
+
+        case DEMUX_GET_TIME:
+            *va_arg(args, vlc_tick_t *) = [demux pts];
+            return VLC_SUCCESS;
+
+        default:
+           return VLC_EGENERIC;
+    }
+    return VLC_EGENERIC;
+}
+
+ at implementation VLCAVCaptureDemux
+- (VLCAVCaptureDemux *)init:(demux_t *)p_demux
+{
     NSString                *avf_currdevice_uid;
     NSArray                 *myVideoDevices;
     NSError                 *o_returnedError;
@@ -266,174 +354,135 @@ static int Open(vlc_object_t *p_this)
 
     char                    *psz_uid = NULL;
 
-    if (p_demux->out == NULL)
-        return VLC_EGENERIC;
-
-    @autoreleasepool {
-        if (p_demux->psz_location && *p_demux->psz_location)
-            psz_uid = strdup(p_demux->psz_location);
+    _demux = p_demux;
 
-        msg_Dbg(p_demux, "avcapture uid = %s", psz_uid);
-        avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid];
+    if (_demux->psz_location && *_demux->psz_location)
+        psz_uid = strdup(_demux->psz_location);
 
-        /* Set up p_demux */
-        p_demux->pf_demux = Demux;
-        p_demux->pf_control = Control;
+    msg_Dbg(_demux, "avcapture uid = %s", psz_uid);
+    avf_currdevice_uid = [[NSString alloc] initWithFormat:@"%s", psz_uid];
 
-        p_demux->p_sys = p_sys = calloc(1, sizeof(demux_sys_t));
-        if ( !p_sys )
-            return VLC_ENOMEM;
-
-        myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
-                           arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]];
-        if ( [myVideoDevices count] == 0 )
-        {
-            vlc_dialog_display_error(p_demux, _("No video devices found"),
-                _("Your Mac does not seem to be equipped with a suitable video input device. "
-                "Please check your connectors and drivers."));
-            msg_Err(p_demux, "Can't find any suitable video device");
-            goto error;
-        }
+    myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
+                       arrayByAddingObjectsFromArray:[AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]];
+    if ( [myVideoDevices count] == 0 )
+    {
+        vlc_dialog_display_error(_demux, _("No video devices found"),
+            _("Your Mac does not seem to be equipped with a suitable video input device. "
+            "Please check your connectors and drivers."));
+        msg_Err(_demux, "Can't find any suitable video device");
+        return nil;
+    }
 
-        deviceCount = [myVideoDevices count];
-        for ( ivideo = 0; ivideo < deviceCount; ivideo++ )
-        {
-            AVCaptureDevice *avf_device;
-            avf_device = [myVideoDevices objectAtIndex:ivideo];
-            msg_Dbg(p_demux, "avcapture %i/%i %s %s", ivideo, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]);
-            if ([[[avf_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:avf_currdevice_uid]) {
-                break;
-            }
+    deviceCount = [myVideoDevices count];
+    for ( ivideo = 0; ivideo < deviceCount; ivideo++ )
+    {
+        AVCaptureDevice *avf_device;
+        avf_device = [myVideoDevices objectAtIndex:ivideo];
+        msg_Dbg(_demux, "avcapture %i/%i %s %s", ivideo, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]);
+        if ([[[avf_device uniqueID]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:avf_currdevice_uid]) {
+            break;
         }
+    }
 
-        if ( ivideo < [myVideoDevices count] )
-        {
-            p_sys->device = CFBridgingRetain([myVideoDevices objectAtIndex:ivideo]);
-        }
-        else
-        {
-            msg_Dbg(p_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]);
-            p_sys->device = CFBridgingRetain([AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]);
-        }
-        if ( !p_sys->device )
-        {
-            vlc_dialog_display_error(p_demux, _("No video devices found"),
-                _("Your Mac does not seem to be equipped with a suitable input device. "
-                "Please check your connectors and drivers."));
-            msg_Err(p_demux, "Can't find any suitable video device");
-            goto error;
-        }
+    if ( ivideo < [myVideoDevices count] )
+    {
+        _device = [myVideoDevices objectAtIndex:ivideo];
+    }
+    else
+    {
+        msg_Dbg(_demux, "Cannot find designated device as %s, falling back to default.", [avf_currdevice_uid UTF8String]);
+        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    }
 
-        if ( [(__bridge AVCaptureDevice *)p_sys->device isInUseByAnotherApplication] == YES )
-        {
-            msg_Err(p_demux, "default capture device is exclusively in use by another application");
-            goto error;
-        }
+    if ( !_device )
+    {
+        vlc_dialog_display_error(_demux, _("No video devices found"),
+            _("Your Mac does not seem to be equipped with a suitable input device. "
+            "Please check your connectors and drivers."));
+        msg_Err(_demux, "Can't find any suitable video device");
+        return nil;
+    }
 
-        if (@available(macOS 10.14, *)) {
-            msg_Dbg(p_demux, "Check user consent for access to the video device");
-
-            dispatch_semaphore_t sema = dispatch_semaphore_create(0);
-            __block bool accessGranted = NO;
-            [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler:^(BOOL granted) {
-                accessGranted = granted;
-                dispatch_semaphore_signal(sema);
-            } ];
-            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
-            dispatch_release(sema);
-            if (!accessGranted) {
-                msg_Err(p_demux, "Can't use the video device as access has not been granted by the user");
-                vlc_dialog_display_error(p_demux, _("Problem accessing a system resource"),
-                    _("Please open \"System Preferences\" -> \"Security & Privacy\" "
-                      "and allow VLC to access your camera."));
-
-                goto error;
-            }
-        }
+    AVCaptureDevice *device = _device;
 
-        input = [AVCaptureDeviceInput deviceInputWithDevice:(__bridge AVCaptureDevice *)p_sys->device error:&o_returnedError];
+    if ( [device isInUseByAnotherApplication] == YES )
+    {
+        msg_Err(_demux, "default capture device is exclusively in use by another application");
+        return nil;
+    }
 
-        if ( !input )
-        {
-            msg_Err(p_demux, "can't create a valid capture input facility: %s (%ld)",[[o_returnedError localizedDescription] UTF8String], [o_returnedError code]);
-            goto error;
+    if (@available(macOS 10.14, *)) {
+        msg_Dbg(_demux, "Check user consent for access to the video device");
+
+        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+        __block bool accessGranted = NO;
+        [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler:^(BOOL granted) {
+            accessGranted = granted;
+            dispatch_semaphore_signal(sema);
+        } ];
+        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
+        dispatch_release(sema);
+        if (!accessGranted) {
+            msg_Err(_demux, "Can't use the video device as access has not been granted by the user");
+            vlc_dialog_display_error(_demux, _("Problem accessing a system resource"),
+                _("Please open \"System Preferences\" -> \"Security & Privacy\" "
+                  "and allow VLC to access your camera."));
+
+            return nil;
         }
+    }
 
+    input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&o_returnedError];
 
-        int chroma = VLC_CODEC_RGB32;
+    if ( !input )
+    {
+        msg_Err(_demux, "can't create a valid capture input facility: %s (%ld)",[[o_returnedError localizedDescription] UTF8String], [o_returnedError code]);
+        return nil;
+    }
 
-        memset(&p_sys->fmt, 0, sizeof(es_format_t));
-        es_format_Init(&p_sys->fmt, VIDEO_ES, chroma);
+    int chroma = VLC_CODEC_BGRA;
 
-        p_sys->session = CFBridgingRetain([[AVCaptureSession alloc] init]);
-        [(__bridge AVCaptureSession *)p_sys->session addInput:input];
+    memset(&_fmt, 0, sizeof(es_format_t));
+    es_format_Init(&_fmt, VIDEO_ES, chroma);
 
-        p_sys->output = CFBridgingRetain([[VLCAVDecompressedVideoOutput alloc] initWithDemux:p_demux]);
-        [(__bridge AVCaptureSession *)p_sys->session addOutput:(__bridge VLCAVDecompressedVideoOutput *)p_sys->output];
+    _session = [[AVCaptureSession alloc] init];
 
-        dispatch_queue_t queue = dispatch_queue_create("avCaptureQueue", NULL);
-        [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setSampleBufferDelegate:(__bridge id)p_sys->output queue:queue];
-        dispatch_release(queue);
+    [_session addInput:input];
 
-        [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
-        [(__bridge AVCaptureSession *)p_sys->session startRunning];
+    _output = [[VLCAVDecompressedVideoOutput alloc] initWithDemux:_demux];
 
-        input = nil;
+    [_session addOutput:_output];
 
-        msg_Dbg(p_demux, "AVCapture: Video device ready!");
+    dispatch_queue_t queue = dispatch_queue_create("avCaptureQueue", NULL);
+    [_output setSampleBufferDelegate:_output queue:queue];
+    dispatch_release(queue);
 
-        return VLC_SUCCESS;
-    error:
-        msg_Err(p_demux, "Error");
-        input = nil;
+    [_output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
+    [_session startRunning];
 
-        free(p_sys);
+    input = nil;
 
-        return VLC_EGENERIC;
-    }
-}
+    msg_Dbg(_demux, "AVCapture: Video device ready!");
 
-/*****************************************************************************
-* Close:
-*****************************************************************************/
-static void Close(vlc_object_t *p_this)
-{
-    demux_t             *p_demux = (demux_t*)p_this;
-    demux_sys_t         *p_sys = p_demux->p_sys;
-
-    @autoreleasepool {
-        msg_Dbg(p_demux,"Close AVCapture");
-
-        // Perform this on main thread, as the framework itself will sometimes try to synchronously
-        // work on main thread. And this will create a dead lock.
-        [(__bridge AVCaptureSession *)p_sys->session performSelectorOnMainThread:@selector(stopRunning) withObject:nil waitUntilDone:NO];
-        CFBridgingRelease(p_sys->output);
-        CFBridgingRelease(p_sys->session);
-
-        free(p_sys);
-    }
+    return self;
 }
 
-/*****************************************************************************
-* Demux:
-*****************************************************************************/
-static int Demux(demux_t *p_demux)
+- (int)demux
 {
-    demux_sys_t *p_sys = p_demux->p_sys;
     block_t     *p_block;
 
     @autoreleasepool {
-        @synchronized ( p_sys->output )
+        @synchronized(_output)
         {
-            p_block = block_Alloc([(__bridge VLCAVDecompressedVideoOutput *)p_sys->output width] * [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output bytesPerRow]);
+            p_block = block_Alloc([_output width] * [_output bytesPerRow]);
 
             if ( !p_block )
             {
-                msg_Err(p_demux, "cannot get block");
+                msg_Err(_demux, "cannot get block");
                 return 0;
             }
 
-            p_block->i_pts = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output copyCurrentFrameToBuffer: p_block->p_buffer];
+            p_block->i_pts = [_output copyCurrentFrameToBuffer: p_block->p_buffer];
 
             if ( !p_block->i_pts )
             {
@@ -442,54 +491,41 @@ static int Demux(demux_t *p_demux)
                 vlc_tick_sleep(VLC_HARD_MIN_SLEEP);
                 return 1;
             }
-            else if ( !p_sys->b_es_setup )
+            else if ( !_es_video )
             {
-                p_sys->fmt.video.i_frame_rate_base = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output timeScale];
-                msg_Dbg(p_demux, "using frame rate base: %i", p_sys->fmt.video.i_frame_rate_base);
-                p_sys->width = p_sys->fmt.video.i_width = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output width];
-                p_sys->height = p_sys->fmt.video.i_height = [(__bridge VLCAVDecompressedVideoOutput *)p_sys->output height];
-                p_sys->p_es_video = es_out_Add(p_demux->out, &p_sys->fmt);
-                msg_Dbg(p_demux, "added new video es %4.4s %dx%d", (char*)&p_sys->fmt.i_codec, p_sys->width, p_sys->height);
-                p_sys->b_es_setup = YES;
+                _fmt.video.i_frame_rate = 1;
+                _fmt.video.i_frame_rate_base = [_output timeScale];
+                msg_Dbg(_demux, "using frame rate base: %i", _fmt.video.i_frame_rate_base);
+                _width
+                    = _fmt.video.i_width
+                    = _fmt.video.i_visible_width
+                    = [_output width];
+                _height
+                    = _fmt.video.i_height
+                    = _fmt.video.i_visible_height
+                    = [_output height];
+                _fmt.video.i_chroma = _fmt.i_codec;
+
+                _es_video = es_out_Add(_demux->out, &_fmt);
+                video_format_Print(&_demux->obj, "added new video es", &_fmt.video);
             }
         }
-        
-        es_out_SetPCR(p_demux->out, p_block->i_pts);
-        es_out_Send(p_demux->out, p_sys->p_es_video, p_block);
-        
+
+        es_out_SetPCR(_demux->out, p_block->i_pts);
+        es_out_Send(_demux->out, _es_video, p_block);
     }
     return 1;
 }
 
-/*****************************************************************************
-* Control:
-*****************************************************************************/
-static int Control(demux_t *p_demux, int i_query, va_list args)
+- (vlc_tick_t)pts
 {
-    bool        *pb;
-
-    switch( i_query )
-    {
-        /* Special for access_demux */
-        case DEMUX_CAN_PAUSE:
-        case DEMUX_CAN_SEEK:
-        case DEMUX_SET_PAUSE_STATE:
-        case DEMUX_CAN_CONTROL_PACE:
-           pb = va_arg(args, bool *);
-           *pb = false;
-           return VLC_SUCCESS;
-
-        case DEMUX_GET_PTS_DELAY:
-           *va_arg(args, vlc_tick_t *) =
-               VLC_TICK_FROM_MS(var_InheritInteger(p_demux, "live-caching"));
-           return VLC_SUCCESS;
-
-        case DEMUX_GET_TIME:
-            *va_arg(args, vlc_tick_t *) = vlc_tick_now();
-            return VLC_SUCCESS;
+    return [_output currentPts];
+}
 
-        default:
-           return VLC_EGENERIC;
-    }
-    return VLC_EGENERIC;
+- (void)dealloc
+{
+    // Perform this on main thread, as the framework itself will sometimes try to synchronously
+    // work on main thread. And this will create a dead lock.
+    [_session performSelectorOnMainThread:@selector(stopRunning) withObject:nil waitUntilDone:NO];
 }
+ at end



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5f8f52991601290d6c37d74e3e3d4d98349127bc...48d50cdf85df551772fd3778db2933cc7aa88e81

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5f8f52991601290d6c37d74e3e3d4d98349127bc...48d50cdf85df551772fd3778db2933cc7aa88e81
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list