H264 Decoded frame order with ICMDecompressionSession
Subject : H264 Decoded frame order with ICMDecompressionSession
From: "Edward Hervey" <email@hidden >
Date: Thu, 22 Mar 2007 19:41:03 +0100
Delivered-to: email@hidden
Delivered-to: email@hidden
Dkim-signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=MG0u0Kj9RVbRFqGLq1DOA+IqKPXzZYjY3u2aR8Y+jWmhGFzk8wmm8ijmHiwWemn3V3ASfIur9W/n9os3aPKNl3igSW0MY+z+vMQpDdA3gHya+tqFX4xIJ7WuaolZ2O22+UENY6Hf71rXhDbys2kznYcUU1jYA0aFZv0B1fkL4Vc=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=eXGxMhGQU3X/8PVjKx4G9SLstj4YMJT85G+/GKJp0nKSBeEMZu7m+pMsuP+ECSjFDcHqyr3ubJb9d0it9r68rmVRYOsuCH8P5pIKFZt/mgLszNWYTU6IlvC82gbzhBTnvBX4yucl5tDUY9NWUHpUENUrnNXxR8USl2KqtB2vhwY=
Hi all,
I'm using the ICMDecompressionSession API to decode an h264 stream
which comes from non-quicktime API in order to send it over to some
other non-quicktime API.
It decodes fine... except that the outputted frames given back in
the inputproc are in decoded order. I have tried various combinations
of settings for the ICMFrameTimeRecord.. in vain.
How does one force that API to return decoded frames in playback
order (and not decoded order) ?
Below is the relevant code
static void decompressCb( void *decompressionTrackingRefCon,
OSStatus result,
ICMDecompressionTrackingFlags decompressionTrackingFlags,
CVPixelBufferRef pixelBuffer,
TimeValue64 displayTime,
TimeValue64 displayDuration,
ICMValidTimeFlags validTimeFlags,
void *reserved,
void *sourceFrameRefCon )
{
MacOSXVideoDecoder * macosx;
GstBuffer *origbuf = (GstBuffer *) sourceFrameRefCon;
macosx = (MacOSXVideoDecoder *) decompressionTrackingRefCon;
GST_LOG_OBJECT (macosx, "result:%d, flags:0x%x, pixelBuffer:%p,
displayTime:%lld, displayDuration:%lld",
result, decompressionTrackingFlags, pixelBuffer, displayTime,
displayDuration);
GST_LOG_OBJECT (macosx, "validTimeFlags:0x%x, reserved:%p,
sourceFrameRefCon:%p",
validTimeFlags, reserved, sourceFrameRefCon);
if (decompressionTrackingFlags &
kICMDecompressionTracking_ReleaseSourceData) {
GST_LOG ("removing previous buffer : %p", origbuf);
gst_buffer_unref (origbuf);
}
if ((decompressionTrackingFlags &
kICMDecompressionTracking_EmittingFrame) && pixelBuffer) {
gpointer addr;
GstBuffer *outbuf;
size_t size = CVPixelBufferGetDataSize(pixelBuffer);
GstClockTime outtime = gst_util_uint64_scale (displayTime, GST_SECOND, 600);
GST_LOG ("Got a buffer ready : %p, outtime : %"GST_TIME_FORMAT,
addr, GST_TIME_ARGS (outtime));
CVPixelBufferRetain (pixelBuffer);
if (CVPixelBufferLockBaseAddress (pixelBuffer, 0))
GST_WARNING ("Couldn't lock base adress on pixel buffer !");
addr = CVPixelBufferGetBaseAddress(pixelBuffer);
...
/* copy data */
GST_LOG ("copying data in buffer from %p to %p",
addr, GST_BUFFER_DATA (outbuf));
g_memmove (GST_BUFFER_DATA (outbuf), addr, size);
GST_LOG ("Releasing pixelbuffer");
CVPixelBufferUnlockBaseAddress (pixelBuffer, 0);
CVPixelBufferRelease (pixelBuffer);
/* Set proper timestamp ! */
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (macosx->srcpad));
GST_BUFFER_TIMESTAMP (outbuf) = outtime;
GST_BUFFER_DURATION (outbuf) = displayDuration;
GST_BUFFER_SIZE (outbuf) = macosx->outsize;
/* push buffer */
GST_LOG ("Pushing buffer out !");
macosx->lastret = gst_pad_push (macosx->srcpad, outbuf);
} else {
macosx->lastret = GST_FLOW_OK;
}
beach:
return;
}
static GstFlowReturn
macosx_video_decoder_chain (GstPad * pad, GstBuffer * buf)
{
MacOSXVideoDecoder *macosx;
GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *outbuf;
TimeValue64 sampleDecodeTime;
ICMFrameTimeRecord frameTime = {0};
OSErr oserr;
guint64 intime;
macosx = (MacOSXVideoDecoder *) gst_pad_get_parent (pad);
intime = gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buf), 600, GST_SECOND);
GST_DEBUG_OBJECT (macosx, "buffer:%p timestamp:%"GST_TIME_FORMAT"
intime:%llu",
buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
intime);
frameTime.recordSize = sizeof (ICMFrameTimeRecord);
frameTime.value.lo = intime;
frameTime.value.hi = 0;
frameTime.base = 0;
frameTime.scale = 600;
frameTime.rate = fixed1;
frameTime.frameNumber = ++macosx->frameNumber;
oserr = ICMDecompressionSessionDecodeFrame(macosx->decsession,
GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf),
NULL,
&frameTime,
buf);
if (oserr != noErr) {
GST_WARNING_OBJECT (macosx, "Error when Calling DecodeFrame() : %d",
oserr);
ret = GST_FLOW_ERROR;
goto beach;
}
beach:
gst_object_unref (macosx);
return macosx->lastret;
}
--
Edward Hervey
Multimedia editing developer / Fluendo S.A.
http://www.pitivi.org/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
QuickTime-API mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quicktime-api/email@hidden
This email sent to email@hidden
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE
Contact Apple | Terms of Use | Privacy Policy
Copyright © 2007 Apple Inc. All rights reserved.