tizen beta release
[profile/ivi/gst-openmax0.10.git] / omx / gstomx_base_videoenc.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_videoenc.h"
23 #include "gstomx.h"
24
25 #include <string.h>             /* for strcmp */
26
27 enum
28 {
29   ARG_0,
30   ARG_BITRATE,
31 };
32
33 #define DEFAULT_BITRATE 0
34
35 GSTOMX_BOILERPLATE (GstOmxBaseVideoEnc, gst_omx_base_videoenc, GstOmxBaseFilter,
36     GST_OMX_BASE_FILTER_TYPE);
37
38 static void
39 type_base_init (gpointer g_class)
40 {
41 }
42
43 static void
44 set_property (GObject * obj,
45     guint prop_id, const GValue * value, GParamSpec * pspec)
46 {
47   GstOmxBaseVideoEnc *self;
48
49   self = GST_OMX_BASE_VIDEOENC (obj);
50
51   switch (prop_id) {
52     case ARG_BITRATE:
53       self->bitrate = g_value_get_uint (value);
54       break;
55     default:
56       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
57       break;
58   }
59 }
60
61 static void
62 get_property (GObject * obj, guint prop_id, GValue * value, GParamSpec * pspec)
63 {
64   GstOmxBaseVideoEnc *self;
65
66   self = GST_OMX_BASE_VIDEOENC (obj);
67
68   switch (prop_id) {
69     case ARG_BITRATE:
70             /** @todo propagate this to OpenMAX when processing. */
71       g_value_set_uint (value, self->bitrate);
72       break;
73     default:
74       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
75       break;
76   }
77 }
78
79 static void
80 type_class_init (gpointer g_class, gpointer class_data)
81 {
82   GObjectClass *gobject_class;
83
84   gobject_class = G_OBJECT_CLASS (g_class);
85
86   /* Properties stuff */
87   {
88     gobject_class->set_property = set_property;
89     gobject_class->get_property = get_property;
90
91     g_object_class_install_property (gobject_class, ARG_BITRATE,
92         g_param_spec_uint ("bitrate", "Bit-rate",
93             "Encoding bit-rate",
94             0, G_MAXUINT, DEFAULT_BITRATE,
95             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
96   }
97 }
98
99 static gboolean
100 sink_setcaps (GstPad * pad, GstCaps * caps)
101 {
102   GstStructure *structure;
103   GstOmxBaseVideoEnc *self;
104   GstOmxBaseFilter *omx_base;
105   GOmxCore *gomx;
106   OMX_COLOR_FORMATTYPE color_format = OMX_COLOR_FormatUnused;
107   gint width = 0;
108   gint height = 0;
109   const GValue *framerate = NULL;
110
111   self = GST_OMX_BASE_VIDEOENC (GST_PAD_PARENT (pad));
112   omx_base = GST_OMX_BASE_FILTER (self);
113   gomx = (GOmxCore *) omx_base->gomx;
114
115   GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
116
117   g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE);
118
119   structure = gst_caps_get_structure (caps, 0);
120
121   gst_structure_get_int (structure, "width", &width);
122   gst_structure_get_int (structure, "height", &height);
123
124   if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
125     guint32 fourcc;
126
127     framerate = gst_structure_get_value (structure, "framerate");
128     if (framerate) {
129       self->framerate_num = gst_value_get_fraction_numerator (framerate);
130       self->framerate_denom = gst_value_get_fraction_denominator (framerate);
131     }
132
133     if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
134       switch (fourcc) {
135         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
136         case GST_MAKE_FOURCC ('S', '4', '2', '0'):
137           color_format = OMX_COLOR_FormatYUV420PackedPlanar;
138           break;
139         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
140           color_format = OMX_COLOR_FormatYCbYCr;
141           break;
142         case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
143           color_format = OMX_COLOR_FormatCbYCrY;
144           break;
145         /* Add extended_color_format */
146         case GST_MAKE_FOURCC ('S', 'T', '1', '2'):
147           color_format = OMX_EXT_COLOR_FormatNV12TPhysicalAddress;
148           break;
149         case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
150           color_format = OMX_EXT_COLOR_FormatNV12LPhysicalAddress;
151           break;
152       }
153     }
154   }
155
156   {
157     OMX_PARAM_PORTDEFINITIONTYPE param;
158
159     G_OMX_INIT_PARAM (param);
160
161     /* Input port configuration. */
162     {
163       param.nPortIndex = omx_base->in_port->port_index;
164       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
165
166       param.format.video.nFrameWidth = width;
167       param.format.video.nFrameHeight = height;
168       param.format.video.eColorFormat = color_format;
169       if (framerate) {
170         /* convert to Q.16 */
171         param.format.video.xFramerate =
172             (gst_value_get_fraction_numerator (framerate) << 16) /
173             gst_value_get_fraction_denominator (framerate);
174       }
175
176       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
177     }
178
179     G_OMX_INIT_PARAM (param);
180
181     param.nPortIndex = omx_base->out_port->port_index;
182     OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
183
184     param.nBufferSize = MAX(param.nBufferSize, width * height * 3 / 2);
185     OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
186   }
187
188   return gst_pad_set_caps (pad, caps);
189 }
190
191 static void
192 omx_setup (GstOmxBaseFilter * omx_base)
193 {
194   GstOmxBaseVideoEnc *self;
195   GOmxCore *gomx;
196
197   self = GST_OMX_BASE_VIDEOENC (omx_base);
198   gomx = (GOmxCore *) omx_base->gomx;
199
200   GST_INFO_OBJECT (omx_base, "begin");
201
202   {
203     OMX_PARAM_PORTDEFINITIONTYPE param;
204
205     G_OMX_INIT_PARAM (param);
206
207     /* Output port configuration. */
208     {
209       param.nPortIndex = omx_base->out_port->port_index;
210       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
211
212       param.format.video.eCompressionFormat = self->compression_format;
213
214       if (self->bitrate != 0)
215         param.format.video.nBitrate = self->bitrate;
216
217       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
218     }
219   }
220
221   /* STATE_TUNING */
222   if (omx_base->use_state_tuning && omx_base->sink_set_caps) {
223     sink_setcaps(omx_base->sinkpad, omx_base->sink_set_caps);
224   }
225
226   GST_INFO_OBJECT (omx_base, "end");
227 }
228
229 static void
230 type_instance_init (GTypeInstance * instance, gpointer g_class)
231 {
232   GstOmxBaseFilter *omx_base;
233   GstOmxBaseVideoEnc *self;
234
235   omx_base = GST_OMX_BASE_FILTER (instance);
236   self = GST_OMX_BASE_VIDEOENC (instance);
237
238   omx_base->omx_setup = omx_setup;
239
240   gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
241
242   self->bitrate = DEFAULT_BITRATE;
243 }