OSStatus MovieWriter::Obj::encodedFrameOutputCallback( void *refCon, ICMCompressionSessionRef session, OSStatus err, ICMEncodedFrameRef encodedFrame, void *reserved ) { MovieWriter::Obj *obj = reinterpret_cast<MovieWriter::Obj*>( refCon ); ImageDescriptionHandle imageDescription = NULL; err = ICMCompressionSessionGetImageDescription( session, &imageDescription ); if( ! err ) { Fixed gammaLevel = qtime::floatToFixed( obj->mFormat.mGamma ); err = ICMImageDescriptionSetProperty(imageDescription, kQTPropertyClass_ImageDescription, kICMImageDescriptionPropertyID_GammaLevel, sizeof(gammaLevel), &gammaLevel); if( err != 0 ) throw; } else throw; OSStatus result = ::AddMediaSampleFromEncodedFrame( obj->mMedia, encodedFrame, NULL ); return result; }
// Prepare to compress frames. // Compressor should record session and sessionOptions for use in later calls. // Compressor may modify imageDescription at this point. // Compressor may create and return pixel buffer options. ComponentResult VP8_Encoder_PrepareToCompressFrames( VP8EncoderGlobals glob, ICMCompressorSessionRef session, ICMCompressionSessionOptionsRef sessionOptions, ImageDescriptionHandle imageDescription, void *reserved, CFDictionaryRef *compressorPixelBufferAttributesOut) { dbg_printf("[vp8e] Prepare to Compress Frames\n", (UInt32)glob); ComponentResult err = noErr; CFMutableDictionaryRef compressorPixelBufferAttributes = NULL; //This format later needs to be converted OSType pixelFormatList[] = { k422YpCbCr8PixelFormat }; // also known as '2vuy' Fixed gammaLevel; int frameIndex; SInt32 widthRoundedUp, heightRoundedUp; // Record the compressor session for later calls to the ICM. // Note: this is NOT a CF type and should NOT be CFRetained or CFReleased. glob->session = session; // Retain the session options for later use. ICMCompressionSessionOptionsRelease(glob->sessionOptions); glob->sessionOptions = sessionOptions; ICMCompressionSessionOptionsRetain(glob->sessionOptions); // Modify imageDescription here if needed. // We'll set the image description gamma level to say "2.2". gammaLevel = kQTCCIR601VideoGammaLevel; err = ICMImageDescriptionSetProperty(imageDescription, kQTPropertyClass_ImageDescription, kICMImageDescriptionPropertyID_GammaLevel, sizeof(gammaLevel), &gammaLevel); if (err) goto bail; // Record the dimensions from the image description. glob->width = (*imageDescription)->width; glob->height = (*imageDescription)->height; dbg_printf("[vp8e - %08lx] Prepare to compress frame width %d height %d\n", (UInt32)glob, glob->width, glob->height); if (glob->width < 16 || glob->width % 2 || glob->height < 16 || glob->height % 2) dbg_printf("[vp8e - %08lx] Warning :: Invalid resolution: %ldx%ld", (UInt32)glob, glob->width, glob->height); if (glob->raw == NULL) glob->raw = calloc(1, sizeof(vpx_image_t)); //Right now I'm only using YV12, this is great for webm, as I control the spit component if (!vpx_img_alloc(glob->raw, IMG_FMT_YV12, glob->width, glob->height, 1)) { dbg_printf("[vp8e - %08lx] Error: Failed to allocate image %dx%d", (UInt32)glob, glob->width, glob->height); err = paramErr; goto bail; } glob->maxEncodedDataSize = glob->width * glob->height * 2; dbg_printf("[vp8e - %08lx] currently allocating %d bytes as my max encoded size\n", (UInt32)glob, glob->maxEncodedDataSize); // Create a pixel buffer attributes dictionary. err = createPixelBufferAttributesDictionary(glob->width, glob->height, pixelFormatList, sizeof(pixelFormatList) / sizeof(OSType), &compressorPixelBufferAttributes); if (err) goto bail; *compressorPixelBufferAttributesOut = compressorPixelBufferAttributes; compressorPixelBufferAttributes = NULL; /* Populate encoder configuration */ glob->res = vpx_codec_enc_config_default((&vpx_codec_vp8_cx_algo), &glob->cfg, 0); if (glob->res) { dbg_printf("[vp8e - %08lx] Failed to get config: %s\n", (UInt32)glob, vpx_codec_err_to_string(glob->res)); err = paramErr; //this may be something different .... goto bail; } glob->cfg.g_w = glob->width; glob->cfg.g_h = glob->height; dbg_printf("[vp8e - %08lx] resolution %dx%d\n", (UInt32)glob, glob->cfg.g_w, glob->cfg.g_h); bail: if (err) dbg_printf("[vp8e - %08lx] Error %d\n", (UInt32)glob, err); if (compressorPixelBufferAttributes) CFRelease(compressorPixelBufferAttributes); return err; }