rvdec: fix compile errors
[glsdk/gst-plugin-ducati.git] / src / gstducatirvdec.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-ducatirvdec
22  *
23  * FIXME:Describe ducatirvdec here.
24  *
25  * <refsect2>
26  * <title>Example launch line</title>
27  * |[
28  * gst-launch -v -m fakesrc ! ducatirvdec ! fakesink silent=TRUE
29  * ]|
30  * </refsect2>
31  */
33 #ifdef HAVE_CONFIG_H
34 #  include <config.h>
35 #endif
37 #include "gstducatirvdec.h"
40 #define PADX  32
41 #define PADY  32
44 GST_BOILERPLATE (GstDucatiRVDec, gst_ducati_rvdec, GstDucatiVidDec,
45     GST_TYPE_DUCATIVIDDEC);
47 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
48     GST_PAD_SINK,
49     GST_PAD_ALWAYS,
50     GST_STATIC_CAPS ("video/x-pn-realvideo, "
51         "systemstream = (boolean)false, "
52         "rmversion = (int){ 3, 4 }, "
53         "width = (int)[ 16, 2048 ], "
54         "height = (int)[ 16, 2048 ], "
55         "framerate = (fraction)[ 0, max ];")
56     );
58 /* GstDucatiVidDec vmethod implementations */
60 static gboolean
61 gst_ducati_rvdec_parse_caps (GstDucatiVidDec * vdec, GstStructure * s)
62 {
63   GstDucatiRVDec *self = GST_DUCATIRVDEC (vdec);
65   if (parent_class->parse_caps (vdec, s)) {
66     gboolean ret = gst_structure_get_int (s, "rmversion", &self->rmversion);
67     if (ret) {
68       IrealVDEC_Params *params = (IrealVDEC_Params *) vdec->params;
69       GST_DEBUG_OBJECT (self, "rmversion: %d", self->rmversion);
71       if (self->rmversion == 3) {
72         params->stream_type = 1;
73         params->codec_version = 8;
74       } else if (self->rmversion == 4) {
75         params->stream_type = 1;
76         params->codec_version = 9;
77       } else {
78         ret = FALSE;
79       }
80     }
82     return ret;
83   }
85   return FALSE;
86 }
88 static void
89 gst_ducati_rvdec_update_buffer_size (GstDucatiVidDec * self)
90 {
91   /* calculate output buffer parameters: */
92   self->padded_width = ALIGN2 (self->width + (2 * PADX), 7);
93   self->padded_height = self->height + 2 * PADY;
94   self->min_buffers = 8;
95 }
97 static gboolean
98 gst_ducati_rvdec_allocate_params (GstDucatiVidDec * vdec, gint params_sz,
99     gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
101   GstDucatiRVDec *self = GST_DUCATIRVDEC (vdec);
102   gboolean ret = parent_class->allocate_params (vdec,
103       sizeof (IrealVDEC_Params), sizeof (IrealVDEC_DynamicParams),
104       sizeof (IrealVDEC_Status), sizeof (IrealVDEC_InArgs),
105       sizeof (IrealVDEC_OutArgs));
107   if (ret) {
108     /*IrealVDEC_Params *params = (IrealVDEC_Params *) vdec->params;*/
109     vdec->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
110     vdec->dynParams->newFrameFlag = FALSE;
111     vdec->dynParams->lateAcquireArg = -1;
112     vdec->params->numInputDataUnits = 1;
113     vdec->params->numOutputDataUnits = 1;
114   }
116   return ret;
119 static GstBuffer *
120 gst_ducati_rvdec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
122   GstDucatiRVDec *self = GST_DUCATIRVDEC (vdec);
123   guint8 *data;
124   guint8 val[4];
125   gint i, sz, slice_count;
127   /* *** on first buffer, build up the stream header for the codec *** */
128   if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codec_data) {
130     sz = GST_BUFFER_SIZE (vdec->codec_data);
131     data = GST_BUFFER_DATA (vdec->codec_data);
133     /* header size, 4 bytes, big-endian */
134     GST_WRITE_UINT32_BE (val, sz + 26);
135     push_input (vdec, val, 4);
137     /* stream type */
138     if (self->rmversion == 3) {
139       push_input (vdec, (guint8 *)"VIDORV30", 8);
140     } else if (self->rmversion == 4) {
141       push_input (vdec, (guint8 *)"VIDORV40", 8);
142     }
144     /* horiz x vert resolution */
145     GST_WRITE_UINT16_BE (val, vdec->width);
146     push_input (vdec, val, 2);
147     GST_WRITE_UINT16_BE (val, vdec->height);
148     push_input (vdec, val, 2);
150     /* unknown? */
151     GST_WRITE_UINT32_BE (val, 0x000c0000);
152     push_input (vdec, val, 4);
154     /* unknown? may be framerate.. */
155     GST_WRITE_UINT32_BE (val, 0x0000000f);
156     push_input (vdec, val, 4);
158     /* unknown? */
159     GST_WRITE_UINT16_BE (val, 0x0000);
160     push_input (vdec, val, 2);
162     /* and rest of stream header is the codec_data */
163     push_input (vdec, data, sz);
164   }
166   data = GST_BUFFER_DATA (buf);
167   sz = GST_BUFFER_SIZE (buf);
168   slice_count = (*data++) + 1;
170   /* payload size, excluding fixed header and slice header */
171   sz -= 1 + (8 * slice_count);
173   /* *** insert frame header *** */
174   /* payload size */
175   GST_WRITE_UINT32_BE (val, sz);
176   push_input (vdec, val, 4);
178   /* unknown? may be timestamp, hopefully decoder doesn't care */
179   GST_WRITE_UINT32_BE (val, 0x00000001);
180   push_input (vdec, val, 4);
182   /* unknown? may be sequence number, hopefully decoder doesn't care */
183   GST_WRITE_UINT16_BE (val, 0x0000);
184   push_input (vdec, val, 2);
186   /* unknown? may indicate I frame, hopefully decoder doesn't care */
187   if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
188     GST_WRITE_UINT16_BE (val, 0x0000);
189   } else {
190     GST_WRITE_UINT16_BE (val, 0x0002);
191   }
192   push_input (vdec, val, 2);
194   /* unknown? seems to be always zeros */
195   GST_WRITE_UINT32_BE (val, 0x00000000);
196   push_input (vdec, val, 4);
198   /* convert the slice_header to big endian, and note that the codec
199    * expects to get slice_count rather than slice_count-1
200    */
201   GST_WRITE_UINT32_BE (val, slice_count);
202   push_input (vdec, val, 4);
204   for (i = 0; i < slice_count; i++) {
205     GST_WRITE_UINT32_BE (val, 0x00000001);
206     push_input (vdec, val, 4);
208     data += 4;
209     GST_WRITE_UINT32_BE (val, GST_READ_UINT32_LE (data));
210     data += 4;
211     push_input (vdec, val, 4);
212   }
214   /* copy the payload (rest of buffer) */
215   push_input (vdec, data, sz);
216   gst_buffer_unref (buf);
218   return NULL;
221 /* GObject vmethod implementations */
223 static void
224 gst_ducati_rvdec_base_init (gpointer gclass)
226   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
228   gst_element_class_set_details_simple (element_class,
229       "DucatiRVDec",
230       "Codec/Decoder/Video",
231       "Decodes video in RealVideo (RV8/9/10) format with ducati",
232       "Rob Clark <rob@ti.com>");
234   gst_element_class_add_pad_template (element_class,
235       gst_static_pad_template_get (&sink_factory));
238 static void
239 gst_ducati_rvdec_class_init (GstDucatiRVDecClass * klass)
241   GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass);
242   bclass->codec_name = "ivahd_realvdec";
243   bclass->parse_caps =
244       GST_DEBUG_FUNCPTR (gst_ducati_rvdec_parse_caps);
245   bclass->update_buffer_size =
246       GST_DEBUG_FUNCPTR (gst_ducati_rvdec_update_buffer_size);
247   bclass->allocate_params =
248       GST_DEBUG_FUNCPTR (gst_ducati_rvdec_allocate_params);
249   bclass->push_input =
250       GST_DEBUG_FUNCPTR (gst_ducati_rvdec_push_input);
253 static void
254 gst_ducati_rvdec_init (GstDucatiRVDec * self,
255     GstDucatiRVDecClass * gclass)