Adding a structure to a NSDictionary

480 Views Asked by At

I am creating a CMVideoFormatDescriptionRef out of thin air using this code:

  CMVideoDimensions dimensions = {
    .width = width,
    .height = height
  };

  CMVideoFormatDescriptionRef videoInfo = NULL;

  NSDictionary *options2 = [NSDictionary dictionaryWithObjectsAndKeys:
                           @(YES), kCVPixelBufferCGImageCompatibilityKey,
                           @(YES), kCVPixelBufferCGBitmapContextCompatibilityKey,
                           dimensions, kCVImageBufferDisplayDimensionsKey,
                            nil];
  CFDictionaryRef dictOptionsRef = (__bridge CFDictionaryRef)options2;

  CMFormatDescriptionCreate(kCFAllocatorDefault, kCMMediaType_Video, 'brga', dictOptionsRef, &videoInfo);

I need to pass that dictionary to CMFormatDescriptionCreate.

The problem is the last line

dimensions, kCVImageBufferDisplayDimensionsKey,

This is not the correct way to add dimensions to that dict. It crashes the app.

I have tried to wrap the whole thing on a NSValue using this:

NSValue *miValue = [NSValue value: &dimensions
                     withObjCType:@encode(CMVideoDimensions)];

It works in theory, no crash, but videoInfo is not created correctly (OSStatus -12731). If I remove this last line from the dictionary, videoInfo is created but has no definition for the dimensions, that are assumed to be 0x0 pixels, or codecType. See below:

<CMVideoFormatDescription 0x17044c270 [0x1b0330bb8]> {
    mediaType:'vide' 
    mediaSubType:'brga' 
    mediaSpecific: {
        codecType: 0        dimensions: 0 x 0    <--HERE!!!
    } 
    extensions: {<CFBasicHash 0x17086dcc0 [0x1b0330bb8]>{type = immutable dict, count = 4,
entries =>
    0 : <CFString 0x1aa9427c8 [0x1b0330bb8]>{contents = "CVImageBufferYCbCrMatrix"} = <CFString 0x1aa942808 [0x1b0330bb8]>{contents = "ITU_R_601_4"}
    3 : <CFString 0x1aa942c68 [0x1b0330bb8]>{contents = "CGImageCompatibility"} = <CFBoolean 0x1b0331110 [0x1b0330bb8]>{value = true}
    5 : <CFString 0x1aa9428a8 [0x1b0330bb8]>{contents = "CVImageBufferColorPrimaries"} = <CFString 0x1aa9427e8 [0x1b0330bb8]>{contents = "ITU_R_709_2"}
    6 : <CFString 0x1aa942c48 [0x1b0330bb8]>{contents = "CGBitmapContextCompatibility"} = <CFBoolean 0x1b0331110 [0x1b0330bb8]>{value = true}
}
}
}

A CMVideoFormatDescriptionRef from a regular CMSampleBufferRef shows codecType as BGRA and the regular dimensions of the frame, 1920x1080, for example.

How do I do that?

1

There are 1 best solutions below

0
On BEST ANSWER

The kCVImageBufferDisplayDimensionsKey header file says the key's value is a

// CFDictionary with the following two keys

kCVImageBufferDisplayWidthKey and kCVImageBufferDisplayHeightKey, both of which are CFNumbers.

You're passing CMVideoDimensions instead, so change that to

NSDictionary *dimensions = [NSDictionary dictionaryWithObjectsAndKeys:@(width), kCVImageBufferDisplayWidthKey, @(height), kCVImageBufferDisplayHeightKey];