iOS 8上的AVCaptureVideoDataOutput不会在指定的调度队列上发布样本缓冲区

m1h*_*1h4 6 avfoundation grand-central-dispatch ios avcapturesession ios8

当使用AVCaptureVideoDataOutput并使用调度队列(setSampleBufferDelegate:queue)定义样本缓冲区委托时,我们在iOS 8上遇到AVFoundation不会在指定的调度队列上发布样本缓冲区,而是始终使用"com.apple.avfoundation.videodataoutput" .bufferqueue".

这在iOS7上按预期工作.

还有其他人经历过这个吗?

一个明显的解决方法是在回调中手动调用dispatch_sync以将处理同步到自定义调度队列,但奇怪的是,这会导致死锁......

产生此问题的示例代码:

- (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!!!");
}
Run Code Online (Sandbox Code Playgroud)

ipm*_*mcc 7

这里可能发生的是他们的队列com.apple.avfoundation.videodataoutput.bufferqueue已被设置为使用你的目标dispatch_set_target_queue.这在功能上等同于调度到您的队列,但会解释名称,并且还会在您尝试调度回队列时解释死锁.

换句话说,仅仅因为队列名称不等于队列的名称并不意味着块没有在队列上执行.

  • 您可以通过预先暂停队列来确定.然后,如果你最终进入街区,你可以确定这是一个错误. (2认同)