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