VTDecompressionSessionDecodeFrame callback fails with -12911 when decompressing ProRes. (Ventura)

Hi Everyone,

When decompressing ProRes sample buffers on macOS Ventura, I get the following error -12911. (Which isn't helpful.)

The code works perfectly with macOS 12 Monterey and earlier, just fine..

Here is some code:

                                                                 2,
                                                                 &kCFTypeDictionaryKeyCallBacks,
                                                                 &kCFTypeDictionaryValueCallBacks);
    
    CFDictionarySetValue(pixelAspectSettings, kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing, valueCfr);
    CFDictionarySetValue(pixelAspectSettings, kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing, valueCfr);
    
    CFMutableDictionaryRef settings = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                                 9,
                                                                 &kCFTypeDictionaryKeyCallBacks,
                                                                 &kCFTypeDictionaryValueCallBacks);
    
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_FormatName, proResFormatName);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_ColorPrimaries, kCMFormatDescriptionColorPrimaries_ITU_R_709_2);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_TransferFunction, kCMFormatDescriptionTransferFunction_ITU_R_709_2);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_YCbCrMatrix, kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_PixelAspectRatio, pixelAspectSettings);

    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_FieldCount, valueCfr);
    if (valueCfr != NULL) {
        CFRelease(valueCfr);
    }
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_Vendor, kCMFormatDescriptionVendor_Apple);
    value = 0x3ff;
    valueCfr = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_SpatialQuality, valueCfr);
    if (valueCfr != NULL) {
        CFRelease(valueCfr);
    }
    value = 0;
    valueCfr = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
    CFDictionarySetValue(settings, kCMFormatDescriptionExtension_TemporalQuality, valueCfr);
    if (valueCfr != NULL) {
        CFRelease(valueCfr);
    }
    OSStatus result = CMVideoFormatDescriptionCreate(kCFAllocatorDefault, codecType, w, h, settings, &formatDescription);
    if (result != 0) {
        NSLog(@"hey..");
    }

Which creates a proper description..

Then I setup the decompression session.. (which throws an series of messages in Xcode.. [Security] delegate_identifier:Performance Diagnostics__:::__message:This method should not be called on the main thread as it may lead to UI unresponsiveness.)

	callBackRecord.decompressionOutputCallback = decompressionSessionDecodeFrameCallback;
	callBackRecord.decompressionOutputRefCon = (__bridge void *)self;
		
    CFMutableDictionaryRef destinationImageBufferAttributes = NULL;
    CFMutableDictionaryRef emptyDictionary = NULL;

    destinationImageBufferAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                                 2,
                                                                 &kCFTypeDictionaryKeyCallBacks,
                                                                 &kCFTypeDictionaryValueCallBacks);

    OSType cvPixelFormatType = kCVPixelFormatType_64RGBAHalf;
    CFNumberRef pixelFormat = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &cvPixelFormatType);
        
    emptyDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                        0,
                                         &kCFTypeDictionaryKeyCallBacks,
                                         &kCFTypeDictionaryValueCallBacks);
    
    CFDictionarySetValue(destinationImageBufferAttributes, kCVPixelBufferPixelFormatTypeKey, pixelFormat);
    CFDictionarySetValue(destinationImageBufferAttributes, kCVPixelBufferIOSurfacePropertiesKey, emptyDictionary);

    status = VTDecompressionSessionCreate(kCFAllocatorDefault, formatDesc, NULL, destinationImageBufferAttributes, &callBackRecord, &self->_decompressionSession);

And then, when running the decompression, my callback gets the error.. SampleBuffer setup:

		if ((status != kCMBlockBufferNoErr) || !_dataBuffer) {
			NSLog(@"Could not create block buffer");
		}
		
		status = CMBlockBufferReplaceDataBytes([dstImgBuf bytes], _dataBuffer, 0, sizes);
		if (status != kCMBlockBufferNoErr) {
			NSLog(@"Could not write into block buffer");
		}
		
		status = CMSampleBufferCreate(kCFAllocatorDefault, _dataBuffer, true, NULL, NULL, formatDescription, 1, 0, NULL, 1, &sizes, &_sampleBuffer);
		if ((status != noErr) || !_sampleBuffer) {
			NSLog(@"Could not create block buffer");
		}

And decompression:

        VTDecodeInfoFlags flagOut;
        result = VTDecompressionSessionDecodeFrame(_decompressionSession, _sampleBuffer, flags, nil, &flagOut);

Any thoughts?

bob

Answered by GT-RobertMonaghan in 754210022

I have been assisted by a knowledgeable insider at Apple. To get the decompression session to work with the current version of macOS Ventura (13.4 at the time of this posting,) I need to disable Hardware Rendering. My contact suggested that I add the following to my VTDecompressionSessionCreate function call:

NSDictionary* decoderSpecification = @{(NSString*)kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder : @NO};
    status = VTDecompressionSessionCreate(kCFAllocatorDefault, formatDesc, (__bridge CFDictionaryRef)decoderSpecification, destinationImageBufferAttributes, &callBackRecord, &self->_decompressionSession);

Upon doing this, I did get the decompression session to work. (YES!!) But I still get the following error:

[Security] __delegate_identifier__:Performance Diagnostics__:::____message__:This method should not be called on the main thread as it may lead to UI unresponsiveness.

I hope this will be fixed in macOS 13.5!

bob

Accepted Answer

I have been assisted by a knowledgeable insider at Apple. To get the decompression session to work with the current version of macOS Ventura (13.4 at the time of this posting,) I need to disable Hardware Rendering. My contact suggested that I add the following to my VTDecompressionSessionCreate function call:

NSDictionary* decoderSpecification = @{(NSString*)kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder : @NO};
    status = VTDecompressionSessionCreate(kCFAllocatorDefault, formatDesc, (__bridge CFDictionaryRef)decoderSpecification, destinationImageBufferAttributes, &callBackRecord, &self->_decompressionSession);

Upon doing this, I did get the decompression session to work. (YES!!) But I still get the following error:

[Security] __delegate_identifier__:Performance Diagnostics__:::____message__:This method should not be called on the main thread as it may lead to UI unresponsiveness.

I hope this will be fixed in macOS 13.5!

bob

VTDecompressionSessionDecodeFrame callback fails with -12911 when decompressing ProRes. (Ventura)
 
 
Q