clean up padded buffer size calculations
[glsdk/gst-plugin-ducati.git] / src / gstducativc1dec.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-ducativc1dec
22  *
23  * FIXME:Describe ducativc1dec here.
24  *
25  * <refsect2>
26  * <title>Example launch line</title>
27  * |[
28  * gst-launch -v -m fakesrc ! ducativc1dec ! fakesink silent=TRUE
29  * ]|
30  * </refsect2>
31  */
33 #ifdef HAVE_CONFIG_H
34 #  include <config.h>
35 #endif
37 #include <gst/gst.h>
38 #include <gst/video/video.h>
40 #include "gstducativc1dec.h"
43 #define PADX  32
44 #define PADY  40
47 GST_BOILERPLATE (GstDucatiVC1Dec, gst_ducati_vc1dec, GstDucatiVidDec,
48     GST_TYPE_DUCATIVIDDEC);
50 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("video/x-wmv, "
54         "wmvversion = (int)[ 2, 3 ], "
55         "format = (fourcc){ WVC1, WMV3, WMV2, WMV1 }, "
56         "width = (int)[ 16, 2048 ], "
57         "height = (int)[ 16, 2048 ], "
58         "framerate = (fraction)[ 0, max ];")
59     );
61 /* GstDucatiVidDec vmethod implementations */
63 static gboolean
64 gst_ducati_vc1dec_parse_caps (GstDucatiVidDec * vdec, GstStructure * s)
65 {
66   GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
68   if (parent_class->parse_caps (vdec, s)) {
69     guint32 format;
70     gboolean ret = gst_structure_get_fourcc (s, "format", &format);
71     if (ret) {
72       switch (format) {
73         case GST_MAKE_FOURCC ('W', 'V', 'C', '1'):
74           self->level = 4;
75           break;
76         case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
77           self->level = 3;
78           break;
79         case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
80           self->level = 2;
81           break;
82         case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
83           self->level = 1;
84           break;
85         default:
86           ret = FALSE;
87           break;
88       }
89     }
90     return ret;
91   }
93   return FALSE;
94 }
96 static void
97 gst_ducati_vc1dec_update_buffer_size (GstDucatiVidDec * self)
98 {
99   gint w = self->width;
100   gint h = self->height;
102   /* calculate output buffer parameters: */
103   self->padded_width = ALIGN2 (w + (2 * PADX), 7);
104   self->padded_height = (ALIGN2 (h / 2, 4) * 2) + 2 * PADY;
105   self->min_buffers = 8;
108 static gboolean
109 gst_ducati_vc1dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
110     gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
112   gboolean ret = parent_class->allocate_params (self,
113       sizeof (IVC1VDEC_Params), sizeof (IVC1VDEC_DynamicParams),
114       sizeof (IVC1VDEC_Status), sizeof (IVC1VDEC_InArgs),
115       sizeof (IVC1VDEC_OutArgs));
117   if (ret) {
118     IVC1VDEC_Params *params = (IVC1VDEC_Params *) self->params;
119     self->params->maxBitRate = 45000000;
120     self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
121     params->FrameLayerDataPresentFlag = FALSE;
122   }
124   return ret;
127 static GstBuffer *
128 gst_ducati_vc1dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
130   GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
132   if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codec_data) {
133     if (self->level == 4) {
134       /* for VC-1 Advanced Profile, strip off first byte, and
135        * send rest of codec_data unmodified;
136        */
137       push_input (vdec, GST_BUFFER_DATA (vdec->codec_data) + 1,
138           GST_BUFFER_SIZE (vdec->codec_data) - 1);
139     } else {
140       guint32 val;
142       /* for VC-1 Simple and Main Profile, build the Table 265 Sequence
143        * Layer Data Structure header (refer to VC-1 spec, Annex L):
144        */
146       val = 0xc5ffffff;         /* we don't know the number of frames */
147       push_input (vdec, (guint8 *) & val, 4);
149       /* STRUCT_C (preceded by length).. see Table 263, 264 */
150       val = GST_BUFFER_SIZE (vdec->codec_data);
151       push_input (vdec, (guint8 *) & val, 4);
152       push_input (vdec, GST_BUFFER_DATA (vdec->codec_data), val);
154       /* STRUCT_A.. see Table 260 and Annex J.2 */
155       push_input (vdec, (guint8 *) & vdec->height, 4);
156       push_input (vdec, (guint8 *) & vdec->width, 4);
158       val = 0x0000000c;
159       push_input (vdec, (guint8 *) & val, 4);
161       /* STRUCT_B.. see Table 261, 262 */
162       val = 0x00000000;         /* not sure how to populate, but codec ignores anyways */
163       push_input (vdec, (guint8 *) & val, 4);
164       push_input (vdec, (guint8 *) & val, 4);
165       push_input (vdec, (guint8 *) & val, 4);
166     }
167   }
169   /* VC-1 Advanced profile needs start-code prepended: */
170   if (self->level == 4) {
171     static guint8 sc[] = { 0x00, 0x00, 0x01, 0x0d };    /* start code */
172     push_input (vdec, sc, sizeof (sc));
173   }
175   push_input (vdec, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
176   gst_buffer_unref (buf);
178   return NULL;
182 /* GObject vmethod implementations */
184 static void
185 gst_ducati_vc1dec_base_init (gpointer gclass)
187   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
189   gst_element_class_set_details_simple (element_class,
190       "DucatiVC1Dec",
191       "Codec/Decoder/Video",
192       "Decodes video in WMV/VC-1 format with ducati",
193       "Rob Clark <rob@ti.com>");
195   gst_element_class_add_pad_template (element_class,
196       gst_static_pad_template_get (&sink_factory));
199 static void
200 gst_ducati_vc1dec_class_init (GstDucatiVC1DecClass * klass)
202   GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass);
203   bclass->codec_name = "ivahd_vc1vdec";
204   bclass->parse_caps =
205       GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_parse_caps);
206   bclass->update_buffer_size =
207       GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_update_buffer_size);
208   bclass->allocate_params =
209       GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_allocate_params);
210   bclass->push_input =
211       GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_push_input);
214 static void
215 gst_ducati_vc1dec_init (GstDucatiVC1Dec * self,
216     GstDucatiVC1DecClass * gclass)