Update imgp for gstreamer 1.x (fix blocking issue)
[platform/core/multimedia/libmm-imgp-gstcs.git] / gstcs / mm_util_gstcs.c
1 /*
2  * libmm-imgp-gstcs
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: YoungHun Kim <yh8004.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 #include "mm_util_gstcs_internal.h"
22 #include <mm_debug.h>
23 #include <gst/check/gstcheck.h>
24 #include <gst/video/video-format.h>
25 #include <mm_error.h>
26 #define MM_UTIL_ROUND_UP_2(num) (((num)+1)&~1)
27 #define MM_UTIL_ROUND_UP_4(num) (((num)+3)&~3)
28 #define MM_UTIL_ROUND_UP_8(num) (((num)+7)&~7)
29 #define MM_UTIL_ROUND_UP_16(num) (((num)+15)&~15)
30
31 #define setup_image_size_I420(width, height) { \
32         int size=0; \
33         size = (MM_UTIL_ROUND_UP_4 (width) * MM_UTIL_ROUND_UP_2 (height) + MM_UTIL_ROUND_UP_8 (width) * MM_UTIL_ROUND_UP_2 (height) /2); \
34         return size; \
35 }
36
37 #define setup_image_size_Y42B(width, height) { \
38         int size=0; \
39         size = (MM_UTIL_ROUND_UP_4 (width) * height + MM_UTIL_ROUND_UP_8 (width) * height); \
40         return size; \
41 }
42
43 #define setup_image_size_Y444(width, height) { \
44         int size=0; \
45         size = (MM_UTIL_ROUND_UP_4 (width) * height * 3); \
46         return size; \
47 }
48
49 #define setup_image_size_UYVY(width, height) { \
50         int size=0; \
51         size = (MM_UTIL_ROUND_UP_2 (width) * 2 * height); \
52         return size; \
53 }
54
55 #define setup_image_size_YUYV(width, height) { \
56         int size=0; \
57         size = (MM_UTIL_ROUND_UP_2 (width) * 2 * height); \
58         return size; \
59 }
60
61 #define setup_image_size_YV12(width, height) { \
62         int size=0; \
63         size = (MM_UTIL_ROUND_UP_4 (width) * MM_UTIL_ROUND_UP_2 (height)+ MM_UTIL_ROUND_UP_8 (width) * MM_UTIL_ROUND_UP_2 (height) / 2); \
64         return size; \
65 }
66
67 #define setup_image_size_NV12(width, height) { \
68         int size=0; \
69         size = (MM_UTIL_ROUND_UP_4 (width) * MM_UTIL_ROUND_UP_2 (height) *1.5); \
70         return size; \
71 }
72
73 #define setup_image_size_RGB565(width, height) { \
74         int size=0; \
75         size = (MM_UTIL_ROUND_UP_4 (width * 2) *height); \
76         return size; \
77 }
78
79 #define setup_image_size_RGB888(width, height) { \
80         int size=0; \
81         size = (MM_UTIL_ROUND_UP_4 (width*3) * height); \
82         return size; \
83 }
84
85 #define setup_image_size_BGR888(width, height) { \
86         int size=0; \
87         size = (MM_UTIL_ROUND_UP_4 (width*3) * height); \
88         return size; \
89 }
90
91 static void
92 _mm_sink_sample (GstElement * appsink, gpointer user_data)
93 {
94         GstBuffer *_buf=NULL;
95         GstSample *_sample = NULL;
96         gstreamer_s * pGstreamer_s = (gstreamer_s*) user_data;
97         _sample = gst_app_sink_pull_sample((GstAppSink*)appsink);
98         _buf = gst_sample_get_buffer(_sample);
99
100         pGstreamer_s->output_buffer = _buf;
101
102         if(pGstreamer_s->output_buffer != NULL) {
103                 GstMapInfo mapinfo = GST_MAP_INFO_INIT;
104                 gst_buffer_map(pGstreamer_s->output_buffer, &mapinfo, GST_MAP_READ);
105                 debug_log("Create Output Buffer: GST_BUFFER_DATA: %p\t GST_BUFFER_SIZE: %d", mapinfo.data, mapinfo.size);
106                 gst_buffer_unmap(pGstreamer_s->output_buffer, &mapinfo);
107         } else {
108                 debug_error("ERROR -Input Prepare Buffer! Check createoutput buffer function");
109         }
110         gst_buffer_ref (pGstreamer_s->output_buffer); /* when you want to avoid flushing */
111         gst_sample_unref(_sample);
112 }
113
114 static void
115 _mm_sink_preroll (GstElement * appsink, gpointer user_data)
116 {
117         GstSample *_sample = NULL;
118         GstBuffer *_buf=NULL;
119         gstreamer_s * pGstreamer_s = (gstreamer_s*) user_data;
120         _buf = gst_app_sink_pull_preroll((GstAppSink*)appsink);
121
122         pGstreamer_s->output_buffer = _buf;
123         /* pGstreamer_s->output_image_format_s->caps = GST_BUFFER_CAPS(_buf); */
124         if(pGstreamer_s->output_buffer != NULL) {
125                 GstMapInfo mapinfo = GST_MAP_INFO_INIT;
126                 gst_buffer_map(pGstreamer_s->output_buffer, &mapinfo, GST_MAP_READ);
127                 debug_log("Create Output Buffer: GST_BUFFER_DATA: %p\t GST_BUFFER_SIZE: %d", mapinfo.data, mapinfo.size);
128                 gst_buffer_unmap(pGstreamer_s->output_buffer, &mapinfo);
129         } else {
130                 debug_error("ERROR -Input Prepare Buffer! Check createoutput buffer function");
131         }
132
133         gst_buffer_ref (pGstreamer_s->output_buffer); /* when you want to avoid flushings */
134         gst_sample_unref(_sample);
135 }
136
137 static gboolean
138 _mm_on_sink_message (GstBus * bus, GstMessage * message, gstreamer_s * pGstreamer_s)
139 {
140         switch (GST_MESSAGE_TYPE (message)) {
141                 case GST_MESSAGE_EOS:
142                         debug_log("Finished playback\n"); /* g_main_loop_quit (pGstreamer_s->loop); */
143                         break;
144                 case GST_MESSAGE_ERROR:
145                         debug_error("Received error\n"); /* g_main_loop_quit (pGstreamer_s->loop); */
146                         break;
147                 case GST_MESSAGE_STATE_CHANGED:
148                         debug_log("[%s] %s(%d) \n", GST_MESSAGE_SRC_NAME(message), GST_MESSAGE_TYPE_NAME(message), GST_MESSAGE_TYPE(message));
149                         break;
150                 case GST_MESSAGE_STREAM_STATUS:
151                         debug_log("[%s] %s(%d) \n", GST_MESSAGE_SRC_NAME(message), GST_MESSAGE_TYPE_NAME(message), GST_MESSAGE_TYPE(message));
152                         break;
153                 default:
154                         debug_log("[%s] %s(%d) \n", GST_MESSAGE_SRC_NAME(message), GST_MESSAGE_TYPE_NAME(message), GST_MESSAGE_TYPE(message));
155                         break;
156         }
157         return TRUE;
158 }
159
160
161 static int
162 _mm_create_pipeline( gstreamer_s* pGstreamer_s)
163 {
164         int ret = MM_ERROR_NONE;
165         pGstreamer_s->pipeline= gst_pipeline_new ("videoconvert");
166         if (!pGstreamer_s->pipeline) {
167                 debug_error("pipeline could not be created. Exiting.\n");
168                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
169         }
170         pGstreamer_s->appsrc= gst_element_factory_make("appsrc","appsrc");
171         if (!pGstreamer_s->appsrc) {
172                 debug_error("appsrc could not be created. Exiting.\n");
173                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
174         }
175         pGstreamer_s->colorspace=gst_element_factory_make("videoconvert","colorconverter");
176         if (!pGstreamer_s->colorspace) {
177                 debug_error("colorspace could not be created. Exiting.\n");
178                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
179         }
180         pGstreamer_s->videoscale=gst_element_factory_make("videoscale", "scale");
181         if (!pGstreamer_s->videoscale) {
182                 debug_error("videoscale could not be created. Exiting.\n");
183                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
184         }
185         pGstreamer_s->videoflip=gst_element_factory_make( "videoflip", "flip" );
186         if (!pGstreamer_s->videoflip) {
187                 debug_error("videoflip could not be created. Exiting.\n");
188                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
189         }
190         pGstreamer_s->appsink=gst_element_factory_make("appsink","appsink");
191         if (!pGstreamer_s->appsink) {
192                 debug_error("appsink could not be created. Exiting.\n");
193                 ret = MM_ERROR_IMAGE_INVALID_VALUE;
194         }
195
196         return ret;
197 }
198
199 static gboolean
200 _mm_check_resize_format(int src_width, int src_height, int dst_width, int dst_height)
201 {
202         gboolean _bool=FALSE;
203
204         if( (src_width != dst_width) || (src_height != dst_height) ) {
205                 _bool = TRUE;
206         }
207
208         return _bool;
209 }
210
211 static gboolean
212 _mm_check_rotate_format(int GstVideoFlipMethod)
213 {
214         gboolean _bool=FALSE;
215
216         if((GstVideoFlipMethod >= 1) && ( GstVideoFlipMethod<= 7)) {
217                 _bool = TRUE;
218         }
219
220         return _bool;
221 }
222
223 static gboolean
224 _mm_check_resize_format_label(char* __format_label)
225 {
226         gboolean _bool = FALSE;
227
228         if(strcmp(__format_label, "AYUV") == 0
229                 || strcmp(__format_label, "UYVY") == 0 ||strcmp(__format_label, "Y800") == 0 || strcmp(__format_label, "I420") == 0 || strcmp(__format_label, "YV12") == 0
230                 || strcmp(__format_label, "RGB888") == 0 || strcmp(__format_label, "RGB565") == 0 || strcmp(__format_label, "BGR888") == 0 || strcmp(__format_label, "RGBA8888") == 0
231                 || strcmp(__format_label, "ARGB8888") == 0 ||strcmp(__format_label, "BGRA8888") == 0 ||strcmp(__format_label, "ABGR8888") == 0 ||strcmp(__format_label, "RGBX") == 0
232                 ||strcmp(__format_label, "XRGB") == 0 ||strcmp(__format_label, "BGRX") == 0 ||strcmp(__format_label, "XBGR") == 0 ||strcmp(__format_label, "Y444") == 0
233                 ||strcmp(__format_label, "Y42B") == 0 ||strcmp(__format_label, "YUY2") == 0 ||strcmp(__format_label, "YUYV") == 0 ||strcmp(__format_label, "UYVY") == 0
234                 ||strcmp(__format_label, "Y41B") == 0 ||strcmp(__format_label, "Y16") == 0 ||strcmp(__format_label, "Y800") == 0 ||strcmp(__format_label, "Y8") == 0
235                 ||strcmp(__format_label, "GREY") == 0 ||strcmp(__format_label, "AY64") == 0 || strcmp(__format_label, "YUV422") == 0) {
236
237                 _bool=TRUE;
238         }
239
240         return _bool;
241 }
242
243 static gboolean
244 _mm_check_rotate_format_label(const char* __format_label)
245 {
246         gboolean _bool = FALSE;
247
248         if(strcmp(__format_label, "I420") == 0 ||strcmp(__format_label, "YV12") == 0 || strcmp(__format_label, "IYUV")
249                 || strcmp(__format_label, "RGB888") ||strcmp(__format_label, "BGR888") == 0 ||strcmp(__format_label, "RGBA8888") == 0
250                 || strcmp(__format_label, "ARGB8888") == 0 ||strcmp(__format_label, "BGRA8888") == 0 ||strcmp(__format_label, "ABGR8888") == 0 ) {
251                 _bool=TRUE;
252         }
253
254         return _bool;
255 }
256
257 static void
258 _mm_check_caps_format(GstCaps* caps)
259 {
260         GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
261         const gchar* formatInfo = gst_structure_get_string (caps_structure, "format");
262         debug_log("[%d] caps: %s", GST_IS_CAPS(caps), formatInfo);
263 }
264
265 static void
266 _mm_link_pipeline(gstreamer_s* pGstreamer_s, image_format_s* input_format, image_format_s* output_format, int value)
267 {
268         /* set property */
269         gst_app_src_set_caps(GST_APP_SRC(pGstreamer_s->appsrc), input_format->caps); /*g_object_set(pGstreamer_s->appsrc, "caps", input_format->caps, NULL);*/
270         gst_app_sink_set_caps(GST_APP_SINK(pGstreamer_s->appsink), output_format->caps); /*g_object_set(pGstreamer_s->appsink, "caps", output_format->caps, NULL); */
271         gst_bin_add_many(GST_BIN(pGstreamer_s->pipeline), pGstreamer_s->appsrc, pGstreamer_s->colorspace, pGstreamer_s->videoscale, pGstreamer_s->videoflip, pGstreamer_s->appsink, NULL);
272         if(!gst_element_link_many(pGstreamer_s->appsrc, pGstreamer_s->colorspace, pGstreamer_s->videoscale, pGstreamer_s->videoflip, pGstreamer_s->appsink, NULL)) {
273                 debug_error("Fail to link pipeline");
274         } else {
275                 debug_log("Success to link pipeline");
276         }
277         
278         g_object_set (G_OBJECT (pGstreamer_s->appsrc), "stream-type", 0, "format", GST_FORMAT_TIME, NULL);
279         g_object_set(pGstreamer_s->appsrc, "num-buffers", 1, NULL);
280         g_object_set(pGstreamer_s->appsrc, "is-live", TRUE, NULL); /* add because of gstreamer_s time issue */
281
282         g_object_set(pGstreamer_s->videoflip, "method", value, NULL ); /* GST_VIDEO_FLIP_METHOD_IDENTITY (0): none- Identity (no rotation) (1): clockwise - Rotate clockwise 90 degrees (2): rotate-180 - Rotate 180 degrees (3): counterclockwise - Rotate counter-clockwise 90 degrees (4): horizontal-flip - Flip horizontally (5): vertical-flip - Flip vertically (6): upper-left-diagonal - Flip across upper left/lower right diagonal (7): upper-right-diagonal - Flip across upper right/lower left diagonal */
283
284         g_object_set(pGstreamer_s->appsink, "drop", TRUE, NULL);
285         g_object_set(pGstreamer_s->appsink, "emit-signals", TRUE, "sync", FALSE, NULL);
286 }
287
288 static void
289 _mm_set_image_format_s_capabilities(image_format_s* __format) /*_format_label: I420 _colorsapace: YUV */
290 {
291         char _format_name[sizeof(GST_VIDEO_FORMATS_ALL)] = {'\0'};
292         GstVideoFormat videoFormat;
293         int _bpp=0; int _depth=0; int _red_mask=0; int _green_mask=0; int _blue_mask=0; int _alpha_mask=0; int _endianness=0;
294
295         if(__format == NULL) {
296                 debug_error("Image format is NULL\n");
297                 return;
298         }
299
300         debug_log("colorspace: %s(%d)\n", __format->colorspace, strlen(__format->colorspace));
301
302         if(strcmp(__format->colorspace,"YUV") == 0) {
303                 if(strcmp(__format->format_label,"I420") == 0
304                 || strcmp(__format->format_label,"Y42B") == 0
305                 || strcmp(__format->format_label,"Y444") == 0
306                 || strcmp(__format->format_label,"YV12") == 0
307                 || strcmp(__format->format_label,"NV12") == 0
308                 || strcmp(__format->format_label,"UYVY") == 0) {
309                         strcpy(_format_name, __format->format_label);
310                 }else if(strcmp(__format->format_label,"YUYV") == 0) {
311                         strcpy(_format_name, "YVYU");
312                 }
313
314                 __format->caps = gst_caps_new_simple ("video/x-raw",
315                         "format", G_TYPE_STRING, _format_name,
316                         "framerate", GST_TYPE_FRACTION, 25, 1,
317                         "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
318                         "width", G_TYPE_INT, __format->width,
319                         "height", G_TYPE_INT, __format->height,
320                         "framerate", GST_TYPE_FRACTION, 1, 1,
321                         NULL);
322         }
323
324         else if(strcmp(__format->colorspace,"RGB") ==0 || strcmp(__format->colorspace,"BGRX") ==0) {
325                 if(strcmp(__format->format_label,"RGB888") == 0) {
326                         _bpp=24; _depth=24; _red_mask=16711680; _green_mask=65280; _blue_mask=255; _endianness=4321;
327                 }else if(strcmp(__format->format_label,"BGR888") == 0) {
328                         _bpp=24; _depth=24; _red_mask=255; _green_mask=65280; _blue_mask=16711680; _endianness=4321;
329                 }else if(strcmp(__format->format_label,"RGB565") == 0) {
330                         _bpp=16; _depth=16; _red_mask=63488; _green_mask=2016; _blue_mask=31; _endianness=1234;
331                 }else if( (strcmp(__format->format_label, "BGRX") == 0)) {
332                         _bpp=32; _depth=24; _red_mask=65280; _green_mask=16711680; _blue_mask=-16777216; _endianness=4321;
333                 }
334
335                 videoFormat = gst_video_format_from_masks(_depth, _bpp, _endianness, _red_mask, _green_mask, _blue_mask, 0);
336                 debug_log("Chosen video format: %s", gst_video_format_to_string(videoFormat));
337
338                 __format->caps = gst_caps_new_simple ("video/x-raw",
339                         "format", G_TYPE_STRING, gst_video_format_to_string(videoFormat),
340                         "width", G_TYPE_INT, __format->width,
341                         "height", G_TYPE_INT, __format->height,
342                         "framerate", GST_TYPE_FRACTION, 1, 1, NULL);
343         }
344
345         else if(strcmp(__format->colorspace,"RGBA") ==0) {
346                 if(strcmp(__format->format_label,"ARGB8888") == 0) { /*[Low Arrary Address] ARGBARGB... [High Array Address]*/
347                         debug_log("ARGB8888");
348                         _bpp=32; _depth=32; _red_mask=16711680; _green_mask=65280; _blue_mask=255; _alpha_mask=-16777216; _endianness=4321;
349                 }else if(strcmp(__format->format_label,"BGRA8888") == 0) { /*[Low Arrary Address] BGRABGRA...[High Array Address]*/
350                         debug_log("BGRA8888");
351                         _bpp=32; _depth=32; _red_mask=65280; _green_mask=16711680; _blue_mask=-16777216; _alpha_mask=255; _endianness=4321;
352                 }else if(strcmp(__format->format_label,"RGBA8888") == 0) { /*[Low Arrary Address] RGBARGBA...[High Array Address]*/
353                         debug_log("RGBA8888");
354                         _bpp=32; _depth=32; _red_mask=-16777216; _green_mask=16711680; _blue_mask=65280; _alpha_mask=255; _endianness=4321;
355                 }else if(strcmp(__format->format_label,"ABGR8888") == 0) { /*[Low Arrary Address] ABGRABGR...[High Array Address]*/
356                         debug_log("ABGR8888");
357                         _bpp=32; _depth=32; _red_mask=255; _green_mask=65280; _blue_mask=16711680; _alpha_mask=-16777216; _endianness=4321;
358                 }else {
359                         debug_error("***Wrong format cs type***\n");
360                 }
361
362                 videoFormat = gst_video_format_from_masks(_depth, _bpp, _endianness, _red_mask, _green_mask, _blue_mask, _alpha_mask);
363                 debug_log("Chosen video format: %s", gst_video_format_to_string(videoFormat));
364
365                 __format->caps = gst_caps_new_simple ("video/x-raw",
366                         "format", G_TYPE_STRING, gst_video_format_to_string(videoFormat),
367                         "width", G_TYPE_INT, __format->width,
368                         "height", G_TYPE_INT, __format->height,
369                         "framerate", GST_TYPE_FRACTION, 1, 1, NULL);
370         }
371
372         if(__format->caps) {
373                 debug_log("###__format->caps is not NULL###, %p", __format->caps);
374                 _mm_check_caps_format(__format->caps);
375         }else {
376                 debug_error("__format->caps is NULL");
377         }
378 }
379
380 static void
381 _mm_set_image_colorspace( image_format_s* __format)
382 {
383         debug_log("format_label: %s\n", __format->format_label);
384
385         __format->colorspace = (char*)malloc(sizeof(char) * IMAGE_FORMAT_LABEL_BUFFER_SIZE);
386         if (__format->colorspace == NULL) {
387                 debug_error("memory allocation failed");
388                 return;
389         }
390         memset(__format->colorspace, 0, IMAGE_FORMAT_LABEL_BUFFER_SIZE);
391         if( (strcmp(__format->format_label, "I420") == 0) ||(strcmp(__format->format_label, "Y42B") == 0) || (strcmp(__format->format_label, "Y444") == 0)
392                 || (strcmp(__format->format_label, "YV12") == 0) ||(strcmp(__format->format_label, "NV12") == 0) ||(strcmp(__format->format_label, "UYVY") == 0) ||(strcmp(__format->format_label, "YUYV") == 0)) {
393                 strncpy(__format->colorspace, "YUV", IMAGE_FORMAT_LABEL_BUFFER_SIZE-1);
394         }else if( (strcmp(__format->format_label, "RGB888") == 0) ||(strcmp(__format->format_label, "BGR888") == 0) ||(strcmp(__format->format_label, "RGB565") == 0)) {
395                 strncpy(__format->colorspace, "RGB", IMAGE_FORMAT_LABEL_BUFFER_SIZE-1);
396         }else if( (strcmp(__format->format_label, "ARGB8888") == 0) || (strcmp(__format->format_label, "BGRA8888") == 0) ||(strcmp(__format->format_label, "RGBA8888") == 0)    || (strcmp(__format->format_label, "ABGR8888") == 0)) {
397                 strncpy(__format->colorspace, "RGBA",IMAGE_FORMAT_LABEL_BUFFER_SIZE-1);
398         }else if( (strcmp(__format->format_label, "BGRX") == 0)) {
399                 strncpy(__format->colorspace, "BGRX", IMAGE_FORMAT_LABEL_BUFFER_SIZE-1);
400         }else {
401                 debug_error("Check your colorspace format label");
402                 GSTCS_FREE(__format->colorspace);
403         }
404 }
405
406 static image_format_s*
407 _mm_set_input_image_format_s_struct(imgp_info_s* pImgp_info) /* char* __format_label, int __width, int __height) */
408 {
409         image_format_s* __format = NULL;
410
411         __format=(image_format_s*)malloc(sizeof(image_format_s));
412         if (__format == NULL) {
413                 debug_error("memory allocation failed");
414                 return NULL;
415         }
416         memset(__format, 0, sizeof(image_format_s));
417
418         __format->format_label = (char *)malloc(sizeof(char) * IMAGE_FORMAT_LABEL_BUFFER_SIZE);
419         if (__format->format_label == NULL) {
420                 debug_error("memory allocation failed");
421                 GSTCS_FREE(__format);
422                 return NULL;
423         }
424         memset(__format->format_label, 0, IMAGE_FORMAT_LABEL_BUFFER_SIZE);
425         strncpy(__format->format_label, pImgp_info->input_format_label, strlen(pImgp_info->input_format_label));
426         debug_log("input_format_label: %s\n", pImgp_info->input_format_label);
427         _mm_set_image_colorspace(__format);
428
429         __format->width=pImgp_info->src_width;
430         __format->height=pImgp_info->src_height;
431
432         __format->blocksize = mm_setup_image_size(pImgp_info->input_format_label, pImgp_info->src_width, pImgp_info->src_height);
433         debug_log("blocksize: %d\n", __format->blocksize);
434         _mm_set_image_format_s_capabilities(__format);
435
436         return __format;
437 }
438
439 static void
440 _mm_round_up_output_image_widh_height(image_format_s* pFormat)
441 {
442         if(strcmp(pFormat->colorspace,"YUV") ==0) {
443                 pFormat->stride=MM_UTIL_ROUND_UP_8(pFormat->width);
444                 pFormat->elevation=MM_UTIL_ROUND_UP_2(pFormat->height);
445         } else if(strcmp(pFormat->colorspace, "RGB") ==0) {
446                 pFormat->stride=MM_UTIL_ROUND_UP_4(pFormat->width);
447                 pFormat->elevation=MM_UTIL_ROUND_UP_2(pFormat->height);
448         }
449 }
450
451 static image_format_s*
452 _mm_set_output_image_format_s_struct(imgp_info_s* pImgp_info)
453 {
454         image_format_s* __format = NULL;
455
456         __format=(image_format_s*)malloc(sizeof(image_format_s));
457         if (__format == NULL) {
458                 debug_error("memory allocation failed");
459                 return NULL;
460         }
461         memset(__format, 0, sizeof(image_format_s));
462
463         __format->format_label = (char *)malloc(sizeof(char) * IMAGE_FORMAT_LABEL_BUFFER_SIZE);
464         if (__format->format_label == NULL) {
465                 debug_error("memory allocation failed");
466                 GSTCS_FREE(__format);
467                 return NULL;
468         }
469         memset(__format->format_label, 0, IMAGE_FORMAT_LABEL_BUFFER_SIZE);
470         strncpy(__format->format_label, pImgp_info->output_format_label, strlen(pImgp_info->output_format_label));
471         _mm_set_image_colorspace(__format);
472
473         __format->width=pImgp_info->dst_width;
474         __format->height=pImgp_info->dst_height;
475         _mm_round_up_output_image_widh_height(__format);
476
477         __format->blocksize = mm_setup_image_size(pImgp_info->output_format_label, pImgp_info->dst_width, pImgp_info->dst_height);
478         debug_log("output_format_label: %s", pImgp_info->output_format_label);
479         _mm_set_image_format_s_capabilities(__format);
480         return __format;
481 }
482
483 static int
484 _mm_push_buffer_into_pipeline(imgp_info_s* pImgp_info, unsigned char *src, gstreamer_s * pGstreamer_s)
485 {
486         int ret = MM_ERROR_NONE;
487
488         if(pGstreamer_s->pipeline == NULL) {
489                 debug_error("pipeline is NULL\n");
490                 return MM_ERROR_IMAGE_INVALID_VALUE;
491         }
492
493         gsize data_size = mm_setup_image_size(pImgp_info->input_format_label, pImgp_info->src_width, pImgp_info->src_height);
494         GstBuffer* gst_buf = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, src, data_size, 0, data_size, NULL, NULL);
495
496         if(gst_buf==NULL) {
497                 debug_error("buffer is NULL\n");
498                 return MM_ERROR_IMAGE_INVALID_VALUE;
499         }
500
501         gst_app_src_push_buffer (GST_APP_SRC (pGstreamer_s->appsrc), gst_buf); /* push buffer to pipeline */
502         return ret;
503 }
504
505
506 static int
507 _mm_imgp_gstcs_processing( gstreamer_s* pGstreamer_s, unsigned char *src, unsigned char *dst, image_format_s* input_format, image_format_s* output_format, imgp_info_s* pImgp_info)
508 {
509         GstBus *bus = NULL;
510         GstStateChangeReturn ret_state;
511         int ret = MM_ERROR_NONE;
512
513         if(src== NULL || dst == NULL) {
514                 debug_error("src || dst is NULL");
515                 return MM_ERROR_IMAGE_INVALID_VALUE;
516         }
517
518         /*create pipeline*/
519         ret = _mm_create_pipeline(pGstreamer_s);
520         if(ret != MM_ERROR_NONE) {
521                 debug_error("ERROR - mm_create_pipeline ");
522         }
523
524         /* Make appsink emit the "new-preroll" and "new-sample" signals. This option is by default disabled because signal emission is expensive and unneeded when the application prefers to operate in pull mode. */
525         gst_app_sink_set_emit_signals ((GstAppSink*)pGstreamer_s->appsink, TRUE);
526
527         bus = gst_pipeline_get_bus (GST_PIPELINE (pGstreamer_s->pipeline)); /* GST_PIPELINE (pipeline)); */
528         /* gst_bus_add_watch (bus, (GstBusFunc) _mm_on_sink_message, pGstreamer_s); thow to appplicaton */
529         gst_object_unref(bus);
530
531         debug_log("Start mm_push_buffer_into_pipeline");
532         ret = _mm_push_buffer_into_pipeline(pImgp_info, src, pGstreamer_s);
533         if(ret != MM_ERROR_NONE) {
534                 debug_error("ERROR - mm_push_buffer_into_pipeline ");
535         }
536         debug_log("End mm_push_buffer_into_pipeline");
537
538         /*link pipeline*/
539         debug_log("Start mm_link_pipeline");
540         _mm_link_pipeline( pGstreamer_s, input_format, output_format, pImgp_info->angle);
541         debug_log("End mm_link_pipeline");
542
543         /* Conecting to the new-sample signal emited by the appsink*/
544         debug_log("Start G_CALLBACK (_mm_sink_sample)");
545         g_signal_connect (pGstreamer_s->appsink, "new-sample", G_CALLBACK (_mm_sink_sample), pGstreamer_s);
546         debug_log("End G_CALLBACK (_mm_sink_sample)");
547
548         /* GST_STATE_PLAYING*/
549         debug_log("Start GST_STATE_PLAYING");
550         ret_state = gst_element_set_state (pGstreamer_s->pipeline, GST_STATE_PLAYING);
551         debug_log("End GST_STATE_PLAYING ret_state: %d", ret_state);
552         ret_state = gst_element_get_state (pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
553         debug_log("Success Get GST_STATE_PLAYING ret_state: %d", ret_state);
554         #if 0
555         /* Conecting to the new-sample signal emited by the appsink*/
556         debug_log("Start G_CALLBACK (mm_sink_buffer)");
557         g_signal_connect (pGstreamer_s->appsink, "new-sample", G_CALLBACK (_mm_sink_buffer), pGstreamer_s);
558         debug_log("End G_CALLBACK (mm_sink_buffer)");
559         #endif
560         if(ret_state == 1) {
561                 debug_log("GST_STATE_PLAYING ret = %d( GST_STATE_CHANGE_SUCCESS)", ret_state);
562         }else if( ret_state == 2) {
563                 debug_log("GST_STATE_PLAYING ret = %d( GST_STATE_CHANGE_ASYNC)", ret_state);
564         }
565
566         debug_log("Sucess GST_STATE_CHANGE");
567
568         /* error */
569         if (ret_state == 0)     {
570                 debug_error("GST_STATE_CHANGE_FAILURE");
571                 return MM_ERROR_IMAGE_INVALID_VALUE;
572         }else {
573                 #if 0
574                         g_main_loop_run (pGstreamer_s->loop);
575                 #endif
576                 debug_log("Set GST_STATE_NULL");
577
578                 /*GST_STATE_NULL*/
579                 gst_element_set_state (pGstreamer_s->pipeline, GST_STATE_NULL);
580                 debug_log("End GST_STATE_NULL");
581
582                 debug_log("###pGstreamer_s->output_buffer### : %p", pGstreamer_s->output_buffer);
583
584                 ret_state = gst_element_get_state (pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
585
586                 if(ret_state == 1) {
587                         debug_log("GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", ret_state);
588                 }else if( ret_state == 2) {
589                         debug_log("GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_ASYNC)\n", ret_state);
590                 }
591
592                 debug_log("Success gst_element_get_state\n");
593
594                 if (ret_state == 0) {
595                         debug_error("GST_STATE_CHANGE_FAILURE");
596                 }else {
597                         if(pGstreamer_s->output_buffer != NULL) {
598                                 GstMapInfo mapinfo = GST_MAP_INFO_INIT;
599                                 gst_buffer_map(pGstreamer_s->output_buffer, &mapinfo, GST_MAP_READ);
600                                 int buffer_size = mapinfo.size;
601                                 debug_log("buffer size: %d\n", buffer_size);
602                                 if( buffer_size != mm_setup_image_size(pImgp_info->output_format_label, pImgp_info->output_stride, pImgp_info->output_elevation)) {
603                                         debug_log("Buffer size is different stride:%d elevation: %d\n", pImgp_info->output_stride, pImgp_info->output_elevation);
604                                 }
605                                 debug_log("pGstreamer_s->output_buffer: 0x%2x\n", pGstreamer_s->output_buffer);
606                                 memcpy(dst, mapinfo.data, buffer_size);
607                                 gst_buffer_unmap(pGstreamer_s->output_buffer, &mapinfo);
608                         }else {
609                                 debug_log("pGstreamer_s->output_buffer is NULL");
610                         }
611                 }
612                 gst_object_unref (pGstreamer_s->pipeline);
613                 pGstreamer_s->output_buffer = NULL;
614                 g_free (pGstreamer_s);
615
616                 debug_log("End gstreamer processing \n");
617         }
618         debug_log("dst: %p", dst);
619         return ret;
620 }
621
622
623 static int
624 mm_setup_image_size(const char* _format_label, int width, int height)
625 {
626         int size=0;
627
628         if(strcmp(_format_label, "I420") == 0) {
629                 setup_image_size_I420(width, height); /*width * height *1.5; */
630         }else if(strcmp(_format_label, "Y42B") == 0) {
631                 setup_image_size_Y42B(width, height); /*width * height *2; */
632         }else if(strcmp(_format_label, "YUV422") == 0) {
633                 setup_image_size_Y42B(width, height); /*width * height *2; */
634         }else if(strcmp(_format_label, "Y444") == 0) {
635                 setup_image_size_Y444(width, height); /* width * height *3; */
636         }else if(strcmp(_format_label, "YV12") == 0) {
637                 setup_image_size_YV12(width, height); /* width * height *1; */
638         }else if(strcmp(_format_label, "NV12") == 0) {
639                 setup_image_size_NV12(width, height); /* width * height *1.5; */
640         }else if(strcmp(_format_label, "RGB565") == 0) {
641                 setup_image_size_RGB565(width, height); /* width * height *2; */
642         }else if(strcmp(_format_label, "RGB888") == 0) {
643                 setup_image_size_RGB888(width, height); /* width * height *3; */
644         }else if(strcmp(_format_label, "BGR888") == 0) {
645                 setup_image_size_BGR888(width, height); /* width * height *3; */
646         }else if(strcmp(_format_label, "UYVY") == 0) {
647                 setup_image_size_UYVY(width, height); /* width * height *2; */
648         }else if(strcmp(_format_label, "YUYV") == 0) {
649                 setup_image_size_YUYV(width, height); /* width * height *2; */
650         }else if(strcmp(_format_label, "ARGB8888") == 0) {
651                 size = width * height *4; debug_log("file_size: %d\n", size);
652         }else if(strcmp(_format_label, "BGRA8888") == 0) {
653                 size = width * height *4; debug_log("file_size: %d\n", size);
654         }else if(strcmp(_format_label, "RGBA8888") == 0) {
655                 size = width * height *4; debug_log("file_size: %d\n", size);
656         }else if(strcmp(_format_label, "ABGR8888") == 0) {
657                 size = width * height *4; debug_log("file_size: %d\n", size);
658         }else if(strcmp(_format_label, "BGRX") == 0) {
659                 size = width * height *4; debug_log("file_size: %d\n", size);
660         }
661
662         return size;
663 }
664
665 static int
666 _mm_imgp_gstcs(imgp_info_s* pImgp_info, unsigned char *src, unsigned char *dst)
667 {
668         image_format_s* input_format=NULL, *output_format=NULL;
669         gstreamer_s* pGstreamer_s;
670         int ret = MM_ERROR_NONE;
671         static const int max_argc = 50;
672         gint* argc = NULL;
673         gchar** argv = NULL;
674
675         g_type_init();
676         if(pImgp_info == NULL) {
677                 debug_error("imgp_info_s is NULL");
678                 return MM_ERROR_IMAGE_INVALID_VALUE;
679         }
680
681         if(src== NULL || dst == NULL) {
682                 debug_error("src || dst is NULL");
683                 return MM_ERROR_IMAGE_INVALID_VALUE;
684         }
685         debug_log("[src %p] [dst %p]", src, dst);
686
687         argc = malloc(sizeof(int));
688         argv = malloc(sizeof(gchar*) * max_argc);
689
690         if (!argc || !argv) {
691                 debug_error("argc ||argv is NULL");
692                 GSTCS_FREE(input_format);
693                 GSTCS_FREE(output_format);
694                 if (argc != NULL) {
695                         free(argc);
696                 }
697                 if (argv != NULL) {
698                         free(argv);
699                 }
700                 return MM_ERROR_IMAGE_INVALID_VALUE;
701         }
702         memset(argv, 0, sizeof(gchar*) * max_argc);
703         debug_log("memset argv");
704
705         /* add initial */
706         *argc = 1;
707         argv[0] = g_strdup( "mmutil_gstcs" );
708         /* check disable registry scan */
709         argv[*argc] = g_strdup("--gst-disable-registry-update");
710         (*argc)++;
711         debug_log("--gst-disable-registry-update");
712
713         gst_init(argc, &argv);
714
715         pGstreamer_s = g_new0 (gstreamer_s, 1);
716
717         GSTCS_FREE(argv);
718         GSTCS_FREE(argc);
719
720         debug_log("[input] format label : %s width: %d height: %d\t[output] format label: %s width: %d height: %d rotation vaule: %d",
721         pImgp_info->input_format_label, pImgp_info->src_width, pImgp_info->src_height, pImgp_info->output_format_label, pImgp_info->dst_width, pImgp_info->dst_height, pImgp_info->angle);
722
723         input_format= _mm_set_input_image_format_s_struct(pImgp_info);
724         if (input_format == NULL) {
725                 debug_error("memory allocation failed");
726                 return MM_ERROR_IMAGE_NO_FREE_SPACE;
727         }
728         output_format= _mm_set_output_image_format_s_struct(pImgp_info);
729         if (output_format == NULL) {
730                 debug_error("memory allocation failed");
731                 GSTCS_FREE(input_format->format_label);
732                 GSTCS_FREE(input_format->colorspace);
733                 GSTCS_FREE(input_format);
734                 return MM_ERROR_IMAGE_NO_FREE_SPACE;
735         }
736
737         pImgp_info->output_stride = output_format->width;
738         pImgp_info->output_elevation = output_format->height;
739
740         /* _format_label : I420, RGB888 etc*/
741         debug_log("Start _mm_imgp_gstcs_processing ");
742         ret =_mm_imgp_gstcs_processing(pGstreamer_s, src, dst, input_format, output_format, pImgp_info); /* input: buffer pointer for input image , input image format, input image width, input image height, output: buffer porinter for output image */
743
744         if(ret == MM_ERROR_NONE) {
745                 debug_log("End _mm_imgp_gstcs_processing [dst: %p]", dst);
746         }else if (ret != MM_ERROR_NONE) {
747                 debug_error("ERROR - _mm_imgp_gstcs_processing");
748         }
749
750         GSTCS_FREE(input_format->format_label);
751         GSTCS_FREE(input_format->colorspace);
752         GSTCS_FREE(input_format);
753
754         GSTCS_FREE(output_format->format_label);
755         GSTCS_FREE(output_format->colorspace);
756         GSTCS_FREE(output_format);
757
758         return ret;
759 }
760
761 int
762 mm_imgp(imgp_info_s* pImgp_info, unsigned char *src, unsigned char *dst, imgp_type_e _imgp_type)
763 {
764         if (pImgp_info == NULL) {
765                 debug_error("input vaule is error");
766         }
767         return _mm_imgp_gstcs(pImgp_info, src, dst);
768 }