tizen beta release
[profile/ivi/gst-openmax0.10.git] / omx / gstomx_jpegenc.c
1 /*
2  * Copyright (C) 2008-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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21
22 #include "gstomx_jpegenc.h"
23 #include "gstomx_base_filter.h"
24 #include "gstomx.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28
29 enum
30 {
31   ARG_0,
32   ARG_QUALITY,
33 };
34
35 #define DEFAULT_QUALITY 90
36
37 GSTOMX_BOILERPLATE (GstOmxJpegEnc, gst_omx_jpegenc, GstOmxBaseFilter,
38     GST_OMX_BASE_FILTER_TYPE);
39
40
41 static void
42 type_base_init (gpointer g_class)
43 {
44   GstElementClass *element_class;
45
46   element_class = GST_ELEMENT_CLASS (g_class);
47
48   gst_element_class_set_details_simple (element_class,
49       "OpenMAX IL JPEG image encoder",
50       "Codec/Encoder/Image",
51       "Encodes image in JPEG format with OpenMAX IL", "Felipe Contreras");
52
53   gst_element_class_add_pad_template (element_class,
54       gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
55           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "sink")));
56
57   gst_element_class_add_pad_template (element_class,
58       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
59           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "src")));
60 }
61
62 static void
63 set_property (GObject * obj,
64     guint prop_id, const GValue * value, GParamSpec * pspec)
65 {
66   GstOmxJpegEnc *self;
67
68   self = GST_OMX_JPEGENC (obj);
69
70   switch (prop_id) {
71     case ARG_QUALITY:
72       self->quality = g_value_get_uint (value);
73       break;
74     default:
75       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
76       break;
77   }
78 }
79
80 static void
81 get_property (GObject * obj, guint prop_id, GValue * value, GParamSpec * pspec)
82 {
83   GstOmxJpegEnc *self;
84
85   self = GST_OMX_JPEGENC (obj);
86
87   switch (prop_id) {
88     case ARG_QUALITY:
89       g_value_set_uint (value, self->quality);
90       break;
91     default:
92       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
93       break;
94   }
95 }
96
97 static void
98 type_class_init (gpointer g_class, gpointer class_data)
99 {
100   GObjectClass *gobject_class;
101
102   gobject_class = G_OBJECT_CLASS (g_class);
103
104   /* Properties stuff */
105   {
106     gobject_class->set_property = set_property;
107     gobject_class->get_property = get_property;
108
109     g_object_class_install_property (gobject_class, ARG_QUALITY,
110         g_param_spec_uint ("quality", "Quality of image",
111             "Set the quality from 0 to 100",
112             0, 100, DEFAULT_QUALITY,
113             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
114   }
115 }
116
117 static void
118 settings_changed_cb (GOmxCore * core)
119 {
120   GstOmxBaseFilter *omx_base;
121   GstOmxJpegEnc *self;
122   guint width;
123   guint height;
124
125   omx_base = core->object;
126   self = GST_OMX_JPEGENC (omx_base);
127
128   GST_DEBUG_OBJECT (omx_base, "settings changed");
129
130   {
131     OMX_PARAM_PORTDEFINITIONTYPE param;
132
133     G_OMX_INIT_PARAM (param);
134
135     param.nPortIndex = omx_base->out_port->port_index;
136     OMX_GetParameter (omx_base->gomx->omx_handle, OMX_IndexParamPortDefinition,
137         &param);
138
139     width = param.format.image.nFrameWidth;
140     height = param.format.image.nFrameHeight;
141   }
142
143   {
144     GstCaps *new_caps;
145
146     new_caps = gst_caps_new_simple ("image/jpeg",
147         "width", G_TYPE_INT, width,
148         "height", G_TYPE_INT, height,
149         "framerate", GST_TYPE_FRACTION,
150         self->framerate_num, self->framerate_denom, NULL);
151
152     GST_INFO_OBJECT (omx_base, "caps are: %" GST_PTR_FORMAT, new_caps);
153     gst_pad_set_caps (omx_base->srcpad, new_caps);
154   }
155 }
156
157 static gboolean
158 sink_setcaps (GstPad * pad, GstCaps * caps)
159 {
160   GstStructure *structure;
161   GstOmxBaseFilter *omx_base;
162   GstOmxJpegEnc *self;
163   GOmxCore *gomx;
164   OMX_COLOR_FORMATTYPE color_format = OMX_COLOR_FormatYUV420PackedPlanar;
165   gint width = 0;
166   gint height = 0;
167
168   omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
169   self = GST_OMX_JPEGENC (omx_base);
170   gomx = (GOmxCore *) omx_base->gomx;
171
172   GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
173
174   g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE);
175
176   structure = gst_caps_get_structure (caps, 0);
177
178   gst_structure_get_int (structure, "width", &width);
179   gst_structure_get_int (structure, "height", &height);
180
181   if (!gst_structure_get_fraction (structure, "framerate",
182           &self->framerate_num, &self->framerate_denom)) {
183     self->framerate_num = 0;
184     self->framerate_denom = 1;
185   }
186
187   if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
188     guint32 fourcc;
189
190     if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
191       switch (fourcc) {
192         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
193           color_format = OMX_COLOR_FormatYUV420PackedPlanar;
194           break;
195         case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
196           color_format = OMX_COLOR_FormatCbYCrY;
197           break;
198       }
199     }
200   }
201
202   {
203     OMX_PARAM_PORTDEFINITIONTYPE param;
204
205     G_OMX_INIT_PARAM (param);
206
207     /* Input port configuration. */
208     {
209       param.nPortIndex = omx_base->in_port->port_index;
210       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
211
212       param.format.image.nFrameWidth = width;
213       param.format.image.nFrameHeight = height;
214       param.format.image.eColorFormat = color_format;
215
216       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
217     }
218   }
219
220   return gst_pad_set_caps (pad, caps);
221 }
222
223 static void
224 omx_setup (GstOmxBaseFilter * omx_base)
225 {
226   GstOmxJpegEnc *self;
227   GOmxCore *gomx;
228
229   self = GST_OMX_JPEGENC (omx_base);
230   gomx = (GOmxCore *) omx_base->gomx;
231
232   GST_INFO_OBJECT (omx_base, "begin");
233
234   {
235     OMX_PARAM_PORTDEFINITIONTYPE param;
236
237     G_OMX_INIT_PARAM (param);
238
239     /* Output port configuration. */
240     {
241       param.nPortIndex = omx_base->out_port->port_index;
242       OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
243
244       param.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
245
246       OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, &param);
247     }
248   }
249
250   {
251     OMX_IMAGE_PARAM_QFACTORTYPE param;
252
253     G_OMX_INIT_PARAM (param);
254
255     param.nQFactor = self->quality;
256     param.nPortIndex = omx_base->out_port->port_index;
257
258     OMX_SetParameter (gomx->omx_handle, OMX_IndexParamQFactor, &param);
259   }
260
261   GST_INFO_OBJECT (omx_base, "end");
262 }
263
264 static void
265 type_instance_init (GTypeInstance * instance, gpointer g_class)
266 {
267   GstOmxBaseFilter *omx_base;
268   GstOmxJpegEnc *self;
269
270   omx_base = GST_OMX_BASE_FILTER (instance);
271   self = GST_OMX_JPEGENC (instance);
272
273   omx_base->omx_setup = omx_setup;
274
275   omx_base->gomx->settings_changed_cb = settings_changed_cb;
276
277   gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
278
279   self->framerate_num = 0;
280   self->framerate_denom = 1;
281   self->quality = DEFAULT_QUALITY;
282 }