2 * Copyright (C) 2007-2009 Nokia Corporation.
4 * Author: Felipe Contreras <felipe.contreras@nokia.com>
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.
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.
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
22 #include "gstomx_videosink.h"
23 #include "gstomx_base_sink.h"
26 #include <string.h> /* for strcmp */
28 GSTOMX_BOILERPLATE (GstOmxVideoSink, gst_omx_videosink, GstOmxBaseSink,
29 GST_OMX_BASE_SINK_TYPE);
40 type_base_init (gpointer g_class)
42 GstElementClass *element_class;
44 element_class = GST_ELEMENT_CLASS (g_class);
46 gst_element_class_set_details_simple (element_class,
47 "OpenMAX IL videosink element",
48 "Video/Sink", "Renders video", "Felipe Contreras");
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")));
56 setcaps (GstBaseSink * gst_sink, GstCaps * caps)
58 GstOmxBaseSink *omx_base;
59 GstOmxVideoSink *self;
62 omx_base = GST_OMX_BASE_SINK (gst_sink);
63 self = GST_OMX_VIDEOSINK (gst_sink);
64 gomx = (GOmxCore *) omx_base->gomx;
66 GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
68 g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE);
71 GstStructure *structure;
72 const GValue *framerate = NULL;
75 OMX_COLOR_FORMATTYPE color_format = OMX_COLOR_FormatUnused;
77 structure = gst_caps_get_structure (caps, 0);
79 gst_structure_get_int (structure, "width", &width);
80 gst_structure_get_int (structure, "height", &height);
82 if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
85 framerate = gst_structure_get_value (structure, "framerate");
87 if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
89 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
90 color_format = OMX_COLOR_FormatYUV420PackedPlanar;
92 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
93 color_format = OMX_COLOR_FormatYCbYCr;
95 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
96 color_format = OMX_COLOR_FormatCbYCrY;
103 OMX_PARAM_PORTDEFINITIONTYPE param;
105 G_OMX_INIT_PARAM (param);
107 param.nPortIndex = omx_base->in_port->port_index;
108 OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, ¶m);
110 switch (color_format) {
111 case OMX_COLOR_FormatYUV420PackedPlanar:
112 param.nBufferSize = (width * height * 1.5);
114 case OMX_COLOR_FormatYCbYCr:
115 case OMX_COLOR_FormatCbYCrY:
116 param.nBufferSize = (width * height * 2);
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;
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);
133 OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, ¶m);
137 OMX_CONFIG_ROTATIONTYPE config;
139 G_OMX_INIT_PARAM (config);
141 config.nPortIndex = omx_base->in_port->port_index;
142 OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
144 config.nRotation = self->rotation;
146 OMX_SetConfig (gomx->omx_handle, OMX_IndexConfigCommonRotate, &config);
150 OMX_CONFIG_SCALEFACTORTYPE config;
152 G_OMX_INIT_PARAM (config);
154 config.nPortIndex = omx_base->in_port->port_index;
155 OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
157 config.xWidth = self->x_scale;
158 config.xHeight = self->y_scale;
160 OMX_SetConfig (gomx->omx_handle, OMX_IndexConfigCommonScale, &config);
168 set_property (GObject * object,
169 guint prop_id, const GValue * value, GParamSpec * pspec)
171 GstOmxVideoSink *self;
173 self = GST_OMX_VIDEOSINK (object);
177 self->x_scale = g_value_get_uint (value);
180 self->y_scale = g_value_get_uint (value);
183 self->rotation = g_value_get_uint (value);
186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
192 get_property (GObject * object,
193 guint prop_id, GValue * value, GParamSpec * pspec)
195 GstOmxVideoSink *self;
197 self = GST_OMX_VIDEOSINK (object);
201 g_value_set_uint (value, self->x_scale);
204 g_value_set_uint (value, self->y_scale);
207 g_value_set_uint (value, self->rotation);
210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
216 type_class_init (gpointer g_class, gpointer class_data)
218 GObjectClass *gobject_class;
219 GstBaseSinkClass *gst_base_sink_class;
221 gobject_class = (GObjectClass *) g_class;
222 gst_base_sink_class = GST_BASE_SINK_CLASS (g_class);
224 gst_base_sink_class->set_caps = setcaps;
226 gobject_class->set_property = set_property;
227 gobject_class->get_property = get_property;
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));
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));
239 g_object_class_install_property (gobject_class, ARG_ROTATION,
240 g_param_spec_uint ("rotation", "Rotation",
242 0, G_MAXUINT, 360, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
246 type_instance_init (GTypeInstance * instance, gpointer g_class)
248 GstOmxBaseSink *omx_base;
250 omx_base = GST_OMX_BASE_SINK (instance);
252 GST_DEBUG_OBJECT (omx_base, "start");