AVCaptureVideoDataOutput на iOS 8 не отправляет выборочные буферы в указанной очереди отправки

При использовании 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!!!"); } 

Что, вероятно, происходит здесь, так это то, что их очередь, com.apple.avfoundation.videodataoutput.bufferqueue , была настроена на таргетинг с помощью dispatch_set_target_queue . Это функционально эквивалентно отправке в вашу очередь, но объяснит это имя, а также объяснит тупик, когда вы попытаетесь отправить обратно в свою очередь.

Другими словами, только потому, что имя очереди не равно имени вашей очереди, это не означает, что блок не выполняется в вашей очереди.

Чтобы обойти эту проблему, мне пришлось изменить мою -captureOutput: ::

 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { dispatch_queue_t queue = ((MyAppDelegate *)UIApplication.sharedApplication.delegate).videoDataOutputQueue; CFRetain(sampleBuffer); dispatch_async(queue, ^{ for (id<AVCaptureVideoDataOutputSampleBufferDelegate> target in captureTargets.copy) [target captureOutput:captureOutput didOutputSampleBuffer:sampleBuffer fromConnection:connection]; CFRelease(sampleBuffer); }); } 
Interesting Posts
Давайте будем гением компьютера.