From b5605b7ce31c43bc29d15507389d980d09eb914a Mon Sep 17 00:00:00 2001 From: Kazunori Kobayashi Date: Mon, 17 Jun 2013 17:41:05 +0900 Subject: [PATCH 08/14] omxwmvdec: support VC-1 stream decoding The input sequence header must be sent to the REL OMX component before pushing the frame data according to the spec. This patch sets codec_data to the the sequence header first, then the processing keeps being passed with doing nothing. Only the Simple/Main profiles are supported by this patch. Advanced profile isn't supported yet. --- omx/gstomxwmvdec.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/omx/gstomxwmvdec.c b/omx/gstomxwmvdec.c index 64460d9..0f8f2db 100644 --- a/omx/gstomxwmvdec.c +++ b/omx/gstomxwmvdec.c @@ -34,12 +34,16 @@ static gboolean gst_omx_wmv_dec_is_format_change (GstOMXVideoDec * dec, GstOMXPort * port, GstVideoCodecState * state); static gboolean gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, GstVideoCodecState * state); +static GstFlowReturn gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * self, + GstVideoCodecFrame * frame); enum { PROP_0 }; +#define SEQ_PARAM_BUF_SIZE 24 + /* class initialization */ #define DEBUG_INIT \ @@ -58,6 +62,8 @@ gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass) videodec_class->is_format_change = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_is_format_change); videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_set_format); + videodec_class->prepare_frame = + GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_prepare_frame); videodec_class->cdata.default_sink_template_caps = "video/x-wmv, " "width=(int) [1,MAX], " "height=(int) [1,MAX]"; @@ -96,3 +102,47 @@ gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, return ret; } + +static GstFlowReturn +gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * self, + GstVideoCodecFrame * frame) +{ + if (self->codec_data) { + OMX_PARAM_PORTDEFINITIONTYPE port_def; + guint32 *SeqHdrBuf; + guint8 *u8ptr; + GstMapInfo info; + + gst_omx_port_get_port_definition (self->dec_in_port, &port_def); + + if (!gst_buffer_map (self->codec_data, &info, GST_MAP_READ)) { + GST_ERROR_OBJECT (self, "Failed to create a gstbuffer mapping"); + return GST_FLOW_ERROR; + } + + SeqHdrBuf = (guint32 *) g_malloc (SEQ_PARAM_BUF_SIZE); + if (SeqHdrBuf == NULL) { + GST_ERROR_OBJECT (self, "Failed to g_malloc"); + return GST_FLOW_ERROR; + } + + /* create sequence header */ + SeqHdrBuf[0] = 0xc5000000; + SeqHdrBuf[1] = 0x00000004; + u8ptr = (guint8 *) & SeqHdrBuf[2]; + u8ptr[0] = info.data[0]; + u8ptr[1] = info.data[1]; + u8ptr[2] = info.data[2]; + u8ptr[3] = info.data[3]; + SeqHdrBuf[3] = port_def.format.video.nFrameHeight; + SeqHdrBuf[4] = port_def.format.video.nFrameWidth; + SeqHdrBuf[5] = 0x0000000c; + + gst_buffer_unmap (self->codec_data, &info); + + gst_buffer_replace (&self->codec_data, NULL); + self->codec_data = gst_buffer_new_wrapped (SeqHdrBuf, SEQ_PARAM_BUF_SIZE); + } + + return GST_FLOW_OK; +} -- 1.8.1.2