Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVCaptureVideoDataOutput on iOS 8 does not post sample buffers on the specified dispatch queue

When using AVCaptureVideoDataOutput and defining a sample buffer delegate with a dispatch queue (setSampleBufferDelegate:queue), we are experiencing on iOS 8 that AVFoundation does not post the sample buffers on the specified dispatch queue but rather always uses "com.apple.avfoundation.videodataoutput.bufferqueue".

This works as expected on iOS7.

Has anyone else experienced this?

An obvious workaround is to manually call dispatch_sync in the callback to sync processing to the custom dispatch queue, but this, strangely, causes a deadlock...

Sample code that produces this issue:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    session.sessionPreset = AVCaptureSessionPresetMedium;

    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    captureVideoPreviewLayer.frame = self.view.bounds;
    [self.view.layer addSublayer:captureVideoPreviewLayer];

    [session addInput:[AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:nil]];

    AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];

    queue = dispatch_queue_create("our.dispatch.queue", DISPATCH_QUEUE_SERIAL);

    [output setSampleBufferDelegate:self queue:queue];

    [session addOutput:output];

    [session startRunning];
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    NSLog(@"Running on queue %@, queue that was set is %@, this is %s", dispatch_get_current_queue(),
      [captureOutput performSelector:@selector(sampleBufferCallbackQueue)],
      queue == dispatch_get_current_queue() ? "our queue" : "not our queue!!!");
}
like image 784
m1h4 Avatar asked Oct 02 '14 12:10

m1h4


1 Answers

What's probably happening here is that their queue, com.apple.avfoundation.videodataoutput.bufferqueue, has been set to target yours using dispatch_set_target_queue. This is functionally equivalent to dispatching to your queue, but would explain the name, and would also explain the deadlock when you tried to dispatch back to your queue.

In other words, just because the queue name isn't equal to your queue's name doesn't mean the block isn't executing on your queue.

like image 94
ipmcc Avatar answered Nov 15 '22 00:11

ipmcc