static ComponentResult _setup_ds(StreamInfoPtr si, ImageDescriptionHandle imgDesc) { ComponentResult err = noErr; CFNumberRef number = NULL; CFMutableDictionaryRef pba = NULL; ICMDecompressionTrackingCallbackRecord dtcr; SInt32 w, h; OSType pbf = k422YpCbCr8PixelFormat; dbg_printf("[ vOE] >> [%08lx] :: _setup_ds()\n", (UInt32) -1); if (si->si_v.ds) { ICMDecompressionSessionFlush(si->si_v.ds); ICMDecompressionSessionRelease(si->si_v.ds); si->si_v.ds = NULL; } pba = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); w = si->si_v.width >> 16; h = si->si_v.height >> 16; number = CFNumberCreate(NULL, kCFNumberSInt32Type, &w); CFDictionaryAddValue(pba, kCVPixelBufferWidthKey, number); CFRelease(number); number = CFNumberCreate(NULL, kCFNumberSInt32Type, &h); CFDictionaryAddValue(pba, kCVPixelBufferHeightKey, number); CFRelease(number); number = CFNumberCreate(NULL, kCFNumberSInt32Type, &pbf); CFDictionaryAddValue(pba, kCVPixelBufferPixelFormatTypeKey, number); CFRelease(number); dtcr.decompressionTrackingCallback = _frame_decompressed; dtcr.decompressionTrackingRefCon = (void *) si; err = ICMDecompressionSessionCreate(NULL, imgDesc, /* sessionOptions */ NULL, pba, &dtcr, &si->si_v.ds); CFRelease(pba); dbg_printf("[ vOE] < [%08lx] :: _setup_ds() = %ld\n", (UInt32) -1, err); return err; }
static HRESULT WINAPI QTVDecoder_StartStreaming(TransformFilter* pTransformFilter) { QTVDecoderImpl* This = impl_from_TransformFilter(pTransformFilter); OSErr err = noErr; ICMDecompressionSessionOptionsRef sessionOptions = NULL; ICMDecompressionTrackingCallbackRecord trackingCallbackRecord; TRACE("(%p)->()\n", This); trackingCallbackRecord.decompressionTrackingCallback = trackingCallback; trackingCallbackRecord.decompressionTrackingRefCon = (void*)This; err = ICMDecompressionSessionCreate(NULL, This->hImageDescription, sessionOptions, This->outputBufferAttributes, &trackingCallbackRecord, &This->decompressionSession); if (err != noErr) { ERR("Error with ICMDecompressionSessionCreate %i\n",err); return E_FAIL; } return S_OK; }
int qCreateDecoderAPI(QDecoder **dptr, char* args, int semaIndex, int width, int height) { QDecoder* decoder; // the decompressor to be initialized ImageDescription* imDesc; // description of input frame images ImageDescriptionHandle myImHandle; CFNumberRef number = NULL; CFMutableDictionaryRef pixelBufferAttributes = NULL; ICMDecompressionTrackingCallbackRecord trackingCallbackRecord; QVideoArgs* decoderArgs = (QVideoArgs*)args; CodecInfo codecInfo; OSType pixelFormat = Q_PIXEL_FORMAT; OSStatus err; // status of QuickTime functions fprintf(QSTDERR, "\nqCreateDecoderQT: START DECODER CREATION! (width: %d height: %d)", width, height); decoder = (QDecoder*)malloc(sizeof(QDecoder)); if (decoder == NULL) { fprintf(QSTDERR, "\nqCreateDecoderQT: failed to malloc decoder struct"); return -2; } // Get codec info decoder->codecType = *((CodecType*)(decoderArgs->codecType)); err = GetCodecInfo(&codecInfo, decoder->codecType, NULL); if (err != noErr) { fprintf(QSTDERR, "\nqCreateDecoderQT: cannot get codec info"); fprintf(QSTDERR, "\n\tQUICKTIME ERROR CODE: %d", err); free(decoder); return -5; } // We have found an available camera to initialize. decoder->timeScale = decoderArgs->timeScale; decoder->semaIndex = semaIndex; decoder->width = width; decoder->height = height; decoder->inFrameCount = decoder->outFrameCount = 0; qInitCallbackData(&(decoder->callbackData)); fprintf(QSTDERR, "\nqCreateDecoderQT: INITIALIZED STRUCTURE"); imDesc = &(decoder->imDesc); imDesc->idSize = 86; // grabbed from camera (total size of ImageDescription including extra data) imDesc->cType = decoder->codecType; //imDesc->resvd1; // reserved for Apple use //imDesc->resvd2; // reserved for Apple use imDesc->dataRefIndex = 0; // docs say that this must be set to zero imDesc->version = codecInfo.version; imDesc->revisionLevel = codecInfo.revisionLevel; imDesc->vendor = codecInfo.vendor; imDesc->temporalQuality = codecNormalQuality; imDesc->spatialQuality = codecNormalQuality; imDesc->width = width; // in pixels imDesc->height = height; // in pixels imDesc->hRes = FloatToFixed(72.0); // DPI, I presume imDesc->vRes = FloatToFixed(72.0); // ditto imDesc->dataSize = 0; // every frame will have a different size imDesc->frameCount = 0; // # of frames this desc applies to (is '1' what we want?) memcpy(imDesc->name, codecInfo.typeName, 32 ); imDesc->depth = 24; // might eventually want to support 32 (to support an alpha-channel) imDesc->clutID = -1; // no color-lookup table fprintf(QSTDERR, "\nqCreateDecoderQT: INITIALIZED IMAGE DESCRIPTION"); pixelBufferAttributes = CFDictionaryCreateMutable( NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); number = CFNumberCreate( NULL, kCFNumberIntType, &width ); CFDictionaryAddValue( pixelBufferAttributes, kCVPixelBufferWidthKey, number ); CFRelease( number ); number = CFNumberCreate( NULL, kCFNumberIntType, &height ); CFDictionaryAddValue( pixelBufferAttributes, kCVPixelBufferHeightKey, number ); CFRelease( number ); number = CFNumberCreate( NULL, kCFNumberSInt32Type, &pixelFormat ); CFDictionaryAddValue( pixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, number ); CFRelease( number ); CFDictionaryAddValue( pixelBufferAttributes, kCVPixelBufferCGBitmapContextCompatibilityKey, kCFBooleanTrue ); CFDictionaryAddValue( pixelBufferAttributes, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanTrue ); fprintf(QSTDERR, "\nqCreateDecoderQT: SET UP PIXEL-BUFFER ATTRIBUTES"); trackingCallbackRecord.decompressionTrackingCallback = (ICMDecompressionTrackingCallback)qQuickTimeDecoderCallback; trackingCallbackRecord.decompressionTrackingRefCon = decoder; fprintf(QSTDERR, "\nqCreateDecoderQT: SET UP CALLBACK RECORD"); // Actually create the session. First, we need to allocate copy the image description into a handle // (Quicktime requires this... we dispose of the handle immediately afterward). myImHandle = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription)); **myImHandle = *imDesc; fprintf(QSTDERR, "\nDECOMPRESSOR IMAGE DESCRIPTION:"); qPrintImageDescription(myImHandle); // err = ICMDecompressionSessionCreate(kCFAllocatorDefault, myImHandle, NULL, pixelBufferAttributes, &trackingCallbackRecord, &(decomp->session)); err = ICMDecompressionSessionCreate(NULL, myImHandle, NULL, pixelBufferAttributes, &trackingCallbackRecord, &(decoder->session)); DisposeHandle((Handle)myImHandle); if (err != noErr) { fprintf(QSTDERR, "\nqCreateDecoderQT: cannot create session"); fprintf(QSTDERR, "\n\tQUICKTIME ERROR CODE: %d", err); free(decoder); return -5; } fprintf(QSTDERR, "\nqCreateDecoderQT: FINISHED!!!"); *dptr = decoder; return 0; }
void QTDecompressionSession::initializeSession() { if (m_session) return; ICMPixelFormatInfo pixelFormatInfo = {sizeof(ICMPixelFormatInfo), 0}; if (ICMGetPixelFormatInfo(m_pixelFormat, &pixelFormatInfo) != noErr) { // The ICM does not know anything about the pixelFormat contained in // the pixel buffer, so it won't be able to convert it to RGBA. return; } // The depth and cType fields of the ImageDescriptionHandle are filled // out according to the instructions in Technical Q&A QA1183: // http://developer.apple.com/library/mac/#qa/qa2001/qa1183.html bool isIndexed = pixelFormatInfo.formatFlags & kICMPixelFormatIsIndexed; bool isQD = pixelFormatInfo.formatFlags & kICMPixelFormatIsSupportedByQD; bool isMonochrome = pixelFormatInfo.formatFlags & kICMPixelFormatIsMonochrome; bool hasAlpha = pixelFormatInfo.formatFlags & kICMPixelFormatHasAlphaChannel; unsigned int depth = 24; // The default depth is 24. if (hasAlpha) depth = 32; // Any pixel format with alpha gets a depth of 32. else if (isMonochrome) { // Grayscale pixel formats get depths 33 through 40, depending // on their bits per pixel. Yes, this means that 16-bit grayscale // and 8-bit grayscale have the same pixel depth. depth = 32 + std::min<unsigned int>(8, pixelFormatInfo.bitsPerPixel[0]); } else if (isIndexed) { // Indexed pixel formats get a depth of 1 through 8, depending on // the their bits per pixel. depth = pixelFormatInfo.bitsPerPixel[0]; } // If QuickDraw supports the given pixel format, the cType should be kRawCodecType. // Otherwise, use the pixel format code for the cType. We are assuming the pixel // buffer is uncompressed. unsigned long cType = isQD ? kRawCodecType : m_pixelFormat; ImageDescriptionHandle description = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); (**description).idSize = sizeof(ImageDescription); (**description).cType = cType; (**description).version = 2; (**description).spatialQuality = codecLosslessQuality; (**description).width = m_width; (**description).height = m_height; (**description).hRes = 72 << 16; // 72 DPI as a fixed-point number (**description).vRes = 72 << 16; // 72 DPI as a fixed-point number (**description).frameCount = 1; (**description).depth = depth; (**description).clutID = -1; // Create the mandatory ICMDecompressionSessionOptions, but leave // all the default values. ICMDecompressionSessionOptionsRef options = 0; ICMDecompressionSessionOptionsCreate(kCFAllocatorDefault, &options); CFDictionaryRef pixelBufferAttributes = QTPixelBuffer::createPixelBufferAttributesDictionary(QTPixelBuffer::ConfigureForCGImage); ICMDecompressionTrackingCallbackRecord callback = { QTDecompressionSessionClient::trackingCallback, this, }; ICMDecompressionSessionCreate(kCFAllocatorDefault, description, options, pixelBufferAttributes, &callback, &m_session); if (pixelBufferAttributes) CFRelease(pixelBufferAttributes); ICMDecompressionSessionOptionsRelease(options); DisposeHandle((Handle)description); }