Initialize Tizen 2.3
[framework/multimedia/gst-openmax.git] / mobile / omx / gstomx_videosink.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_videosink.h"
23 #include "gstomx_base_sink.h"
24 #include "gstomx.h"
25
26 #include <string.h>             /* for strcmp */
27
28 GSTOMX_BOILERPLATE (GstOmxVideoSink, gst_omx_videosink, GstOmxBaseSink,
29     GST_OMX_BASE_SINK_TYPE);
30
31 enum
32 {
33   ARG_0,
34   ARG_X_SCALE,
35   ARG_Y_SCALE,
36   ARG_ROTATION,
37 };
38
39 static void
40 type_base_init (gpointer g_class)
41 {
42   GstElementClass *element_class;
43
44   element_class = GST_ELEMENT_CLASS (g_class);
45
46   gst_element_class_set_details_simple (element_class,
47       "OpenMAX IL videosink element",
48       "Video/Sink", "Renders video", "Felipe Contreras");
49
50   gst_element_class_add_pad_template (element_class,
51       gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
52           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "sink")));
53 }
54
55 static gboolean
56 setcaps (GstBaseSink * gst_sink, GstCaps * caps)
57 {
58   GstOmxBaseSink *omx_base;
59   GstOmxVideoSink *self;
60   GOmxCore *gomx;
61
62   omx_base = GST_OMX_BASE_SINK (gst_sink);
63   self = GST_OMX_VIDEOSINK (gst_sink);
64   gomx = (GOmxCore *) omx_base->gomx;
65
66   GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
67
68   g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE);
69
70   {
71     GstStructure *structure;
72     const GValue *framerate = NULL;
73     gint width;
74     gint height;
75     OMX_COLOR_FORMATTYPE color_format = OMX_COLOR_FormatUnused;
76
77     structure = gst_caps_get_structure (caps, 0);
78
79     gst_structure_get_int (structure, "width", &width);
80     gst_structure_get_int (structure, "height", &height);
81
82     if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
83       guint32 fourcc;
84
85       framerate = gst_structure_get_value (structure, "framerate");
86
87       if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
88         switch (fourcc) {
89           case GST_MAKE_FOURCC ('I', '4', '2', '0'):
90             color_format = OMX_COLOR_FormatYUV420PackedPlanar;
91             break;
92           case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
93             color_format = OMX_COLOR_FormatYCbYCr;
94             break;
95           case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
96             color_format = OMX_COLOR_FormatCbYCrY;
97             break;
98         }
99       }
100     }
101
102     {
103       OMX_PARAM_PORTDEFINITIONTYPE param;
104
105       G_OMX_INIT_PARAM (param);
106
107       param.nPortIndex = omx_base->in_port->port_index;
108       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
109
110       switch (color_format) {
111         case OMX_COLOR_FormatYUV420PackedPlanar:
112           param.nBufferSize = (width * height * 1.5);
113           break;
114         case OMX_COLOR_FormatYCbYCr:
115         case OMX_COLOR_FormatCbYCrY:
116           param.nBufferSize = (width * height * 2);
117           break;
118         default:
119           break;
120       }
121
122       param.format.video.nFrameWidth = width;
123       param.format.video.nFrameHeight = height;
124       param.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
125       param.format.video.eColorFormat = color_format;
126       if (framerate) {
127         /* convert to Q.16 */
128         param.format.video.xFramerate =
129             (gst_value_get_fraction_numerator (framerate) << 16) /
130             gst_value_get_fraction_denominator (framerate);
131       }
132
133       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
134     }
135
136     {
137       OMX_CONFIG_ROTATIONTYPE config;
138
139       G_OMX_INIT_PARAM (config);
140
141       config.nPortIndex = omx_base->in_port->port_index;
142       OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
143
144       config.nRotation = self->rotation;
145
146       OMX_SetConfig (gomx->omx_handle, OMX_IndexConfigCommonRotate, &config);
147     }
148
149     {
150       OMX_CONFIG_SCALEFACTORTYPE config;
151
152       G_OMX_INIT_PARAM (config);
153
154       config.nPortIndex = omx_base->in_port->port_index;
155       OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
156
157       config.xWidth = self->x_scale;
158       config.xHeight = self->y_scale;
159
160       OMX_SetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
161     }
162   }
163
164   return TRUE;
165 }
166
167 static void
168 set_property (GObject * object,
169     guint prop_id, const GValue * value, GParamSpec * pspec)
170 {
171   GstOmxVideoSink *self;
172
173   self = GST_OMX_VIDEOSINK (object);
174
175   switch (prop_id) {
176     case ARG_X_SCALE:
177       self->x_scale = g_value_get_uint (value);
178       break;
179     case ARG_Y_SCALE:
180       self->y_scale = g_value_get_uint (value);
181       break;
182     case ARG_ROTATION:
183       self->rotation = g_value_get_uint (value);
184       break;
185     default:
186       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187       break;
188   }
189 }
190
191 static void
192 get_property (GObject * object,
193     guint prop_id, GValue * value, GParamSpec * pspec)
194 {
195   GstOmxVideoSink *self;
196
197   self = GST_OMX_VIDEOSINK (object);
198
199   switch (prop_id) {
200     case ARG_X_SCALE:
201       g_value_set_uint (value, self->x_scale);
202       break;
203     case ARG_Y_SCALE:
204       g_value_set_uint (value, self->y_scale);
205       break;
206     case ARG_ROTATION:
207       g_value_set_uint (value, self->rotation);
208       break;
209     default:
210       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
211       break;
212   }
213 }
214
215 static void
216 type_class_init (gpointer g_class, gpointer class_data)
217 {
218   GObjectClass *gobject_class;
219   GstBaseSinkClass *gst_base_sink_class;
220
221   gobject_class = (GObjectClass *) g_class;
222   gst_base_sink_class = GST_BASE_SINK_CLASS (g_class);
223
224   gst_base_sink_class->set_caps = setcaps;
225
226   gobject_class->set_property = set_property;
227   gobject_class->get_property = get_property;
228
229   g_object_class_install_property (gobject_class, ARG_X_SCALE,
230       g_param_spec_uint ("x-scale", "X Scale",
231           "How much to scale the image in the X axis (100 means nothing)",
232           0, G_MAXUINT, 100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
233
234   g_object_class_install_property (gobject_class, ARG_Y_SCALE,
235       g_param_spec_uint ("y-scale", "Y Scale",
236           "How much to scale the image in the Y axis (100 means nothing)",
237           0, G_MAXUINT, 100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
238
239   g_object_class_install_property (gobject_class, ARG_ROTATION,
240       g_param_spec_uint ("rotation", "Rotation",
241           "Rotation angle",
242           0, G_MAXUINT, 360, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
243 }
244
245 static void
246 type_instance_init (GTypeInstance * instance, gpointer g_class)
247 {
248   GstOmxBaseSink *omx_base;
249
250   omx_base = GST_OMX_BASE_SINK (instance);
251
252   GST_DEBUG_OBJECT (omx_base, "start");
253 }