47-[AVCaptureVideoDataOutput _ updateRemoteQueue:] occasionally crashes

(void) captureOutput: (AVCaptureOutput ) captureOutput didOutputSampleBuffer: (CMSampleBufferRef) sampleBuffer fromConnection: (AVCaptureConnection ) connection

calling this proxy method occasionally crashes the bugly as follows

8 AVFoundation-[AVCaptureVideoDataOutput _ handleRemoteQueueOperation:] + 344
9 AVFoundation _ 47-[AVCaptureVideoDataOutput _ updateRemoteQueue:] _ block_invoke + 100
10 CoreMedia _ FigRemoteOperationReceiverCreateMessageReceiver_block_invoke + 272
11 CoreMedia _ FigRemoteQueueReceiverSetHandler_block_invoke.2 + 224
12 libdispatch.dylib _ dispatch_client_callout + 16-sharp-sharp-sharp description

related codes

/ / Please paste the code text below (do not replace the code with pictures)

< H1 > pragma mark camera related < / H1 >
  • (AVCaptureSession *) captureSession {
    if (! _ captureSession) {

    //
    _captureSession = [[AVCaptureSession alloc] init];
    [_captureSession setSessionPreset:AVCaptureSessionPreset1920x1080];

    }
    return _ captureSession;

}

  • (AVCaptureDeviceInput *) captureInput {
    if (! _ captureInput) {

    _captureInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];

    }
    return _ captureInput;

}

  • (AVCaptureStillImageOutput *) captureOutput {
    if (! _ captureOutput) {

    //
    _captureOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
    [_captureOutput setOutputSettings:outputSettings];

    }
    return _ captureOutput;

}

  • (AVCaptureVideoDataOutput *) captureDataOutput {
    if (! _ captureDataOutput) {

    _captureDataOutput = [[AVCaptureVideoDataOutput alloc] init];
    _captureDataOutput.alwaysDiscardsLateVideoFrames = YES;
    dispatch_queue_t queue = dispatch_queue_create("cameraQueue", NULL);
    [_captureDataOutput setSampleBufferDelegate:self queue:queue];
    NSString* formatKey = (NSString*)kCVPixelBufferPixelFormatTypeKey;
    NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
    NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:formatKey];
    [_captureDataOutput setVideoSettings:videoSettings];

    }
    return _ captureDataOutput;

}

  • (AVCaptureVideoPreviewLayer *) capturePreviewLayer {
    if (! _ capturePreviewLayer) {

    _capturePreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession];
    _capturePreviewLayer.frame = CGRectMake(0,0, ScreenW, ScreenH);
    _capturePreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    }
    return _ capturePreviewLayer;

}

  • (AVCaptureDevice *) captureDevice {
    if (! _ captureDevice) {

    NSArray *deviceArr = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in deviceArr)
    {
        if (device.position == AVCaptureDevicePositionBack){
            _captureDevice = device;
            _captureInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        }
    }

    }
    return _ captureDevice;

}
/ / input device

if ([self.captureSession canAddInput:self.captureInput]) {
    [self.captureSession addInput:self.captureInput];
}
//
if ([self.captureSession canAddOutput:self.captureDataOutput]) {
    [self.captureSession addOutput:self.captureDataOutput];
}
//
if ([self.captureSession canAddOutput:self.captureOutput]) {
    [self.captureSession addOutput:self.captureOutput];
}
//
[self.view.layer addSublayer:self.capturePreviewLayer];

 [self.view.layer addSublayer:self.detectLayer];
 self.view.layer.masksToBounds = YES;
 [self.view addSubview:self.squareView];
Ios
Jun.18,2022

this queue is not appropriate as a local variable of the function.

dispatch_queue_t queue = dispatch_queue_create("cameraQueue", NULL);
[_captureDataOutput setSampleBufferDelegate:self queue:queue];

The

system's proxy callback is performed in a created local queue variable, and
then if the queue happens not to be reclaimed by the system, the proxy call is valid.
if the queue is reclaimed by the system, the proxy call fails

< hr >
< hr >

this must not be created in a function, dispatch_queue_t queue

it's weird to see it

you can use the queue provided by the system.

if you want to use what you customize,

that's what Apple does

@property (nonatomic) dispatch_queue_t sessionQueue;

use AVFoundation, Apple's example code , you should take a look.

AFN uses a single case.


static dispatch_queue_t url_session_manager_processing_queue() {
    static dispatch_queue_t af_url_session_manager_processing_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        af_url_session_manager_processing_queue = dispatch_queue_create("com.alamofire.networking.session.manager.processing", DISPATCH_QUEUE_CONCURRENT);
    });

    return af_url_session_manager_processing_queue;
}
Menu