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