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