Tizen 2.1 base
[profile/ivi/gst-openmax0.10.git] / omx / gstomx_base_videodec.c
1 /*
2  * Copyright (C) 2007-2009 Nokia Corporation.
3  *
4  * Author: Felipe Contreras <felipe.contreras@nokia.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include "gstomx_base_videodec.h"
23 #include "gstomx.h"
24
25 enum
26 {
27   ARG_0,
28   ARG_USE_STATETUNING, /* STATE_TUNING */
29 };
30
31 GSTOMX_BOILERPLATE (GstOmxBaseVideoDec, gst_omx_base_videodec, GstOmxBaseFilter,
32     GST_OMX_BASE_FILTER_TYPE);
33
34 static GstOmxReturn
35 process_input_buf (GstOmxBaseFilter * omx_base_filter, GstBuffer **buf)
36 {
37   return GSTOMX_RETURN_OK;
38 }
39
40 static void
41 type_base_init (gpointer g_class)
42 {
43 }
44
45 /* MODIFICATION: add state tuning property */
46 static void
47 set_property (GObject * obj,
48     guint prop_id, const GValue * value, GParamSpec * pspec)
49 {
50   GstOmxBaseVideoDec *self;
51
52   self = GST_OMX_BASE_VIDEODEC (obj);
53
54   switch (prop_id) {
55     /* STATE_TUNING */
56     case ARG_USE_STATETUNING:
57       self->omx_base.use_state_tuning = g_value_get_boolean(value);
58       break;
59     default:
60       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
61       break;
62   }
63 }
64
65 static void
66 get_property (GObject * obj, guint prop_id, GValue * value, GParamSpec * pspec)
67 {
68   GstOmxBaseVideoDec *self;
69
70   self = GST_OMX_BASE_VIDEODEC (obj);
71
72   switch (prop_id) {
73     /* STATE_TUNING */
74     case ARG_USE_STATETUNING:
75       g_value_set_boolean(value, self->omx_base.use_state_tuning);
76       break;
77     default:
78       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
79       break;
80   }
81 }
82
83 static void
84 type_class_init (gpointer g_class, gpointer class_data)
85 {
86   GObjectClass *gobject_class;
87   GstOmxBaseFilterClass *basefilter_class;
88
89   gobject_class = G_OBJECT_CLASS (g_class);
90   basefilter_class = GST_OMX_BASE_FILTER_CLASS (g_class);
91
92   /* Properties stuff */
93   {
94     gobject_class->set_property = set_property;
95     gobject_class->get_property = get_property;
96
97     /* STATE_TUNING */
98     g_object_class_install_property (gobject_class, ARG_USE_STATETUNING,
99         g_param_spec_boolean ("state-tuning", "start omx component in gst paused state",
100         "Whether or not to use state-tuning feature",
101         FALSE, G_PARAM_READWRITE));
102   }
103   basefilter_class->process_input_buf = process_input_buf;
104 }
105
106 static void
107 settings_changed_cb (GOmxCore * core)
108 {
109   GstOmxBaseFilter *omx_base;
110   GstOmxBaseVideoDec *self;
111   guint width;
112   guint height;
113   guint32 format = 0;
114
115   omx_base = core->object;
116   self = GST_OMX_BASE_VIDEODEC (omx_base);
117
118   GST_DEBUG_OBJECT (omx_base, "settings changed");
119
120   {
121     OMX_PARAM_PORTDEFINITIONTYPE param;
122
123     G_OMX_INIT_PARAM (param);
124
125     param.nPortIndex = omx_base->out_port->port_index;
126     OMX_GetParameter (omx_base->gomx->omx_handle, OMX_IndexParamPortDefinition,
127         &param);
128
129     width = param.format.video.nFrameWidth;
130     height = param.format.video.nFrameHeight;
131
132     GST_LOG_OBJECT (omx_base, "settings changed: fourcc =0x%x", (guint)param.format.video.eColorFormat);
133     switch ((guint)param.format.video.eColorFormat) {
134       case OMX_COLOR_FormatYUV420Planar:
135       case OMX_COLOR_FormatYUV420PackedPlanar:
136         format = GST_MAKE_FOURCC ('I', '4', '2', '0');
137         break;
138       case OMX_COLOR_FormatYCbYCr:
139         format = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
140         break;
141       case OMX_COLOR_FormatCbYCrY:
142         format = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
143         break;
144       /* MODIFICATION: Add extended_color_format */
145       case OMX_EXT_COLOR_FormatNV12TFdValue:
146       case OMX_EXT_COLOR_FormatNV12TPhysicalAddress:
147         format = GST_MAKE_FOURCC ('S', 'T', '1', '2');
148         break;
149       case OMX_EXT_COLOR_FormatNV12LPhysicalAddress:
150         format = GST_MAKE_FOURCC ('S', 'N', '1', '2');
151         break;
152       case OMX_COLOR_FormatYUV420SemiPlanar:
153         format = GST_MAKE_FOURCC ('N', 'V', '1', '2');
154         break;
155       default:
156         break;
157     }
158   }
159
160   {
161     GstCaps *new_caps;
162     GstStructure *struc;
163
164     new_caps = gst_caps_new_empty ();
165     struc = gst_structure_new ("video/x-raw-yuv",
166         "width", G_TYPE_INT, width,
167         "height", G_TYPE_INT, height, "format", GST_TYPE_FOURCC, format, NULL);
168
169     if (self->framerate_denom != 0)
170       gst_structure_set (struc, "framerate", GST_TYPE_FRACTION,
171           self->framerate_num, self->framerate_denom, NULL);
172     else
173       /* FIXME this is a workaround for xvimagesink */
174       gst_structure_set (struc, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
175
176     gst_caps_append_structure (new_caps, struc);
177
178     GST_INFO_OBJECT (omx_base, "caps are: %" GST_PTR_FORMAT, new_caps);
179     gst_pad_set_caps (omx_base->srcpad, new_caps);
180     gst_caps_unref (new_caps); /* Modification: unref caps */
181   }
182 }
183
184 static gboolean
185 sink_setcaps (GstPad * pad, GstCaps * caps)
186 {
187   GstStructure *structure;
188   GstOmxBaseVideoDec *self;
189   GstOmxBaseFilter *omx_base;
190   GOmxCore *gomx;
191   OMX_PARAM_PORTDEFINITIONTYPE param;
192   gint width = 0;
193   gint height = 0;
194
195   self = GST_OMX_BASE_VIDEODEC (GST_PAD_PARENT (pad));
196   omx_base = GST_OMX_BASE_FILTER (self);
197
198   gomx = (GOmxCore *) omx_base->gomx;
199
200   GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
201
202   g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE);
203
204   structure = gst_caps_get_structure (caps, 0);
205
206   gst_structure_get_int (structure, "width", &width);
207   gst_structure_get_int (structure, "height", &height);
208
209   {
210     const GValue *framerate = NULL;
211     framerate = gst_structure_get_value (structure, "framerate");
212     if (framerate) {
213       self->framerate_num = gst_value_get_fraction_numerator (framerate);
214       self->framerate_denom = gst_value_get_fraction_denominator (framerate);
215     }
216   }
217
218   G_OMX_INIT_PARAM (param);
219
220   {
221     const GValue *codec_data;
222     GstBuffer *buffer;
223
224     codec_data = gst_structure_get_value (structure, "codec_data");
225     if (codec_data) {
226       buffer = gst_value_get_buffer (codec_data);
227       omx_base->codec_data = buffer;
228       gst_buffer_ref (buffer);
229     }
230   }
231
232   /* Input port configuration. */
233   {
234     param.nPortIndex = omx_base->in_port->port_index;
235     OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
236
237     param.format.video.nFrameWidth = width;
238     param.format.video.nFrameHeight = height;
239
240     OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
241   }
242
243   return gst_pad_set_caps (pad, caps);
244 }
245
246 static void
247 omx_setup (GstOmxBaseFilter * omx_base)
248 {
249   GstOmxBaseVideoDec *self;
250   GOmxCore *gomx;
251
252   self = GST_OMX_BASE_VIDEODEC (omx_base);
253   gomx = (GOmxCore *) omx_base->gomx;
254
255   GST_INFO_OBJECT (omx_base, "begin");
256
257   {
258     OMX_PARAM_PORTDEFINITIONTYPE param;
259
260     G_OMX_INIT_PARAM (param);
261
262     /* Input port configuration. */
263     {
264       param.nPortIndex = omx_base->in_port->port_index;
265       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
266
267       param.format.video.eCompressionFormat = self->compression_format;
268
269       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
270     }
271   }
272
273   GST_INFO_OBJECT (omx_base, "end");
274 }
275
276 static void
277 type_instance_init (GTypeInstance * instance, gpointer g_class)
278 {
279   GstOmxBaseFilter *omx_base;
280
281   omx_base = GST_OMX_BASE_FILTER (instance);
282
283   omx_base->omx_setup = omx_setup;
284
285   omx_base->gomx->settings_changed_cb = settings_changed_cb;
286
287   gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
288 }