예제 #1
0
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);
}
예제 #2
0
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;
}