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