static void HapCodecRegisterYCoCgPixelFormat(void) { ICMPixelFormatInfo pixelInfo; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); HAP_BZERO(&pixelInfo, sizeof(pixelInfo)); pixelInfo.size = sizeof(ICMPixelFormatInfo); pixelInfo.formatFlags = 0; pixelInfo.bitsPerPixel[0] = 32; pixelInfo.cmpCount = 4; pixelInfo.cmpSize = 8; // Ignore any errors here as this could be a duplicate registration ICMSetPixelFormatInfo(kHapCVPixelFormat_CoCgXY, &pixelInfo); addNumberToDictionary(dict, kCVPixelFormatConstant, kHapCVPixelFormat_CoCgXY); addNumberToDictionary(dict, kCVPixelFormatBitsPerBlock, 32); // kCVPixelFormatContainsAlpha is only defined in the SDK for 10.7 plus CFDictionarySetValue(dict, CFSTR("ContainsAlpha"), kCFBooleanFalse); CVPixelFormatDescriptionRegisterDescriptionWithPixelFormatType(dict, kHapCVPixelFormat_CoCgXY); CFRelease(dict); }
static void HapCodecRegisterDXTPixelFormat(OSType fmt, short bits_per_pixel, SInt32 open_gl_internal_format, Boolean has_alpha) { /* * See http://developer.apple.com/legacy/mac/library/#qa/qa1401/_index.html */ ICMPixelFormatInfo pixelInfo; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); HAP_BZERO(&pixelInfo, sizeof(pixelInfo)); pixelInfo.size = sizeof(ICMPixelFormatInfo); pixelInfo.formatFlags = (has_alpha ? kICMPixelFormatHasAlphaChannel : 0); pixelInfo.bitsPerPixel[0] = bits_per_pixel; pixelInfo.cmpCount = 4; pixelInfo.cmpSize = bits_per_pixel / 4; // Ignore any errors here as this could be a duplicate registration ICMSetPixelFormatInfo(fmt, &pixelInfo); addNumberToDictionary(dict, kCVPixelFormatConstant, fmt); // CV has a bug where it disregards kCVPixelFormatBlockHeight, so we lie about block size // (4x1 instead of actual 4x4) and add a vertical block-alignment key instead addNumberToDictionary(dict, kCVPixelFormatBitsPerBlock, bits_per_pixel * 4); addNumberToDictionary(dict, kCVPixelFormatBlockWidth, 4); addNumberToDictionary(dict, kCVPixelFormatBlockVerticalAlignment, 4); addNumberToDictionary(dict, kCVPixelFormatOpenGLInternalFormat, open_gl_internal_format); CFDictionarySetValue(dict, kCVPixelFormatOpenGLCompatibility, kCFBooleanTrue); // kCVPixelFormatContainsAlpha is only defined in the SDK for 10.7 plus CFDictionarySetValue(dict, CFSTR("ContainsAlpha"), (has_alpha ? kCFBooleanTrue : kCFBooleanFalse)); CVPixelFormatDescriptionRegisterDescriptionWithPixelFormatType(dict, fmt); CFRelease(dict); }
// Create a dictionary that describes the kinds of pixel buffers that we want to receive. // The important keys to add are kCVPixelBufferPixelFormatTypeKey, // kCVPixelBufferWidthKey and kCVPixelBufferHeightKey. // Many compressors will also want to set kCVPixelBufferExtendedPixels, // kCVPixelBufferBytesPerRowAlignmentKey, kCVImageBufferGammaLevelKey and kCVImageBufferYCbCrMatrixKey. static OSStatus createPixelBufferAttributesDictionary(SInt32 width, SInt32 height, const OSType *pixelFormatList, int pixelFormatCount, CFMutableDictionaryRef *pixelBufferAttributesOut) { OSStatus err = memFullErr; int i; CFMutableDictionaryRef pixelBufferAttributes = NULL; CFNumberRef number = NULL; CFMutableArrayRef array = NULL; SInt32 widthRoundedUp, heightRoundedUp, extendRight, extendBottom; pixelBufferAttributes = CFDictionaryCreateMutable( NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (! pixelBufferAttributes) goto bail; array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (! array) goto bail; // Under kCVPixelBufferPixelFormatTypeKey, add the list of source pixel formats. // This can be a CFNumber or a CFArray of CFNumbers. for (i = 0; i < pixelFormatCount; i++) { number = CFNumberCreate(NULL, kCFNumberSInt32Type, &pixelFormatList[i]); if (! number) goto bail; CFArrayAppendValue(array, number); CFRelease(number); number = NULL; } CFDictionaryAddValue(pixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, array); CFRelease(array); array = NULL; // Add kCVPixelBufferWidthKey and kCVPixelBufferHeightKey to specify the dimensions // of the source pixel buffers. Normally this is the same as the compression target dimensions. addNumberToDictionary(pixelBufferAttributes, kCVPixelBufferWidthKey, width); addNumberToDictionary(pixelBufferAttributes, kCVPixelBufferHeightKey, height); // If you want to require that extra scratch pixels be allocated on the edges of source pixel buffers, // add the kCVPixelBufferExtendedPixels{Left,Top,Right,Bottom}Keys to indicate how much. // Internally our encoded can only support multiples of 16x16 macroblocks; // we will round the compression dimensions up to a multiple of 16x16 and encode that size. // (Note that if your compressor needs to copy the pixels anyhow (eg, in order to convert to a different // format) you may get better performance if your copy routine does not require extended pixels.) widthRoundedUp = roundUpToMultipleOf16(width); heightRoundedUp = roundUpToMultipleOf16(height); extendRight = widthRoundedUp - width; extendBottom = heightRoundedUp - height; if (extendRight || extendBottom) { addNumberToDictionary(pixelBufferAttributes, kCVPixelBufferExtendedPixelsRightKey, extendRight); addNumberToDictionary(pixelBufferAttributes, kCVPixelBufferExtendedPixelsBottomKey, extendBottom); } // Altivec code is most efficient reading data aligned at addresses that are multiples of 16. // Pretending that we have some altivec code, we set kCVPixelBufferBytesPerRowAlignmentKey to // ensure that each row of pixels starts at a 16-byte-aligned address. addNumberToDictionary(pixelBufferAttributes, kCVPixelBufferBytesPerRowAlignmentKey, 16); // This codec accepts YCbCr input in the form of '2vuy' format pixel buffers. // We recommend explicitly defining the gamma level and YCbCr matrix that should be used. addDoubleToDictionary(pixelBufferAttributes, kCVImageBufferGammaLevelKey, 2.2); CFDictionaryAddValue(pixelBufferAttributes, kCVImageBufferYCbCrMatrixKey, kCVImageBufferYCbCrMatrix_ITU_R_601_4); err = noErr; *pixelBufferAttributesOut = pixelBufferAttributes; pixelBufferAttributes = NULL; bail: if (pixelBufferAttributes) CFRelease(pixelBufferAttributes); if (number) CFRelease(number); if (array) CFRelease(array); return err; }