Converting NSDictionary to CFDictionary in VideoToolbox

2.2k views Asked by At

What's the difference between

const void *keys[] = { kCVPixelBufferPixelFormatTypeKey };
OSStatus pixelFormatType = kCVPixelFormatType_32BGRA;
CFNumberRef pixelFormatTypeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormatType);
const void *values[] = { pixelFormatTypeRef };
CFDictionaryRef destinationImageBufferAttrs = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);

and

CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)(@{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)});

?

I am getting an EXC_BAD_ACCESS error if I use the second one. Why?

2

There are 2 answers

1
CRD On BEST ANSWER

In your first code sample, the reference stored into destinationImageBufferAttrs is owned and must be later released using CFRelease (or transferred to ARC control).

In the second code sample, the reference stored into destinationImageBufferAttrs is under ARC control and ARC can free it immediately after the assignment as there are no longer ARC-owned references to it.

Change __bridge to __bridge_retained to transfer ownership from ARC to your own code, you will then be responsible for calling CFRelease for the object.

0
viz On

It turned out that @{} literal was not retained after putting into the CFDictionaryRef when I wanted to access again. So below code will work instead:

NSDictionary *dic = @{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; // "dic" reference will retain the nsdic created with @ literal
CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)dic;