Clean up _mc_gst_set_flush_output()
[platform/core/api/mediacodec.git] / src / media_codec_port_gst.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <dlog.h>
21 #include <media_codec_queue.h>
22 #include <media_codec_port_gst.h>
23 #include <media_packet_internal.h>
24 #include <media_codec_util.h>
25
26 #include <gst/gst.h>
27 #include <gst/gstelement.h>
28 #include <gst/app/gstappsrc.h>
29 #include <gst/pbutils/pbutils.h>
30 #include <gst/tag/tag.h>
31
32 /*
33  * Internal Implementation
34  */
35 static gpointer feed_task(gpointer data);
36 static void _mc_gst_feed_task_new(mc_gst_core_t *core);
37 static void _mc_gst_feed_task_free(mc_gst_core_t *core);
38 static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data);
39 static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data);
40 static media_packet_h _mc_get_input_buffer(mc_gst_core_t *core);
41
42 static gboolean __mc_gst_init_gstreamer();
43 static int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime);
44 static mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, const gchar *factory_name);
45 static mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core);
46 static void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data);
47 static int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data);
48 static gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format);
49 static GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h packet, bool codec_config);
50 static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer);
51 static gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool is_hw);
52 static GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer);
53 static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data);
54 static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data);
55 static GstMemory *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, GstMCBuffer *mcbuffer);
56 static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_h packet, uint64_t size);
57 static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer);
58 static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size);
59 static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint codecdata_size);
60 static void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer);
61 static int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer);
62 static void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet);
63
64 static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message);
65 static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, GError *error);
66 static gint __gst_handle_resource_error(mc_gst_core_t *core, int code);
67 static gint __gst_handle_library_error(mc_gst_core_t *core, int code);
68 static gint __gst_handle_core_error(mc_gst_core_t *core, int code);
69 static const gchar * _mc_error_to_string(mc_ret_e err);
70 static const gchar * _mc_bit_to_string(int bit);
71
72 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw);
73 static int _mc_gst_flush_buffers(mc_gst_core_t *core);
74 static void _mc_gst_set_flush_input(mc_gst_core_t *core);
75 static void _mc_gst_set_flush_output(mc_gst_core_t *core);
76
77 #ifdef TIZEN_EXYNOS_SPECIFIC
78 static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);
79 static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest,
80                 unsigned char *nv12t_src, int yuv420_width, int yuv420_height,
81                 int left, int top, int right, int buttom);
82 #endif
83
84 static void _mc_send_eos_signal(mc_gst_core_t *core);
85 static void _mc_wait_for_eos(mc_gst_core_t *core);
86 static int _mc_get_mime(mc_gst_core_t *core);
87 static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config);
88 GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index);
89 GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index);
90
91 static int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer);
92 static int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer);
93
94 static int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer);
95 static int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer);
96 static int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer);
97
98 static int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer);
99 static int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer);
100 static int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer);
101 static int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer);
102
103 static mc_gst_core_t *mc_gst_core_new();
104 static void mc_gst_core_free(mc_gst_core_t *core);
105
106 static mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core);
107 static void mc_gst_port_free(mc_gst_port_t *port);
108 /* video vtable */
109 __attribute__((unused))
110 static int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer};
111
112 static int(*venc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer};
113
114 static int(*vdec_h264_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* S/W H.264 Decoder Vtable */
115                                                                 &__mc_fill_vdec_packet_with_output_buffer};
116
117 static int(*vdec_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                   /* S/W MPEG4 Decoder Vtable */
118                                                                 &__mc_fill_vdec_packet_with_output_buffer};
119
120 static int(*vdec_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* S/W MPEG4 Decoder Vtable */
121                                                                 &__mc_fill_vdec_packet_with_output_buffer};
122
123 static int(*vdec_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* H/W H.264 Decoder Vtable */
124                                                                 &__mc_fill_vdec_packet_with_output_buffer};
125
126 static int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                   /* H/W MPEG4 Decoder Vtable */
127                                                                 &__mc_fill_vdec_packet_with_output_buffer};
128
129 static int(*vdec_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* H/W MPEG4 Decoder Vtable */
130                                                                 &__mc_fill_vdec_packet_with_output_buffer};
131
132 static int(*venc_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet,              /* S/W MPEG4 Encoder Vtable */
133                                                                 &__mc_fill_venc_packet_with_output_buffer};
134
135 static int(*venc_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet,               /* S/W MPEG4 Encoder Vtable */
136                                                                 &__mc_fill_venc_packet_with_output_buffer};
137
138 static int(*venc_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet,               /* H/W H.264 Encoder Vtable */
139                                                                 &__mc_fill_venc_packet_with_output_buffer};
140
141 static int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet,              /* H/W MPEG4 Encoder Vtable */
142                                                                 &__mc_fill_venc_packet_with_output_buffer};
143
144 static int(*venc_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet,               /* H/W MPEG4 Encoder Vtable */
145                                                                 &__mc_fill_venc_packet_with_output_buffer};
146
147 __attribute__((unused))
148 static int(*aenc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer};
149
150 static int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer};
151
152 static int(*aenc_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* AAC LC Encoder vtable */
153                                                         &__mc_fill_aenc_packet_with_output_buffer};
154
155 static int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet,               /* AAC LC Decoder Vtable */
156                                                         &__mc_fill_packet_with_output_buffer};
157
158 static int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet,            /* AAC HE Decoder Vtable */
159                                                         &__mc_fill_packet_with_output_buffer};
160
161 static int(*adec_mp3_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* MP3 Decoder Vtable */
162                                                         &__mc_fill_packet_with_output_buffer};
163
164 static int(*adec_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet,                  /* AMR-NB Decoder Vtable */
165                                                         &__mc_fill_packet_with_output_buffer};
166
167 static int(*adec_amrwb_vtable[])() = {&__mc_fill_input_buffer_with_packet,                  /* AMR-WB Decoder Vtable */
168                                                         &__mc_fill_packet_with_output_buffer};
169
170 static int(*aenc_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet,                  /* AMR-NB Encoder Vtable */
171                                                         &__mc_fill_packet_with_output_buffer};
172
173 static int(*adec_vorbis_vtable[])() = {&__mc_fill_input_buffer_with_packet,                 /* VORBIS Decoder Vtable */
174                                                         &__mc_fill_packet_with_output_buffer};
175
176 static int(*adec_flac_vtable[])() = {&__mc_fill_input_buffer_with_packet,                   /* FLAC Decoder Vtable */
177                                                         &__mc_fill_packet_with_output_buffer};
178
179 static int(*adec_wma_vtable[])() = {&__mc_fill_input_buffer_with_packet,                    /* WMA Decoder Vtable */
180                                                         &__mc_fill_packet_with_output_buffer};
181
182 static int(*aenc_opus_vtable[])() =  {&__mc_fill_input_buffer_with_packet,                  /* Opus Encoder Vtable */
183                                                         &__mc_fill_aenc_packet_with_output_buffer};
184
185 #define MEDIACODEC_ELEMENT_SET_STATE(x_element, x_state)                                          \
186         do {                                                                                            \
187                 LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME(x_element)); \
188                 if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(x_element, x_state)) {                    \
189                         LOGE("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME(x_element));        \
190                         goto STATE_CHANGE_FAILED;                                                               \
191                 }                                                                                           \
192         } while (0)
193
194 /*
195  * fill_inbuf virtual functions
196  */
197 int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
198 {
199         return core->vtable[fill_inbuf](core, packet, mcbuffer);
200 }
201
202 int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
203 {
204         gint ret = MC_ERROR_NONE;
205         uint64_t buf_size = 0;
206         GstMemory *mem;
207         void *buf_data = NULL;
208
209         ret = media_packet_get_buffer_size(packet, &buf_size);
210         if (ret != MEDIA_PACKET_ERROR_NONE) {
211                 LOGW("buffer size get failed");
212                 return MC_ERROR;
213         }
214
215         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
216         if (ret != MEDIA_PACKET_ERROR_NONE) {
217                 LOGW("buffer data get failed");
218                 return MC_ERROR;
219         }
220
221         mem = __mc_gst_make_tbm_buffer(core, mcbuffer);
222         if (mem == NULL) {
223                 LOGW("Failed to make tizen memory");
224                 return MC_ERROR;
225         }
226
227         gst_buffer_append_memory(mcbuffer->buffer, mem);
228         LOGD("tizen memory appended");
229
230         return ret;
231 }
232
233 static int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
234 {
235         gint ret = MC_ERROR_NONE;
236         void *buf_data = NULL;
237         uint64_t buf_size = 0;
238
239         ret = media_packet_get_buffer_size(packet, &buf_size);
240         if (ret != MEDIA_PACKET_ERROR_NONE) {
241                 LOGW("buffer size get failed");
242                 return MC_ERROR;
243         }
244
245         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
246         if (ret != MEDIA_PACKET_ERROR_NONE) {
247                 LOGW("buffer data get failed");
248                 return MC_ERROR;
249         }
250
251         if (buf_data == NULL)
252                 return MC_ERROR;
253
254         gst_buffer_append_memory(mcbuffer->buffer,
255                 gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
256                         buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
257         LOGD("packet data apended");
258
259         return ret;
260 }
261
262 static int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
263 {
264         gint ret = MC_ERROR_NONE;
265         uint64_t buf_size = 0;
266         unsigned int codec_size = 0;
267         bool codec_config = FALSE;
268         void *buf_data = NULL;
269         void *codec_data = NULL;
270
271         ret = media_packet_get_buffer_size(packet, &buf_size);
272         if (ret != MEDIA_PACKET_ERROR_NONE) {
273                 LOGW("buffer size get failed");
274                 return MC_ERROR;
275         }
276
277         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
278         if (ret != MEDIA_PACKET_ERROR_NONE) {
279                 LOGW("buffer data get failed");
280                 return MC_ERROR;
281         }
282
283         if (media_packet_is_codec_config(packet, &codec_config) != MEDIA_PACKET_ERROR_NONE) {
284                 LOGE("media_packet_is_codec_config failed");
285                 return MC_ERROR;
286         }
287
288         if (buf_data != NULL) {
289                 media_packet_get_codec_data(packet, &codec_data, &codec_size);
290
291                 if (!codec_data && codec_config) {
292                         gst_buffer_append_memory(mcbuffer->buffer,
293                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
294                                                 buf_size, NULL, NULL));
295                         LOGD("csd packet data apended");
296                 } else {
297                         gst_buffer_append_memory(mcbuffer->buffer,
298                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
299                                                 buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
300                         LOGD("packet data apended");
301                 }
302         }
303
304         return ret;
305 }
306
307 static int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
308 {
309         gint ret = MC_ERROR_NONE;
310         gint i;
311         gint j;
312         gint stride = 0;
313         gint buf_size = 0;
314         gint stride_width;
315         gint stride_height;
316         gint width;
317         gint height;
318         uint32_t plane_num;
319         guint8 *planes[2];
320
321         mc_gst_port_def_t *port_def = &core->ports[in_port_index]->port_def;
322
323         width = port_def->info.video.width;
324         height = port_def->info.video.height;
325
326         ret = media_packet_get_number_of_video_planes(packet, &plane_num);
327         if (ret != MEDIA_PACKET_ERROR_NONE) {
328                 LOGW("media_packet_get_number_of_video_planes failed");
329                 return MC_ERROR;
330         }
331
332         ret = media_packet_get_video_plane_data_ptr(packet, 0, (void **)&planes[0]);
333         if (ret != MEDIA_PACKET_ERROR_NONE) {
334                 LOGW("media_packet_get_video_plane_data_ptr failed");
335                 return MC_ERROR;
336         }
337
338         ret = media_packet_get_video_stride_width(packet, 0, &stride_width);
339         if (ret != MEDIA_PACKET_ERROR_NONE) {
340                 LOGW("media_packet_get_video_stride_width failed");
341                 return MC_ERROR;
342         }
343
344         ret = media_packet_get_video_stride_height(packet, 0, &stride_height);
345         if (ret != MEDIA_PACKET_ERROR_NONE) {
346                 LOGW("media_packet_get_video_stride_width failed");
347                 return MC_ERROR;
348         }
349
350         if (!core->is_hw) {
351                 if (width == stride_width) {
352                         mcbuffer->buf_size += stride_width * stride_height;
353
354                         for (i = 1; i < plane_num; i++) {
355                                 media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]);
356                                 media_packet_get_video_stride_width(packet, i, &stride_width);
357                                 media_packet_get_video_stride_height(packet, i, &stride_height);
358
359                                 buf_size = stride_width * stride_height;
360
361                                 memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size);
362                                 mcbuffer->buf_size += buf_size;
363                                 LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size);
364                         }
365                 } else {
366
367                         for (j = 0; j < height; j++) {
368                                 memcpy(planes[0] + mcbuffer->buf_size, planes[0] + stride, width);
369                                 mcbuffer->buf_size += width;
370                                 stride += stride_width;
371                         }
372
373                         stride = 0;
374
375                         for (i = 1; i < plane_num; i++) {
376                                 media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]);
377                                 media_packet_get_video_stride_width(packet, i, &stride_width);
378                                 media_packet_get_video_stride_height(packet, i, &stride_height);
379
380                                 for (j = 0; j < height>>1; j++) {
381                                         memcpy(planes[0] + mcbuffer->buf_size, planes[1] + stride, width>>1);
382                                         mcbuffer->buf_size += width>>1;
383                                         stride += stride_width;
384                                 }
385
386                                 memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size);
387                                 LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size);
388                                 mcbuffer->buf_size += buf_size;
389                         }
390                 }
391         } else {
392                 GstMemory *mem = NULL;
393
394                 mem = __mc_gst_make_tbm_buffer(core, mcbuffer);
395                 if (mem == NULL) {
396                         LOGW("Failed to make tizen memory");
397                         return MC_ERROR;
398                 }
399
400                 gst_buffer_append_memory(mcbuffer->buffer, mem);
401                 LOGD("tizen memory appended");
402         }
403         return ret;
404 }
405
406
407 /*
408  * fill_outbuf virtual functions
409  */
410
411 static int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
412 {
413         return core->vtable[fill_outbuf](core, data, size, mcbuffer);
414 }
415
416 static int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
417 {
418         int i;
419         int stride_width;
420         int stride_height;
421         uint32_t width;
422         uint32_t height;
423         uint32_t buf_size;
424         tbm_surface_info_s tsurf_info;
425         tbm_bo bo[MM_VIDEO_BUFFER_PLANE_MAX];
426         tbm_bo_handle thandle;
427         tbm_surface_h tsurf = NULL;
428         media_packet_h packet = NULL;
429
430         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
431
432         mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def;
433
434         if (!core->is_hw) {
435                 width = port_def->info.video.width;
436                 height = port_def->info.video.height;
437                 stride_width = GST_ROUND_UP_4(width);
438                 stride_height = height;
439                 buf_size = stride_width * stride_height * 3 / 2;
440
441                 memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
442
443                 bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC);
444                 if (!bo[0]) {
445                         LOGE("bo allocation failed");
446                         return MC_ERROR;
447                 }
448
449                 tsurf_info.width = port_def->info.video.width;
450                 tsurf_info.height = port_def->info.video.height;
451                 tsurf_info.format = TBM_FORMAT_YVU420;
452                 tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420);
453                 tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420);
454                 tsurf_info.size = 0;
455
456                 for (i = 0; i < tsurf_info.num_planes; i++) {
457                         if (i == 0) {
458                                 tsurf_info.planes[i].stride = stride_width;
459                                 tsurf_info.planes[i].size = stride_width * stride_height;
460                                 tsurf_info.planes[i].offset = 0;
461                                 tsurf_info.size = tsurf_info.planes[i].size;
462                         } else {
463                                 tsurf_info.planes[i].stride = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2);
464                                 tsurf_info.planes[i].size = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2) * (height / 2);
465                                 tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size);
466                                 tsurf_info.size += tsurf_info.planes[i].size;
467                         }
468                 }
469
470                 thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
471                 memcpy(thandle.ptr, data, tsurf_info.size);
472                 tbm_bo_unmap(bo[0]);
473
474                 tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1);
475         } else {
476                 tsurf = (tbm_surface_h)data;
477         }
478
479         if (tsurf) {
480                 media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
481                                 (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, mcbuffer, &packet);
482                 mcbuffer->packet = packet;
483         }
484
485         return MC_ERROR_NONE;
486 }
487
488 static int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
489 {
490         gint ret = MC_ERROR_NONE;
491         gchar *ext_mem = NULL;
492         gint mem_size = 0;
493         void *packet_data = NULL;
494         media_packet_h packet = NULL;
495
496         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
497
498         if (core->encoder && core->codec_id == MEDIACODEC_AAC)
499                 media_format_set_audio_aac_type(core->output_fmt, FALSE);
500
501         mem_size = GST_ROUND_UP_4(size);
502         ext_mem = g_malloc0(mem_size);
503
504         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
505         if (ret != MEDIA_PACKET_ERROR_NONE) {
506                 LOGW("media_packet_create_alloc failed");
507                 g_free(ext_mem);
508                 return MC_ERROR;
509         }
510         mcbuffer->packet = packet;
511         mcbuffer->ext_mem = ext_mem;
512
513         media_packet_set_buffer_size(packet, size);
514         media_packet_get_buffer_data_ptr(packet, &packet_data);
515         memcpy(packet_data, data, size);
516
517         return MC_ERROR_NONE;
518 }
519
520 static int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
521 {
522         gint ret = MC_ERROR_NONE;
523         bool codec_config = FALSE;
524         bool sync_flag = FALSE;
525         bool slice = FALSE;
526         gint mem_size = 0;
527         gchar *ext_mem = NULL;
528         gint data_size = 0;
529         void *packet_data = NULL;
530         media_packet_h packet = NULL;
531
532         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
533
534         switch (core->ports[out_port_index]->port_def.coding_type) {
535         case MEDIA_FORMAT_H264_SP:
536         case MEDIA_FORMAT_H264_MP:
537         case MEDIA_FORMAT_H264_HP:
538                 data_size = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice);
539
540                 if (data_size < 0) {
541                         LOGE("No valid SPS/PPS ...");
542                         return MC_INVALID_IN_BUF;
543                 }
544                 break;
545         case MEDIA_FORMAT_MPEG4_SP:
546         case MEDIA_FORMAT_MPEG4_ASP:
547                 _mc_check_mpeg4_out_bytestream((unsigned char *)data, size, &codec_config, &sync_flag);
548                 break;
549         case MEDIA_FORMAT_H263:
550         case MEDIA_FORMAT_H263P:
551                 if (!_mc_check_h263_out_bytestream((unsigned char *)data, size, &sync_flag))
552                         return MC_INVALID_IN_BUF;
553                 break;
554         default:
555                 return MC_INVALID_IN_BUF;
556         }
557         LOGD("codec_config : %d, sync_flag : %d, slice : %d", codec_config, sync_flag, slice);
558
559         mem_size = GST_ROUND_UP_4(size);
560         ext_mem = g_malloc0(mem_size);
561
562         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
563         if (ret != MEDIA_PACKET_ERROR_NONE) {
564                 LOGW("media_packet_create_alloc failed");
565                 g_free(ext_mem);
566                 return MC_ERROR;
567         }
568         mcbuffer->packet = packet;
569         mcbuffer->ext_mem = ext_mem;
570
571         media_packet_set_buffer_size(packet, size);
572         media_packet_get_buffer_data_ptr(packet, &packet_data);
573         memcpy(packet_data, data, size);
574
575         core->need_sync_flag = sync_flag ? 1 : 0;
576         core->need_codec_data = codec_config ? 1 : 0;
577
578         return ret;
579 }
580
581 static int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
582 {
583         int ret = MC_ERROR_NONE;
584         gint mem_size = 0;
585         GstPad *pad;
586         GstCaps *peercaps;
587         GstMapInfo map;
588         guint8 *ptr;
589         gsize len;
590         gchar *ext_mem = NULL;
591         const GValue *codec_data = NULL;
592         void *packet_data = NULL;
593         media_packet_h packet = NULL;
594
595         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
596
597         if (core->encoder && core->codec_id == MEDIACODEC_AAC)
598                 media_format_set_audio_aac_type(core->output_fmt, FALSE);
599
600         mem_size = GST_ROUND_UP_4(size);
601         ext_mem = g_malloc0(mem_size);
602
603         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
604         if (ret != MEDIA_PACKET_ERROR_NONE) {
605                 LOGW("media_packet_create_alloc failed");
606                 g_free(ext_mem);
607                 return MC_ERROR;
608         }
609         mcbuffer->packet = packet;
610         mcbuffer->ext_mem = ext_mem;
611
612         media_packet_set_buffer_size(packet, size);
613         media_packet_get_buffer_data_ptr(packet, &packet_data);
614         memcpy(packet_data, data, size);
615
616         if (!core->codec_data) {
617                 pad = gst_element_get_static_pad(core->fakesink, "sink");
618                 peercaps = gst_pad_get_current_caps(pad);
619                 if (peercaps) {
620                         GstStructure *s;
621                         if (gst_caps_is_empty(peercaps)) {
622                                 gst_caps_unref(peercaps);
623                                 gst_object_unref(pad);
624                                 LOGW("Empty caps");
625                                 return ret;
626                         }
627
628                         s = gst_caps_get_structure(peercaps, 0);
629                         codec_data = gst_structure_get_value(s, "codec_data");
630                         if (codec_data  == NULL && gst_structure_has_field(s, "streamheader"))
631                                 codec_data = gst_structure_get_value(s, "streamheader");
632
633                         core->codec_data = GST_BUFFER(g_value_dup_boxed(codec_data));
634                         gst_caps_unref(peercaps);
635                 }
636                 gst_object_unref(pad);
637                 LOGD("codec data set");
638         }
639
640         if (core->codec_data) {
641                 gst_buffer_map(core->codec_data, &map, GST_MAP_READ);
642                 ptr = map.data;
643                 len = map.size;
644                 ret = media_packet_set_codec_data(packet, ptr, len);
645                 if (ret != MEDIA_PACKET_ERROR_NONE) {
646                         LOGW("media_packet_set_codec_data failed");
647                         gst_buffer_unmap(core->codec_data, &map);
648                         return MC_ERROR;
649                 }
650                 gst_buffer_unmap(core->codec_data, &map);
651         }
652
653         return ret;
654 }
655
656 static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * name, GstBuffer * buf, ...)
657 {
658         GstStructure *struc = NULL;
659         va_list va;
660         GValue arr_val = { 0 };
661         GValue buf_val = { 0 };
662
663         g_return_val_if_fail(name != NULL, NULL);
664         g_return_val_if_fail(caps != NULL, NULL);
665         g_return_val_if_fail(gst_caps_is_fixed(caps), NULL);
666         caps = gst_caps_make_writable(caps);
667
668         struc = gst_caps_get_structure(caps, 0);
669         if (!struc)
670                 LOGW("cannot get structure from caps.\n");
671
672         g_value_init(&arr_val, GST_TYPE_ARRAY);
673
674         va_start(va, buf);
675         while (buf) {
676                 g_value_init(&buf_val, GST_TYPE_BUFFER);
677                 gst_value_set_buffer(&buf_val, buf);
678                 gst_value_array_append_value(&arr_val, &buf_val);
679                 g_value_unset(&buf_val);
680
681                 buf = va_arg(va, GstBuffer *);
682         }
683         va_end(va);
684
685         gst_structure_take_value(struc, name, &arr_val);
686
687         return caps;
688 }
689
690 int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size)
691 {
692         gint ret = MEDIA_PACKET_ERROR_NONE;
693         uint64_t buf_size = 0;
694         GstBuffer *header1, *header2, *header3;
695         guint hsize1, hsize2, hsize3;
696         GstBuffer *tmp_header;
697         GstMapInfo map;
698         guint8 *buf_data = NULL;
699         guint8 *tmp_buf = NULL;
700
701         ret = media_packet_get_buffer_size(mcbuffer->packet, &buf_size);
702         if (ret != MEDIA_PACKET_ERROR_NONE) {
703                 LOGW("buffer size get failed");
704                 return ret;
705         }
706
707         ret = media_packet_get_buffer_data_ptr(mcbuffer->packet, (void **)&buf_data);
708         if (ret != MEDIA_PACKET_ERROR_NONE) {
709                 LOGW("buffer data get failed");
710                 return ret;
711         }
712
713         LOGD("Set caps for streamheader in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
714
715         if (core->codec_id == MEDIACODEC_VORBIS) {
716                 /*
717                  * hsize1 : Identification Header (packet type 1) - fixed 30 byte
718                  * hsize2 : Comment Header (packet type 3) - variable byte (need calculate)
719                  * hsize3 : Setup Header (packet type 5) - variable byte (Used remained bytes)
720                  */
721
722                 /* First of all, Need to fins and calculate size of hsize2 */
723                 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
724                 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
725                 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
726                 tmp_buf = map.data;
727                 tmp_buf += (30 + 7);                /* hsize1 + '0x03' + 'vorbis'*/
728                 hsize2 = (7 + 4);
729                 hsize2 += GST_READ_UINT32_LE(tmp_buf);
730                 hsize2 += (4 + 1);
731                 LOGD("Find streamheader hsize2(%d)", hsize2);
732                 gst_buffer_unmap(tmp_header, &map);
733                 gst_buffer_unref(tmp_header);
734
735                 /*  hsize1 : Identification Header (packet type 1) - fixed 30 byte */
736                 hsize1 = 30;
737                 header1 = gst_buffer_new_and_alloc(hsize1);
738                 gst_buffer_fill(header1, 0, buf_data, hsize1);
739                 gst_buffer_map(header1, &map, GST_MAP_READ);
740                 tmp_buf = map.data;
741                 /* '0x01' + 'vorbis' */
742                 if (*tmp_buf != 0x01) {
743                         LOGE("[ERROR] Invalid Caps of Stream header1");
744                         gst_buffer_unmap(header1, &map);
745                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
746                 }
747                 gst_buffer_unmap(header1, &map);
748
749                 /* hsize2 : Comment Header (packet type 3) - variable byte */
750                 header2 = gst_buffer_new_and_alloc(hsize2);
751                 gst_buffer_fill(header2, 0,  (buf_data + (hsize1)), hsize2);
752                 gst_buffer_map(header2, &map, GST_MAP_READ);
753                 tmp_buf = map.data;
754                 /* '0x03' + 'vorbis' */
755                 if (*tmp_buf != 0x03) {
756                         LOGE("[ERROR] Invalid Caps of Stream header2");
757                         gst_buffer_unmap(header2, &map);
758                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
759                 }
760                 gst_buffer_unmap(header2, &map);
761
762                 /* hsize3 : Setup Header (packet type 5) - variable byte */
763                 hsize3 = streamheader_size - (hsize1 + hsize2);
764                 header3 = gst_buffer_new_and_alloc(hsize3);
765                 gst_buffer_fill(header3, 0,  (buf_data + (hsize1 + hsize2)), hsize3);
766                 gst_buffer_map(header3, &map, GST_MAP_READ);
767                 tmp_buf = map.data;
768                 /* '0x05' + 'vorbis' */
769                 if (*tmp_buf != 0x05) {
770                         LOGE("[ERROR] Invalid Caps of Stream header3");
771                         gst_buffer_unmap(header3, &map);
772                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
773                 }
774                 gst_buffer_unmap(header3, &map);
775
776                 LOGD("[vorbis] streamheader hsize1 (%d) + hsize2 (%d) + hsize3 (%d) = Total (%d)",
777                                 hsize1, hsize2, hsize3, (hsize1 + hsize2 + hsize3));
778
779                 __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, header3, NULL);
780
781                 gst_buffer_unref(header1);
782                 gst_buffer_unref(header2);
783                 gst_buffer_unref(header3);
784         } else if (core->codec_id == MEDIACODEC_FLAC) {
785                 /*
786                  * hsize1 : Stream Info (type 0) - fixed 51 byte
787                  * hsize2 : Stream Comment (type 4) - variable byte (need calculate)
788                  */
789
790                 /* First of all, Need to fins and calculate size of hsize2 */
791                 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
792                 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
793                 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
794                 tmp_buf = map.data;
795                 hsize2 = 4 + ((tmp_buf[52] << 16) | (tmp_buf[53] << 8) | (tmp_buf[54]));
796                 LOGD("Find streamheader hsize2(%d)", hsize2);
797                 gst_buffer_unmap(tmp_header, &map);
798                 gst_buffer_unref(tmp_header);
799
800                 /*  hsize1 :  Stream Info (type 0) - fixed 51 byte */
801                 hsize1 = 51;
802                 header1 = gst_buffer_new_and_alloc(hsize1);
803                 gst_buffer_fill(header1, 0, buf_data, hsize1);
804                 gst_buffer_map(header1, &map, GST_MAP_READ);
805                 tmp_buf = map.data;
806                 /* '0x7f' + 'FLAC' */
807                 if (*tmp_buf != 0x07f) {
808                         LOGE("[ERROR] Invalid Caps of Stream header1 (Info)");
809                         gst_buffer_unmap(header1, &map);
810                         gst_buffer_unref(header1);
811                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
812                 }
813                 gst_buffer_unmap(header1, &map);
814
815                 /* hsize2 : Stream Comment (type 4) - variable byte (need calculate) */
816                 header2 = gst_buffer_new_and_alloc(hsize2);
817                 gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
818                 gst_buffer_map(header2, &map, GST_MAP_READ);
819                 tmp_buf = map.data;
820                 /* '0x84' */
821                 if (*tmp_buf != 0x84) {
822                         LOGE("[ERROR] Invalid Caps of Stream header2 (Comment)");
823                         gst_buffer_unmap(header2, &map);
824                         gst_buffer_unref(header1);
825                         gst_buffer_unref(header2);
826                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
827                 }
828                 gst_buffer_unmap(header2, &map);
829
830                 LOGD("[flac] streamheader hsize1 (%d) + hsize2 (%d)  = Total (%d)", hsize1, hsize2, (hsize1 + hsize2));
831                 __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, NULL);
832                 gst_buffer_unref(header1);
833                 gst_buffer_unref(header2);
834         } else if (core->codec_id == MEDIACODEC_OPUS) {
835                 const GstTagList *tags;
836                 GstTagList *empty_tags = NULL;
837                 GstBuffer *header, *comments;
838                 guint8 *decoding_channel_mapping = NULL;
839                 mc_gst_port_def_t *port_def = &core->ports[in_port_index]->port_def;
840
841                 header = gst_codec_utils_opus_create_header(port_def->info.audio.samplerate,
842                         port_def->info.audio.channel,
843                         0, /* channel mapping family */
844                         1, /* stream count */
845                         0, /* coupled count */
846                         decoding_channel_mapping,
847                         0, /* FIXME: look ahead configured value */
848                         0);
849                 tags = gst_tag_setter_get_tag_list(GST_TAG_SETTER(core->codec));
850                 if (!tags)
851                         tags = empty_tags = gst_tag_list_new_empty();
852                 comments = gst_tag_list_to_vorbiscomment_buffer(tags, (const guint8 *) "OpusTags",
853                         8, "Encoded with GStreamer opusenc");
854                 core->caps = gst_codec_utils_opus_create_caps_from_header(header, comments);
855                 if (empty_tags)
856                         gst_tag_list_unref(empty_tags);
857                 gst_buffer_unref(header);
858                 gst_buffer_unref(comments);
859         } else {
860                 LOGE("Not support case of Stream header Caps");
861         }
862
863         /* Update gstbuffer's data ptr and size for using previous streamheader.*/
864         LOGD("BEFORE : mcbuffer->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer));
865         gst_buffer_remove_memory_range(mcbuffer->buffer, streamheader_size, -1);
866         gst_buffer_set_size(mcbuffer->buffer, buf_size - streamheader_size);
867         LOGD("AFTER  : mcbuffer->buffer of size %" G_GSIZE_FORMAT "",  gst_buffer_get_size(mcbuffer->buffer));
868
869         return ret;
870 }
871
872 int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint fixed_size)
873 {
874         gint ret = MC_ERROR_NONE;
875         uint32_t codec_data_size = 0;
876         GstMapInfo map;
877         GstBuffer *codecdata_buffer;
878         guint8 *data = NULL;
879         void *codec_data = NULL;
880
881         media_packet_get_codec_data(mcbuffer->packet, &codec_data, &codec_data_size);
882
883         if (codec_data != NULL) {               /* get the codec data from media_packet_get_codec_data() */
884                 data = g_malloc0(codec_data_size);
885                 memcpy(data, codec_data, codec_data_size);
886                 codecdata_buffer = gst_buffer_new_wrapped(data, codec_data_size);
887                 gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
888                 LOGD("set codec data : %" G_GSIZE_FORMAT "", gst_buffer_get_size(codecdata_buffer));
889                 gst_buffer_unref(codecdata_buffer);
890         } else {                                        /* get the codec data from media_packet_get_buffer_data_ptr() */
891                 uint64_t buffer_size = 0;
892                 void *buff_data = NULL;
893
894                 media_packet_get_buffer_size(mcbuffer->packet, &buffer_size);
895                 media_packet_get_buffer_data_ptr(mcbuffer->packet, &buff_data);
896
897                 /* For audio, it's necessary to change the offset value of buffer after extracting csd */
898                 /* it's not necessary to set csd to caps in case of annex-b */
899                 if (buffer_size > fixed_size) {
900                         data = g_malloc0(fixed_size);
901                         gst_buffer_map(mcbuffer->buffer, &map, GST_MAP_READ);
902                         memcpy(data, map.data, fixed_size);
903                         codecdata_buffer = gst_buffer_new_wrapped(data, fixed_size);
904                         gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
905                         gst_buffer_unref(codecdata_buffer);
906
907                         gst_buffer_replace_memory(mcbuffer->buffer, 0,
908                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, map.data + fixed_size , buffer_size - fixed_size, 0,
909                                                 buffer_size - fixed_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
910
911                         LOGD("after : set codec data from packet: %" G_GSIZE_FORMAT "",  gst_buffer_get_size(mcbuffer->buffer));
912                         gst_buffer_unmap(mcbuffer->buffer, &map);
913                 }
914         }
915         return ret;
916 }
917
918 int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime)
919 {
920         if (media_format_create(&core->output_fmt) != MEDIA_FORMAT_ERROR_NONE) {
921                 LOGE("media format create failed");
922                 return MC_ERROR;
923         }
924         mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def;
925
926         if (video) {
927                 media_format_set_video_mime(core->output_fmt, out_mime);
928                 media_format_set_video_width(core->output_fmt, port_def->info.video.width);
929                 media_format_set_video_height(core->output_fmt, port_def->info.video.height);
930
931                 if (encoder)
932                         media_format_set_video_avg_bps(core->output_fmt, port_def->info.video.bitrate);
933         } else {
934                 media_format_set_audio_mime(core->output_fmt, out_mime);
935                 media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel);
936                 media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate);
937                 media_format_set_audio_bit(core->output_fmt, port_def->info.audio.bit_depth);
938
939                 if (encoder)
940                         media_format_set_audio_avg_bps(core->output_fmt, port_def->info.audio.bitrate);
941         }
942
943         return MC_ERROR_NONE;
944 }
945
946 /*
947  * mc_gst_core functions
948  */
949 static mc_gst_core_t *mc_gst_core_new()
950 {
951         mc_gst_core_t *core;
952
953         MEDIACODEC_FENTER();
954
955         core = g_new0(mc_gst_core_t, 1);
956
957         /* 0 : input, 1 : output */
958         core->ports[0] = mc_gst_port_new(core);
959         core->ports[0]->index = 0;
960         core->ports[1] = mc_gst_port_new(core);
961         core->ports[1]->index = 1;
962
963         core->available_queue = g_new0(mc_aqueue_t, 1);
964         core->available_queue->input = mc_async_queue_new();
965
966         g_mutex_init(&core->eos_mutex);
967         g_cond_init(&core->eos_cond);
968         g_cond_init(&core->buffer_cond);
969         g_cond_init(&core->out_buffer_cond);
970         g_mutex_init(&core->prepare_lock);
971         g_mutex_init(&core->drain_lock);
972
973         core->need_drain = false;
974         core->need_feed = false;
975         core->eos = false;
976         core->need_codec_data = false;
977         core->need_sync_flag = false;
978         core->unprepare_flag = false;
979         core->prepare_count = 0;
980         core->etb_count = 0;
981         core->codec_data = NULL;
982         core->allocator = gst_tizen_allocator_new();
983
984         core->bufmgr = NULL;
985         core->drm_fd = -1;
986
987         LOGD("gst_core(%p) is created", core);
988
989         MEDIACODEC_FLEAVE();
990
991         return core;
992 }
993
994 static void mc_gst_core_free(mc_gst_core_t *core)
995 {
996         MEDIACODEC_FENTER();
997
998         g_mutex_clear(&core->eos_mutex);
999         g_mutex_clear(&core->prepare_lock);
1000         g_mutex_clear(&core->drain_lock);
1001         g_cond_clear(&core->eos_cond);
1002         g_cond_clear(&core->buffer_cond);
1003         g_cond_clear(&core->out_buffer_cond);
1004
1005         mc_async_queue_free(core->available_queue->input);
1006         g_free(core->available_queue);
1007         core->available_queue = NULL;
1008
1009         if (core->allocator) {
1010                 gst_object_unref(core->allocator);
1011                 core->allocator = NULL;
1012         }
1013
1014         if (core->codec_data)
1015                 gst_buffer_unref(core->codec_data);
1016
1017         if (core->ports[0] != NULL) {
1018                 mc_gst_port_free(core->ports[0]);
1019                 core->ports[0] = NULL;
1020         }
1021
1022         if (core->ports[1] != NULL) {
1023                 mc_gst_port_free(core->ports[1]);
1024                 core->ports[1] = NULL;
1025         }
1026
1027         LOGD("gst_core(%p) destroyed", core);
1028         g_free(core);
1029
1030         MEDIACODEC_FLEAVE();
1031 }
1032
1033 /*
1034  * mc_gst_port functions
1035  */
1036 static mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
1037 {
1038         MEDIACODEC_FENTER();
1039
1040         mc_gst_port_t *port;
1041
1042         port = g_new0(mc_gst_port_t, 1);
1043         port->core = core;
1044         port->num_buffers = -1;
1045         port->buffer_size = 0;
1046         port->is_allocated = 0;
1047
1048         g_mutex_init(&port->mutex);
1049         port->queue = g_queue_new();
1050
1051         LOGD("gst_port(%p) created", port);
1052
1053         MEDIACODEC_FLEAVE();
1054         return port;
1055 }
1056
1057 static void mc_gst_port_free(mc_gst_port_t *port)
1058 {
1059         MEDIACODEC_FENTER();
1060
1061         g_mutex_clear(&port->mutex);
1062         g_queue_free(port->queue);
1063
1064         LOGD("gst_port(%p) freed", port);
1065         g_free(port);
1066
1067         MEDIACODEC_FLEAVE();
1068
1069         return;
1070 }
1071
1072 gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format)
1073 {
1074         gboolean is_format_change = FALSE;
1075
1076         mc_gst_port_def_t *input_port_def = &core->ports[in_port_index]->port_def;
1077
1078         if (core->video) {
1079                 gint width = 0;
1080                 gint height = 0;
1081                 gint bitrate = 0;
1082                 gint framerate = 0;
1083                 gchar *sformat = NULL;
1084                 media_format_mimetype_e mimetype = 0;
1085
1086                 media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL);
1087                 media_format_get_video_frame_rate(format, &framerate);
1088
1089                 is_format_change |= input_port_def->info.video.width != width;
1090                 is_format_change |= input_port_def->info.video.height != height;
1091                 is_format_change |= ((input_port_def->info.video.framerate != framerate) && (framerate != 0));
1092                 if (is_format_change) {
1093                         LOGD("Format changed : resolution %dx%d -> %dx%d, framerate %d -> %d",
1094                                 input_port_def->info.video.width, input_port_def->info.video.height, width, height,
1095                                 input_port_def->info.video.framerate, framerate);
1096                         input_port_def->info.video.width = width;
1097                         input_port_def->info.video.height = height;
1098                 }
1099
1100                 if (core->encoder) {
1101                         sformat = __mc_get_gst_input_format(mimetype, core->is_hw);
1102                         is_format_change |= ((input_port_def->info.video.bitrate != bitrate * 1000) && (bitrate != 0));
1103                         is_format_change |= g_strcmp0(input_port_def->info.video.format, sformat);
1104                         if (is_format_change) {
1105                                 LOGD("Bitrate changed : %d -> %d", input_port_def->info.video.bitrate, bitrate);
1106                                 LOGD("Format changed : %s -> %s", input_port_def->info.video.format, sformat);
1107                                 input_port_def->info.video.bitrate = bitrate * 1000;
1108                                 input_port_def->info.video.format = g_strdup(sformat);
1109                         }
1110                 }
1111         } else {
1112                 gint channel;
1113                 gint samplerate;
1114                 gint bit;
1115                 gint bitrate;
1116
1117                 media_format_get_audio_info(format, NULL, &channel, &samplerate, &bit, &bitrate);
1118
1119                 is_format_change |= input_port_def->info.audio.channel != channel;
1120                 is_format_change |= input_port_def->info.audio.samplerate != samplerate;
1121                 is_format_change |= input_port_def->info.audio.bit_depth != bit;
1122                 if (is_format_change) {
1123                         LOGD("Audio info. changed : %d -> %d, %d -> %d, %d -> %d",
1124                                 input_port_def->info.audio.channel, channel,
1125                                 input_port_def->info.audio.samplerate, samplerate,
1126                                 input_port_def->info.audio.bit_depth, bit);
1127                         input_port_def->info.audio.channel = channel;
1128                         input_port_def->info.audio.samplerate = samplerate;
1129                         input_port_def->info.audio.bit_depth = bit;
1130                 }
1131
1132                 if (core->encoder) {
1133                         is_format_change |= ((input_port_def->info.audio.bitrate != bitrate * 1000) && (bitrate != 0));
1134                         if (is_format_change) {
1135                                 LOGD("Bitrate changed : %d -> %d", input_port_def->info.audio.bitrate, bitrate);
1136                                 input_port_def->info.audio.bitrate = bitrate * 1000;
1137                         }
1138                 }
1139         }
1140
1141         return is_format_change;
1142 }
1143
1144 static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config)
1145 {
1146         MEDIACODEC_FENTER();
1147
1148         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1149         g_return_val_if_fail(mcbuffer != NULL, MC_PARAM_ERROR);
1150
1151         int ret = MC_ERROR_NONE;
1152
1153         switch (core->codec_id) {
1154         case MEDIACODEC_AAC:
1155         case MEDIACODEC_AAC_HE:
1156         case MEDIACODEC_AAC_HE_PS:
1157                 if (codec_config) {
1158                         ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE);
1159                         if (ret != MC_ERROR_NONE)
1160                                 LOGW("__mc_set_caps_codecdata failed");
1161                 }
1162                 break;
1163         case MEDIACODEC_WMAV1:
1164         case MEDIACODEC_WMAV2:
1165         case MEDIACODEC_WMAPRO:
1166         case MEDIACODEC_WMALSL:
1167                 if (codec_config) {
1168                         ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE);
1169                         if (ret != MC_ERROR_NONE)
1170                                 LOGW("__mc_set_caps_codecdata failed");
1171                 }
1172                 break;
1173         case MEDIACODEC_VORBIS:
1174         case MEDIACODEC_FLAC:
1175         case MEDIACODEC_OPUS:
1176                 if (codec_config) {
1177                         ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE);
1178                         if (ret != MC_ERROR_NONE)
1179                                 LOGW("__mc_set_caps_streamheader failed");
1180                 }
1181                 break;
1182         case MEDIACODEC_H264:
1183         case MEDIACODEC_MPEG4:
1184                 ret = __mc_set_caps_codecdata(core, mcbuffer, CODECDATA_NOT_USE);
1185                 if (ret != MC_ERROR_NONE)
1186                         LOGW("__mc_set_caps_codecdata failed");
1187                 break;
1188         default:
1189                 LOGD("doesn't need to set codecdata");
1190                 break;
1191         }
1192
1193         MEDIACODEC_FLEAVE();
1194         return ret;
1195
1196
1197 }
1198
1199 static gpointer feed_task(gpointer data)
1200 {
1201         gint ret = MC_ERROR_NONE;
1202         bool codec_config = FALSE;
1203         bool eos = FALSE;
1204         bool initiative = TRUE;
1205         bool is_format_change = FALSE;
1206         media_format_h format = NULL;
1207         media_packet_h input_buffer = NULL;
1208         GstMCBuffer *mcbuffer = NULL;
1209
1210         MEDIACODEC_FENTER();
1211
1212         mc_gst_core_t *core = (mc_gst_core_t *)data;
1213
1214         while (g_atomic_int_get(&core->available_queue->running)) {
1215                 LOGD("waiting for next input....");
1216                 input_buffer = _mc_get_input_buffer(core);
1217                 if (!input_buffer)
1218                         goto LEAVE;
1219
1220                 media_packet_get_format(input_buffer,  &format);
1221                 if (format) {
1222                         if (_mc_update_packet_info(core, format))
1223                                 is_format_change = TRUE;
1224                         media_format_unref(format);
1225                 }
1226
1227                 if (media_packet_is_codec_config(input_buffer, &codec_config) != MEDIA_PACKET_ERROR_NONE) {
1228                         LOGE("media_packet_is_codec_config failed");
1229                         goto ERROR;
1230                 }
1231
1232                 if (media_packet_is_end_of_stream(input_buffer, &eos) != MEDIA_PACKET_ERROR_NONE) {
1233                         LOGE("media_packet_is_end_of_stream failed");
1234                         goto ERROR;
1235                 }
1236                 /*
1237                  * receive an eos packet. For decoder + encoder case, encoder always get tbm surface plane first from input data,
1238                  * but eos packet only has flag not valid data, so we don't put it to downstream.
1239                  */
1240                 if (eos) {
1241                         LOGD("end of stream");
1242                         gst_app_src_end_of_stream(GST_APP_SRC(core->appsrc));
1243                         _mc_wait_for_eos(core);
1244                         initiative = TRUE;
1245
1246                         _mc_gst_handle_input_buffer_used(core, input_buffer);
1247                         goto LEAVE;
1248                 }
1249
1250                 mcbuffer = _mc_gst_media_packet_to_gstbuffer(core, input_buffer, codec_config);
1251                 if (!mcbuffer) {
1252                         LOGW("gstbuffer can't make");
1253                         goto ERROR;
1254                 }
1255                 /* mcbuffer took the ownership of the input_buffer, so set input_buffer to NULL to aviod double unref */
1256                 input_buffer = NULL;
1257
1258                 if (codec_config || initiative) {
1259                         GstPad *pad = NULL;
1260                         if (!core->encoder) {
1261                                 ret = _mc_set_codec_data(core, mcbuffer, codec_config);
1262                                 if (ret != MC_ERROR_NONE) {
1263                                         LOGE("failed to set codec data");
1264                                         gst_buffer_unref(mcbuffer->buffer);
1265                                         goto ERROR;
1266                                 }
1267                         }
1268                         pad = gst_element_get_static_pad(core->appsrc, "src");
1269                         gst_pad_push_event(pad, gst_event_new_stream_start("start"));
1270                         gst_object_unref(pad);
1271                         is_format_change = TRUE;
1272                         initiative = FALSE;
1273                         core->offset = GST_BUFFER_OFFSET_NONE;
1274                 }
1275
1276                 if (is_format_change) {
1277                         int bitrate = core->video ? \
1278                                 core->ports[in_port_index]->port_def.info.video.bitrate : \
1279                                 core->ports[in_port_index]->port_def.info.audio.bitrate;
1280                         GstCaps *caps = core->mc_caps_new(core, core->codec_id, in_port_index);
1281
1282                         g_object_set(core->appsrc, "caps", caps, NULL);
1283                         gst_caps_unref(caps);
1284
1285                         LOGD("caps updated");
1286
1287                         g_object_set(core->codec, core->codec_type->property->bitrate_name, bitrate, NULL);
1288
1289                         LOGI("bitrate[property:%s,v:%d] %d updated",
1290                                 core->codec_type->property->bitrate_name, core->video, bitrate);
1291
1292                         is_format_change = FALSE;
1293                 }
1294
1295
1296                 /* inject buffer */
1297                 ret = _mc_gst_gstbuffer_to_appsrc(core, mcbuffer);
1298                 if (ret != GST_FLOW_OK) {
1299                         LOGE("Failed to push gst buffer");
1300                         goto ERROR;
1301                 }
1302
1303                 continue;
1304 ERROR:
1305                 if (input_buffer)
1306                         _mc_gst_handle_input_buffer_used(core, input_buffer);
1307
1308                 _mc_gst_set_flush_input(core);
1309
1310                 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
1311                         ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
1312                                 (MC_INTERNAL_ERROR, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
1313                 }
1314
1315                 continue;
1316 LEAVE:
1317                 /*LOGE("status : input_buffer : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", input_buffer, codec_config, eos, core->encoder);*/
1318                 continue;
1319
1320         }
1321
1322         LOGI("status : input_buffer : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task",
1323                         input_buffer, codec_config, eos, core->video, core->encoder);
1324         LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder);
1325
1326         MEDIACODEC_FLEAVE();
1327
1328         return NULL;
1329 }
1330
1331 static void _mc_gst_feed_task_new(mc_gst_core_t *core)
1332 {
1333         g_return_if_fail(core && core->available_queue);
1334
1335         g_atomic_int_set(&core->available_queue->running, 1);
1336         core->available_queue->thread = g_thread_new("feed thread", &feed_task, core);
1337
1338         LOGI("new thread for feed[%p]", core->available_queue->thread);
1339 }
1340
1341 static void _mc_gst_feed_task_free(mc_gst_core_t *core)
1342 {
1343         g_return_if_fail(core && core->available_queue);
1344
1345         mc_async_queue_disable(core->available_queue->input);
1346
1347         g_atomic_int_set(&core->available_queue->running, 0);
1348         g_thread_join(core->available_queue->thread);
1349
1350         LOGI("feed thread[%p] is released", core->available_queue->thread);
1351 }
1352
1353 static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data)
1354 {
1355         mc_gst_core_t *core = (mc_gst_core_t *)data;
1356
1357         LOGI("stop_feed called");
1358         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1359                 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1360                         (MEDIACODEC_ENOUGH_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1361         }
1362 }
1363
1364 static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data)
1365 {
1366         mc_gst_core_t *core = (mc_gst_core_t *)data;
1367
1368         LOGI("start_feed called");
1369
1370         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1371                 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1372                         (MEDIACODEC_NEED_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1373         }
1374 }
1375
1376 GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index)
1377 {
1378         GstCaps *caps = NULL;
1379         mc_gst_port_def_t *port_def = &core->ports[index]->port_def;
1380
1381         caps = gst_caps_new_simple(core->mime,
1382                 "rate", G_TYPE_INT, port_def->info.audio.samplerate,
1383                 "channels", G_TYPE_INT, port_def->info.audio.channel, NULL);
1384
1385         switch (codec_id) {
1386         case MEDIACODEC_AAC:
1387                 if (core->encoder) {
1388                         gst_caps_set_simple(caps,
1389                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1390                                 "layout", G_TYPE_STRING, "interleaved", NULL);
1391                         g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
1392                 } else {
1393                         gst_caps_set_simple(caps,
1394                                 "framed", G_TYPE_BOOLEAN, TRUE,
1395                                 "mpegversion", G_TYPE_INT, 4,
1396                                 "stream-format", G_TYPE_STRING, "adts",
1397                                 NULL);
1398                         LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
1399                 }
1400                 break;
1401         case MEDIACODEC_AAC_HE:
1402         case MEDIACODEC_AAC_HE_PS:
1403                 if (core->encoder) {
1404                         LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
1405                         return NULL;
1406                 } else {
1407                         gst_caps_set_simple(caps,
1408                                 "mpegversion", G_TYPE_INT, 4,
1409                                 "framed", G_TYPE_BOOLEAN, TRUE,
1410                                 "stream-format", G_TYPE_STRING, "raw",
1411                                 NULL);
1412                         LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE)");
1413                 }
1414                 break;
1415         case MEDIACODEC_MP3:
1416                 if (core->encoder) {
1417                         LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
1418                         return NULL;
1419                 } else {
1420                         gst_caps_set_simple(caps,
1421                                 "framed", G_TYPE_BOOLEAN, TRUE,
1422                                 "mpegversion", G_TYPE_INT, 1,       /* To-Do : plz check */
1423                                 "mpegaudioversion", G_TYPE_INT, 1,  /* To-Do : plz check */
1424                                 "layer", G_TYPE_INT, 3,             /* To-Do : plz check */
1425                                 NULL);
1426                         LOGD("CAPS for codec_id (MEDIACODEC_MP3)");
1427                 }
1428                 break;
1429         case MEDIACODEC_AMR_NB:
1430                 if (core->encoder) {
1431                         gst_caps_set_simple(caps,
1432                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1433                                 "layout", G_TYPE_STRING, "interleaved",
1434                                 NULL);
1435                         LOGD("CAPS for codec_id (MEDIACODEC_AMR_NB)");
1436                 } else {
1437                         gst_caps_set_simple(caps,
1438                                 "rate", G_TYPE_INT, 8000,
1439                                 NULL);
1440                 }
1441                 break;
1442         case MEDIACODEC_AMR_WB:
1443                 if (core->encoder) {
1444                         LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
1445                         return NULL;
1446                 } else {
1447                         gst_caps_set_simple(caps,
1448                                 "rate", G_TYPE_INT, 16000,
1449                                 NULL);
1450                 }
1451                 break;
1452         case MEDIACODEC_VORBIS:
1453                 if (core->encoder) {
1454                         LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!");
1455                         return NULL;
1456                 } else {
1457                 }
1458                 break;
1459         case MEDIACODEC_FLAC:
1460                 if (core->encoder) {
1461                         LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
1462                         return NULL;
1463                 } else {
1464                         gst_caps_set_simple(caps,
1465                                 "framed", G_TYPE_BOOLEAN, TRUE,
1466                                 /* FIXME - Insert More Info */
1467                                 NULL);
1468                 }
1469                 break;
1470         case MEDIACODEC_WMAV1:
1471         case MEDIACODEC_WMAV2:
1472         case MEDIACODEC_WMAPRO:
1473         case MEDIACODEC_WMALSL:
1474                 if (core->encoder) {
1475                         LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
1476                         return NULL;
1477                 } else {
1478                         /*
1479                          * Need to extract from Stream Type Specific ... or
1480                          * Need to get Demuxer's Caps from Stream Type Specific
1481                          */
1482                         guint16 format_tag = 0;
1483                         gint wma_version = 0;
1484                         gint block_align = 1024;      /*FIXME : Need checking */
1485                         gint bitrate = 128000;        /*FIXME : Need checking */
1486
1487                         LOGD(" ----- WMA Need Additional Caps -----------");
1488                         if (core->codec_id == MEDIACODEC_WMAV1) {
1489                                 format_tag = 352;       /* 0x160 */
1490                                 wma_version = 1;
1491                         } else if (core->codec_id == MEDIACODEC_WMAV2) {
1492                                 format_tag = 353;       /* 0x161 */
1493                                 wma_version = 2;
1494                         } else if (core->codec_id == MEDIACODEC_WMAPRO) {
1495                                 format_tag = 354;       /* 0x162 */
1496                                 wma_version = 3;
1497                         } else if (core->codec_id == MEDIACODEC_WMALSL) {
1498                                 format_tag = 355;       /* 0x163 */
1499                                 wma_version = 3;
1500                         } else {
1501                                 LOGE("Not support WMA format");
1502                         }
1503
1504                         gst_caps_set_simple(caps,
1505                                 "bitrate", G_TYPE_INT, bitrate,
1506                                 "depth", G_TYPE_INT, port_def->info.audio.bit_depth,
1507                                 /* FIXME - Need More Info */
1508                                 "wmaversion", G_TYPE_INT, wma_version,
1509                                 "format_tag", G_TYPE_INT, format_tag,
1510                                 "block_align", G_TYPE_INT, block_align,
1511                                 NULL);
1512                 }
1513                 break;
1514         case MEDIACODEC_OPUS:
1515                 if (core->encoder) {
1516                         gst_caps_set_simple(caps,
1517                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1518                                 "layout", G_TYPE_STRING, "interleaved", NULL);
1519                 } else {
1520                         LOGD("[MC_NOT_SUPPORTED] opus decoder is not supported yet!!!");
1521                         return NULL;
1522                 }
1523                 break;
1524         default:
1525                 break;
1526         }
1527         return caps;
1528 }
1529
1530 GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index)
1531 {
1532         GstCaps *caps = NULL;
1533         mc_gst_port_def_t *port_def = &core->ports[index]->port_def;
1534
1535         caps = gst_caps_new_simple(core->mime,
1536                 "width", G_TYPE_INT, port_def->info.video.width,
1537                 "height", G_TYPE_INT, port_def->info.video.height,
1538                 "framerate", GST_TYPE_FRACTION, port_def->info.video.framerate, 1,
1539                 NULL);
1540
1541         switch (codec_id) {
1542         case MEDIACODEC_H263:
1543                 if (core->encoder) {
1544                         gst_caps_set_simple(caps,
1545                                 "format", G_TYPE_STRING, port_def->info.video.format,
1546                                 NULL);
1547                 } else {
1548                         gst_caps_set_simple(caps,
1549                                 "mpegversion", G_TYPE_INT, 4,
1550                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1551                                 NULL);
1552                 }
1553                 break;
1554         case MEDIACODEC_MPEG4:
1555                 if (core->encoder) {
1556                         gst_caps_set_simple(caps,
1557                                 "format", G_TYPE_STRING, port_def->info.video.format,
1558                                 NULL);
1559                 } else {
1560                         gst_caps_set_simple(caps,
1561                                 "mpegversion", G_TYPE_INT, 4,
1562                                 "systemstream", G_TYPE_BOOLEAN, false,
1563                                 "parsed", G_TYPE_BOOLEAN, TRUE,
1564                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1565                                 NULL);
1566                 }
1567                 break;
1568         case MEDIACODEC_H264:
1569                 if (core->encoder) {
1570                         gst_caps_set_simple(caps,
1571                                 "format", G_TYPE_STRING, port_def->info.video.format,
1572                                 NULL);
1573                         g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
1574                         LOGE("format : %s", port_def->info.video.format);
1575                 } else {
1576                         gst_caps_set_simple(caps,
1577                                 "parsed", G_TYPE_BOOLEAN, TRUE,  /* FIXME different from sw */
1578                                 "alignment", G_TYPE_STRING, "au",
1579                                 "stream-format", G_TYPE_STRING, "byte-stream",
1580                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1581                                 NULL);
1582                 }
1583                 break;
1584         default:
1585                 break;
1586         }
1587
1588         return caps;
1589 }
1590
1591 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean encoder, gboolean is_hw)
1592 {
1593         MEDIACODEC_FENTER();
1594
1595         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1596
1597         switch (id) {
1598         case MEDIACODEC_AAC:
1599                 if (encoder)
1600                         core->vtable = aenc_aac_vtable;
1601                 else
1602                         core->vtable = adec_aac_vtable;
1603                 break;
1604         case MEDIACODEC_AAC_HE:
1605         case MEDIACODEC_AAC_HE_PS:
1606                 if (encoder) {
1607                         LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
1608                         return MC_NOT_SUPPORTED;
1609                 } else {
1610                         core->vtable = adec_aacv12_vtable;
1611                 }
1612                 break;
1613         case MEDIACODEC_MP3:
1614                 if (encoder) {
1615                         LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
1616                         return MC_NOT_SUPPORTED;
1617                 } else {
1618                         core->vtable = adec_mp3_vtable;
1619                 }
1620                 break;
1621         case MEDIACODEC_AMR_NB:
1622                 LOGD("amrnb vtable");
1623                 if (encoder)
1624                         core->vtable = aenc_amrnb_vtable;
1625                 else
1626                         core->vtable = adec_amrnb_vtable;
1627                 break;
1628         case MEDIACODEC_AMR_WB:
1629                 LOGD("amrwb vtable - Only support decoder");
1630                 if (encoder) {
1631                         LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
1632                         return MC_NOT_SUPPORTED;
1633                 } else {
1634                         core->vtable = adec_amrwb_vtable;
1635                 }
1636                 break;
1637         case MEDIACODEC_VORBIS:
1638                 LOGD("vorbis vtable");
1639                 if (encoder)
1640                         return MC_NOT_SUPPORTED;
1641                 else
1642                         core->vtable = adec_vorbis_vtable;
1643                 break;
1644         case MEDIACODEC_FLAC:
1645                 LOGD("flac vtable");
1646                 if (encoder) {
1647                         LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
1648                         return MC_NOT_SUPPORTED;
1649                 } else {
1650                         core->vtable = adec_flac_vtable;
1651                 }
1652                 break;
1653         case MEDIACODEC_OPUS:
1654                 LOGD("opus vtable");
1655                 if (encoder)
1656                         core->vtable = aenc_opus_vtable;
1657                 else
1658                         core->vtable = adec_vtable;
1659                 break;
1660         case MEDIACODEC_WMAV1:
1661         case MEDIACODEC_WMAV2:
1662         case MEDIACODEC_WMAPRO:
1663         case MEDIACODEC_WMALSL:
1664                 LOGD("wma(V1 / V2 / LSL / PRO) vtable");
1665                 if (encoder) {
1666                         LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
1667                         return MC_NOT_SUPPORTED;
1668                 } else {
1669                         core->vtable = adec_wma_vtable;
1670                 }
1671                 break;
1672         case MEDIACODEC_H263:
1673                 LOGD("h263 vtable");
1674                 if (encoder) {
1675                         core->vtable = is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable;
1676                 } else {
1677                         if (is_hw)
1678                                 core->vtable = vdec_h263_hw_vtable;
1679                         else
1680                                 core->vtable = vdec_h263_sw_vtable;
1681                 }
1682                 break;
1683         case MEDIACODEC_MPEG4:
1684                 LOGD("mpeg4 vtable");
1685                 if (encoder)
1686                         core->vtable = is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable;
1687                 else
1688                         core->vtable = is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable;
1689                 break;
1690         case MEDIACODEC_H264:
1691                 LOGD("h264 vtable");
1692                 if (encoder) {
1693                         core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable;
1694                 } else {
1695                         if (is_hw)
1696                                 core->vtable = vdec_h264_hw_vtable;
1697                         else
1698                                 core->vtable = vdec_h264_sw_vtable;
1699                 }
1700                 break;
1701         default:
1702                 break;
1703         }
1704
1705         MEDIACODEC_FLEAVE();
1706
1707         return MC_ERROR_NONE;
1708 }
1709
1710 static gint _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer)
1711 {
1712         return gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer);
1713 }
1714
1715 media_packet_h _mc_get_input_buffer(mc_gst_core_t *core)
1716 {
1717         LOGD("waiting for input...");
1718         return mc_async_queue_pop(core->available_queue->input);
1719 }
1720
1721 mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle)
1722 {
1723         int ret = MC_ERROR_NONE;
1724         int num_supported_codec = 0;
1725         int i = 0;
1726         bool video;
1727         bool encoder;
1728         bool hardware;
1729         gchar *factory_name = NULL;
1730         GstCaps *caps = NULL;
1731         media_format_mimetype_e out_mime;
1732         mediacodec_codec_type_e id;
1733         mc_codec_map_t *codec_map;
1734
1735         MEDIACODEC_FENTER();
1736
1737         if (!mc_handle)
1738                 return MC_PARAM_ERROR;
1739
1740         id = mc_handle->codec_id;
1741         video = mc_handle->is_video;
1742         encoder = mc_handle->is_encoder;
1743         hardware = mc_handle->is_hw;
1744         codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
1745         num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
1746
1747         for (i = 0; i < num_supported_codec; i++) {
1748                 if ((id == codec_map[i].id) && (hardware == codec_map[i].hardware))
1749                         break;
1750         }
1751
1752         if (i == num_supported_codec)
1753                 return MC_NOT_SUPPORTED;
1754
1755         factory_name = codec_map[i].type.factory_name;
1756         out_mime = codec_map[i].type.out_format;
1757
1758         /* gst_core create */
1759         mc_gst_core_t *new_core = mc_gst_core_new();
1760
1761         new_core->mime = codec_map[i].type.mime;
1762         new_core->is_hw = hardware;
1763         new_core->eos = false;
1764         new_core->encoder = encoder;
1765         new_core->video = video;
1766         memcpy(&new_core->ports[in_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info));
1767         memcpy(&new_core->ports[out_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info));
1768         new_core->ports[out_port_index]->port_def.coding_type = out_mime;
1769         new_core->codec_id = id;
1770         new_core->codec_type = &codec_map[i].type;
1771         new_core->mc_caps_new = video ? &_mc_gst_vid_caps_new : &_mc_gst_aud_caps_new;
1772
1773         new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd);
1774         if (new_core->bufmgr == NULL) {
1775                 LOGE("TBM initialization failed");
1776                 return MC_ERROR;
1777         }
1778
1779         LOGD("@%p(%p) core is initializing...v(%d)e(%d)", mc_handle, new_core, new_core->video, new_core->encoder);
1780         LOGD("factory name : %s, output_fmt : %x", factory_name, out_mime);
1781
1782         /* create media_packet for output fmt */
1783         ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime);
1784         if (ret != MC_ERROR_NONE) {
1785                 LOGE("Failed to create output pakcet");
1786                 return ret;
1787         }
1788
1789         for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++) {
1790                 LOGD("copy cb function [%d]", i);
1791                 if (mc_handle->user_cb[i]) {
1792                         new_core->user_cb[i] = mc_handle->user_cb[i];
1793                         new_core->user_data[i] = mc_handle->user_data[i];
1794                         LOGD("user_cb[%d] %p, %p", i, new_core->user_cb[i], mc_handle->user_cb[i]);
1795                 }
1796         }
1797
1798         /* create basic core elements */
1799         ret = _mc_gst_create_pipeline(new_core, factory_name);
1800         if (ret != MC_ERROR_NONE) {
1801                 LOGE("failed to create pipeline");
1802                 return ret;
1803         }
1804
1805         /* link vtable */
1806         ret = _mc_link_vtable(new_core, id, encoder, hardware);
1807         if (ret != MC_ERROR_NONE) {
1808                 LOGE("vtable link failed");
1809                 return ret;
1810         }
1811
1812         /* set caps in capsfilter as default*/
1813         caps = new_core->mc_caps_new(new_core, id, out_port_index);
1814
1815         new_core->caps = caps;
1816         /* FIXME will parse input format from ini. format is needed when linking elements*/
1817         if (new_core->video && new_core->encoder) {
1818                 gchar *format = NULL;
1819
1820                 format = new_core->is_hw ? "SN12" : "I420";
1821                 gst_caps_set_simple(caps,
1822                         "format", G_TYPE_STRING, format,
1823                         NULL);
1824         }
1825         g_object_set(new_core->capsfilter, "caps", caps, NULL);
1826         gst_caps_unref(caps);
1827
1828         _mc_gst_feed_task_new(new_core);
1829
1830         mc_handle->core = new_core;
1831         LOGD("initialized... %d", ret);
1832         MEDIACODEC_FLEAVE();
1833
1834         return ret;
1835 }
1836
1837 mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle)
1838 {
1839         MEDIACODEC_FENTER();
1840
1841         int i;
1842         int ret = MC_ERROR_NONE;
1843         mc_gst_core_t *core = NULL;
1844
1845         if (!mc_handle)
1846                 return MC_PARAM_ERROR;
1847
1848         core = (mc_gst_core_t *)mc_handle->core;
1849
1850         if (core) {
1851                 LOGD("@%p(%p) core is uninitializing... v(%d)e(%d)", mc_handle, core, core->video, core->encoder);
1852
1853                 g_mutex_lock(&core->drain_lock);
1854                 core->unprepare_flag = TRUE;
1855                 g_mutex_unlock(&core->drain_lock);
1856
1857                 if (core->eos)
1858                         _mc_send_eos_signal(core);
1859
1860                 _mc_gst_feed_task_free(core);
1861
1862                 _mc_gst_set_flush_input(core);
1863
1864                 ret = _mc_gst_destroy_pipeline(core);
1865
1866                 /* unset callback */
1867                 for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER; i++) {
1868                         LOGD("unset cb function [%d]", i);
1869                         if (mc_handle->user_cb[i]) {
1870                                 core->user_cb[i] = NULL;
1871                                 core->user_data[i] = NULL;
1872                                 LOGD("user_cb[%d] %p, %p", i, core->user_cb[i], mc_handle->user_cb[i]);
1873                         }
1874                 }
1875
1876                 media_format_unref(core->output_fmt);
1877
1878                 if (core->bufmgr != NULL) {
1879                         tbm_bufmgr_deinit(core->bufmgr);
1880                         core->bufmgr = NULL;
1881                 }
1882
1883                 if (core->drm_fd != -1) {
1884                         close(core->drm_fd);
1885                         LOGD("close drm_fd");
1886                 }
1887
1888                 if (core != NULL) {
1889                         mc_gst_core_free(core);
1890                         mc_handle->core = NULL;
1891                 }
1892         }
1893
1894         MEDIACODEC_FLEAVE();
1895
1896         return ret;
1897 }
1898
1899 mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint64_t timeout_us)
1900 {
1901         MEDIACODEC_FENTER();
1902
1903         int ret = MC_ERROR_NONE;
1904         mc_gst_core_t *core = NULL;
1905
1906         if (!mc_handle)
1907                 return MC_PARAM_ERROR;
1908
1909         core = (mc_gst_core_t *)mc_handle->core;
1910
1911         g_mutex_lock(&core->drain_lock);
1912
1913         while (g_atomic_int_get(&core->etb_count) == MAXINUM_QNUM) {
1914                 LOGD("Waiting until packets are drained..");
1915                 core->need_drain = true;
1916                 g_cond_wait(&core->buffer_cond, &core->drain_lock);
1917         }
1918         g_mutex_unlock(&core->drain_lock);
1919
1920         if (core->prepare_count == 0)
1921                 return MC_INVALID_STATUS;
1922
1923         g_mutex_lock(&core->drain_lock);
1924
1925         if (!core->eos || !core->unprepare_flag) {
1926                 mc_async_queue_push(core->available_queue->input, inbuf);
1927
1928         } else {
1929                 ret = MC_INVALID_IN_BUF;
1930                 g_mutex_unlock(&core->drain_lock);
1931                 return ret;
1932         }
1933
1934         g_mutex_unlock(&core->drain_lock);
1935         g_atomic_int_inc(&core->etb_count);
1936         LOGI("@v(%d)e(%d)process_input(%d): %p", core->video, core->encoder, core->etb_count, inbuf);
1937
1938         MEDIACODEC_FLEAVE();
1939
1940         return ret;
1941 }
1942
1943 mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeout_us)
1944 {
1945         gint ret = MC_ERROR_NONE;
1946         gint64 end_time = -1;
1947         gboolean signalled;
1948         mc_gst_core_t *core = NULL;
1949         media_packet_h out_packet = NULL;
1950
1951         MEDIACODEC_FENTER();
1952         end_time = g_get_monotonic_time() + timeout_us;
1953
1954         if (!mc_handle)
1955                 return MC_PARAM_ERROR;
1956
1957         core = (mc_gst_core_t *)mc_handle->core;
1958
1959         g_mutex_lock(&core->ports[1]->mutex);
1960
1961         if (!g_queue_is_empty(core->ports[1]->queue))
1962                 signalled = TRUE;
1963         else {
1964                 LOGD("no buffer, wait for signal");
1965                 signalled = g_cond_wait_until(&core->out_buffer_cond, &core->ports[1]->mutex, end_time);
1966         }
1967
1968         if (signalled)
1969                 out_packet = g_queue_pop_head(core->ports[1]->queue);
1970         else {
1971                 LOGW("Failed to get buffer");
1972                 ret = MC_OUTPUT_BUFFER_EMPTY;
1973         }
1974
1975         *outbuf = out_packet;
1976         LOGI("@%p v(%d)e(%d) got buffer :%p", core, core->video, core->encoder, out_packet);
1977
1978         g_mutex_unlock(&core->ports[1]->mutex);
1979
1980         MEDIACODEC_FLEAVE();
1981
1982         return ret;
1983 }
1984
1985 mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle)
1986 {
1987         gint ret = MC_ERROR_NONE;
1988         mc_gst_core_t *core = NULL;
1989
1990         MEDIACODEC_FENTER();
1991
1992         if (!mc_handle)
1993                 return MC_PARAM_ERROR;
1994
1995         core = (mc_gst_core_t *)mc_handle->core;
1996         LOGI("@%p v(%d)e(%d) flush_buffers", core, core->video, core->encoder);
1997
1998         ret = _mc_gst_flush_buffers(core);
1999
2000         MEDIACODEC_FLEAVE();
2001
2002         return ret;
2003 }
2004
2005 static gboolean __mc_gst_init_gstreamer()
2006 {
2007         MEDIACODEC_FENTER();
2008
2009         gint i = 0;
2010         gint arg_count = 0;
2011         static gboolean initialized = FALSE;
2012         static const int max_argc = 50;
2013         gint *argc = NULL;
2014         gchar **argv = NULL;
2015         gchar **argv2 = NULL;
2016         GError *err = NULL;
2017
2018         if (initialized) {
2019                 LOGD("gstreamer already initialized.\n");
2020                 return TRUE;
2021         }
2022
2023         /* alloc */
2024         argc = malloc(sizeof(int));
2025         argv = malloc(sizeof(gchar *) *max_argc);
2026         argv2 = malloc(sizeof(gchar *) *max_argc);
2027
2028         if (!argc || !argv || !argv2)
2029                 goto ERROR;
2030
2031         memset(argv, 0, sizeof(gchar *) *max_argc);
2032         memset(argv2, 0, sizeof(gchar *) *max_argc);
2033
2034         /* add initial */
2035         *argc = 1;
2036         argv[0] = g_strdup("media codec");
2037
2038         /* we would not do fork for scanning plugins */
2039         argv[*argc] = g_strdup("--gst-disable-registry-fork");
2040         (*argc)++;
2041
2042         /* check disable registry scan */
2043         argv[*argc] = g_strdup("--gst-disable-registry-update");
2044         (*argc)++;
2045
2046         /* check disable segtrap */
2047         argv[*argc] = g_strdup("--gst-disable-segtrap");
2048         (*argc)++;
2049
2050         LOGD("initializing gstreamer with following parameter\n");
2051         LOGD("argc : %d\n", *argc);
2052         arg_count = *argc;
2053
2054         for (i = 0; i < arg_count; i++) {
2055                 argv2[i] = argv[i];
2056                 LOGD("argv[%d] : %s\n", i, argv2[i]);
2057         }
2058
2059         /* initializing gstreamer */
2060         if (!gst_init_check(argc, &argv, &err)) {
2061                 LOGE("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
2062                 if (err)
2063                         g_error_free(err);
2064
2065                 goto ERROR;
2066         }
2067
2068         /* release */
2069         for (i = 0; i < arg_count; i++)
2070                 MC_FREEIF(argv2[i]);
2071
2072         MC_FREEIF(argv);
2073         MC_FREEIF(argv2);
2074         MC_FREEIF(argc);
2075
2076         /* done */
2077         initialized = TRUE;
2078
2079         MEDIACODEC_FLEAVE();
2080         return TRUE;
2081
2082 ERROR:
2083         /* release */
2084         for (i = 0; i < arg_count; i++) {
2085                 LOGD("free[%d] : %s\n", i, argv2[i]);
2086                 MC_FREEIF(argv2[i]);
2087         }
2088
2089         MC_FREEIF(argv);
2090         MC_FREEIF(argv2);
2091         MC_FREEIF(argc);
2092
2093         return FALSE;
2094 }
2095
2096 mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, const gchar *factory_name)
2097 {
2098         int i = 0;
2099         int bitrate = 0;
2100         GstBus *bus = NULL;
2101
2102         MEDIACODEC_FENTER();
2103
2104         g_mutex_lock(&core->prepare_lock);
2105
2106         if (core->prepare_count == 0) {
2107                 if (!__mc_gst_init_gstreamer()) {
2108                         LOGE("gstreamer initialize fail");
2109                         g_mutex_unlock(&core->prepare_lock);
2110                         return MC_NOT_INITIALIZED;
2111                 }
2112
2113                 core->codec = gst_element_factory_make(factory_name, NULL);
2114                 if (!core->codec) {
2115                         LOGE("codec element create fail");
2116                         goto ERROR;
2117                 }
2118
2119                 LOGD("@%p v(%d)e(%d) create_pipeline", core, core->video, core->encoder);
2120                 MEDIACODEC_ELEMENT_SET_STATE(core->codec, GST_STATE_READY);
2121
2122                 /* create common elements */
2123                 core->pipeline = gst_pipeline_new(NULL);
2124                 if (!core->pipeline) {
2125                         LOGE("pipeline create fail");
2126                         goto ERROR;
2127                 }
2128
2129                 core->appsrc = gst_element_factory_make("appsrc", NULL);
2130                 if (!core->appsrc) {
2131                         LOGE("appsrc can't create");
2132                         goto ERROR;
2133                 }
2134
2135                 if (!core->video && core->encoder) {
2136                         core->audioconvert = gst_element_factory_make("audioconvert", NULL);
2137
2138                         if (!core->audioconvert) {
2139                                 LOGE("capsfilter can't create");
2140                                 goto ERROR;
2141                         }
2142
2143                         core->audioresample = gst_element_factory_make("audioresample", NULL);
2144
2145                         if (!core->audioresample) {
2146                                 LOGE("capsfilter can't create");
2147                                 goto ERROR;
2148                         }
2149                 }
2150
2151                 if (core->video && core->encoder) {
2152                         core->videoconvert = gst_element_factory_make("videoconvert", NULL);
2153
2154                         if (!core->videoconvert) {
2155                                 LOGE("videoconvert can't create");
2156                                 goto ERROR;
2157                         }
2158
2159                         core->videoscale = gst_element_factory_make("videoscale", NULL);
2160                         if (!core->videoscale) {
2161                                 LOGE("videoscale can't create");
2162                                 goto ERROR;
2163                         }
2164                 }
2165
2166                 core->capsfilter = gst_element_factory_make("capsfilter", NULL);
2167                 if (!core->capsfilter) {
2168                         LOGE("capsfilter can't create");
2169                         goto ERROR;
2170                 }
2171
2172                 core->fakesink = gst_element_factory_make("fakesink", NULL);
2173                 if (!core->fakesink) {
2174                         LOGE("fakesink create fail");
2175                         goto ERROR;
2176                 }
2177
2178                 g_object_set(core->fakesink, "enable-last-sample", FALSE, NULL);
2179
2180                 /*__mc_link_elements(core);*/
2181                 if (!core->video && core->encoder) {
2182                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL);
2183
2184                         /* link elements */
2185                         if (!(gst_element_link_many(core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL))) {
2186                                 LOGE("gst_element_link_many is failed");
2187                                 goto ERROR;
2188                         }
2189                 } else if (core->video && core->encoder) {
2190                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2191
2192                         /* link elements */
2193                         if (!(gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL))) {
2194                                 LOGE("gst_element_link_many is failed");
2195                                 goto ERROR;
2196                         }
2197                 } else {
2198                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2199
2200                         /* link elements */
2201                         if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL))) {
2202                                 LOGE("gst_element_link_many is failed");
2203                                 goto ERROR;
2204                         }
2205                 }
2206
2207                 /* connect signals, bus watcher */
2208                 bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline));
2209                 core->bus_watch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core);
2210                 core->thread_default = g_main_context_get_thread_default();
2211
2212                 /* set sync handler to get tag synchronously */
2213                 gst_bus_set_sync_handler(bus, __mc_gst_bus_sync_callback, core, NULL);
2214                 gst_object_unref(GST_OBJECT(bus));
2215
2216                 /* app src */
2217                 g_signal_connect(core->appsrc, "need-data", G_CALLBACK(__mc_gst_start_feed), core);
2218                 g_signal_connect(core->appsrc, "enough-data", G_CALLBACK(__mc_gst_stop_feed), core);
2219
2220                 /* connect handoff */
2221                 g_object_set(GST_OBJECT(core->fakesink), "signal-handoffs", TRUE, NULL);
2222                 core->signal_handoff = g_signal_connect(core->fakesink, "handoff", G_CALLBACK(__mc_gst_buffer_add), core);
2223
2224                 /* set bitrate and properties */
2225                 if (core->encoder) {
2226                         if (core->video)
2227                                 bitrate = core->ports[in_port_index]->port_def.info.video.bitrate;
2228                         else
2229                                 bitrate = core->ports[in_port_index]->port_def.info.audio.bitrate;
2230
2231                         LOGI("set encoder bitrate[property:%s,v:%d] %d",
2232                                 core->codec_type->property->bitrate_name, core->video, bitrate);
2233
2234                         g_object_set(core->codec,
2235                                 core->codec_type->property->bitrate_name, bitrate,
2236                                 NULL);
2237                 }
2238
2239                 for (i = 0 ; i < core->codec_type->property->ext_num ; i++) {
2240                         LOGI("set property [%s] -> [%s]",
2241                                 core->codec_type->property->ext_name[i],
2242                                 core->codec_type->property->ext_value[i]);
2243
2244                         gst_util_set_object_arg((GObject *)core->codec,
2245                                 core->codec_type->property->ext_name[i],
2246                                 core->codec_type->property->ext_value[i]);
2247                 }
2248
2249                 /* set state PLAYING */
2250                 MEDIACODEC_ELEMENT_SET_STATE(GST_ELEMENT_CAST(core->pipeline), GST_STATE_PLAYING);
2251         }
2252
2253         core->prepare_count++;
2254         g_mutex_unlock(&core->prepare_lock);
2255
2256         MEDIACODEC_FLEAVE();
2257
2258         return MC_ERROR_NONE;
2259
2260 STATE_CHANGE_FAILED:
2261 ERROR:
2262
2263         if (core->codec)
2264                 gst_object_unref(GST_OBJECT(core->codec));
2265
2266         if (core->pipeline)
2267                 gst_object_unref(GST_OBJECT(core->pipeline));
2268
2269         if (core->appsrc)
2270                 gst_object_unref(GST_OBJECT(core->appsrc));
2271
2272         if (core->capsfilter)
2273                 gst_object_unref(GST_OBJECT(core->capsfilter));
2274
2275         if (core->audioresample)
2276                 gst_object_unref(GST_OBJECT(core->audioresample));
2277
2278         if (core->videoscale)
2279                 gst_object_unref(GST_OBJECT(core->videoscale));
2280
2281         if (core->videoconvert)
2282                 gst_object_unref(GST_OBJECT(core->videoconvert));
2283
2284         if (core->audioconvert)
2285                 gst_object_unref(GST_OBJECT(core->audioconvert));
2286
2287         if (core->fakesink)
2288                 gst_object_unref(GST_OBJECT(core->fakesink));
2289
2290         g_mutex_unlock(&core->prepare_lock);
2291
2292         return MC_ERROR;
2293 }
2294
2295 mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core)
2296 {
2297         int ret = MC_ERROR_NONE;
2298
2299         MEDIACODEC_FENTER();
2300
2301         g_mutex_lock(&core->prepare_lock);
2302         core->prepare_count--;
2303         if (core->prepare_count == 0) {
2304
2305                 if (core->pipeline) {
2306                         /* disconnect signal */
2307                         if (core->fakesink && GST_IS_ELEMENT(core->fakesink)) {
2308                                 if (g_signal_handler_is_connected(core->fakesink, core->signal_handoff)) {
2309                                         g_signal_handler_disconnect(core->fakesink, core->signal_handoff);
2310                                         LOGD("handoff signal destroy");
2311                                 }
2312                         }
2313
2314                         if (core->bus_watch_id) {
2315                                 GSource *source = NULL;
2316                                 source = g_main_context_find_source_by_id(core->thread_default, core->bus_watch_id);
2317                                 g_source_destroy(source);
2318                                 LOGD("bus_watch_id destroy");
2319                         }
2320
2321                         MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL);
2322
2323                         gst_object_unref(GST_OBJECT(core->pipeline));
2324                         if (core->caps) {
2325                                 gst_caps_unref(core->caps);
2326                                 core->caps = NULL;
2327                         }
2328                 }
2329         }
2330
2331         LOGD("@%p v(%d)e(%d) destroy_pipeline : %d ", core, core->video, core->encoder, core->prepare_count);
2332         g_mutex_unlock(&core->prepare_lock);
2333
2334         MEDIACODEC_FLEAVE();
2335
2336         return ret;
2337
2338 STATE_CHANGE_FAILED:
2339         if (core->pipeline)
2340                 gst_object_unref(GST_OBJECT(core->pipeline));
2341
2342         LOGD("@%p v(%d)e(%d) destroy_pipeline failed", core, core->video, core->encoder);
2343         g_mutex_unlock(&core->prepare_lock);
2344
2345         return MC_ERROR;
2346 }
2347
2348 void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer)
2349 {
2350         g_mutex_lock(&core->ports[1]->mutex);
2351
2352         /* push it to output buffer queue */
2353         g_queue_push_tail(core->ports[1]->queue, mcbuffer->packet);
2354         g_cond_broadcast(&core->out_buffer_cond);
2355
2356         if (mcbuffer->buffer) {
2357                 LOGD("dq : v(%d)e(%d) TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder,
2358                         GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(mcbuffer->buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(mcbuffer->buffer)));
2359         } else {
2360                 LOGD("dq : v(%d)e(%d)", core->video, core->encoder);
2361         }
2362
2363         g_mutex_unlock(&core->ports[1]->mutex);
2364
2365         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
2366                 ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
2367                         (mcbuffer->packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]);
2368         }
2369 }
2370
2371 void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data)
2372 {
2373         GstMCBuffer *mcbuffer = NULL;
2374
2375         MEDIACODEC_FENTER();
2376
2377         mc_gst_core_t *core = (mc_gst_core_t *)data;
2378
2379         gst_buffer_ref(buffer);
2380
2381         mcbuffer = __mc_gst_make_media_packet(core, buffer);
2382
2383         LOGI("@%p(%d) out_packet : %p", core, core->encoder, mcbuffer->packet);
2384
2385         if (mcbuffer->packet) {
2386                 media_packet_set_pts(mcbuffer->packet, GST_BUFFER_TIMESTAMP(buffer));
2387                 media_packet_set_dts(mcbuffer->packet, GST_BUFFER_DTS(buffer));
2388                 media_packet_set_duration(mcbuffer->packet, GST_BUFFER_DURATION(buffer));
2389
2390                 if (core->need_codec_data) {
2391                         media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_CODEC_CONFIG);
2392                         core->need_codec_data = false;
2393                 }
2394
2395                 if (core->need_sync_flag) {
2396                         media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_SYNC_FRAME);
2397                         core->need_sync_flag = false;
2398                 }
2399
2400                 __mc_push_output_to_queue(core, mcbuffer);
2401         } else {
2402                 gst_buffer_unref(buffer);
2403                 LOGE("Failed to dequeue output packet");
2404         }
2405
2406         MEDIACODEC_FLEAVE();
2407
2408         return;
2409 }
2410
2411 int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data)
2412 {
2413         MEDIACODEC_FENTER();
2414
2415         GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data;
2416
2417         gst_buffer_unref((GstBuffer *)mcbuffer->buffer);
2418
2419         if (mcbuffer->ext_mem) {
2420                 g_free(mcbuffer->ext_mem);
2421                 LOGD("freed external memory");
2422                 mcbuffer->ext_mem = NULL;
2423         }
2424
2425         LOGD("output port filled buffer : %p", packet);
2426         g_free(mcbuffer);
2427
2428         MEDIACODEC_FLEAVE();
2429
2430         return MEDIA_PACKET_FINALIZE;
2431 }
2432
2433 gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool is_hw)
2434 {
2435         gchar *format = NULL;
2436
2437         switch (mimetype) {
2438         case MEDIA_FORMAT_I420:
2439                 format = "I420";
2440                 break;
2441         case MEDIA_FORMAT_NV12:
2442                 if (is_hw)
2443                         format = "SN12";
2444                 else
2445                         format = "NV12";
2446                 break;
2447         case MEDIA_FORMAT_ARGB:
2448                 format = "ARGB";
2449                 break;
2450         default:
2451                 break;
2452         }
2453         LOGD("input packet format : %s", format);
2454         return format;
2455 }
2456
2457 GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h packet, bool codec_config)
2458 {
2459         gint ret = MEDIA_PACKET_ERROR_NONE;
2460         uint64_t buf_size = 0;
2461         uint64_t pts = 0;
2462         uint64_t dts = 0;
2463         uint64_t dur = 0;
2464         void *buf_data = NULL;
2465         GstMCBuffer *mcbuffer = NULL;
2466
2467         ret = media_packet_get_buffer_size(packet, &buf_size);
2468         if (ret != MEDIA_PACKET_ERROR_NONE) {
2469                 LOGW("buffer size get fail");
2470                 return NULL;
2471         }
2472
2473         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
2474         if (ret != MEDIA_PACKET_ERROR_NONE) {
2475                 LOGW("buffer data get fail");
2476                 return NULL;
2477         }
2478
2479         mcbuffer = gst_mediacodec_buffer_new(core, packet, buf_size);
2480         if (mcbuffer == NULL) {
2481                 LOGW("failed to create inbuf");
2482                 return NULL;
2483         }
2484
2485         LOGD("packet :v(%d)e(%d) %p, buf_size : %d", core->video, core->encoder, packet, (int)buf_size);
2486
2487         ret = __mc_fill_input_buffer(core, packet, mcbuffer);
2488         if (ret != MC_ERROR_NONE) {
2489                 LOGW("failed to fill inbuf: %s (ox%08x)", _mc_error_to_string(ret), ret);
2490                 /*
2491                  * if __mc_fill_input_buffer() failed, no memory appended to mcbuffer->buffer, so gst_mediacodec_buffer_finalize()
2492                  * will not be invoked
2493                  */
2494                 gst_buffer_unref(mcbuffer->buffer);
2495                 g_free(mcbuffer);
2496                 return NULL;
2497         }
2498
2499         /* dts */
2500         media_packet_get_pts(packet, &dts);
2501         GST_BUFFER_DTS(mcbuffer->buffer) = dts;
2502
2503         /* pts */
2504         media_packet_get_pts(packet, &pts);
2505         GST_BUFFER_PTS(mcbuffer->buffer) = pts;
2506
2507         /* duration */
2508         media_packet_get_duration(packet, &dur);
2509         GST_BUFFER_DURATION(mcbuffer->buffer) = dur;
2510
2511         GST_BUFFER_OFFSET(mcbuffer->buffer) = core->offset;
2512
2513         core->offset += buf_size;
2514         GST_BUFFER_OFFSET_END(mcbuffer->buffer) = core->offset;
2515
2516         return mcbuffer;
2517 }
2518
2519 GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer)
2520 {
2521         gint ret = MEDIA_PACKET_ERROR_NONE;
2522         GstMemory *mem;
2523         GstMapInfo map = GST_MAP_INFO_INIT;
2524         GstMCBuffer *mcbuffer = NULL;
2525         void *data = NULL;
2526         gint size = 0;
2527
2528         mem = gst_buffer_peek_memory(buffer, 0);
2529
2530         if (gst_is_tizen_memory(mem)) {
2531                 data = (void *)gst_tizen_memory_get_surface(mem);
2532                 size = tbm_surface_internal_get_size((tbm_surface_h)data);
2533         } else {
2534                 if (!gst_memory_map(mem, &map, GST_MAP_READ)) {
2535                         LOGE("gst_memory_map failed for buffer[%p]", buffer);
2536                         return NULL;
2537                 }
2538
2539                 data = map.data;
2540                 size = map.size;
2541         }
2542
2543         mcbuffer = g_new0(GstMCBuffer, 1);
2544
2545         mcbuffer->buffer = buffer;
2546         mcbuffer->core = core;
2547         mcbuffer->buf_size = size;
2548
2549         ret = __mc_fill_output_buffer(core, data, mcbuffer->buf_size,  mcbuffer);
2550
2551         if (!gst_is_tizen_memory(mem))
2552                 gst_memory_unmap(mem, &map);
2553
2554         if (ret != MC_ERROR_NONE) {
2555                 LOGW("failed to fill outbuf: %s (ox%08x)", _mc_error_to_string(ret), ret);
2556                 g_free(mcbuffer);
2557                 return NULL;
2558         }
2559
2560         return mcbuffer;
2561 }
2562
2563 int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer)
2564 {
2565         gint ret = MC_ERROR_NONE;
2566         media_packet_h packet = NULL;
2567
2568         MEDIACODEC_FENTER();
2569         if (media_packet_create(fmt, __mc_output_buffer_finalize_cb, mcbuffer, &packet)) {
2570                 LOGE("media_packet_create failed\n");
2571                 ret = MC_ERROR;
2572                 goto ERROR;
2573         }
2574
2575         if (media_packet_set_flags(packet, MEDIA_PACKET_END_OF_STREAM)) {
2576                 LOGE("unable to set EOS flag\n");
2577                 ret = MC_ERROR;
2578                 goto ERROR;
2579         }
2580
2581         mcbuffer->buffer = NULL;
2582         mcbuffer->ext_mem = NULL;
2583         mcbuffer->buf_size = 0;
2584         mcbuffer->packet = packet;
2585         MEDIACODEC_FLEAVE();
2586
2587         return ret;
2588 ERROR:
2589         if (packet)
2590                 media_packet_destroy(packet);
2591         MEDIACODEC_FLEAVE();
2592         return ret;
2593 }
2594
2595 void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet)
2596 {
2597         if (core) {
2598                 g_atomic_int_dec_and_test(&core->etb_count);
2599                 LOGD("@v(%d)e(%d) input port used(%d)----- ", core->video, core->encoder, core->etb_count);
2600         }
2601
2602         if (core && core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
2603                 ((mc_empty_buffer_cb)core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
2604                         (packet, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
2605
2606                 g_mutex_lock(&core->drain_lock);
2607
2608                 if (core->need_drain) {
2609                         LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder);
2610                         core->need_drain = false;
2611                         g_cond_signal(&core->buffer_cond);
2612                 }
2613                 g_mutex_unlock(&core->drain_lock);
2614         }
2615 }
2616
2617 gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
2618 {
2619         gint ret  = MC_ERROR_NONE;
2620         GstMCBuffer *mcbuffer = NULL;
2621
2622         mc_gst_core_t *core = (mc_gst_core_t *)data;
2623         LOGI("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
2624
2625         switch (GST_MESSAGE_TYPE(msg)) {
2626
2627         case GST_MESSAGE_EOS:
2628                 _mc_send_eos_signal(core);
2629
2630                 mcbuffer = g_new0(GstMCBuffer, 1);
2631                 if (__mc_gst_create_eos_packet(core->output_fmt, mcbuffer) == MC_ERROR_NONE) {
2632                         __mc_push_output_to_queue(core, mcbuffer);
2633                         LOGD("send eos packet.");
2634                 } else {
2635                         LOGE("failed to create eos packet.");
2636                         g_free(mcbuffer);
2637                 }
2638
2639                 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
2640                         LOGD("eos callback invoked");
2641                         ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
2642                 }
2643
2644                 LOGD("End of stream\n");
2645                 break;
2646
2647         case GST_MESSAGE_ERROR:
2648         {
2649                 GError *error = NULL;
2650
2651                 gst_message_parse_error(msg, &error, NULL);
2652
2653                 if (!error) {
2654                         LOGW("GST error message parsing failed");
2655                         break;
2656                 }
2657
2658                 if (error) {
2659                         if (error->domain == GST_STREAM_ERROR)
2660                                 ret = __gst_handle_stream_error(core, error, msg);
2661                         else if (error->domain == GST_RESOURCE_ERROR)
2662                                 ret = __gst_handle_resource_error(core, error->code);
2663                         else if (error->domain == GST_LIBRARY_ERROR)
2664                                 ret = __gst_handle_library_error(core, error->code);
2665                         else if (error->domain == GST_CORE_ERROR)
2666                                 ret = __gst_handle_core_error(core, error->code);
2667                         else
2668                                 LOGW("Unexpected error has occured");
2669
2670                 g_mutex_lock(&core->drain_lock);
2671
2672                 if (core->need_drain) {
2673                         LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder);
2674                         core->need_drain = false;
2675                         g_cond_signal(&core->buffer_cond);
2676                 }
2677
2678                 g_mutex_unlock(&core->drain_lock);
2679
2680                         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
2681                                 ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
2682                                         (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
2683                                         LOGW("Error : %s (ox%08x)", _mc_error_to_string(ret), ret);
2684                         }
2685                 }
2686                 g_error_free(error);
2687         }
2688                 break;
2689
2690         default:
2691                 break;
2692         }
2693
2694         return TRUE;
2695 }
2696
2697 static gboolean __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg)
2698 {
2699         gboolean retval = FALSE;
2700
2701         if (!core->pipeline) {
2702                 LOGE("mediacodec pipeline handle is null");
2703                 return TRUE;
2704         }
2705
2706         switch (GST_MESSAGE_TYPE(msg)) {
2707         case GST_MESSAGE_TAG:
2708         case GST_MESSAGE_EOS:
2709         case GST_MESSAGE_ERROR:
2710         case GST_MESSAGE_WARNING:
2711                 retval = TRUE;
2712                 break;
2713         default:
2714                 retval = FALSE;
2715                 break;
2716         }
2717
2718         return retval;
2719 }
2720
2721 static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data)
2722 {
2723         mc_gst_core_t *core = (mc_gst_core_t *)data;
2724         GstBusSyncReply reply = GST_BUS_DROP;
2725
2726         LOGD("__mc_gst_bus_sync_callback is called : %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
2727
2728         if (!core->pipeline) {
2729                 LOGE("mediacodec pipeline handle is null");
2730                 return GST_BUS_PASS;
2731         }
2732
2733         if (!__mc_gst_check_useful_message(core, msg)) {
2734                 gst_message_unref(msg);
2735                 return GST_BUS_DROP;
2736         }
2737
2738         switch (GST_MESSAGE_TYPE(msg)) {
2739         case GST_MESSAGE_EOS:
2740         case GST_MESSAGE_ERROR:
2741                 __mc_gst_bus_callback(NULL, msg, core);
2742                 reply = GST_BUS_DROP;
2743                 break;
2744
2745         default:
2746                 reply = GST_BUS_PASS;
2747                 break;
2748         }
2749
2750         if (reply == GST_BUS_DROP)
2751                 gst_message_unref(msg);
2752
2753         return reply;
2754 }
2755
2756 static GstMemory *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, GstMCBuffer *mcbuffer)
2757 {
2758         int ret = MEDIA_PACKET_ERROR_NONE;
2759         tbm_surface_h surface = NULL;
2760         GstVideoInfo vinfo;
2761         GstMemory *mem = NULL;
2762
2763         if (!mcbuffer->packet) {
2764                 LOGE("output is null");
2765                 return NULL;
2766         }
2767
2768         ret = media_packet_get_tbm_surface(mcbuffer->packet, &surface);
2769         if (ret != MEDIA_PACKET_ERROR_NONE) {
2770                 LOGE("Failed to get tbm surface");
2771                 return NULL;
2772         }
2773
2774         if (!gst_video_info_from_caps(&vinfo, core->caps)) {
2775                 LOGE("Failed to get video info");
2776                 return NULL;
2777         }
2778
2779         mem = gst_tizen_allocator_alloc_surface(core->allocator,
2780                         &vinfo, surface, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb);
2781
2782         return mem;
2783 }
2784
2785 static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer)
2786 {
2787         MEDIACODEC_FENTER();
2788
2789         if (!mcbuffer)
2790                 return;
2791
2792         LOGD("============>>>>>  _finalize_cb  : %p, %p", mcbuffer, mcbuffer->packet);
2793
2794         _mc_gst_handle_input_buffer_used(mcbuffer->core, mcbuffer->packet);
2795
2796         g_free(mcbuffer);
2797
2798         MEDIACODEC_FLEAVE();
2799 }
2800
2801 static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_h packet, uint64_t size)
2802 {
2803         GstMCBuffer *mcbuffer = NULL;
2804
2805         mcbuffer = g_new0(GstMCBuffer, 1);
2806
2807         mcbuffer->buffer = gst_buffer_new();
2808         mcbuffer->buf_size = 0;
2809
2810         LOGD("creating buffer : %p, %p", mcbuffer, mcbuffer->buffer);
2811         mcbuffer->core = core;
2812         mcbuffer->packet = packet;
2813
2814         return mcbuffer;
2815 }
2816
2817 static gint __gst_handle_core_error(mc_gst_core_t *core, int code)
2818 {
2819         gint trans_err = MEDIACODEC_ERROR_NONE;
2820
2821         g_return_val_if_fail(core, MC_PARAM_ERROR);
2822
2823         switch (code) {
2824         case GST_CORE_ERROR_MISSING_PLUGIN:
2825                 return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
2826         case GST_CORE_ERROR_STATE_CHANGE:
2827         case GST_CORE_ERROR_SEEK:
2828         case GST_CORE_ERROR_NOT_IMPLEMENTED:
2829         case GST_CORE_ERROR_FAILED:
2830         case GST_CORE_ERROR_TOO_LAZY:
2831         case GST_CORE_ERROR_PAD:
2832         case GST_CORE_ERROR_THREAD:
2833         case GST_CORE_ERROR_NEGOTIATION:
2834         case GST_CORE_ERROR_EVENT:
2835         case GST_CORE_ERROR_CAPS:
2836         case GST_CORE_ERROR_TAG:
2837         case GST_CORE_ERROR_CLOCK:
2838         case GST_CORE_ERROR_DISABLED:
2839         default:
2840                 trans_err =  MEDIACODEC_ERROR_INVALID_STREAM;
2841                 break;
2842         }
2843
2844         return trans_err;
2845 }
2846
2847 static gint __gst_handle_library_error(mc_gst_core_t *core, int code)
2848 {
2849         gint trans_err = MEDIACODEC_ERROR_NONE;
2850
2851         g_return_val_if_fail(core, MC_PARAM_ERROR);
2852
2853         switch (code) {
2854         case GST_LIBRARY_ERROR_FAILED:
2855         case GST_LIBRARY_ERROR_TOO_LAZY:
2856         case GST_LIBRARY_ERROR_INIT:
2857         case GST_LIBRARY_ERROR_SHUTDOWN:
2858         case GST_LIBRARY_ERROR_SETTINGS:
2859         case GST_LIBRARY_ERROR_ENCODE:
2860         default:
2861                 trans_err =  MEDIACODEC_ERROR_INVALID_STREAM;
2862                 break;
2863         }
2864
2865         return trans_err;
2866 }
2867
2868
2869 static gint __gst_handle_resource_error(mc_gst_core_t *core, int code)
2870 {
2871         gint trans_err = MEDIACODEC_ERROR_NONE;
2872
2873         g_return_val_if_fail(core, MC_PARAM_ERROR);
2874
2875         switch (code) {
2876         case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
2877                 trans_err = MEDIACODEC_ERROR_NO_FREE_SPACE;
2878                 break;
2879         case GST_RESOURCE_ERROR_WRITE:
2880         case GST_RESOURCE_ERROR_FAILED:
2881         case GST_RESOURCE_ERROR_SEEK:
2882         case GST_RESOURCE_ERROR_TOO_LAZY:
2883         case GST_RESOURCE_ERROR_BUSY:
2884         case GST_RESOURCE_ERROR_OPEN_WRITE:
2885         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
2886         case GST_RESOURCE_ERROR_CLOSE:
2887         case GST_RESOURCE_ERROR_SYNC:
2888         case GST_RESOURCE_ERROR_SETTINGS:
2889         default:
2890                 trans_err = MEDIACODEC_ERROR_INTERNAL;
2891                 break;
2892         }
2893
2894         return trans_err;
2895 }
2896
2897 static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message)
2898 {
2899         gint trans_err = MEDIACODEC_ERROR_NONE;
2900
2901         g_return_val_if_fail(core, MC_PARAM_ERROR);
2902         g_return_val_if_fail(error, MC_PARAM_ERROR);
2903         g_return_val_if_fail(message, MC_PARAM_ERROR);
2904
2905         switch (error->code) {
2906         case GST_STREAM_ERROR_FAILED:
2907         case GST_STREAM_ERROR_TYPE_NOT_FOUND:
2908         case GST_STREAM_ERROR_DECODE:
2909         case GST_STREAM_ERROR_WRONG_TYPE:
2910         case GST_STREAM_ERROR_DECRYPT:
2911         case GST_STREAM_ERROR_DECRYPT_NOKEY:
2912         case GST_STREAM_ERROR_CODEC_NOT_FOUND:
2913                 trans_err = __gst_transform_gsterror(core, message, error);
2914                 break;
2915
2916         case GST_STREAM_ERROR_NOT_IMPLEMENTED:
2917         case GST_STREAM_ERROR_TOO_LAZY:
2918         case GST_STREAM_ERROR_ENCODE:
2919         case GST_STREAM_ERROR_DEMUX:
2920         case GST_STREAM_ERROR_MUX:
2921         case GST_STREAM_ERROR_FORMAT:
2922         default:
2923                 trans_err = MEDIACODEC_ERROR_INVALID_STREAM;
2924                 break;
2925         }
2926
2927         return trans_err;
2928 }
2929
2930 static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, GError *error)
2931 {
2932         gchar *src_element_name = NULL;
2933         GstElement *src_element = NULL;
2934         GstElementFactory *factory = NULL;
2935         const gchar *klass = NULL;
2936
2937
2938         src_element = GST_ELEMENT_CAST(message->src);
2939         if (!src_element)
2940                 goto INTERNAL_ERROR;
2941
2942         src_element_name = GST_ELEMENT_NAME(src_element);
2943         if (!src_element_name)
2944                 goto INTERNAL_ERROR;
2945
2946         factory = gst_element_get_factory(src_element);
2947         if (!factory)
2948                 goto INTERNAL_ERROR;
2949
2950         klass = gst_element_factory_get_klass(factory);
2951         if (!klass)
2952                 goto INTERNAL_ERROR;
2953
2954         LOGD("error code=%d, msg=%s, src element=%s, class=%s\n",
2955                         error->code, error->message, src_element_name, klass);
2956
2957         switch (error->code) {
2958         case GST_STREAM_ERROR_DECODE:
2959         case GST_STREAM_ERROR_FAILED:
2960                 return MEDIACODEC_ERROR_INVALID_STREAM;
2961                 break;
2962
2963         case GST_STREAM_ERROR_CODEC_NOT_FOUND:
2964         case GST_STREAM_ERROR_TYPE_NOT_FOUND:
2965         case GST_STREAM_ERROR_WRONG_TYPE:
2966                 return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
2967                 break;
2968
2969         default:
2970                 return MEDIACODEC_ERROR_INTERNAL;
2971                 break;
2972         }
2973
2974 INTERNAL_ERROR:
2975         return MEDIACODEC_ERROR_INTERNAL;
2976 }
2977
2978 static gint _mc_gst_flush_buffers(mc_gst_core_t *core)
2979 {
2980         gboolean ret = FALSE;
2981         GstEvent *event = NULL;
2982
2983         MEDIACODEC_FENTER();
2984
2985         _mc_gst_set_flush_input(core);
2986
2987         LOGW("Trying send flush_start .... ");
2988         event = gst_event_new_flush_start();
2989         ret = gst_element_send_event(core->appsrc, event);
2990         if (ret != TRUE) {
2991                 LOGE("failed to send Flush_Start event");
2992                 return MC_ERROR;
2993         }
2994
2995         LOGW("Trying send flush_stop .... ");
2996         event = gst_event_new_flush_stop(TRUE);
2997         ret = gst_element_send_event(core->appsrc, event);
2998         if (ret != TRUE) {
2999                 LOGE("failed to send Flush_Stop event");
3000                 return MC_ERROR;
3001         }
3002
3003         LOGW("Trying send seek .... ");
3004         event = gst_event_new_seek(1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
3005                         GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1);
3006
3007         ret = gst_element_send_event(core->appsrc, event);
3008         if (ret != TRUE) {
3009                 LOGE("failed to send seek event");
3010                 return MC_ERROR;
3011         }
3012
3013         _mc_gst_set_flush_output(core);
3014
3015         MEDIACODEC_FLEAVE();
3016
3017         return MC_ERROR_NONE;
3018 }
3019
3020
3021 static void _mc_gst_set_flush_input(mc_gst_core_t *core)
3022 {
3023         media_packet_h packet = NULL;
3024
3025         MEDIACODEC_FENTER();
3026         LOGI("_mc_gst_set_flush_input called : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count);
3027
3028         while (!mc_async_queue_is_empty(core->available_queue->input)) {
3029                 packet = mc_async_queue_pop_forced(core->available_queue->input);
3030                 LOGD("%p poped(%d)", packet, core->etb_count);
3031
3032                 _mc_gst_handle_input_buffer_used(core, packet);
3033         }
3034
3035         mc_async_queue_flush(core->available_queue->input);
3036         LOGI("_mc_gst_set_flush_input ended : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count);
3037         MEDIACODEC_FLEAVE();
3038 }
3039
3040 static void _mc_gst_set_flush_output(mc_gst_core_t *core)
3041 {
3042         media_packet_h packet = NULL;
3043
3044         MEDIACODEC_FENTER();
3045
3046         g_mutex_lock(&core->ports[1]->mutex);
3047
3048         while ((packet = g_queue_pop_head(core->ports[1]->queue))) {
3049                 LOGD("destroy packet[%p]", packet);
3050                 media_packet_destroy(packet);
3051         }
3052
3053         g_mutex_unlock(&core->ports[1]->mutex);
3054
3055         MEDIACODEC_FLEAVE();
3056 }
3057
3058 #if TIZEN_EXYNOS_SPECIFIC
3059 /*
3060  * Get tiled address of position(x,y)
3061  *
3062  * @param x_size
3063  *   width of tiled[in]
3064  *
3065  * @param y_size
3066  *   height of tiled[in]
3067  *
3068  * @param x_pos
3069  *   x position of tield[in]
3070  *
3071  * @param src_size
3072  *   y position of tield[in]
3073  *
3074  * @return
3075  *   address of tiled data
3076  */
3077 static gint __tile_4x2_read(gint x_size, gint y_size, gint x_pos, gint y_pos)
3078 {
3079         gint pixel_x_m1, pixel_y_m1;
3080         gint roundup_x;
3081         gint linear_addr0, linear_addr1, bank_addr ;
3082         gint x_addr;
3083         gint trans_addr;
3084
3085         pixel_x_m1 = x_size - 1;
3086         pixel_y_m1 = y_size - 1;
3087
3088         roundup_x = ((pixel_x_m1 >> 7) + 1);
3089
3090         x_addr = x_pos >> 2;
3091
3092         if ((y_size <= y_pos+32) && (y_pos < y_size) &&
3093                         (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
3094                 linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
3095                 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
3096
3097                 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
3098                         bank_addr = ((x_addr >> 4) & 0x1);
3099                 else
3100                         bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
3101         } else {
3102                 linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
3103                 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
3104
3105                 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
3106                         bank_addr = ((x_addr >> 4) & 0x1);
3107                 else
3108                         bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
3109         }
3110
3111         linear_addr0 = linear_addr0 << 2;
3112         trans_addr = (linear_addr1 << 13) | (bank_addr << 11) | linear_addr0;
3113
3114         return trans_addr;
3115 }
3116
3117 /*
3118  * Converts tiled data to linear
3119  * Crops left, top, right, buttom
3120  * 1. Y of NV12T to Y of YUV420P
3121  * 2. Y of NV12T to Y of YUV420S
3122  * 3. UV of NV12T to UV of YUV420S
3123  *
3124  * @param yuv420_dest
3125  *   Y or UV plane address of YUV420[out]
3126  *
3127  * @param nv12t_src
3128  *   Y or UV plane address of NV12T[in]
3129  *
3130  * @param yuv420_width
3131  *   Width of YUV420[in]
3132  *
3133  * @param yuv420_height
3134  *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
3135  *
3136  * @param left
3137  *   Crop size of left
3138  *
3139  * @param top
3140  *   Crop size of top
3141  *
3142  * @param right
3143  *   Crop size of right
3144  *
3145  * @param buttom
3146  *   Crop size of buttom
3147  */
3148 static void __csc_tiled_to_linear_crop(gchar *yuv420_dest, gchar *nv12t_src,
3149                 gint yuv420_width, gint yuv420_height,
3150                 gint left, int top, gint right, gint buttom)
3151 {
3152         gint i, j;
3153         gint tiled_offset = 0, tiled_offset1 = 0;
3154         gint linear_offset = 0;
3155         gint temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
3156
3157         temp3 = yuv420_width-right;
3158         temp1 = temp3-left;
3159         /* real width is greater than or equal 256 */
3160         if (temp1 >= 256) {
3161                 for (i = top; i < yuv420_height-buttom; i += 1) {
3162                         j = left;
3163                         temp3 = (j>>8)<<8;
3164                         temp3 = temp3>>6;
3165                         temp4 = i>>5;
3166                         if (temp4 & 0x1) {
3167                                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
3168                                 tiled_offset = temp4-1;
3169                                 temp1 = ((yuv420_width+127)>>7)<<7;
3170                                 tiled_offset = tiled_offset*(temp1>>6);
3171                                 tiled_offset = tiled_offset+temp3;
3172                                 tiled_offset = tiled_offset+2;
3173                                 temp1 = (temp3>>2)<<2;
3174                                 tiled_offset = tiled_offset+temp1;
3175                                 tiled_offset = tiled_offset<<11;
3176                                 tiled_offset1 = tiled_offset+2048*2;
3177                                 temp4 = 8;
3178                         } else {
3179                                 temp2 = ((yuv420_height+31)>>5)<<5;
3180                                 if ((i + 32) < temp2) {
3181                                         /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
3182                                         temp1 = temp3+2;
3183                                         temp1 = (temp1>>2)<<2;
3184                                         tiled_offset = temp3+temp1;
3185                                         temp1 = ((yuv420_width+127)>>7)<<7;
3186                                         tiled_offset = tiled_offset+temp4*(temp1>>6);
3187                                         tiled_offset = tiled_offset<<11;
3188                                         tiled_offset1 = tiled_offset + 2048 * 6;
3189                                         temp4 = 8;
3190                                 } else {
3191                                         /* even2 fomula: x+x_block_num*y */
3192                                         temp1 = ((yuv420_width+127)>>7)<<7;
3193                                         tiled_offset = temp4*(temp1>>6);
3194                                         tiled_offset = tiled_offset+temp3;
3195                                         tiled_offset = tiled_offset<<11;
3196                                         tiled_offset1 = tiled_offset+2048*2;
3197                                         temp4 = 4;
3198                                 }
3199                         }
3200
3201                         temp1 = i&0x1F;
3202                         tiled_offset = tiled_offset+64*(temp1);
3203                         tiled_offset1 = tiled_offset1+64*(temp1);
3204                         temp2 = yuv420_width-left-right;
3205                         linear_offset = temp2*(i-top);
3206                         temp3 = ((j+256)>>8)<<8;
3207                         temp3 = temp3-j;
3208                         temp1 = left&0x3F;
3209
3210                         if (temp3 > 192) {
3211                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
3212                                 temp2 = ((left+63)>>6)<<6;
3213                                 temp3 = ((yuv420_width-right)>>6)<<6;
3214
3215                                 if (temp2 == temp3)
3216                                         temp2 = yuv420_width-right-(64-temp1);
3217
3218                                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
3219                                 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
3220                                 memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
3221                                 linear_offset = linear_offset+256-temp1;
3222                         } else if (temp3 > 128) {
3223                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
3224                                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
3225                                 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
3226                                 linear_offset = linear_offset+192-temp1;
3227                         } else if (temp3 > 64) {
3228                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
3229                                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
3230                                 linear_offset = linear_offset+128-temp1;
3231                         } else if (temp3 > 0) {
3232                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
3233                                 linear_offset = linear_offset+64-temp1;
3234                         }
3235
3236                         tiled_offset = tiled_offset+temp4*2048;
3237                         j = (left>>8)<<8;
3238                         j = j + 256;
3239                         temp2 = yuv420_width-right-256;
3240                         for (; j <= temp2; j += 256) {
3241                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3242                                 tiled_offset1 = tiled_offset1+temp4*2048;
3243                                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3244                                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
3245                                 tiled_offset = tiled_offset+temp4*2048;
3246                                 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
3247                                 linear_offset = linear_offset+256;
3248                         }
3249
3250                         tiled_offset1 = tiled_offset1+temp4*2048;
3251                         temp2 = yuv420_width-right-j;
3252                         if (temp2 > 192) {
3253                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3254                                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3255                                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
3256                                 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
3257                         } else if (temp2 > 128) {
3258                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3259                                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3260                                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
3261                         } else if (temp2 > 64) {
3262                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3263                                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
3264                         } else {
3265                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3266                         }
3267                 }
3268         } else if (temp1 >= 64) {
3269                 for (i = top; i < (yuv420_height-buttom); i += 1) {
3270                         j = left;
3271                         tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3272                         temp2 = ((j+64)>>6)<<6;
3273                         temp2 = temp2-j;
3274                         linear_offset = temp1*(i-top);
3275                         temp4 = j&0x3;
3276                         tiled_offset = tiled_offset+temp4;
3277                         memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3278                         linear_offset = linear_offset+temp2;
3279                         j = j+temp2;
3280                         if ((j+64) <= temp3) {
3281                                 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3282                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3283                                 linear_offset = linear_offset+64;
3284                                 j = j+64;
3285                         }
3286                         if ((j+64) <= temp3) {
3287                                 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3288                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3289                                 linear_offset = linear_offset+64;
3290                                 j = j+64;
3291                         }
3292                         if (j < temp3) {
3293                                 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3294                                 temp2 = temp3-j;
3295                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3296                         }
3297                 }
3298         } else {
3299                 for (i = top; i < (yuv420_height-buttom); i += 1) {
3300                         linear_offset = temp1*(i-top);
3301                         for (j = left; j < (yuv420_width - right); j += 2) {
3302                                 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3303                                 temp4 = j&0x3;
3304                                 tiled_offset = tiled_offset+temp4;
3305                                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
3306                                 linear_offset = linear_offset+2;
3307                         }
3308                 }
3309         }
3310 }
3311 #endif
3312
3313 void _mc_send_eos_signal(mc_gst_core_t *core)
3314 {
3315         g_mutex_lock(&core->eos_mutex);
3316         core->eos = FALSE;
3317         g_cond_broadcast(&core->eos_cond);
3318         g_mutex_unlock(&core->eos_mutex);
3319         LOGD("send EOS signal");
3320 }
3321
3322 void _mc_wait_for_eos(mc_gst_core_t *core)
3323 {
3324         g_mutex_lock(&core->eos_mutex);
3325         core->eos = TRUE;
3326         LOGD("waiting for EOS");
3327
3328         while (core->eos)
3329                 g_cond_wait(&core->eos_cond, &core->eos_mutex);
3330
3331         LOGD("received EOS");
3332         g_mutex_unlock(&core->eos_mutex);
3333 }
3334
3335 const gchar * _mc_error_to_string(mc_ret_e err)
3336 {
3337         guint err_u = (guint) err;
3338
3339         switch (err_u) {
3340         case MC_ERROR:
3341                 return "Error";
3342         case MC_PARAM_ERROR:
3343                 return "Parameter error";
3344         case MC_INVALID_ARG:
3345                 return "Invailid argument";
3346         case MC_PERMISSION_DENIED:
3347                 return "Permission denied";
3348         case MC_INVALID_STATUS:
3349                 return "Invalid status";
3350         case MC_NOT_SUPPORTED:
3351                 return "Not supported";
3352         case MC_INVALID_IN_BUF:
3353                 return "Invalid inputbuffer";
3354         case MC_INVALID_OUT_BUF:
3355                 return "Invalid outputbuffer";
3356         case MC_INTERNAL_ERROR:
3357                 return "Internal error";
3358         case MC_HW_ERROR:
3359                 return "Hardware error";
3360         case MC_NOT_INITIALIZED:
3361                 return "Not initialized";
3362         case MC_INVALID_STREAM:
3363                 return "Invalid stream";
3364         case MC_CODEC_NOT_FOUND:
3365                 return "Codec not found";
3366         case MC_ERROR_DECODE:
3367                 return "Decode error";
3368         case MC_OUTPUT_BUFFER_EMPTY:
3369                 return "Outputbuffer empty";
3370         case MC_OUTPUT_BUFFER_OVERFLOW:
3371                 return "Outputbuffer overflow";
3372         case MC_MEMORY_ALLOCED:
3373                 return "Memory allocated";
3374         case MC_COURRPTED_INI:
3375                 return "Courrpted ini";
3376         default:
3377                 return "Unknown error";
3378
3379         }
3380 }
3381
3382 const gchar * _mc_bit_to_string(int bit)
3383 {
3384         switch (bit) {
3385         case 16:
3386                 return "S16LE";
3387         case 32:
3388                 return "F32LE";
3389         default:
3390                 return "NULL";
3391
3392         }
3393 }
3394
3395 int _mc_get_mime(mc_gst_core_t *core)
3396 {
3397         media_format_mimetype_e mime = MEDIA_FORMAT_MAX;
3398
3399         switch (core->codec_id) {
3400         case MEDIACODEC_H264:
3401                 if (core->encoder)
3402                         mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
3403                 else
3404                         mime = MEDIA_FORMAT_H264_SP;
3405                 break;
3406         case MEDIACODEC_MPEG4:
3407                 if (core->encoder)
3408                         mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
3409                 else
3410                         mime = MEDIA_FORMAT_MPEG4_SP;
3411
3412                 break;
3413         case MEDIACODEC_H263:
3414                 if (core->encoder)
3415                         mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
3416                 else
3417                         mime = MEDIA_FORMAT_H263P;
3418
3419                 break;
3420         case MEDIACODEC_AAC:
3421                 if (core->encoder)
3422                         mime = MEDIA_FORMAT_PCM_F32LE;  /*FIXME need to change PCM supported by chipset */
3423                 else
3424                         mime = MEDIA_FORMAT_AAC;
3425
3426                 break;
3427         case MEDIACODEC_AAC_HE:
3428                 if (core->encoder)
3429                         mime = MEDIA_FORMAT_PCM_F32LE;  /* FIXME need to change PCM supported by chipset */
3430                 else
3431                         mime = MEDIA_FORMAT_AAC_HE;
3432
3433                 break;
3434         case MEDIACODEC_AAC_HE_PS:
3435                 break;
3436         case MEDIACODEC_MP3:
3437                 mime = MEDIA_FORMAT_MP3;
3438                 break;
3439         case MEDIACODEC_VORBIS:
3440                 break;
3441         case MEDIACODEC_FLAC:
3442                 break;
3443         case MEDIACODEC_WMAV1:
3444                 break;
3445         case MEDIACODEC_WMAV2:
3446                 break;
3447         case MEDIACODEC_WMAPRO:
3448                 break;
3449         case MEDIACODEC_WMALSL:
3450                 break;
3451         case MEDIACODEC_AMR_NB:
3452                 mime = MEDIA_FORMAT_AMR_NB;
3453                 break;
3454         case MEDIACODEC_AMR_WB:
3455                 mime = MEDIA_FORMAT_AMR_WB;
3456                 break;
3457         case MEDIACODEC_OPUS:
3458                 if (core->encoder)
3459                         mime = MEDIA_FORMAT_OPUS;
3460                 else
3461                         mime = MEDIA_FORMAT_PCM_S16LE;
3462                 break;
3463         default:
3464                 LOGE("NOT SUPPORTED!!!! 0x%x ", core->codec_id);
3465                 break;
3466         }
3467         return mime;
3468 }
3469
3470 mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *packet_pool)
3471 {
3472         gint ret = MC_ERROR_NONE;
3473         gint curr_size;
3474         gint max_size, min_size;
3475         media_format_mimetype_e mime_format = MEDIA_FORMAT_MAX;
3476         media_format_h fmt_handle = NULL;
3477         media_packet_pool_h pool = NULL;
3478         mc_gst_core_t *core = NULL;
3479
3480         if (!mc_handle)
3481                 return MC_PARAM_ERROR;
3482
3483         core = (mc_gst_core_t *)mc_handle->core;
3484
3485         ret = media_packet_pool_create(&pool);
3486         if (ret != MEDIA_PACKET_ERROR_NONE) {
3487                 LOGE("media_packet_pool_create failed");
3488                 return MC_ERROR;
3489         }
3490
3491         if (media_format_create(&fmt_handle) != MEDIA_FORMAT_ERROR_NONE) {
3492                 LOGE("media format create failed");
3493                 media_packet_pool_destroy(pool);
3494                 return MC_ERROR;
3495         }
3496
3497         mime_format = _mc_get_mime(core);
3498
3499         if (core->video) {
3500                 media_format_set_video_mime(fmt_handle, mime_format);
3501                 media_format_set_video_width(fmt_handle, mc_handle->info.video.width);
3502                 media_format_set_video_height(fmt_handle, mc_handle->info.video.height);
3503
3504                 if (core->encoder)
3505                         media_format_set_video_avg_bps(fmt_handle, mc_handle->info.video.bitrate);
3506         } else {
3507                         media_format_set_audio_mime(fmt_handle, mime_format);
3508                         media_format_set_audio_channel(fmt_handle, mc_handle->info.audio.channel);
3509                         media_format_set_audio_samplerate(fmt_handle, mc_handle->info.audio.samplerate);
3510                         media_format_set_audio_bit(fmt_handle, mc_handle->info.audio.bit_depth);
3511                 if (core->encoder)
3512                         media_format_set_audio_avg_bps(fmt_handle, mc_handle->info.audio.bitrate);
3513         }
3514
3515         ret = media_packet_pool_set_media_format(pool, fmt_handle);
3516         if (ret != MEDIA_PACKET_ERROR_NONE) {
3517                 media_packet_pool_destroy(pool);
3518                 LOGE("media_packet_pool_set_media_format failed");
3519                 return MC_ERROR;
3520         }
3521
3522         /* will use default size temporarily */
3523         max_size = core->encoder ? DEFAULT_ENC_POOL_SIZE : DEFAULT_DEC_POOL_SIZE;
3524
3525         min_size = max_size;
3526         ret = media_packet_pool_set_size(pool, min_size, max_size);
3527         if (ret != MEDIA_PACKET_ERROR_NONE) {
3528                 media_packet_pool_destroy(pool);
3529                 LOGE("media_packet_pool_set_size failed");
3530                 return MC_ERROR;
3531         }
3532
3533         ret = media_packet_pool_allocate(pool);
3534         if (ret != MEDIA_PACKET_ERROR_NONE) {
3535                 media_packet_pool_destroy(pool);
3536                 LOGE("media_packet_pool_allocate failed");
3537                 return MC_OUT_OF_MEMORY;
3538         }
3539         media_packet_pool_get_size(pool, &min_size, &max_size, &curr_size);
3540         LOGD("curr_size is  %d min_size is %d and max_size is %d \n", curr_size, min_size, max_size);
3541
3542         *packet_pool = pool;
3543         return MC_ERROR_NONE;
3544 }