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