Remove unused function
[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 static int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
203 {
204         gint ret = MC_ERROR_NONE;
205         void *buf_data = NULL;
206         uint64_t buf_size = 0;
207
208         ret = media_packet_get_buffer_size(packet, &buf_size);
209         if (ret != MEDIA_PACKET_ERROR_NONE) {
210                 LOGW("buffer size get failed");
211                 return MC_ERROR;
212         }
213
214         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
215         if (ret != MEDIA_PACKET_ERROR_NONE) {
216                 LOGW("buffer data get failed");
217                 return MC_ERROR;
218         }
219
220         if (buf_data == NULL)
221                 return MC_ERROR;
222
223         gst_buffer_append_memory(mcbuffer->buffer,
224                 gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
225                         buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
226         LOGD("packet data apended");
227
228         return ret;
229 }
230
231 static int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
232 {
233         gint ret = MC_ERROR_NONE;
234         uint64_t buf_size = 0;
235         unsigned int codec_size = 0;
236         bool codec_config = FALSE;
237         void *buf_data = NULL;
238         void *codec_data = NULL;
239
240         ret = media_packet_get_buffer_size(packet, &buf_size);
241         if (ret != MEDIA_PACKET_ERROR_NONE) {
242                 LOGW("buffer size get failed");
243                 return MC_ERROR;
244         }
245
246         ret = media_packet_get_buffer_data_ptr(packet, &buf_data);
247         if (ret != MEDIA_PACKET_ERROR_NONE) {
248                 LOGW("buffer data get failed");
249                 return MC_ERROR;
250         }
251
252         if (media_packet_is_codec_config(packet, &codec_config) != MEDIA_PACKET_ERROR_NONE) {
253                 LOGE("media_packet_is_codec_config failed");
254                 return MC_ERROR;
255         }
256
257         if (buf_data != NULL) {
258                 media_packet_get_codec_data(packet, &codec_data, &codec_size);
259
260                 if (!codec_data && codec_config) {
261                         gst_buffer_append_memory(mcbuffer->buffer,
262                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
263                                                 buf_size, NULL, NULL));
264                         LOGD("csd packet data apended");
265                 } else {
266                         gst_buffer_append_memory(mcbuffer->buffer,
267                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
268                                                 buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
269                         LOGD("packet data apended");
270                 }
271
272                 if (codec_data)
273                         free(codec_data);
274         }
275
276         return ret;
277 }
278
279 static int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer)
280 {
281         gint ret = MC_ERROR_NONE;
282         gint i;
283         gint j;
284         gint stride = 0;
285         gint buf_size = 0;
286         gint stride_width;
287         gint stride_height;
288         gint width;
289         gint height;
290         uint32_t plane_num;
291         guint8 *planes[2];
292         GstMemory *mem = NULL;
293
294         mc_gst_port_def_t *port_def = &core->ports[in_port_index]->port_def;
295
296         width = port_def->info.video.width;
297         height = port_def->info.video.height;
298
299         ret = media_packet_get_number_of_video_planes(packet, &plane_num);
300         if (ret != MEDIA_PACKET_ERROR_NONE) {
301                 LOGW("media_packet_get_number_of_video_planes failed");
302                 return MC_ERROR;
303         }
304
305         ret = media_packet_get_video_plane_data_ptr(packet, 0, (void **)&planes[0]);
306         if (ret != MEDIA_PACKET_ERROR_NONE) {
307                 LOGW("media_packet_get_video_plane_data_ptr failed");
308                 return MC_ERROR;
309         }
310
311         ret = media_packet_get_video_stride_width(packet, 0, &stride_width);
312         if (ret != MEDIA_PACKET_ERROR_NONE) {
313                 LOGW("media_packet_get_video_stride_width failed");
314                 return MC_ERROR;
315         }
316
317         ret = media_packet_get_video_stride_height(packet, 0, &stride_height);
318         if (ret != MEDIA_PACKET_ERROR_NONE) {
319                 LOGW("media_packet_get_video_stride_width failed");
320                 return MC_ERROR;
321         }
322
323         if (!core->is_hw) {
324                 if (width == stride_width) {
325                         mcbuffer->buf_size += stride_width * stride_height;
326
327                         for (i = 1; i < plane_num; i++) {
328                                 media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]);
329                                 media_packet_get_video_stride_width(packet, i, &stride_width);
330                                 media_packet_get_video_stride_height(packet, i, &stride_height);
331
332                                 buf_size = stride_width * stride_height;
333
334                                 memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size);
335                                 mcbuffer->buf_size += buf_size;
336                                 LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size);
337                         }
338                 } else {
339
340                         for (j = 0; j < height; j++) {
341                                 memcpy(planes[0] + mcbuffer->buf_size, planes[0] + stride, width);
342                                 mcbuffer->buf_size += width;
343                                 stride += stride_width;
344                         }
345
346                         stride = 0;
347
348                         for (i = 1; i < plane_num; i++) {
349                                 media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]);
350                                 media_packet_get_video_stride_width(packet, i, &stride_width);
351                                 media_packet_get_video_stride_height(packet, i, &stride_height);
352
353                                 for (j = 0; j < height>>1; j++) {
354                                         memcpy(planes[0] + mcbuffer->buf_size, planes[1] + stride, width>>1);
355                                         mcbuffer->buf_size += width>>1;
356                                         stride += stride_width;
357                                 }
358
359                                 memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size);
360                                 LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size);
361                                 mcbuffer->buf_size += buf_size;
362                         }
363                 }
364
365                 mem = gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
366                                 planes[0], mcbuffer->buf_size, 0,
367                                 mcbuffer->buf_size, mcbuffer,
368                                 (GDestroyNotify)__mc_input_buffer_finalize_cb);
369         } else {
370                 mem = __mc_gst_make_tbm_buffer(core, mcbuffer);
371                 LOGD("tizen memory[%p]", mem);
372         }
373
374         if (mem == NULL) {
375                 LOGE("gstmemory failed[is_hw:%d]", core->is_hw);
376                 return MC_ERROR;
377         }
378
379         gst_buffer_append_memory(mcbuffer->buffer, mem);
380
381         return ret;
382 }
383
384
385 /*
386  * fill_outbuf virtual functions
387  */
388
389 static int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
390 {
391         return core->vtable[fill_outbuf](core, data, size, mcbuffer);
392 }
393
394 static int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
395 {
396         int i;
397         int stride_width;
398         int stride_height;
399         uint32_t width;
400         uint32_t height;
401         uint32_t buf_size;
402         tbm_surface_info_s tsurf_info;
403         tbm_bo bo[MM_VIDEO_BUFFER_PLANE_MAX];
404         tbm_bo_handle thandle;
405         tbm_surface_h tsurf = NULL;
406         media_packet_h packet = NULL;
407
408         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
409
410         mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def;
411
412         if (!core->is_hw) {
413                 width = port_def->info.video.width;
414                 height = port_def->info.video.height;
415                 stride_width = GST_ROUND_UP_4(width);
416                 stride_height = height;
417                 buf_size = stride_width * stride_height * 3 / 2;
418
419                 memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
420
421                 bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC);
422                 if (!bo[0]) {
423                         LOGE("bo allocation failed");
424                         return MC_ERROR;
425                 }
426
427                 tsurf_info.width = port_def->info.video.width;
428                 tsurf_info.height = port_def->info.video.height;
429                 tsurf_info.format = TBM_FORMAT_YVU420;
430                 tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420);
431                 tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420);
432                 tsurf_info.size = 0;
433
434                 for (i = 0; i < tsurf_info.num_planes; i++) {
435                         if (i == 0) {
436                                 tsurf_info.planes[i].stride = stride_width;
437                                 tsurf_info.planes[i].size = stride_width * stride_height;
438                                 tsurf_info.planes[i].offset = 0;
439                                 tsurf_info.size = tsurf_info.planes[i].size;
440                         } else {
441                                 tsurf_info.planes[i].stride = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2);
442                                 tsurf_info.planes[i].size = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2) * (height / 2);
443                                 tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size);
444                                 tsurf_info.size += tsurf_info.planes[i].size;
445                         }
446                 }
447
448                 thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
449                 memcpy(thandle.ptr, data, tsurf_info.size);
450                 tbm_bo_unmap(bo[0]);
451
452                 tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1);
453         } else {
454                 tsurf = (tbm_surface_h)data;
455         }
456
457         if (tsurf) {
458                 media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
459                                 (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, mcbuffer, &packet);
460                 mcbuffer->packet = packet;
461         }
462
463         return MC_ERROR_NONE;
464 }
465
466 static int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
467 {
468         gint ret = MC_ERROR_NONE;
469         gchar *ext_mem = NULL;
470         gint mem_size = 0;
471         void *packet_data = NULL;
472         media_packet_h packet = NULL;
473
474         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
475
476         if (core->encoder && core->codec_id == MEDIACODEC_AAC)
477                 media_format_set_audio_aac_type(core->output_fmt, FALSE);
478
479         mem_size = GST_ROUND_UP_4(size);
480         ext_mem = g_malloc0(mem_size);
481
482         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
483         if (ret != MEDIA_PACKET_ERROR_NONE) {
484                 LOGW("media_packet_create_alloc failed");
485                 g_free(ext_mem);
486                 return MC_ERROR;
487         }
488         mcbuffer->packet = packet;
489         mcbuffer->ext_mem = ext_mem;
490
491         media_packet_set_buffer_size(packet, size);
492         media_packet_get_buffer_data_ptr(packet, &packet_data);
493         memcpy(packet_data, data, size);
494
495         return MC_ERROR_NONE;
496 }
497
498 static int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
499 {
500         gint ret = MC_ERROR_NONE;
501         bool codec_config = FALSE;
502         bool sync_flag = FALSE;
503         bool slice = FALSE;
504         gint mem_size = 0;
505         gchar *ext_mem = NULL;
506         gint data_size = 0;
507         void *packet_data = NULL;
508         media_packet_h packet = NULL;
509
510         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
511
512         switch (core->ports[out_port_index]->port_def.coding_type) {
513         case MEDIA_FORMAT_H264_SP:
514         case MEDIA_FORMAT_H264_MP:
515         case MEDIA_FORMAT_H264_HP:
516                 data_size = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice);
517
518                 if (data_size < 0) {
519                         LOGE("No valid SPS/PPS ...");
520                         return MC_INVALID_IN_BUF;
521                 }
522                 break;
523         case MEDIA_FORMAT_MPEG4_SP:
524         case MEDIA_FORMAT_MPEG4_ASP:
525                 _mc_check_mpeg4_out_bytestream((unsigned char *)data, size, &codec_config, &sync_flag);
526                 break;
527         case MEDIA_FORMAT_H263:
528         case MEDIA_FORMAT_H263P:
529                 if (!_mc_check_h263_out_bytestream((unsigned char *)data, size, &sync_flag))
530                         return MC_INVALID_IN_BUF;
531                 break;
532         default:
533                 return MC_INVALID_IN_BUF;
534         }
535         LOGD("codec_config : %d, sync_flag : %d, slice : %d", codec_config, sync_flag, slice);
536
537         mem_size = GST_ROUND_UP_4(size);
538         ext_mem = g_malloc0(mem_size);
539
540         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
541         if (ret != MEDIA_PACKET_ERROR_NONE) {
542                 LOGW("media_packet_create_alloc failed");
543                 g_free(ext_mem);
544                 return MC_ERROR;
545         }
546         mcbuffer->packet = packet;
547         mcbuffer->ext_mem = ext_mem;
548
549         media_packet_set_buffer_size(packet, size);
550         media_packet_get_buffer_data_ptr(packet, &packet_data);
551         memcpy(packet_data, data, size);
552
553         core->need_sync_flag = sync_flag ? 1 : 0;
554         core->need_codec_data = codec_config ? 1 : 0;
555
556         return ret;
557 }
558
559 static int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer)
560 {
561         int ret = MC_ERROR_NONE;
562         gint mem_size = 0;
563         GstPad *pad;
564         GstCaps *peercaps;
565         GstMapInfo map;
566         guint8 *ptr;
567         gsize len;
568         gchar *ext_mem = NULL;
569         const GValue *codec_data = NULL;
570         void *packet_data = NULL;
571         media_packet_h packet = NULL;
572
573         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
574
575         if (core->encoder && core->codec_id == MEDIACODEC_AAC)
576                 media_format_set_audio_aac_type(core->output_fmt, FALSE);
577
578         mem_size = GST_ROUND_UP_4(size);
579         ext_mem = g_malloc0(mem_size);
580
581         ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet);
582         if (ret != MEDIA_PACKET_ERROR_NONE) {
583                 LOGW("media_packet_create_alloc failed");
584                 g_free(ext_mem);
585                 return MC_ERROR;
586         }
587         mcbuffer->packet = packet;
588         mcbuffer->ext_mem = ext_mem;
589
590         media_packet_set_buffer_size(packet, size);
591         media_packet_get_buffer_data_ptr(packet, &packet_data);
592         memcpy(packet_data, data, size);
593
594         if (!core->codec_data) {
595                 pad = gst_element_get_static_pad(core->fakesink, "sink");
596                 peercaps = gst_pad_get_current_caps(pad);
597                 if (peercaps) {
598                         GstStructure *s;
599                         if (gst_caps_is_empty(peercaps)) {
600                                 gst_caps_unref(peercaps);
601                                 gst_object_unref(pad);
602                                 LOGW("Empty caps");
603                                 return ret;
604                         }
605
606                         s = gst_caps_get_structure(peercaps, 0);
607                         codec_data = gst_structure_get_value(s, "codec_data");
608                         if (codec_data  == NULL && gst_structure_has_field(s, "streamheader"))
609                                 codec_data = gst_structure_get_value(s, "streamheader");
610
611                         core->codec_data = GST_BUFFER(g_value_dup_boxed(codec_data));
612                         gst_caps_unref(peercaps);
613                 }
614                 gst_object_unref(pad);
615                 LOGD("codec data set");
616         }
617
618         if (core->codec_data) {
619                 gst_buffer_map(core->codec_data, &map, GST_MAP_READ);
620                 ptr = map.data;
621                 len = map.size;
622                 ret = media_packet_set_codec_data(packet, ptr, len);
623                 if (ret != MEDIA_PACKET_ERROR_NONE) {
624                         LOGW("media_packet_set_codec_data failed");
625                         gst_buffer_unmap(core->codec_data, &map);
626                         return MC_ERROR;
627                 }
628                 gst_buffer_unmap(core->codec_data, &map);
629         }
630
631         return ret;
632 }
633
634 static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * name, GstBuffer * buf, ...)
635 {
636         GstStructure *struc = NULL;
637         va_list va;
638         GValue arr_val = { 0 };
639         GValue buf_val = { 0 };
640
641         g_return_val_if_fail(name != NULL, NULL);
642         g_return_val_if_fail(caps != NULL, NULL);
643         g_return_val_if_fail(gst_caps_is_fixed(caps), NULL);
644         caps = gst_caps_make_writable(caps);
645
646         struc = gst_caps_get_structure(caps, 0);
647         if (!struc)
648                 LOGW("cannot get structure from caps.\n");
649
650         g_value_init(&arr_val, GST_TYPE_ARRAY);
651
652         va_start(va, buf);
653         while (buf) {
654                 g_value_init(&buf_val, GST_TYPE_BUFFER);
655                 gst_value_set_buffer(&buf_val, buf);
656                 gst_value_array_append_value(&arr_val, &buf_val);
657                 g_value_unset(&buf_val);
658
659                 buf = va_arg(va, GstBuffer *);
660         }
661         va_end(va);
662
663         gst_structure_take_value(struc, name, &arr_val);
664
665         return caps;
666 }
667
668 int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size)
669 {
670         gint ret = MEDIA_PACKET_ERROR_NONE;
671         uint64_t buf_size = 0;
672         GstBuffer *header1, *header2, *header3;
673         guint hsize1, hsize2, hsize3;
674         GstBuffer *tmp_header;
675         GstMapInfo map;
676         guint8 *buf_data = NULL;
677         guint8 *tmp_buf = NULL;
678
679         ret = media_packet_get_buffer_size(mcbuffer->packet, &buf_size);
680         if (ret != MEDIA_PACKET_ERROR_NONE) {
681                 LOGW("buffer size get failed");
682                 return ret;
683         }
684
685         ret = media_packet_get_buffer_data_ptr(mcbuffer->packet, (void **)&buf_data);
686         if (ret != MEDIA_PACKET_ERROR_NONE) {
687                 LOGW("buffer data get failed");
688                 return ret;
689         }
690
691         LOGD("Set caps for streamheader in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
692
693         if (core->codec_id == MEDIACODEC_VORBIS) {
694                 /*
695                  * hsize1 : Identification Header (packet type 1) - fixed 30 byte
696                  * hsize2 : Comment Header (packet type 3) - variable byte (need calculate)
697                  * hsize3 : Setup Header (packet type 5) - variable byte (Used remained bytes)
698                  */
699
700                 /* First of all, Need to fins and calculate size of hsize2 */
701                 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
702                 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
703                 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
704                 tmp_buf = map.data;
705                 tmp_buf += (30 + 7);                /* hsize1 + '0x03' + 'vorbis'*/
706                 hsize2 = (7 + 4);
707                 hsize2 += GST_READ_UINT32_LE(tmp_buf);
708                 hsize2 += (4 + 1);
709                 LOGD("Find streamheader hsize2(%d)", hsize2);
710                 gst_buffer_unmap(tmp_header, &map);
711                 gst_buffer_unref(tmp_header);
712
713                 /*  hsize1 : Identification Header (packet type 1) - fixed 30 byte */
714                 hsize1 = 30;
715                 header1 = gst_buffer_new_and_alloc(hsize1);
716                 gst_buffer_fill(header1, 0, buf_data, hsize1);
717                 gst_buffer_map(header1, &map, GST_MAP_READ);
718                 tmp_buf = map.data;
719                 /* '0x01' + 'vorbis' */
720                 if (*tmp_buf != 0x01) {
721                         LOGE("[ERROR] Invalid Caps of Stream header1");
722                         gst_buffer_unmap(header1, &map);
723                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
724                 }
725                 gst_buffer_unmap(header1, &map);
726
727                 /* hsize2 : Comment Header (packet type 3) - variable byte */
728                 header2 = gst_buffer_new_and_alloc(hsize2);
729                 gst_buffer_fill(header2, 0,  (buf_data + (hsize1)), hsize2);
730                 gst_buffer_map(header2, &map, GST_MAP_READ);
731                 tmp_buf = map.data;
732                 /* '0x03' + 'vorbis' */
733                 if (*tmp_buf != 0x03) {
734                         LOGE("[ERROR] Invalid Caps of Stream header2");
735                         gst_buffer_unmap(header2, &map);
736                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
737                 }
738                 gst_buffer_unmap(header2, &map);
739
740                 /* hsize3 : Setup Header (packet type 5) - variable byte */
741                 hsize3 = streamheader_size - (hsize1 + hsize2);
742                 header3 = gst_buffer_new_and_alloc(hsize3);
743                 gst_buffer_fill(header3, 0,  (buf_data + (hsize1 + hsize2)), hsize3);
744                 gst_buffer_map(header3, &map, GST_MAP_READ);
745                 tmp_buf = map.data;
746                 /* '0x05' + 'vorbis' */
747                 if (*tmp_buf != 0x05) {
748                         LOGE("[ERROR] Invalid Caps of Stream header3");
749                         gst_buffer_unmap(header3, &map);
750                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
751                 }
752                 gst_buffer_unmap(header3, &map);
753
754                 LOGD("[vorbis] streamheader hsize1 (%d) + hsize2 (%d) + hsize3 (%d) = Total (%d)",
755                                 hsize1, hsize2, hsize3, (hsize1 + hsize2 + hsize3));
756
757                 __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, header3, NULL);
758
759                 gst_buffer_unref(header1);
760                 gst_buffer_unref(header2);
761                 gst_buffer_unref(header3);
762         } else if (core->codec_id == MEDIACODEC_FLAC) {
763                 /*
764                  * hsize1 : Stream Info (type 0) - fixed 51 byte
765                  * hsize2 : Stream Comment (type 4) - variable byte (need calculate)
766                  */
767
768                 /* First of all, Need to fins and calculate size of hsize2 */
769                 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
770                 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
771                 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
772                 tmp_buf = map.data;
773                 hsize2 = 4 + ((tmp_buf[52] << 16) | (tmp_buf[53] << 8) | (tmp_buf[54]));
774                 LOGD("Find streamheader hsize2(%d)", hsize2);
775                 gst_buffer_unmap(tmp_header, &map);
776                 gst_buffer_unref(tmp_header);
777
778                 /*  hsize1 :  Stream Info (type 0) - fixed 51 byte */
779                 hsize1 = 51;
780                 header1 = gst_buffer_new_and_alloc(hsize1);
781                 gst_buffer_fill(header1, 0, buf_data, hsize1);
782                 gst_buffer_map(header1, &map, GST_MAP_READ);
783                 tmp_buf = map.data;
784                 /* '0x7f' + 'FLAC' */
785                 if (*tmp_buf != 0x07f) {
786                         LOGE("[ERROR] Invalid Caps of Stream header1 (Info)");
787                         gst_buffer_unmap(header1, &map);
788                         gst_buffer_unref(header1);
789                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
790                 }
791                 gst_buffer_unmap(header1, &map);
792
793                 /* hsize2 : Stream Comment (type 4) - variable byte (need calculate) */
794                 header2 = gst_buffer_new_and_alloc(hsize2);
795                 gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
796                 gst_buffer_map(header2, &map, GST_MAP_READ);
797                 tmp_buf = map.data;
798                 /* '0x84' */
799                 if (*tmp_buf != 0x84) {
800                         LOGE("[ERROR] Invalid Caps of Stream header2 (Comment)");
801                         gst_buffer_unmap(header2, &map);
802                         gst_buffer_unref(header1);
803                         gst_buffer_unref(header2);
804                         return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
805                 }
806                 gst_buffer_unmap(header2, &map);
807
808                 LOGD("[flac] streamheader hsize1 (%d) + hsize2 (%d)  = Total (%d)", hsize1, hsize2, (hsize1 + hsize2));
809                 __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, NULL);
810                 gst_buffer_unref(header1);
811                 gst_buffer_unref(header2);
812         } else if (core->codec_id == MEDIACODEC_OPUS) {
813                 const GstTagList *tags;
814                 GstTagList *empty_tags = NULL;
815                 GstBuffer *header, *comments;
816                 guint8 *decoding_channel_mapping = NULL;
817                 mc_gst_port_def_t *port_def = &core->ports[in_port_index]->port_def;
818
819                 header = gst_codec_utils_opus_create_header(port_def->info.audio.samplerate,
820                         port_def->info.audio.channel,
821                         0, /* channel mapping family */
822                         1, /* stream count */
823                         0, /* coupled count */
824                         decoding_channel_mapping,
825                         0, /* FIXME: look ahead configured value */
826                         0);
827                 tags = gst_tag_setter_get_tag_list(GST_TAG_SETTER(core->codec));
828                 if (!tags)
829                         tags = empty_tags = gst_tag_list_new_empty();
830                 comments = gst_tag_list_to_vorbiscomment_buffer(tags, (const guint8 *) "OpusTags",
831                         8, "Encoded with GStreamer opusenc");
832                 core->caps = gst_codec_utils_opus_create_caps_from_header(header, comments);
833                 if (empty_tags)
834                         gst_tag_list_unref(empty_tags);
835                 gst_buffer_unref(header);
836                 gst_buffer_unref(comments);
837         } else {
838                 LOGE("Not support case of Stream header Caps");
839         }
840
841         /* Update gstbuffer's data ptr and size for using previous streamheader.*/
842         LOGD("BEFORE : mcbuffer->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer));
843         gst_buffer_remove_memory_range(mcbuffer->buffer, streamheader_size, -1);
844         gst_buffer_set_size(mcbuffer->buffer, buf_size - streamheader_size);
845         LOGD("AFTER  : mcbuffer->buffer of size %" G_GSIZE_FORMAT "",  gst_buffer_get_size(mcbuffer->buffer));
846
847         return ret;
848 }
849
850 int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint fixed_size)
851 {
852         gint ret = MC_ERROR_NONE;
853         uint32_t codec_data_size = 0;
854         GstMapInfo map;
855         GstBuffer *codecdata_buffer;
856         guint8 *data = NULL;
857         void *codec_data = NULL;
858
859         media_packet_get_codec_data(mcbuffer->packet, &codec_data, &codec_data_size);
860
861         if (codec_data != NULL) {               /* get the codec data from media_packet_get_codec_data() */
862                 data = g_malloc0(codec_data_size);
863
864                 memcpy(data, codec_data, codec_data_size);
865
866                 free(codec_data);
867                 codec_data = NULL;
868
869                 codecdata_buffer = gst_buffer_new_wrapped(data, codec_data_size);
870                 gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
871
872                 LOGD("set codec data : %" G_GSIZE_FORMAT "", gst_buffer_get_size(codecdata_buffer));
873
874                 gst_buffer_unref(codecdata_buffer);
875         } else {                                        /* get the codec data from media_packet_get_buffer_data_ptr() */
876                 uint64_t buffer_size = 0;
877                 void *buff_data = NULL;
878
879                 media_packet_get_buffer_size(mcbuffer->packet, &buffer_size);
880                 media_packet_get_buffer_data_ptr(mcbuffer->packet, &buff_data);
881
882                 /* For audio, it's necessary to change the offset value of buffer after extracting csd */
883                 /* it's not necessary to set csd to caps in case of annex-b */
884                 if (buffer_size > fixed_size) {
885                         data = g_malloc0(fixed_size);
886                         gst_buffer_map(mcbuffer->buffer, &map, GST_MAP_READ);
887                         memcpy(data, map.data, fixed_size);
888                         codecdata_buffer = gst_buffer_new_wrapped(data, fixed_size);
889                         gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
890                         gst_buffer_unref(codecdata_buffer);
891
892                         gst_buffer_replace_memory(mcbuffer->buffer, 0,
893                                         gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, map.data + fixed_size , buffer_size - fixed_size, 0,
894                                                 buffer_size - fixed_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb));
895
896                         LOGD("after : set codec data from packet: %" G_GSIZE_FORMAT "",  gst_buffer_get_size(mcbuffer->buffer));
897                         gst_buffer_unmap(mcbuffer->buffer, &map);
898                 }
899         }
900         return ret;
901 }
902
903 int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime)
904 {
905         if (media_format_create(&core->output_fmt) != MEDIA_FORMAT_ERROR_NONE) {
906                 LOGE("media format create failed");
907                 return MC_ERROR;
908         }
909         mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def;
910
911         if (video) {
912                 media_format_set_video_mime(core->output_fmt, out_mime);
913                 media_format_set_video_width(core->output_fmt, port_def->info.video.width);
914                 media_format_set_video_height(core->output_fmt, port_def->info.video.height);
915
916                 if (encoder)
917                         media_format_set_video_avg_bps(core->output_fmt, port_def->info.video.bitrate);
918         } else {
919                 media_format_set_audio_mime(core->output_fmt, out_mime);
920                 media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel);
921                 media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate);
922                 media_format_set_audio_bit(core->output_fmt, port_def->info.audio.bit_depth);
923
924                 if (encoder)
925                         media_format_set_audio_avg_bps(core->output_fmt, port_def->info.audio.bitrate);
926         }
927
928         return MC_ERROR_NONE;
929 }
930
931 /*
932  * mc_gst_core functions
933  */
934 static mc_gst_core_t *mc_gst_core_new()
935 {
936         mc_gst_core_t *core;
937
938         MEDIACODEC_FENTER();
939
940         core = g_new0(mc_gst_core_t, 1);
941
942         /* 0 : input, 1 : output */
943         core->ports[0] = mc_gst_port_new(core);
944         core->ports[0]->index = 0;
945         core->ports[1] = mc_gst_port_new(core);
946         core->ports[1]->index = 1;
947
948         core->available_queue = g_new0(mc_aqueue_t, 1);
949         core->available_queue->input = mc_async_queue_new();
950
951         g_mutex_init(&core->eos_mutex);
952         g_cond_init(&core->eos_cond);
953         g_cond_init(&core->buffer_cond);
954         g_cond_init(&core->out_buffer_cond);
955         g_mutex_init(&core->prepare_lock);
956         g_mutex_init(&core->drain_lock);
957
958         core->need_drain = false;
959         core->need_feed = false;
960         core->eos = false;
961         core->need_codec_data = false;
962         core->need_sync_flag = false;
963         core->unprepare_flag = false;
964         core->prepare_count = 0;
965         core->etb_count = 0;
966         core->codec_data = NULL;
967         core->allocator = gst_tizen_allocator_new();
968
969         core->bufmgr = NULL;
970         core->drm_fd = -1;
971
972         LOGD("gst_core(%p) is created", core);
973
974         MEDIACODEC_FLEAVE();
975
976         return core;
977 }
978
979 static void mc_gst_core_free(mc_gst_core_t *core)
980 {
981         MEDIACODEC_FENTER();
982
983         g_mutex_clear(&core->eos_mutex);
984         g_mutex_clear(&core->prepare_lock);
985         g_mutex_clear(&core->drain_lock);
986         g_cond_clear(&core->eos_cond);
987         g_cond_clear(&core->buffer_cond);
988         g_cond_clear(&core->out_buffer_cond);
989
990         mc_async_queue_free(core->available_queue->input);
991         g_free(core->available_queue);
992         core->available_queue = NULL;
993
994         if (core->allocator) {
995                 gst_object_unref(core->allocator);
996                 core->allocator = NULL;
997         }
998
999         if (core->codec_data)
1000                 gst_buffer_unref(core->codec_data);
1001
1002         if (core->ports[0] != NULL) {
1003                 mc_gst_port_free(core->ports[0]);
1004                 core->ports[0] = NULL;
1005         }
1006
1007         if (core->ports[1] != NULL) {
1008                 mc_gst_port_free(core->ports[1]);
1009                 core->ports[1] = NULL;
1010         }
1011
1012         LOGD("gst_core(%p) destroyed", core);
1013         g_free(core);
1014
1015         MEDIACODEC_FLEAVE();
1016 }
1017
1018 /*
1019  * mc_gst_port functions
1020  */
1021 static mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
1022 {
1023         MEDIACODEC_FENTER();
1024
1025         mc_gst_port_t *port;
1026
1027         port = g_new0(mc_gst_port_t, 1);
1028         port->core = core;
1029         port->num_buffers = -1;
1030         port->buffer_size = 0;
1031         port->is_allocated = 0;
1032
1033         g_mutex_init(&port->mutex);
1034         port->queue = g_queue_new();
1035
1036         LOGD("gst_port(%p) created", port);
1037
1038         MEDIACODEC_FLEAVE();
1039         return port;
1040 }
1041
1042 static void mc_gst_port_free(mc_gst_port_t *port)
1043 {
1044         MEDIACODEC_FENTER();
1045
1046         g_mutex_clear(&port->mutex);
1047         g_queue_free(port->queue);
1048
1049         LOGD("gst_port(%p) freed", port);
1050         g_free(port);
1051
1052         MEDIACODEC_FLEAVE();
1053
1054         return;
1055 }
1056
1057 gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format)
1058 {
1059         gint bitrate = 0;
1060         gboolean is_format_change = FALSE;
1061
1062         mc_gst_port_def_t *input_port_def = &core->ports[in_port_index]->port_def;
1063
1064         if (core->video) {
1065                 gint width = 0;
1066                 gint height = 0;
1067                 gint framerate = 0;
1068                 gchar *sformat = NULL;
1069                 media_format_mimetype_e mimetype = 0;
1070
1071                 media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL);
1072                 media_format_get_video_frame_rate(format, &framerate);
1073
1074                 is_format_change |= input_port_def->info.video.width != width;
1075                 is_format_change |= input_port_def->info.video.height != height;
1076                 is_format_change |= ((input_port_def->info.video.framerate != framerate) && (framerate != 0));
1077                 if (is_format_change) {
1078                         LOGD("Format changed : resolution %dx%d -> %dx%d, framerate %d -> %d",
1079                                 input_port_def->info.video.width, input_port_def->info.video.height, width, height,
1080                                 input_port_def->info.video.framerate, framerate);
1081                         input_port_def->info.video.width = width;
1082                         input_port_def->info.video.height = height;
1083                 }
1084
1085                 if (core->encoder) {
1086                         bitrate *= 1000;
1087                         sformat = __mc_get_gst_input_format(mimetype, core->is_hw);
1088                         is_format_change |= ((input_port_def->info.video.bitrate != bitrate) && (bitrate != 0));
1089                         is_format_change |= g_strcmp0(input_port_def->info.video.format, sformat);
1090                         if (is_format_change) {
1091                                 if (bitrate != 0) {
1092                                         LOGD("Bitrate changed : %d -> %d", input_port_def->info.video.bitrate, bitrate);
1093                                         input_port_def->info.video.bitrate = bitrate;
1094                                 }
1095                                 LOGD("Format changed : %s -> %s", input_port_def->info.video.format, sformat);
1096                                 input_port_def->info.video.format = g_strdup(sformat);
1097                         }
1098                 }
1099         } else {
1100                 gint channel;
1101                 gint samplerate;
1102                 gint bit;
1103
1104                 media_format_get_audio_info(format, NULL, &channel, &samplerate, &bit, &bitrate);
1105
1106                 is_format_change |= input_port_def->info.audio.channel != channel;
1107                 is_format_change |= input_port_def->info.audio.samplerate != samplerate;
1108                 is_format_change |= input_port_def->info.audio.bit_depth != bit;
1109                 if (is_format_change) {
1110                         LOGD("Audio info. changed : %d -> %d, %d -> %d, %d -> %d",
1111                                 input_port_def->info.audio.channel, channel,
1112                                 input_port_def->info.audio.samplerate, samplerate,
1113                                 input_port_def->info.audio.bit_depth, bit);
1114                         input_port_def->info.audio.channel = channel;
1115                         input_port_def->info.audio.samplerate = samplerate;
1116                         input_port_def->info.audio.bit_depth = bit;
1117                 }
1118
1119                 if (core->encoder) {
1120                         bitrate *= 1000;
1121                         is_format_change |= ((input_port_def->info.audio.bitrate != bitrate) && (bitrate != 0));
1122                         if (is_format_change) {
1123                                 LOGD("Bitrate changed : %d -> %d", input_port_def->info.audio.bitrate, bitrate);
1124                                 input_port_def->info.audio.bitrate = bitrate;
1125                         }
1126                 }
1127         }
1128
1129         return is_format_change;
1130 }
1131
1132 static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config)
1133 {
1134         MEDIACODEC_FENTER();
1135
1136         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1137         g_return_val_if_fail(mcbuffer != NULL, MC_PARAM_ERROR);
1138
1139         int ret = MC_ERROR_NONE;
1140
1141         switch (core->codec_id) {
1142         case MEDIACODEC_AAC:
1143         case MEDIACODEC_AAC_HE:
1144         case MEDIACODEC_AAC_HE_PS:
1145                 if (codec_config) {
1146                         ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE);
1147                         if (ret != MC_ERROR_NONE)
1148                                 LOGW("__mc_set_caps_codecdata failed");
1149                 }
1150                 break;
1151         case MEDIACODEC_WMAV1:
1152         case MEDIACODEC_WMAV2:
1153         case MEDIACODEC_WMAPRO:
1154         case MEDIACODEC_WMALSL:
1155                 if (codec_config) {
1156                         ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE);
1157                         if (ret != MC_ERROR_NONE)
1158                                 LOGW("__mc_set_caps_codecdata failed");
1159                 }
1160                 break;
1161         case MEDIACODEC_VORBIS:
1162         case MEDIACODEC_FLAC:
1163         case MEDIACODEC_OPUS:
1164                 if (codec_config) {
1165                         ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE);
1166                         if (ret != MC_ERROR_NONE)
1167                                 LOGW("__mc_set_caps_streamheader failed");
1168                 }
1169                 break;
1170         case MEDIACODEC_H264:
1171         case MEDIACODEC_MPEG4:
1172                 ret = __mc_set_caps_codecdata(core, mcbuffer, CODECDATA_NOT_USE);
1173                 if (ret != MC_ERROR_NONE)
1174                         LOGW("__mc_set_caps_codecdata failed");
1175                 break;
1176         default:
1177                 LOGD("doesn't need to set codecdata");
1178                 break;
1179         }
1180
1181         MEDIACODEC_FLEAVE();
1182         return ret;
1183
1184
1185 }
1186
1187 static gpointer feed_task(gpointer data)
1188 {
1189         gint ret = MC_ERROR_NONE;
1190         bool codec_config = FALSE;
1191         bool eos = FALSE;
1192         bool initiative = TRUE;
1193         bool is_format_change = FALSE;
1194         media_format_h format = NULL;
1195         media_packet_h input_buffer = NULL;
1196         GstMCBuffer *mcbuffer = NULL;
1197
1198         MEDIACODEC_FENTER();
1199
1200         mc_gst_core_t *core = (mc_gst_core_t *)data;
1201
1202         while (g_atomic_int_get(&core->available_queue->running)) {
1203                 LOGD("waiting for next input....");
1204                 input_buffer = _mc_get_input_buffer(core);
1205                 if (!input_buffer)
1206                         goto LEAVE;
1207
1208                 media_packet_get_format(input_buffer,  &format);
1209                 if (format) {
1210                         if (_mc_update_packet_info(core, format))
1211                                 is_format_change = TRUE;
1212                         media_format_unref(format);
1213                 }
1214
1215                 if (media_packet_is_codec_config(input_buffer, &codec_config) != MEDIA_PACKET_ERROR_NONE) {
1216                         LOGE("media_packet_is_codec_config failed");
1217                         goto ERROR;
1218                 }
1219
1220                 if (media_packet_is_end_of_stream(input_buffer, &eos) != MEDIA_PACKET_ERROR_NONE) {
1221                         LOGE("media_packet_is_end_of_stream failed");
1222                         goto ERROR;
1223                 }
1224                 /*
1225                  * receive an eos packet. For decoder + encoder case, encoder always get tbm surface plane first from input data,
1226                  * but eos packet only has flag not valid data, so we don't put it to downstream.
1227                  */
1228                 if (eos) {
1229                         LOGD("end of stream");
1230                         gst_app_src_end_of_stream(GST_APP_SRC(core->appsrc));
1231                         _mc_wait_for_eos(core);
1232                         initiative = TRUE;
1233
1234                         _mc_gst_handle_input_buffer_used(core, input_buffer);
1235                         goto LEAVE;
1236                 }
1237
1238                 mcbuffer = _mc_gst_media_packet_to_gstbuffer(core, input_buffer, codec_config);
1239                 if (!mcbuffer) {
1240                         LOGW("gstbuffer can't make");
1241                         goto ERROR;
1242                 }
1243                 /* mcbuffer took the ownership of the input_buffer, so set input_buffer to NULL to aviod double unref */
1244                 input_buffer = NULL;
1245
1246                 if (codec_config || initiative) {
1247                         GstPad *pad = NULL;
1248                         if (!core->encoder) {
1249                                 ret = _mc_set_codec_data(core, mcbuffer, codec_config);
1250                                 if (ret != MC_ERROR_NONE) {
1251                                         LOGE("failed to set codec data");
1252                                         gst_buffer_unref(mcbuffer->buffer);
1253                                         goto ERROR;
1254                                 }
1255                         }
1256                         pad = gst_element_get_static_pad(core->appsrc, "src");
1257                         gst_pad_push_event(pad, gst_event_new_stream_start("start"));
1258                         gst_object_unref(pad);
1259                         is_format_change = TRUE;
1260                         initiative = FALSE;
1261                         core->offset = GST_BUFFER_OFFSET_NONE;
1262                 }
1263
1264                 if (is_format_change) {
1265                         GstCaps *caps = core->mc_caps_new(core, core->codec_id, in_port_index);
1266
1267                         g_object_set(core->appsrc, "caps", caps, NULL);
1268                         gst_caps_unref(caps);
1269
1270                         LOGD("caps updated");
1271
1272                         if (core->encoder) {
1273                                 int bitrate = core->video ? \
1274                                         core->ports[in_port_index]->port_def.info.video.bitrate : \
1275                                         core->ports[in_port_index]->port_def.info.audio.bitrate;
1276
1277                                 g_object_set(core->codec, core->codec_type->property->bitrate_name, bitrate, NULL);
1278
1279                                 LOGI("bitrate[property:%s,v:%d] %d updated",
1280                                         core->codec_type->property->bitrate_name, core->video, bitrate);
1281                         }
1282
1283                         is_format_change = FALSE;
1284                 }
1285
1286
1287                 /* inject buffer */
1288                 ret = _mc_gst_gstbuffer_to_appsrc(core, mcbuffer);
1289                 if (ret != GST_FLOW_OK) {
1290                         LOGE("Failed to push gst buffer");
1291                         goto ERROR;
1292                 }
1293
1294                 continue;
1295 ERROR:
1296                 if (input_buffer)
1297                         _mc_gst_handle_input_buffer_used(core, input_buffer);
1298
1299                 _mc_gst_set_flush_input(core);
1300
1301                 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
1302                         ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
1303                                 (MC_INTERNAL_ERROR, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
1304                 }
1305
1306                 continue;
1307 LEAVE:
1308                 /*LOGE("status : input_buffer : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", input_buffer, codec_config, eos, core->encoder);*/
1309                 continue;
1310
1311         }
1312
1313         LOGI("status : input_buffer : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task",
1314                         input_buffer, codec_config, eos, core->video, core->encoder);
1315         LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder);
1316
1317         MEDIACODEC_FLEAVE();
1318
1319         return NULL;
1320 }
1321
1322 static void _mc_gst_feed_task_new(mc_gst_core_t *core)
1323 {
1324         g_return_if_fail(core && core->available_queue);
1325
1326         g_atomic_int_set(&core->available_queue->running, 1);
1327         core->available_queue->thread = g_thread_new("feed thread", &feed_task, core);
1328
1329         LOGI("new thread for feed[%p]", core->available_queue->thread);
1330 }
1331
1332 static void _mc_gst_feed_task_free(mc_gst_core_t *core)
1333 {
1334         g_return_if_fail(core && core->available_queue);
1335
1336         mc_async_queue_disable(core->available_queue->input);
1337
1338         g_atomic_int_set(&core->available_queue->running, 0);
1339         g_thread_join(core->available_queue->thread);
1340
1341         LOGI("feed thread[%p] is released", core->available_queue->thread);
1342 }
1343
1344 static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data)
1345 {
1346         mc_gst_core_t *core = (mc_gst_core_t *)data;
1347
1348         LOGI("stop_feed called");
1349         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1350                 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1351                         (MEDIACODEC_ENOUGH_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1352         }
1353 }
1354
1355 static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data)
1356 {
1357         mc_gst_core_t *core = (mc_gst_core_t *)data;
1358
1359         LOGI("start_feed called");
1360
1361         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1362                 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1363                         (MEDIACODEC_NEED_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1364         }
1365 }
1366
1367 GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index)
1368 {
1369         GstCaps *caps = NULL;
1370         mc_gst_port_def_t *port_def = &core->ports[index]->port_def;
1371
1372         caps = gst_caps_new_simple(core->mime,
1373                 "rate", G_TYPE_INT, port_def->info.audio.samplerate,
1374                 "channels", G_TYPE_INT, port_def->info.audio.channel, NULL);
1375
1376         switch (codec_id) {
1377         case MEDIACODEC_AAC:
1378                 if (core->encoder) {
1379                         gst_caps_set_simple(caps,
1380                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1381                                 "layout", G_TYPE_STRING, "interleaved", NULL);
1382                         g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
1383                 } else {
1384                         gst_caps_set_simple(caps,
1385                                 "framed", G_TYPE_BOOLEAN, TRUE,
1386                                 "mpegversion", G_TYPE_INT, 4,
1387                                 "stream-format", G_TYPE_STRING, "adts",
1388                                 NULL);
1389                         LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
1390                 }
1391                 break;
1392         case MEDIACODEC_AAC_HE:
1393         case MEDIACODEC_AAC_HE_PS:
1394                 if (core->encoder) {
1395                         LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
1396                         return NULL;
1397                 } else {
1398                         gst_caps_set_simple(caps,
1399                                 "mpegversion", G_TYPE_INT, 4,
1400                                 "framed", G_TYPE_BOOLEAN, TRUE,
1401                                 "stream-format", G_TYPE_STRING, "raw",
1402                                 NULL);
1403                         LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE)");
1404                 }
1405                 break;
1406         case MEDIACODEC_MP3:
1407                 if (core->encoder) {
1408                         LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
1409                         return NULL;
1410                 } else {
1411                         gst_caps_set_simple(caps,
1412                                 "framed", G_TYPE_BOOLEAN, TRUE,
1413                                 "mpegversion", G_TYPE_INT, 1,       /* To-Do : plz check */
1414                                 "mpegaudioversion", G_TYPE_INT, 1,  /* To-Do : plz check */
1415                                 "layer", G_TYPE_INT, 3,             /* To-Do : plz check */
1416                                 NULL);
1417                         LOGD("CAPS for codec_id (MEDIACODEC_MP3)");
1418                 }
1419                 break;
1420         case MEDIACODEC_AMR_NB:
1421                 if (core->encoder) {
1422                         gst_caps_set_simple(caps,
1423                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1424                                 "layout", G_TYPE_STRING, "interleaved",
1425                                 NULL);
1426                         LOGD("CAPS for codec_id (MEDIACODEC_AMR_NB)");
1427                 } else {
1428                         gst_caps_set_simple(caps,
1429                                 "rate", G_TYPE_INT, 8000,
1430                                 NULL);
1431                 }
1432                 break;
1433         case MEDIACODEC_AMR_WB:
1434                 if (core->encoder) {
1435                         LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
1436                         return NULL;
1437                 } else {
1438                         gst_caps_set_simple(caps,
1439                                 "rate", G_TYPE_INT, 16000,
1440                                 NULL);
1441                 }
1442                 break;
1443         case MEDIACODEC_VORBIS:
1444                 if (core->encoder) {
1445                         LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!");
1446                         return NULL;
1447                 } else {
1448                 }
1449                 break;
1450         case MEDIACODEC_FLAC:
1451                 if (core->encoder) {
1452                         LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
1453                         return NULL;
1454                 } else {
1455                         gst_caps_set_simple(caps,
1456                                 "framed", G_TYPE_BOOLEAN, TRUE,
1457                                 /* FIXME - Insert More Info */
1458                                 NULL);
1459                 }
1460                 break;
1461         case MEDIACODEC_WMAV1:
1462         case MEDIACODEC_WMAV2:
1463         case MEDIACODEC_WMAPRO:
1464         case MEDIACODEC_WMALSL:
1465                 if (core->encoder) {
1466                         LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
1467                         return NULL;
1468                 } else {
1469                         /*
1470                          * Need to extract from Stream Type Specific ... or
1471                          * Need to get Demuxer's Caps from Stream Type Specific
1472                          */
1473                         guint16 format_tag = 0;
1474                         gint wma_version = 0;
1475                         gint block_align = 1024;      /*FIXME : Need checking */
1476                         gint bitrate = 128000;        /*FIXME : Need checking */
1477
1478                         LOGD(" ----- WMA Need Additional Caps -----------");
1479                         if (core->codec_id == MEDIACODEC_WMAV1) {
1480                                 format_tag = 352;       /* 0x160 */
1481                                 wma_version = 1;
1482                         } else if (core->codec_id == MEDIACODEC_WMAV2) {
1483                                 format_tag = 353;       /* 0x161 */
1484                                 wma_version = 2;
1485                         } else if (core->codec_id == MEDIACODEC_WMAPRO) {
1486                                 format_tag = 354;       /* 0x162 */
1487                                 wma_version = 3;
1488                         } else if (core->codec_id == MEDIACODEC_WMALSL) {
1489                                 format_tag = 355;       /* 0x163 */
1490                                 wma_version = 3;
1491                         } else {
1492                                 LOGE("Not support WMA format");
1493                         }
1494
1495                         gst_caps_set_simple(caps,
1496                                 "bitrate", G_TYPE_INT, bitrate,
1497                                 "depth", G_TYPE_INT, port_def->info.audio.bit_depth,
1498                                 /* FIXME - Need More Info */
1499                                 "wmaversion", G_TYPE_INT, wma_version,
1500                                 "format_tag", G_TYPE_INT, format_tag,
1501                                 "block_align", G_TYPE_INT, block_align,
1502                                 NULL);
1503                 }
1504                 break;
1505         case MEDIACODEC_OPUS:
1506                 if (core->encoder) {
1507                         gst_caps_set_simple(caps,
1508                                 "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth),
1509                                 "layout", G_TYPE_STRING, "interleaved", NULL);
1510                 } else {
1511                         LOGD("[MC_NOT_SUPPORTED] opus decoder is not supported yet!!!");
1512                         return NULL;
1513                 }
1514                 break;
1515         default:
1516                 break;
1517         }
1518         return caps;
1519 }
1520
1521 GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index)
1522 {
1523         gchar *caps_string = NULL;
1524         GstCaps *caps = NULL;
1525         mc_gst_port_def_t *port_def = &core->ports[index]->port_def;
1526
1527         caps = gst_caps_new_simple(core->mime,
1528                 "width", G_TYPE_INT, port_def->info.video.width,
1529                 "height", G_TYPE_INT, port_def->info.video.height,
1530                 "framerate", GST_TYPE_FRACTION, port_def->info.video.framerate, 1,
1531                 NULL);
1532
1533         switch (codec_id) {
1534         case MEDIACODEC_H263:
1535                 if (core->encoder) {
1536                         gst_caps_set_simple(caps,
1537                                 "format", G_TYPE_STRING, port_def->info.video.format,
1538                                 NULL);
1539                 } else {
1540                         gst_caps_set_simple(caps,
1541                                 "mpegversion", G_TYPE_INT, 4,
1542                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1543                                 NULL);
1544                 }
1545                 break;
1546         case MEDIACODEC_MPEG4:
1547                 if (core->encoder) {
1548                         gst_caps_set_simple(caps,
1549                                 "format", G_TYPE_STRING, port_def->info.video.format,
1550                                 NULL);
1551                 } else {
1552                         gst_caps_set_simple(caps,
1553                                 "mpegversion", G_TYPE_INT, 4,
1554                                 "systemstream", G_TYPE_BOOLEAN, false,
1555                                 "parsed", G_TYPE_BOOLEAN, TRUE,
1556                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1557                                 NULL);
1558                 }
1559                 break;
1560         case MEDIACODEC_H264:
1561                 if (core->encoder) {
1562                         gst_caps_set_simple(caps,
1563                                 "format", G_TYPE_STRING, port_def->info.video.format,
1564                                 NULL);
1565                         g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
1566                         LOGE("format : %s", port_def->info.video.format);
1567                 } else {
1568                         gst_caps_set_simple(caps,
1569                                 "parsed", G_TYPE_BOOLEAN, TRUE,  /* FIXME different from sw */
1570                                 "alignment", G_TYPE_STRING, "au",
1571                                 "stream-format", G_TYPE_STRING, "byte-stream",
1572                                 "framerate", GST_TYPE_FRACTION, 30, 1,
1573                                 NULL);
1574                 }
1575                 break;
1576         default:
1577                 break;
1578         }
1579
1580         caps_string = gst_caps_to_string(caps);
1581         if (caps_string) {
1582                 LOGI("new caps[%s]", caps_string);
1583                 g_free(caps_string);
1584         }
1585
1586         return caps;
1587 }
1588
1589 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean encoder, gboolean is_hw)
1590 {
1591         MEDIACODEC_FENTER();
1592
1593         g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1594
1595         switch (id) {
1596         case MEDIACODEC_AAC:
1597                 if (encoder)
1598                         core->vtable = aenc_aac_vtable;
1599                 else
1600                         core->vtable = adec_aac_vtable;
1601                 break;
1602         case MEDIACODEC_AAC_HE:
1603         case MEDIACODEC_AAC_HE_PS:
1604                 if (encoder) {
1605                         LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
1606                         return MC_NOT_SUPPORTED;
1607                 } else {
1608                         core->vtable = adec_aacv12_vtable;
1609                 }
1610                 break;
1611         case MEDIACODEC_MP3:
1612                 if (encoder) {
1613                         LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
1614                         return MC_NOT_SUPPORTED;
1615                 } else {
1616                         core->vtable = adec_mp3_vtable;
1617                 }
1618                 break;
1619         case MEDIACODEC_AMR_NB:
1620                 LOGD("amrnb vtable");
1621                 if (encoder)
1622                         core->vtable = aenc_amrnb_vtable;
1623                 else
1624                         core->vtable = adec_amrnb_vtable;
1625                 break;
1626         case MEDIACODEC_AMR_WB:
1627                 LOGD("amrwb vtable - Only support decoder");
1628                 if (encoder) {
1629                         LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
1630                         return MC_NOT_SUPPORTED;
1631                 } else {
1632                         core->vtable = adec_amrwb_vtable;
1633                 }
1634                 break;
1635         case MEDIACODEC_VORBIS:
1636                 LOGD("vorbis vtable");
1637                 if (encoder)
1638                         return MC_NOT_SUPPORTED;
1639                 else
1640                         core->vtable = adec_vorbis_vtable;
1641                 break;
1642         case MEDIACODEC_FLAC:
1643                 LOGD("flac vtable");
1644                 if (encoder) {
1645                         LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
1646                         return MC_NOT_SUPPORTED;
1647                 } else {
1648                         core->vtable = adec_flac_vtable;
1649                 }
1650                 break;
1651         case MEDIACODEC_OPUS:
1652                 LOGD("opus vtable");
1653                 if (encoder)
1654                         core->vtable = aenc_opus_vtable;
1655                 else
1656                         core->vtable = adec_vtable;
1657                 break;
1658         case MEDIACODEC_WMAV1:
1659         case MEDIACODEC_WMAV2:
1660         case MEDIACODEC_WMAPRO:
1661         case MEDIACODEC_WMALSL:
1662                 LOGD("wma(V1 / V2 / LSL / PRO) vtable");
1663                 if (encoder) {
1664                         LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
1665                         return MC_NOT_SUPPORTED;
1666                 } else {
1667                         core->vtable = adec_wma_vtable;
1668                 }
1669                 break;
1670         case MEDIACODEC_H263:
1671                 LOGD("h263 vtable");
1672                 if (encoder) {
1673                         core->vtable = is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable;
1674                 } else {
1675                         if (is_hw)
1676                                 core->vtable = vdec_h263_hw_vtable;
1677                         else
1678                                 core->vtable = vdec_h263_sw_vtable;
1679                 }
1680                 break;
1681         case MEDIACODEC_MPEG4:
1682                 LOGD("mpeg4 vtable");
1683                 if (encoder)
1684                         core->vtable = is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable;
1685                 else
1686                         core->vtable = is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable;
1687                 break;
1688         case MEDIACODEC_H264:
1689                 LOGD("h264 vtable");
1690                 if (encoder) {
1691                         core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable;
1692                 } else {
1693                         if (is_hw)
1694                                 core->vtable = vdec_h264_hw_vtable;
1695                         else
1696                                 core->vtable = vdec_h264_sw_vtable;
1697                 }
1698                 break;
1699         default:
1700                 break;
1701         }
1702
1703         MEDIACODEC_FLEAVE();
1704
1705         return MC_ERROR_NONE;
1706 }
1707
1708 static gint _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer)
1709 {
1710         return gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer);
1711 }
1712
1713 media_packet_h _mc_get_input_buffer(mc_gst_core_t *core)
1714 {
1715         LOGD("waiting for input...");
1716         return mc_async_queue_pop(core->available_queue->input);
1717 }
1718
1719 mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle)
1720 {
1721         int ret = MC_ERROR_NONE;
1722         int num_supported_codec = 0;
1723         int i = 0;
1724         bool video;
1725         bool encoder;
1726         bool hardware;
1727         gchar *factory_name = NULL;
1728         GstCaps *caps = NULL;
1729         media_format_mimetype_e out_mime;
1730         mediacodec_codec_type_e id;
1731         mc_codec_map_t *codec_map;
1732
1733         MEDIACODEC_FENTER();
1734
1735         if (!mc_handle)
1736                 return MC_PARAM_ERROR;
1737
1738         id = mc_handle->codec_id;
1739         video = mc_handle->is_video;
1740         encoder = mc_handle->is_encoder;
1741         hardware = mc_handle->is_hw;
1742         codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
1743         num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
1744
1745         for (i = 0; i < num_supported_codec; i++) {
1746                 if ((id == codec_map[i].id) && (hardware == codec_map[i].hardware))
1747                         break;
1748         }
1749
1750         if (i == num_supported_codec)
1751                 return MC_NOT_SUPPORTED;
1752
1753         factory_name = codec_map[i].type.factory_name;
1754         out_mime = codec_map[i].type.out_format;
1755
1756         /* gst_core create */
1757         mc_gst_core_t *new_core = mc_gst_core_new();
1758
1759         new_core->mime = codec_map[i].type.mime;
1760         new_core->is_hw = hardware;
1761         new_core->eos = false;
1762         new_core->encoder = encoder;
1763         new_core->video = video;
1764         memcpy(&new_core->ports[in_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info));
1765         memcpy(&new_core->ports[out_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info));
1766         new_core->ports[out_port_index]->port_def.coding_type = out_mime;
1767         new_core->codec_id = id;
1768         new_core->codec_type = &codec_map[i].type;
1769         new_core->mc_caps_new = video ? &_mc_gst_vid_caps_new : &_mc_gst_aud_caps_new;
1770
1771         new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd);
1772         if (new_core->bufmgr == NULL) {
1773                 LOGE("TBM initialization failed");
1774                 return MC_ERROR;
1775         }
1776
1777         LOGD("@%p(%p) core is initializing...v(%d)e(%d)", mc_handle, new_core, new_core->video, new_core->encoder);
1778         LOGD("factory name : %s, output_fmt : %x", factory_name, out_mime);
1779
1780         /* create media_packet for output fmt */
1781         ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime);
1782         if (ret != MC_ERROR_NONE) {
1783                 LOGE("Failed to create output pakcet");
1784                 return ret;
1785         }
1786
1787         for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++) {
1788                 LOGD("copy cb function [%d]", i);
1789                 if (mc_handle->user_cb[i]) {
1790                         new_core->user_cb[i] = mc_handle->user_cb[i];
1791                         new_core->user_data[i] = mc_handle->user_data[i];
1792                         LOGD("user_cb[%d] %p, %p", i, new_core->user_cb[i], mc_handle->user_cb[i]);
1793                 }
1794         }
1795
1796         /* create basic core elements */
1797         ret = _mc_gst_create_pipeline(new_core, factory_name);
1798         if (ret != MC_ERROR_NONE) {
1799                 LOGE("failed to create pipeline");
1800                 return ret;
1801         }
1802
1803         /* link vtable */
1804         ret = _mc_link_vtable(new_core, id, encoder, hardware);
1805         if (ret != MC_ERROR_NONE) {
1806                 LOGE("vtable link failed");
1807                 return ret;
1808         }
1809
1810         /* set caps in capsfilter as default*/
1811         caps = new_core->mc_caps_new(new_core, id, out_port_index);
1812
1813         new_core->caps = caps;
1814         /* FIXME will parse input format from ini. format is needed when linking elements*/
1815         if (new_core->video && new_core->encoder) {
1816                 gchar *format = NULL;
1817
1818                 format = new_core->is_hw ? "SN12" : "I420";
1819                 gst_caps_set_simple(caps,
1820                         "format", G_TYPE_STRING, format,
1821                         NULL);
1822         }
1823         g_object_set(new_core->capsfilter, "caps", caps, NULL);
1824         gst_caps_unref(caps);
1825
1826         _mc_gst_feed_task_new(new_core);
1827
1828         mc_handle->core = new_core;
1829         LOGD("initialized... %d", ret);
1830         MEDIACODEC_FLEAVE();
1831
1832         return ret;
1833 }
1834
1835 mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle)
1836 {
1837         MEDIACODEC_FENTER();
1838
1839         int i;
1840         int ret = MC_ERROR_NONE;
1841         mc_gst_core_t *core = NULL;
1842
1843         if (!mc_handle)
1844                 return MC_PARAM_ERROR;
1845
1846         core = (mc_gst_core_t *)mc_handle->core;
1847
1848         if (core) {
1849                 LOGD("@%p(%p) core is uninitializing... v(%d)e(%d)", mc_handle, core, core->video, core->encoder);
1850
1851                 g_mutex_lock(&core->drain_lock);
1852                 core->unprepare_flag = TRUE;
1853                 g_mutex_unlock(&core->drain_lock);
1854
1855                 if (core->eos)
1856                         _mc_send_eos_signal(core);
1857
1858                 _mc_gst_feed_task_free(core);
1859
1860                 _mc_gst_set_flush_input(core);
1861
1862                 ret = _mc_gst_destroy_pipeline(core);
1863
1864                 /* unset callback */
1865                 for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER; i++) {
1866                         LOGD("unset cb function [%d]", i);
1867                         if (mc_handle->user_cb[i]) {
1868                                 core->user_cb[i] = NULL;
1869                                 core->user_data[i] = NULL;
1870                                 LOGD("user_cb[%d] %p, %p", i, core->user_cb[i], mc_handle->user_cb[i]);
1871                         }
1872                 }
1873
1874                 media_format_unref(core->output_fmt);
1875
1876                 if (core->bufmgr != NULL) {
1877                         tbm_bufmgr_deinit(core->bufmgr);
1878                         core->bufmgr = NULL;
1879                 }
1880
1881                 if (core->drm_fd != -1) {
1882                         close(core->drm_fd);
1883                         LOGD("close drm_fd");
1884                 }
1885
1886                 if (core != NULL) {
1887                         mc_gst_core_free(core);
1888                         mc_handle->core = NULL;
1889                 }
1890         }
1891
1892         MEDIACODEC_FLEAVE();
1893
1894         return ret;
1895 }
1896
1897 mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint64_t timeout_us)
1898 {
1899         MEDIACODEC_FENTER();
1900
1901         int ret = MC_ERROR_NONE;
1902         mc_gst_core_t *core = NULL;
1903
1904         if (!mc_handle)
1905                 return MC_PARAM_ERROR;
1906
1907         core = (mc_gst_core_t *)mc_handle->core;
1908
1909         g_mutex_lock(&core->drain_lock);
1910
1911         while (g_atomic_int_get(&core->etb_count) == MAXINUM_QNUM) {
1912                 LOGD("Waiting until packets are drained..");
1913                 core->need_drain = true;
1914                 g_cond_wait(&core->buffer_cond, &core->drain_lock);
1915         }
1916         g_mutex_unlock(&core->drain_lock);
1917
1918         if (core->prepare_count == 0)
1919                 return MC_INVALID_STATUS;
1920
1921         g_mutex_lock(&core->drain_lock);
1922
1923         if (!core->eos || !core->unprepare_flag) {
1924                 mc_async_queue_push(core->available_queue->input, inbuf);
1925
1926         } else {
1927                 ret = MC_INVALID_IN_BUF;
1928                 g_mutex_unlock(&core->drain_lock);
1929                 return ret;
1930         }
1931
1932         g_mutex_unlock(&core->drain_lock);
1933         g_atomic_int_inc(&core->etb_count);
1934         LOGI("@v(%d)e(%d)process_input(%d): %p", core->video, core->encoder, core->etb_count, inbuf);
1935
1936         MEDIACODEC_FLEAVE();
1937
1938         return ret;
1939 }
1940
1941 mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeout_us)
1942 {
1943         gint ret = MC_ERROR_NONE;
1944         gint64 end_time = -1;
1945         gboolean signalled;
1946         mc_gst_core_t *core = NULL;
1947         media_packet_h out_packet = NULL;
1948
1949         MEDIACODEC_FENTER();
1950         end_time = g_get_monotonic_time() + timeout_us;
1951
1952         if (!mc_handle)
1953                 return MC_PARAM_ERROR;
1954
1955         core = (mc_gst_core_t *)mc_handle->core;
1956
1957         g_mutex_lock(&core->ports[1]->mutex);
1958
1959         if (!g_queue_is_empty(core->ports[1]->queue))
1960                 signalled = TRUE;
1961         else {
1962                 LOGD("no buffer, wait for signal");
1963                 signalled = g_cond_wait_until(&core->out_buffer_cond, &core->ports[1]->mutex, end_time);
1964         }
1965
1966         if (signalled)
1967                 out_packet = g_queue_pop_head(core->ports[1]->queue);
1968         else {
1969                 LOGW("Failed to get buffer");
1970                 ret = MC_OUTPUT_BUFFER_EMPTY;
1971         }
1972
1973         *outbuf = out_packet;
1974         LOGI("@%p v(%d)e(%d) got buffer :%p", core, core->video, core->encoder, out_packet);
1975
1976         g_mutex_unlock(&core->ports[1]->mutex);
1977
1978         MEDIACODEC_FLEAVE();
1979
1980         return ret;
1981 }
1982
1983 mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle)
1984 {
1985         gint ret = MC_ERROR_NONE;
1986         mc_gst_core_t *core = NULL;
1987
1988         MEDIACODEC_FENTER();
1989
1990         if (!mc_handle)
1991                 return MC_PARAM_ERROR;
1992
1993         core = (mc_gst_core_t *)mc_handle->core;
1994         LOGI("@%p v(%d)e(%d) flush_buffers", core, core->video, core->encoder);
1995
1996         ret = _mc_gst_flush_buffers(core);
1997
1998         MEDIACODEC_FLEAVE();
1999
2000         return ret;
2001 }
2002
2003 static gboolean __mc_gst_init_gstreamer()
2004 {
2005         MEDIACODEC_FENTER();
2006
2007         gint i = 0;
2008         gint arg_count = 0;
2009         static gboolean initialized = FALSE;
2010         static const int max_argc = 50;
2011         gint *argc = NULL;
2012         gchar **argv = NULL;
2013         gchar **argv2 = NULL;
2014         GError *err = NULL;
2015
2016         if (initialized) {
2017                 LOGD("gstreamer already initialized.\n");
2018                 return TRUE;
2019         }
2020
2021         /* alloc */
2022         argc = malloc(sizeof(int));
2023         argv = malloc(sizeof(gchar *) *max_argc);
2024         argv2 = malloc(sizeof(gchar *) *max_argc);
2025
2026         if (!argc || !argv || !argv2)
2027                 goto ERROR;
2028
2029         memset(argv, 0, sizeof(gchar *) *max_argc);
2030         memset(argv2, 0, sizeof(gchar *) *max_argc);
2031
2032         /* add initial */
2033         *argc = 1;
2034         argv[0] = g_strdup("media codec");
2035
2036         /* we would not do fork for scanning plugins */
2037         argv[*argc] = g_strdup("--gst-disable-registry-fork");
2038         (*argc)++;
2039
2040         /* check disable registry scan */
2041         argv[*argc] = g_strdup("--gst-disable-registry-update");
2042         (*argc)++;
2043
2044         /* check disable segtrap */
2045         argv[*argc] = g_strdup("--gst-disable-segtrap");
2046         (*argc)++;
2047
2048         LOGD("initializing gstreamer with following parameter\n");
2049         LOGD("argc : %d\n", *argc);
2050         arg_count = *argc;
2051
2052         for (i = 0; i < arg_count; i++) {
2053                 argv2[i] = argv[i];
2054                 LOGD("argv[%d] : %s\n", i, argv2[i]);
2055         }
2056
2057         /* initializing gstreamer */
2058         if (!gst_init_check(argc, &argv, &err)) {
2059                 LOGE("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
2060                 if (err)
2061                         g_error_free(err);
2062
2063                 goto ERROR;
2064         }
2065
2066         /* release */
2067         for (i = 0; i < arg_count; i++)
2068                 MC_FREEIF(argv2[i]);
2069
2070         MC_FREEIF(argv);
2071         MC_FREEIF(argv2);
2072         MC_FREEIF(argc);
2073
2074         /* done */
2075         initialized = TRUE;
2076
2077         MEDIACODEC_FLEAVE();
2078         return TRUE;
2079
2080 ERROR:
2081         /* release */
2082         for (i = 0; i < arg_count; i++) {
2083                 LOGD("free[%d] : %s\n", i, argv2[i]);
2084                 MC_FREEIF(argv2[i]);
2085         }
2086
2087         MC_FREEIF(argv);
2088         MC_FREEIF(argv2);
2089         MC_FREEIF(argc);
2090
2091         return FALSE;
2092 }
2093
2094 mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, const gchar *factory_name)
2095 {
2096         int i = 0;
2097         int bitrate = 0;
2098         GstBus *bus = NULL;
2099
2100         MEDIACODEC_FENTER();
2101
2102         g_mutex_lock(&core->prepare_lock);
2103
2104         if (core->prepare_count == 0) {
2105                 if (!__mc_gst_init_gstreamer()) {
2106                         LOGE("gstreamer initialize fail");
2107                         g_mutex_unlock(&core->prepare_lock);
2108                         return MC_NOT_INITIALIZED;
2109                 }
2110
2111                 core->codec = gst_element_factory_make(factory_name, NULL);
2112                 if (!core->codec) {
2113                         LOGE("codec element create fail");
2114                         goto ERROR;
2115                 }
2116
2117                 LOGD("@%p v(%d)e(%d) create_pipeline", core, core->video, core->encoder);
2118                 MEDIACODEC_ELEMENT_SET_STATE(core->codec, GST_STATE_READY);
2119
2120                 /* create common elements */
2121                 core->pipeline = gst_pipeline_new(NULL);
2122                 if (!core->pipeline) {
2123                         LOGE("pipeline create fail");
2124                         goto ERROR;
2125                 }
2126
2127                 core->appsrc = gst_element_factory_make("appsrc", NULL);
2128                 if (!core->appsrc) {
2129                         LOGE("appsrc can't create");
2130                         goto ERROR;
2131                 }
2132
2133                 if (!core->video && core->encoder) {
2134                         core->audioconvert = gst_element_factory_make("audioconvert", NULL);
2135
2136                         if (!core->audioconvert) {
2137                                 LOGE("capsfilter can't create");
2138                                 goto ERROR;
2139                         }
2140
2141                         core->audioresample = gst_element_factory_make("audioresample", NULL);
2142
2143                         if (!core->audioresample) {
2144                                 LOGE("capsfilter can't create");
2145                                 goto ERROR;
2146                         }
2147                 }
2148
2149                 if (core->video && core->encoder) {
2150                         core->videoconvert = gst_element_factory_make("videoconvert", NULL);
2151
2152                         if (!core->videoconvert) {
2153                                 LOGE("videoconvert can't create");
2154                                 goto ERROR;
2155                         }
2156
2157                         core->videoscale = gst_element_factory_make("videoscale", NULL);
2158                         if (!core->videoscale) {
2159                                 LOGE("videoscale can't create");
2160                                 goto ERROR;
2161                         }
2162                 }
2163
2164                 core->capsfilter = gst_element_factory_make("capsfilter", NULL);
2165                 if (!core->capsfilter) {
2166                         LOGE("capsfilter can't create");
2167                         goto ERROR;
2168                 }
2169
2170                 core->fakesink = gst_element_factory_make("fakesink", NULL);
2171                 if (!core->fakesink) {
2172                         LOGE("fakesink create fail");
2173                         goto ERROR;
2174                 }
2175
2176                 g_object_set(core->fakesink, "enable-last-sample", FALSE, NULL);
2177
2178                 /*__mc_link_elements(core);*/
2179                 if (!core->video && core->encoder) {
2180                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL);
2181
2182                         /* link elements */
2183                         if (!(gst_element_link_many(core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL))) {
2184                                 LOGE("gst_element_link_many is failed");
2185                                 goto ERROR;
2186                         }
2187                 } else if (core->video && core->encoder) {
2188                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2189
2190                         /* link elements */
2191                         if (!(gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL))) {
2192                                 LOGE("gst_element_link_many is failed");
2193                                 goto ERROR;
2194                         }
2195                 } else {
2196                         gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2197
2198                         /* link elements */
2199                         if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL))) {
2200                                 LOGE("gst_element_link_many is failed");
2201                                 goto ERROR;
2202                         }
2203                 }
2204
2205                 /* connect signals, bus watcher */
2206                 bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline));
2207                 core->bus_watch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core);
2208                 core->thread_default = g_main_context_get_thread_default();
2209
2210                 /* set sync handler to get tag synchronously */
2211                 gst_bus_set_sync_handler(bus, __mc_gst_bus_sync_callback, core, NULL);
2212                 gst_object_unref(GST_OBJECT(bus));
2213
2214                 /* app src */
2215                 g_signal_connect(core->appsrc, "need-data", G_CALLBACK(__mc_gst_start_feed), core);
2216                 g_signal_connect(core->appsrc, "enough-data", G_CALLBACK(__mc_gst_stop_feed), core);
2217
2218                 /* connect handoff */
2219                 g_object_set(GST_OBJECT(core->fakesink), "signal-handoffs", TRUE, NULL);
2220                 core->signal_handoff = g_signal_connect(core->fakesink, "handoff", G_CALLBACK(__mc_gst_buffer_add), core);
2221
2222                 /* set bitrate and properties */
2223                 if (core->encoder) {
2224                         if (core->video)
2225                                 bitrate = core->ports[in_port_index]->port_def.info.video.bitrate;
2226                         else
2227                                 bitrate = core->ports[in_port_index]->port_def.info.audio.bitrate;
2228
2229                         LOGI("set encoder bitrate[property:%s,v:%d] %d",
2230                                 core->codec_type->property->bitrate_name, core->video, bitrate);
2231
2232                         g_object_set(core->codec,
2233                                 core->codec_type->property->bitrate_name, bitrate,
2234                                 NULL);
2235                 }
2236
2237                 for (i = 0 ; i < core->codec_type->property->ext_num ; i++) {
2238                         LOGI("set property [%s] -> [%s]",
2239                                 core->codec_type->property->ext_name[i],
2240                                 core->codec_type->property->ext_value[i]);
2241
2242                         gst_util_set_object_arg((GObject *)core->codec,
2243                                 core->codec_type->property->ext_name[i],
2244                                 core->codec_type->property->ext_value[i]);
2245                 }
2246
2247                 /* set state PLAYING */
2248                 MEDIACODEC_ELEMENT_SET_STATE(GST_ELEMENT_CAST(core->pipeline), GST_STATE_PLAYING);
2249         }
2250
2251         core->prepare_count++;
2252         g_mutex_unlock(&core->prepare_lock);
2253
2254         MEDIACODEC_FLEAVE();
2255
2256         return MC_ERROR_NONE;
2257
2258 STATE_CHANGE_FAILED:
2259 ERROR:
2260
2261         if (core->codec)
2262                 gst_object_unref(GST_OBJECT(core->codec));
2263
2264         if (core->pipeline)
2265                 gst_object_unref(GST_OBJECT(core->pipeline));
2266
2267         if (core->appsrc)
2268                 gst_object_unref(GST_OBJECT(core->appsrc));
2269
2270         if (core->capsfilter)
2271                 gst_object_unref(GST_OBJECT(core->capsfilter));
2272
2273         if (core->audioresample)
2274                 gst_object_unref(GST_OBJECT(core->audioresample));
2275
2276         if (core->videoscale)
2277                 gst_object_unref(GST_OBJECT(core->videoscale));
2278
2279         if (core->videoconvert)
2280                 gst_object_unref(GST_OBJECT(core->videoconvert));
2281
2282         if (core->audioconvert)
2283                 gst_object_unref(GST_OBJECT(core->audioconvert));
2284
2285         if (core->fakesink)
2286                 gst_object_unref(GST_OBJECT(core->fakesink));
2287
2288         g_mutex_unlock(&core->prepare_lock);
2289
2290         return MC_ERROR;
2291 }
2292
2293 mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core)
2294 {
2295         int ret = MC_ERROR_NONE;
2296
2297         MEDIACODEC_FENTER();
2298
2299         g_mutex_lock(&core->prepare_lock);
2300         core->prepare_count--;
2301         if (core->prepare_count == 0) {
2302
2303                 if (core->pipeline) {
2304                         /* disconnect signal */
2305                         if (core->fakesink && GST_IS_ELEMENT(core->fakesink)) {
2306                                 if (g_signal_handler_is_connected(core->fakesink, core->signal_handoff)) {
2307                                         g_signal_handler_disconnect(core->fakesink, core->signal_handoff);
2308                                         LOGD("handoff signal destroy");
2309                                 }
2310                         }
2311
2312                         if (core->bus_watch_id) {
2313                                 GSource *source = NULL;
2314                                 source = g_main_context_find_source_by_id(core->thread_default, core->bus_watch_id);
2315                                 g_source_destroy(source);
2316                                 LOGD("bus_watch_id destroy");
2317                         }
2318
2319                         MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL);
2320
2321                         gst_object_unref(GST_OBJECT(core->pipeline));
2322                         if (core->caps) {
2323                                 gst_caps_unref(core->caps);
2324                                 core->caps = NULL;
2325                         }
2326                 }
2327         }
2328
2329         LOGD("@%p v(%d)e(%d) destroy_pipeline : %d ", core, core->video, core->encoder, core->prepare_count);
2330         g_mutex_unlock(&core->prepare_lock);
2331
2332         MEDIACODEC_FLEAVE();
2333
2334         return ret;
2335
2336 STATE_CHANGE_FAILED:
2337         if (core->pipeline)
2338                 gst_object_unref(GST_OBJECT(core->pipeline));
2339
2340         LOGD("@%p v(%d)e(%d) destroy_pipeline failed", core, core->video, core->encoder);
2341         g_mutex_unlock(&core->prepare_lock);
2342
2343         return MC_ERROR;
2344 }
2345
2346 void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer)
2347 {
2348         g_mutex_lock(&core->ports[1]->mutex);
2349
2350         /* push it to output buffer queue */
2351         g_queue_push_tail(core->ports[1]->queue, mcbuffer->packet);
2352         g_cond_broadcast(&core->out_buffer_cond);
2353
2354         if (mcbuffer->buffer) {
2355                 LOGD("dq : v(%d)e(%d) TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder,
2356                         GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(mcbuffer->buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(mcbuffer->buffer)));
2357         } else {
2358                 LOGD("dq : v(%d)e(%d)", core->video, core->encoder);
2359         }
2360
2361         g_mutex_unlock(&core->ports[1]->mutex);
2362
2363         if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
2364                 ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
2365                         (mcbuffer->packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]);
2366         }
2367 }
2368
2369 void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data)
2370 {
2371         GstMCBuffer *mcbuffer = NULL;
2372
2373         MEDIACODEC_FENTER();
2374
2375         mc_gst_core_t *core = (mc_gst_core_t *)data;
2376
2377         gst_buffer_ref(buffer);
2378
2379         mcbuffer = __mc_gst_make_media_packet(core, buffer);
2380
2381         LOGI("@%p(%d) out_packet : %p", core, core->encoder, mcbuffer->packet);
2382
2383         if (mcbuffer->packet) {
2384                 media_packet_set_pts(mcbuffer->packet, GST_BUFFER_TIMESTAMP(buffer));
2385                 media_packet_set_dts(mcbuffer->packet, GST_BUFFER_DTS(buffer));
2386                 media_packet_set_duration(mcbuffer->packet, GST_BUFFER_DURATION(buffer));
2387
2388                 if (core->need_codec_data) {
2389                         media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_CODEC_CONFIG);
2390                         core->need_codec_data = false;
2391                 }
2392
2393                 if (core->need_sync_flag) {
2394                         media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_SYNC_FRAME);
2395                         core->need_sync_flag = false;
2396                 }
2397
2398                 __mc_push_output_to_queue(core, mcbuffer);
2399         } else {
2400                 gst_buffer_unref(buffer);
2401                 LOGE("Failed to dequeue output packet");
2402         }
2403
2404         MEDIACODEC_FLEAVE();
2405
2406         return;
2407 }
2408
2409 int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data)
2410 {
2411         MEDIACODEC_FENTER();
2412
2413         GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data;
2414
2415         gst_buffer_unref((GstBuffer *)mcbuffer->buffer);
2416
2417         if (mcbuffer->ext_mem) {
2418                 g_free(mcbuffer->ext_mem);
2419                 LOGD("freed external memory");
2420                 mcbuffer->ext_mem = NULL;
2421         }
2422
2423         LOGD("output port filled buffer : %p", packet);
2424         g_free(mcbuffer);
2425
2426         MEDIACODEC_FLEAVE();
2427
2428         return MEDIA_PACKET_FINALIZE;
2429 }
2430
2431 gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool is_hw)
2432 {
2433         gchar *format = NULL;
2434
2435         switch (mimetype) {
2436         case MEDIA_FORMAT_I420:
2437                 format = "I420";
2438                 break;
2439         case MEDIA_FORMAT_NV12:
2440                 if (is_hw)
2441                         format = "SN12";
2442                 else
2443                         format = "NV12";
2444                 break;
2445         case MEDIA_FORMAT_ARGB:
2446                 format = "ARGB";
2447                 break;
2448         default:
2449                 break;
2450         }
2451
2452         LOGD("input packet format : %s", format ? format : "(null)" );
2453
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_unref(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("release packet[%p]", packet);
3050                 media_packet_unref(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 }