mpeg2dec: Fix negotiation issue with playbin
[glsdk/gst-plugin-ducati.git] / src / gstducatimpeg2dec.c
1 /*
2  * GStreamer
3  * Copyright (c) 2010, Texas Instruments Incorporated
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation
8  * version 2.1 of the License.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
20 /**
21  * SECTION:element-ducatimpeg2dec
22  *
23  * FIXME:Describe ducatimpeg2dec here.
24  *
25  * <refsect2>
26  * <title>Example launch line</title>
27  * |[
28  * gst-launch -v -m fakesrc ! ducatimpeg2dec ! fakesink silent=TRUE
29  * ]|
30  * </refsect2>
31  */
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
37 #include "gstducatimpeg2dec.h"
39 static void gst_ducati_mpeg2dec_class_init (GstDucatiMpeg2DecClass * klass);
40 static void gst_ducati_mpeg2dec_init (GstDucatiMpeg2Dec * self, gpointer klass);
41 static void gst_ducati_mpeg2dec_base_init (gpointer gclass);
42 static GstDucatiVidDecClass *parent_class = NULL;
44 GType
45 gst_ducati_mpeg2dec_get_type (void)
46 {
47   static GType ducati_mpeg2dec_type = 0;
49   if (!ducati_mpeg2dec_type) {
50     static const GTypeInfo ducati_mpeg2dec_info = {
51       sizeof (GstDucatiMpeg2DecClass),
52       (GBaseInitFunc) gst_ducati_mpeg2dec_base_init,
53       NULL,
54       (GClassInitFunc) gst_ducati_mpeg2dec_class_init,
55       NULL,
56       NULL,
57       sizeof (GstDucatiMpeg2Dec),
58       0,
59       (GInstanceInitFunc) gst_ducati_mpeg2dec_init,
60     };
62     ducati_mpeg2dec_type = g_type_register_static (GST_TYPE_DUCATIVIDDEC,
63         "GstDucatiMpeg2Dec", &ducati_mpeg2dec_info, 0);
64   }
65   return ducati_mpeg2dec_type;
66 }
68 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
69     GST_PAD_SINK,
70     GST_PAD_ALWAYS,
71     GST_STATIC_CAPS ("video/mpeg, " "mpegversion = (int)[ 1, 2 ], "     // XXX check on MPEG-1..
72         "systemstream = (boolean)false, "
73         "parsed = (boolean)true;")
74     );
76 /* GstDucatiVidDec vmethod implementations */
78 static void
79 gst_ducati_mpeg2dec_update_buffer_size (GstDucatiVidDec * self)
80 {
81   gint w = self->width;
82   gint h = self->height;
84   /* calculate output buffer parameters: */
85   self->padded_width = w;
86   self->padded_height = h;
87   self->min_buffers = 8;
88 }
90 static gboolean
91 gst_ducati_mpeg2dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
92     gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
93 {
94   gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
95       sizeof (IVIDDEC3_Params), sizeof (IVIDDEC3_DynamicParams),
96       sizeof (IVIDDEC3_Status), sizeof (IVIDDEC3_InArgs),
97       sizeof (IVIDDEC3_OutArgs));
99   if (ret)
100     self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
102   return ret;
105 static GstBuffer *
106 gst_ducati_mpeg2dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
108   GstDucatiMpeg2Dec *self = GST_DUCATIMPEG2DEC (vdec);
110   GstMapInfo info;
111   gboolean mapped;
112   mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
114   /* skip codec_data, which is same as first buffer from mpegvideoparse (and
115    * appears to be periodically resent) and instead prepend to next frame..
116    */
117   if (vdec->codecdata && (info.size == vdec->codecdatasize) &&
118       !memcmp (info.data, vdec->codecdata, info.size)) {
119     GST_DEBUG_OBJECT (self, "skipping codec_data buffer");
120     self->prepend_codec_data = TRUE;
121   } else {
122     if (self->prepend_codec_data) {
123       GST_DEBUG_OBJECT (self, "prepending codec_data buffer");
124       push_input (vdec, vdec->codecdata, vdec->codecdatasize);
125       self->prepend_codec_data = FALSE;
126     }
127     if (mapped) {
128       push_input (vdec, info.data, info.size);
129     }
130   }
131   if (mapped) {
132     gst_buffer_unmap (buf, &info);
133   }
134   gst_buffer_unref (buf);
136   return NULL;
139 static gboolean
140 gst_ducati_mpeg2dec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps)
142   GstStructure *structure;
143   const gchar *profile;
145   GST_DEBUG_OBJECT (self, "set_sink_caps: %" GST_PTR_FORMAT, caps);
147   if (!GST_CALL_PARENT_WITH_DEFAULT (GST_DUCATIVIDDEC_CLASS, set_sink_caps,
148           (self, caps), TRUE))
149     return FALSE;
151   /* I have at least one case where incoming timestamps are ordered,
152      but frames are not, so we'd need to find out how to get correct
153      ordering from the internals of the frames. For now, let the hw
154      codec do the reordering to avoid more aggravation (and the 1.0
155      port will let the codec do it anyway). */
156 #if 0
157   /* Simple profile does not have B frames */
158   structure = gst_caps_get_structure (caps, 0);
159   profile = gst_structure_get_string (structure, "profile");
160   if (!profile || strcmp (profile, "simple")) {
161     /* TODO: can a better bound be found from stream headers ? */
162     self->backlog_maxframes = self->backlog_max_maxframes;
163   }
164 #endif
166   return TRUE;
169 static GstFlowReturn
170 gst_ducati_mpeg2dec_push_output (GstDucatiVidDec * self, GstBuffer * buf)
172   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_PTS (buf);
173   return GST_DUCATIVIDDEC_CLASS (parent_class)->push_output (self, buf);
176 /* GObject vmethod implementations */
178 static void
179 gst_ducati_mpeg2dec_base_init (gpointer gclass)
181   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
183   gst_element_class_set_static_metadata (element_class,
184       "DucatiMpeg2Dec",
185       "Codec/Decoder/Video",
186       "Decodes video in MPEG-2 format with ducati", "Rob Clark <rob@ti.com>");
188   gst_element_class_add_pad_template (element_class,
189       gst_static_pad_template_get (&sink_factory));
192 static void
193 gst_ducati_mpeg2dec_class_init (GstDucatiMpeg2DecClass * klass)
195   GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass);
196   parent_class = g_type_class_peek_parent (klass);
197   bclass->codec_name = "ivahd_mpeg2vdec";
198   bclass->update_buffer_size =
199       GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_update_buffer_size);
200   bclass->allocate_params =
201       GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_allocate_params);
202   bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_push_input);
203   bclass->set_sink_caps = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_set_sink_caps);
204   bclass->push_output = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_push_output);
207 static void
208 gst_ducati_mpeg2dec_init (GstDucatiMpeg2Dec * self, gpointer gclass)
210   GstDucatiVidDec *vdec = GST_DUCATIVIDDEC (self);
211   vdec->pageMemType = XDM_MEMTYPE_RAW;