diff --git a/src/gstducativc1dec.c b/src/gstducativc1dec.c
index 2c4067135b22393eb3be2cf062ff9708b26ee5d5..324e75d8a37493f6576a49c9b60fdf64857ef3d0 100644 (file)
--- a/src/gstducativc1dec.c
+++ b/src/gstducativc1dec.c
*/
#ifdef HAVE_CONFIG_H
-# include <config.h>
+#include <config.h>
#endif
#include "gstducativc1dec.h"
#define GST_BUFFER_FLAG_B_FRAME (GST_BUFFER_FLAG_LAST << 0)
-GST_BOILERPLATE (GstDucatiVC1Dec, gst_ducati_vc1dec, GstDucatiVidDec,
- GST_TYPE_DUCATIVIDDEC);
+static void gst_ducati_vc1dec_base_init (gpointer gclass);
+static void gst_ducati_vc1dec_class_init (GstDucatiVC1DecClass * klass);
+static void gst_ducati_vc1dec_init (GstDucatiVC1Dec * self, gpointer klass);
+
+static GstDucatiVidDecClass *parent_class = NULL;
+
+GType
+gst_ducati_vc1dec_get_type (void)
+{
+ static GType ducati_vc1dec_type = 0;
+
+ if (!ducati_vc1dec_type) {
+ static const GTypeInfo ducati_vc1dec_info = {
+ sizeof (GstDucatiVC1DecClass),
+ (GBaseInitFunc) gst_ducati_vc1dec_base_init,
+ NULL,
+ (GClassInitFunc) gst_ducati_vc1dec_class_init,
+ NULL,
+ NULL,
+ sizeof (GstDucatiVC1Dec),
+ 0,
+ (GInstanceInitFunc) gst_ducati_vc1dec_init,
+ };
+
+ ducati_vc1dec_type = g_type_register_static (GST_TYPE_DUCATIVIDDEC,
+ "GstDucatiVC1Dec", &ducati_vc1dec_info, 0);
+ }
+ return ducati_vc1dec_type;
+}
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-wmv, "
"wmvversion = (int) 3, "
- "format = (fourcc){ WVC1, WMV3 }, "
+ "format = (string){ WVC1, WMV3 }, "
"width = (int)[ 16, 2048 ], "
- "height = (int)[ 16, 2048 ], "
- "framerate = (fraction)[ 0, max ];")
+ "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];")
);
/* GstDucatiVidDec vmethod implementations */
{
GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
- if (parent_class->parse_caps (vdec, s)) {
- guint32 format;
- gboolean ret = gst_structure_get_fourcc (s, "format", &format);
- if (ret) {
- switch (format) {
- case GST_MAKE_FOURCC ('W', 'V', 'C', '1'):
- self->level = 4;
- break;
- case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
- self->level = 3;
- break;
- default:
- ret = FALSE;
- break;
+ if (GST_DUCATIVIDDEC_CLASS (parent_class)->parse_caps (vdec, s)) {
+ gchar *format;
+ gboolean ret = FALSE;
+ format = gst_structure_get_string (s, "format");
+ if (format) {
+ if (strcmp (format, "WVC1") == 0) {
+
+ ret = TRUE;
+ self->level = 4;
+ return ret;
+ }
+
+ if (strcmp (format, "WMV3") == 0) {
+ ret = TRUE;
+ self->level = 3;
+ return ret;
+
}
}
- return ret;
+ GST_INFO_OBJECT (vdec, "level %d", self->level);
}
- GST_INFO_OBJECT (vdec, "level %d", self->level);
-
return FALSE;
}
/* calculate output buffer parameters: */
self->padded_width = ALIGN2 (w + (2 * PADX), 7);
- self->padded_height = (ALIGN2 (h / 2, 4) * 2) + 2 * PADY;
+ self->padded_height = (ALIGN2 (h / 2, 4) * 2) + 4 * PADY;
self->min_buffers = 8;
}
gst_ducati_vc1dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret = parent_class->allocate_params (self,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
sizeof (IVC1VDEC_Params), sizeof (IVC1VDEC_DynamicParams),
sizeof (IVC1VDEC_Status), sizeof (IVC1VDEC_InArgs),
sizeof (IVC1VDEC_OutArgs));
params->frameLayerDataPresentFlag = FALSE;
/* enable concealment */
- params->ErrorConcealmentON = 1;
+ params->errorConcealmentON = 1;
/* codec wants lateAcquireArg = -1 */
self->dynParams->lateAcquireArg = -1;
GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
IVC1VDEC_Params *params = (IVC1VDEC_Params *) vdec->params;
guint32 val;
+ GstMapInfo info;
+ gboolean mapped;
/* need a base ts for frame layer timestamps */
if (self->first_ts == GST_CLOCK_TIME_NONE)
- self->first_ts = GST_BUFFER_TIMESTAMP (buf);
+ self->first_ts = GST_BUFFER_PTS (buf);
+
+ if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codecdata) {
+ if (vdec->codecdatasize > 0) {
+ /* There is at least one VC1 stream that claims it is simple profile,
+ but goes on to have frames that use some feature that is unavailable
+ in simple profile(intensity compensation). Since ducati supports
+ both, we frob the header to claim all simple profile videos are
+ main profile. This is a lie, but it should not cause any trouble
+ (I'm sure all liars must say that). */
+
+ if (!(vdec->codecdata[0] & 192))
+ vdec->codecdata[0] |= 64;
+ }
- if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codec_data) {
if (self->level == 4) {
/* for VC-1 Advanced Profile, strip off first byte, and
* send rest of codec_data unmodified;
*/
- push_input (vdec, GST_BUFFER_DATA (vdec->codec_data) + 1,
- GST_BUFFER_SIZE (vdec->codec_data) - 1);
+ push_input (vdec, vdec->codecdata + 1, vdec->codecdatasize - 1);
} else {
/* for VC-1 Simple and Main Profile, build the Table 265 Sequence
* Layer Data Structure header (refer to VC-1 spec, Annex L):
*/
-
val = 0xc5ffffff; /* we don't know the number of frames */
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
/* STRUCT_C (preceded by length).. see Table 263, 264 */
val = 0x00000004;
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
- val = GST_READ_UINT32_LE (GST_BUFFER_DATA (vdec->codec_data));
+ val = GST_READ_UINT32_LE (vdec->codecdata);
/* FIXME: i have NO idea why asfdemux gives me something I need to patch... */
val |= 0x01 << 24;
- push_input (vdec, (guint8 *) & val, 4);
-
+ push_input (vdec, (const guint8 *) &val, 4);
/* STRUCT_A.. see Table 260 and Annex J.2 */
val = vdec->height;
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
val = vdec->width;
- push_input (vdec, (guint8 *) & val, 4);
- GST_INFO_OBJECT (vdec, "seq hdr resolution: %dx%d", vdec->width, vdec->height);
+ push_input (vdec, (const guint8 *) &val, 4);
+ GST_INFO_OBJECT (vdec, "seq hdr resolution: %dx%d", vdec->width,
+ vdec->height);
val = 0x0000000c;
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
/* STRUCT_B.. see Table 261, 262 */
val = 0x00000000; /* not sure how to populate, but codec ignores anyways */
- push_input (vdec, (guint8 *) & val, 4);
- push_input (vdec, (guint8 *) & val, 4);
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
}
}
/* VC-1 Advanced profile needs start-code prepended: */
if (self->level == 4) {
- static guint8 sc[] = { 0x00, 0x00, 0x01, 0x0d }; /* start code */
+ static const guint8 sc[] = { 0x00, 0x00, 0x01, 0x0d }; /* start code */
push_input (vdec, sc, sizeof (sc));
}
-
+
if (params->frameLayerDataPresentFlag) {
- val = GST_BUFFER_SIZE (buf);
+ val = gst_buffer_get_sizes (buf, NULL, NULL);
if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT))
val |= 0x80 << 24;
else
val |= 0x00 << 24;
- push_input (vdec, (guint8 *) & val, 4);
- val = GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buf) - self->first_ts);
- push_input (vdec, (guint8 *) & val, 4);
+ push_input (vdec, (const guint8 *) &val, 4);
+ val = GST_TIME_AS_MSECONDS (GST_BUFFER_PTS (buf) - self->first_ts);
+ push_input (vdec, (const guint8 *) &val, 4);
}
- push_input (vdec, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
+ if (mapped) {
+ push_input (vdec, info.data, info.size);
+ gst_buffer_unmap (buf, &info);
+ }
gst_buffer_unref (buf);
return NULL;
*/
ret = XDM_EOK;
else
- ret = parent_class->handle_error (self, ret, extended_error,
- status_extended_error);
+ ret =
+ GST_DUCATIVIDDEC_CLASS (parent_class)->handle_error (self, ret,
+ extended_error, status_extended_error);
return ret;
}
static gboolean
-gst_ducati_vc1dec_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
+gst_ducati_vc1dec_can_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
gint64 diff)
{
gboolean is_bframe = GST_BUFFER_FLAG_IS_SET (buf,
/* GstElement vmethod implementations */
static GstStateChangeReturn
-gst_ducati_vc1dec_change_state (GstElement * element,
- GstStateChange transition)
+gst_ducati_vc1dec_change_state (GstElement * element, GstStateChange transition)
{
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (element);
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
- gst_element_class_set_details_simple (element_class,
+ gst_element_class_set_static_metadata (element_class,
"DucatiVC1Dec",
"Codec/Decoder/Video",
"Decodes video in WMV3/VC-1 format with ducati",
{
GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_change_state);
bclass->codec_name = "ivahd_vc1vdec";
- bclass->parse_caps =
- GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_parse_caps);
+ bclass->parse_caps = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_parse_caps);
bclass->update_buffer_size =
GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_update_buffer_size);
bclass->allocate_params =
GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_allocate_params);
- bclass->push_input =
- GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_push_input);
+ bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_push_input);
bclass->handle_error = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_handle_error);
- bclass->drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_drop_frame);
+ bclass->can_drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_can_drop_frame);
}
static void
-gst_ducati_vc1dec_init (GstDucatiVC1Dec * self,
- GstDucatiVC1DecClass * gclass)
+gst_ducati_vc1dec_init (GstDucatiVC1Dec * self, gpointer gclass)
{
GstDucatiVidDec *vdec = GST_DUCATIVIDDEC (self);
+#ifndef GST_DISABLE_GST_DEBUG
+ vdec->error_strings[0] = "unsupported VIDDEC3 params";
+ vdec->error_strings[1] = "unsupported dynamic VIDDEC3 params";
+ vdec->error_strings[2] = "unsupported VC1 VIDDEC3 params";
+ vdec->error_strings[3] = "bad datasync settings";
+ vdec->error_strings[4] = "no slice";
+ vdec->error_strings[5] = "corrupted slice header";
+ vdec->error_strings[6] = "corrupted MB data";
+ vdec->error_strings[7] = "unsupported VC1 feature";
+ vdec->error_strings[16] = "stream end";
+ vdec->error_strings[17] = "unsupported resolution";
+ vdec->error_strings[18] = "IVA standby";
+ vdec->error_strings[19] = "invalid mbox message";
+ vdec->error_strings[20] = "corrupted sequence header";
+ vdec->error_strings[21] = "corrupted entry point header";
+ vdec->error_strings[22] = "corrupted picture header";
+ vdec->error_strings[23] = "ref picture buffer error";
+ vdec->error_strings[24] = "no sequence header";
+ vdec->error_strings[30] = "invalid buffer descriptor";
+ vdec->error_strings[31] = "pic size change";
+#endif
+
self->level = -1;
self->first_ts = GST_CLOCK_TIME_NONE;
vdec->pageMemType = XDM_MEMTYPE_RAW;