2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <media_codec_queue.h>
23 #include <media_codec_port_gst.h>
24 #include <media_codec_util.h>
27 #include <gst/gstelement.h>
28 #include <gst/app/gstappsrc.h>
30 #ifdef TIZEN_PROFILE_LITE
32 #include <sys/ioctl.h>
33 #include <linux/ion.h>
36 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
38 * Internal Implementation
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);
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);
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);
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);
74 static void _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);
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);
83 static void _mc_send_eos_signal(mc_gst_core_t *core);
84 static void _mc_wait_for_eos(mc_gst_core_t *core);
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};
91 int(*vdec_h264_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG H.264 Decoder Vtable */
92 &__mc_fill_vdec_packet_with_outbuf,
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,
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,
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,
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,
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};
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};
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};
162 * fill_inbuf virtual functions
164 int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff)
166 return core->vtable[fill_inbuf](core, pkt, buff);
169 int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
171 int ret = MC_ERROR_NONE;
173 MMVideoBuffer *mm_vbuffer = NULL;
174 void *buf_data = NULL;
175 uint64_t buf_size = 0;
177 ret = media_packet_get_buffer_size(pkt, &buf_size);
178 if (ret != MEDIA_PACKET_ERROR_NONE) {
179 LOGW("buffer size get fail");
183 ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
184 if (ret != MEDIA_PACKET_ERROR_NONE) {
185 LOGW("buffer size get fail");
189 mm_vbuffer = __mc_gst_make_tbm_buffer(core, mc_buffer->pkt);
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));
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));
207 int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
209 int ret = MC_ERROR_NONE;
210 void *buf_data = NULL;
211 uint64_t buf_size = 0;
213 ret = media_packet_get_buffer_size(pkt, &buf_size);
214 if (ret != MEDIA_PACKET_ERROR_NONE) {
215 LOGW("buffer size get fail");
219 ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
220 if (ret != MEDIA_PACKET_ERROR_NONE) {
221 LOGW("buffer size get fail");
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");
235 int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
237 int ret = MC_ERROR_NONE;
250 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
252 width = enc_info->width;
253 height = enc_info->height;
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");
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");
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");
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");
279 if (width == stride_width) {
280 mc_buffer->buf_size += stride_width * stride_height;
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);
287 buf_size = stride_width * stride_height;
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;
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;
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);
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;
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;
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);
335 * fill_outbuf virtual functions
338 int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
340 return core->vtable[fill_outbuf](core, data, size, out_pkt);
343 int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt)
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;
360 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
362 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
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;
373 memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
375 bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC);
377 LOGE("bo allocation failed");
380 tsurf_info.width = dec_info->width;
381 tsurf_info.height = dec_info->height;
382 tsurf_info.format = TBM_FORMAT_YVU420;
383 tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420);
384 tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420);
387 for (i = 0; i < tsurf_info.num_planes; i++) {
389 tsurf_info.planes[i].stride = stride_width;
390 tsurf_info.planes[i].size = stride_width * stride_height;
391 tsurf_info.planes[i].offset = 0;
392 tsurf_info.size = tsurf_info.planes[i].size;
394 tsurf_info.planes[i].stride = stride_width>>1;
395 tsurf_info.planes[i].size = (stride_width>>1) * (stride_height>>1);
396 tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size);
397 tsurf_info.size += tsurf_info.planes[i].size;
401 thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
402 memcpy(thandle.ptr, data, tsurf_info.size);
405 tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1);
408 media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
409 (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt);
412 ret = media_packet_get_number_of_video_planes(*pkt, &plane_num);
413 if (ret != MEDIA_PACKET_ERROR_NONE) {
414 LOGW("media_packet_get_number_of_video_planes failed");
418 return MC_ERROR_NONE;
421 int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
423 void *pkt_data = NULL;
424 MMVideoBuffer *mm_vbuffer = NULL;
428 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
430 mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info;
431 mm_vbuffer = (MMVideoBuffer *)data;
433 LOGD("buf_share_method %d", mm_vbuffer->type);
435 LOGD("a[0] : %p, a[1] : %p, p[0] : %p, p[1] : %p",
436 mm_vbuffer->data[0], mm_vbuffer->data[1], mm_vbuffer->handle.paddr[0], mm_vbuffer->handle.paddr[1]);
437 LOGD("s[0]:%d, e[0]:%d, w[0]:%d, h[0]:%d",
438 mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], mm_vbuffer->width[0], mm_vbuffer->height[0]);
440 if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) {
441 media_packet_set_buffer_size(*out_pkt, mm_vbuffer->width[0]*mm_vbuffer->height[0]*3/2);
442 media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
444 __csc_tiled_to_linear_crop(pkt_data, mm_vbuffer->data[0],
445 mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], 0, 0, 0, 0);
446 __csc_tiled_to_linear_crop(pkt_data+mm_vbuffer->stride_width[0]*mm_vbuffer->stride_height[0],
447 mm_vbuffer->data[1], mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0]/2, 0, 0, 0, 0);
448 } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_DMABUF_FD) {
450 } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
451 tbm_surface_h tsurf = NULL;
452 tbm_surface_info_s tsurf_info;
453 memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
455 /* create tbm surface */
456 for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) {
457 if (mm_vbuffer->handle.bo[i]) {
459 tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
464 tsurf_info.width = codec_info->width;
465 tsurf_info.height = codec_info->height;
466 tsurf_info.format = TBM_FORMAT_NV12; /* bo_format */
467 tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12);
468 tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12);
471 for (i = 0; i < tsurf_info.num_planes; i++) {
472 tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
473 tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i];
476 tsurf_info.planes[i].offset = 0;
478 tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size;
480 tsurf_info.size += tsurf_info.planes[i].size;
482 LOGD("%d plane stride : %d, size : %d",tsurf_info.planes[i].stride, tsurf_info.planes[i].size);
483 tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num);
487 media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
488 (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, out_pkt);
492 return MC_ERROR_NONE;
495 int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
497 void *pkt_data = NULL;
498 int ret = MC_ERROR_NONE;
499 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
501 ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt);
502 if (ret != MEDIA_PACKET_ERROR_NONE) {
503 LOGW("media_packet_create_alloc failed");
507 media_packet_set_buffer_size(*out_pkt, size);
508 media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
509 memcpy(pkt_data, data, size);
511 return MC_ERROR_NONE;
514 int __mc_fill_venc_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
516 void *pkt_data = NULL;
517 bool codec_config = FALSE;
518 bool sync_flag = FALSE;
520 int codec_data_size = 0;
521 int ret = MC_ERROR_NONE;
523 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
525 switch (core->out_mime) {
526 case MEDIA_FORMAT_H264_SP:
527 case MEDIA_FORMAT_H264_MP:
528 case MEDIA_FORMAT_H264_HP:
529 ret = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice);
531 case MEDIA_FORMAT_MPEG4_SP:
532 case MEDIA_FORMAT_MPEG4_ASP:
533 codec_data_size = _mc_check_mpeg4_out_bytestream((unsigned char *)data, size, &codec_config, &sync_flag);
535 case MEDIA_FORMAT_H263:
536 case MEDIA_FORMAT_H263P:
537 if (!_mc_check_h263_out_bytestream((unsigned char *)data, size, &sync_flag))
538 return MC_INVALID_IN_BUF;
541 return MC_INVALID_IN_BUF;
543 LOGD("codec_config : %d, sync_flag : %d, slice : %d", codec_config, sync_flag, slice);
545 ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt);
546 if (ret != MEDIA_PACKET_ERROR_NONE) {
547 LOGW("media_packet_create_alloc failed");
551 media_packet_set_buffer_size(*out_pkt, size);
552 media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
553 memcpy(pkt_data, data, size);
555 core->need_sync_flag = sync_flag ? 1 : 0;
556 core->need_codec_data = codec_config ? 1 : 0;
562 * create_caps virtual functions
565 int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
567 return core->vtable[create_caps](core, caps, buff, codec_config);
570 int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
572 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
574 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
576 *caps = gst_caps_new_simple("video/x-raw",
577 "format", G_TYPE_STRING, "I420",
578 "width", G_TYPE_INT, enc_info->width,
579 "height", G_TYPE_INT, enc_info->height,
580 "framerate", GST_TYPE_FRACTION, enc_info->fps, 1,
583 LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps);
585 return MC_ERROR_NONE;
588 int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
590 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
592 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
594 *caps = gst_caps_new_simple(core->mime,
595 "format", G_TYPE_STRING, "SN12",
596 "width", G_TYPE_INT, enc_info->width,
597 "height", G_TYPE_INT, enc_info->height,
598 "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL);
600 g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
601 g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
603 LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
606 return MC_ERROR_NONE;
609 int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
611 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
613 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
615 *caps = gst_caps_new_simple("video/x-raw",
616 "format", G_TYPE_STRING, "SN12",
617 "width", G_TYPE_INT, enc_info->width,
618 "height", G_TYPE_INT, enc_info->height,
619 "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL);
621 g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
623 LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
626 return MC_ERROR_NONE;
629 int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
631 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
633 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
635 LOGD("%d, %d, ", dec_info->width, dec_info->height);
636 *caps = gst_caps_new_simple(core->mime,
637 "parsed", G_TYPE_BOOLEAN, TRUE,
638 "alignment", G_TYPE_STRING, "au",
639 "stream-format", G_TYPE_STRING, "byte-stream",
640 "width", G_TYPE_INT, dec_info->width,
641 "height", G_TYPE_INT, dec_info->height, NULL);
643 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
644 return MC_ERROR_NONE;
647 int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
649 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
652 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
654 LOGD("%d, %d, ", dec_info->width, dec_info->height);
656 *caps = gst_caps_new_simple(core->mime,
657 "mpegversion", G_TYPE_INT, 4,
658 "width", G_TYPE_INT, dec_info->width,
659 "height", G_TYPE_INT, dec_info->height,
660 "framerate", GST_TYPE_FRACTION, 30, 1,
663 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
665 return MC_ERROR_NONE;
668 int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
670 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
673 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
675 LOGD("%d, %d, ", dec_info->width, dec_info->height);
676 *caps = gst_caps_new_simple(core->mime,
677 "width", G_TYPE_INT, dec_info->width,
678 "height", G_TYPE_INT, dec_info->height,
679 "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
681 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
683 return MC_ERROR_NONE;
686 int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
688 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
690 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
692 *caps = gst_caps_new_simple(core->mime,
693 "variant", G_TYPE_STRING, "itu", NULL);
695 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
696 return MC_ERROR_NONE;
699 int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
701 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
703 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
705 *caps = gst_caps_new_simple(core->mime,
706 "mpegversion", G_TYPE_INT, 4,
707 "systemstream", G_TYPE_BOOLEAN, false, NULL);
709 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
710 return MC_ERROR_NONE;
713 int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
715 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
717 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
719 *caps = gst_caps_new_simple(core->mime,
720 "alignment", G_TYPE_STRING, "au",
721 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
723 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
724 return MC_ERROR_NONE;
727 int __mc_vdec_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
729 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
731 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
733 *caps = gst_caps_new_simple(core->mime,
734 "alignment", G_TYPE_STRING, "au",
735 "stream-format", G_TYPE_STRING, "byte-stream", NULL);
737 LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
738 return MC_ERROR_NONE;
741 int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
743 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
745 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
747 *caps = gst_caps_new_simple(core->mime,
748 "rate", G_TYPE_INT, enc_info->samplerate,
749 "channels", G_TYPE_INT, enc_info->channel,
750 "format", G_TYPE_STRING, "F32LE",
751 "layout", G_TYPE_STRING, "interleaved", NULL);
758 compliance : Adherence of the encoder to the specifications
759 flags: readable, writable
760 Enum "GstFFMpegCompliance" Default: 0, "normal"
761 (2): verystrict - Strictly conform to older spec
762 (1): strict - Strictly conform to current spec
763 (0): normal - Normal behavior
764 (-1): unofficial - Allow unofficial extensions
765 (-2): experimental - Allow nonstandardized experimental things
767 g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
769 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
771 return MC_ERROR_NONE;
774 int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
776 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
778 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
780 *caps = gst_caps_new_simple(core->mime,
781 "rate", G_TYPE_INT, enc_info->samplerate,
782 "channels", G_TYPE_INT, enc_info->channel,
783 "format", G_TYPE_STRING, "F32LE",
784 "layout", G_TYPE_STRING, "interleaved", NULL);
786 g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
788 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
790 return MC_ERROR_NONE;
793 int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
795 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
797 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
799 *caps = gst_caps_new_simple(core->mime,
800 "rate", G_TYPE_INT, enc_info->samplerate,
801 "channels", G_TYPE_INT, enc_info->channel,
802 "format", G_TYPE_STRING, "S16LE",
803 "layout", G_TYPE_STRING, "interleaved",
806 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
808 return MC_ERROR_NONE;
811 int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
813 int ret = MC_ERROR_NONE;
814 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
816 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
818 LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
819 *caps = gst_caps_new_simple(core->mime,
820 "framed", G_TYPE_BOOLEAN, TRUE,
821 "mpegversion", G_TYPE_INT, 4,
822 "stream-format", G_TYPE_STRING, "adts",
823 "rate", G_TYPE_INT, dec_info->samplerate,
824 "channels", G_TYPE_INT, dec_info->channel,
827 if (codec_config && (!core->encoder)) {
828 guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
829 ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
830 if (ret != MC_ERROR_NONE) {
831 LOGW("__mc_set_caps_codecdata failed");
836 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
841 int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
843 int ret = MC_ERROR_NONE;
844 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
846 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
848 LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
849 *caps = gst_caps_new_simple(core->mime,
850 "framed", G_TYPE_BOOLEAN, TRUE,
851 "mpegversion", G_TYPE_INT, 4,
852 "stream-format", G_TYPE_STRING, "adts",
853 "rate", G_TYPE_INT, dec_info->samplerate,
854 "channels", G_TYPE_INT, dec_info->channel,
857 if (codec_config && (!core->encoder)) {
858 guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
859 ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
860 if (ret != MC_ERROR_NONE) {
861 LOGW("__mc_set_caps_codecdata failed");
866 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
871 int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
873 int ret = MC_ERROR_NONE;
874 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
876 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
878 LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE and _PS - MP4/M4A case)");
879 *caps = gst_caps_new_simple(core->mime,
880 "mpegversion", G_TYPE_INT, 4, /*TODO : need adding version /profile*/
881 "framed", G_TYPE_BOOLEAN, TRUE,
882 "stream-format", G_TYPE_STRING, "raw",
883 "channels", G_TYPE_INT, dec_info->channel,
884 "rate", G_TYPE_INT, dec_info->samplerate,
887 if (codec_config && (!core->encoder)) {
888 guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
889 ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
890 if (ret != MC_ERROR_NONE) {
891 LOGW("__mc_set_caps_codecdata failed");
896 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
901 int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
903 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
905 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
907 *caps = gst_caps_new_simple(core->mime,
908 "framed", G_TYPE_BOOLEAN, TRUE,
909 "mpegversion", G_TYPE_INT, 1, /* To-Do : plz check */
910 "mpegaudioversion", G_TYPE_INT, 1, /* To-Do : plz check */
911 "layer", G_TYPE_INT, 3, /* To-Do : plz check */
912 "rate", G_TYPE_INT, dec_info->samplerate,
913 "channels", G_TYPE_INT, dec_info->channel,
916 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
918 return MC_ERROR_NONE;
921 int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
923 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
925 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
927 *caps = gst_caps_new_simple(core->mime,
928 "rate", G_TYPE_INT, 8000,
929 "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */
932 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
934 return MC_ERROR_NONE;
937 int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
939 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
941 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
943 *caps = gst_caps_new_simple(core->mime,
944 "rate", G_TYPE_INT, 16000,
945 "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */
948 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
950 return MC_ERROR_NONE;
953 int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
955 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
957 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
958 int ret = MC_ERROR_NONE;
960 *caps = gst_caps_new_simple(core->mime,
961 "channels", G_TYPE_INT, dec_info->channel,
962 "rate", G_TYPE_INT, dec_info->samplerate,
963 /* FIXME - Insert 'Stream Header' */
966 LOGD(" ----- VORBIS Need Additional Caps -----------");
968 * Need to extract from each Stream header ... or
969 * Need to get Demuxer's Caps from each Stream heade
971 if (codec_config && (!core->encoder)) {
972 guint streamheader_size = 4096; /* VORBIS_CODECDATA_SIZE = 4096 */
973 ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size);
974 if (ret != MC_ERROR_NONE) {
975 LOGW("__mc_set_caps_streamheader failed");
980 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
985 int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
987 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
989 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
990 int ret = MC_ERROR_NONE;
992 *caps = gst_caps_new_simple(core->mime,
993 "channels", G_TYPE_INT, dec_info->channel,
994 "rate", G_TYPE_INT, dec_info->samplerate,
995 "framed", G_TYPE_BOOLEAN, TRUE,
996 /* FIXME - Insert More Info */
999 LOGD(" ----- FLAC Need Additional Caps -----------");
1001 * Need to extract from each Stream header ... or
1002 * Need to get Demuxer's Caps from each Stream heade
1004 if (codec_config && (!core->encoder)) {
1005 guint streamheader_size = 4096; /* FLAC_CODECDATA_SIZE = 4096 */
1006 ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size);
1007 if (ret != MC_ERROR_NONE) {
1008 LOGW("__mc_set_caps_streamheader failed");
1013 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
1018 int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
1020 int ret = MC_ERROR_NONE;
1021 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1023 mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
1026 * Need to extract from Stream Type Specific ... or
1027 * Need to get Demuxer's Caps from Stream Type Specific
1029 guint16 format_tag = 0;
1030 gint wma_version = 0;
1031 gint block_align = 1024; /*FIXME : Need checking */
1032 gint bitrate = 128000; /*FIXME : Need checking */
1034 LOGD(" ----- WMA Need Additional Caps -----------");
1035 if (core->codec_id == MEDIACODEC_WMAV1) {
1036 format_tag = 352; /* 0x160 */
1038 } else if (core->codec_id == MEDIACODEC_WMAV2) {
1039 format_tag = 353; /* 0x161 */
1041 } else if (core->codec_id == MEDIACODEC_WMAPRO) {
1042 format_tag = 354; /* 0x162 */
1044 } else if (core->codec_id == MEDIACODEC_WMALSL) {
1045 format_tag = 355; /* 0x163 */
1048 LOGE("Not support WMA format");
1051 *caps = gst_caps_new_simple(core->mime,
1052 "rate", G_TYPE_INT, dec_info->samplerate,
1053 "channels", G_TYPE_INT, dec_info->channel,
1054 "bitrate", G_TYPE_INT, bitrate,
1055 "depth", G_TYPE_INT, dec_info->bit,
1056 /* FIXME - Need More Info */
1057 "wmaversion", G_TYPE_INT, wma_version,
1058 "format_tag", G_TYPE_INT, format_tag,
1059 "block_align", G_TYPE_INT, block_align,
1062 if (codec_config && (!core->encoder)) {
1063 guint codecdata_size = 64; /* WMA_CODECDATA_SIZE = 64 */
1064 ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
1065 if (ret != MC_ERROR_NONE) {
1066 LOGW("__mc_set_caps_codecdata failed");
1071 LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
1076 static GstCaps *__mc_caps_buffer_set_array(GstCaps * caps, const gchar * name, GstBuffer * buf, ...)
1078 GstStructure *struc = NULL;
1080 GValue arr_val = { 0 };
1081 GValue buf_val = { 0 };
1083 g_return_val_if_fail(name != NULL, NULL);
1084 g_return_val_if_fail(caps != NULL, NULL);
1085 g_return_val_if_fail(gst_caps_is_fixed(caps), NULL);
1086 caps = gst_caps_make_writable(caps);
1088 struc = gst_caps_get_structure(caps, 0);
1090 LOGW("cannot get structure from caps.\n");
1092 g_value_init(&arr_val, GST_TYPE_ARRAY);
1096 g_value_init(&buf_val, GST_TYPE_BUFFER);
1097 gst_value_set_buffer(&buf_val, buf);
1098 gst_value_array_append_value(&arr_val, &buf_val);
1099 g_value_unset(&buf_val);
1101 buf = va_arg(va, GstBuffer *);
1105 gst_structure_take_value(struc, name, &arr_val);
1110 int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint streamheader_size)
1112 int ret = MEDIA_PACKET_ERROR_NONE;
1113 void *buf_data = NULL;
1114 uint64_t buf_size = 0;
1115 GstBuffer *header1, *header2, *header3;
1116 guint hsize1, hsize2, hsize3;
1117 GstBuffer *tmp_header;
1118 guint8 *tmp_buf = NULL;
1121 ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
1122 if (ret != MEDIA_PACKET_ERROR_NONE) {
1123 LOGW("buffer size get fail");
1127 ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
1128 if (ret != MEDIA_PACKET_ERROR_NONE) {
1129 LOGW("buffer size get fail");
1133 LOGD("Set caps for streamheader in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
1135 if (core->codec_id == MEDIACODEC_VORBIS) {
1137 * hsize1 : Identification Header (packet type 1) - fixed 30 byte
1138 * hsize2 : Comment Header (packet type 3) - variable byte (need calculate)
1139 * hsize3 : Setup Header (packet type 5) - variable byte (Used remained bytes)
1142 /* First of all, Need to fins and calculate size of hsize2 */
1143 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
1144 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
1145 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
1147 tmp_buf += (30 + 7); /* hsize1 + '0x03' + 'vorbis'*/
1149 hsize2 += GST_READ_UINT32_LE(tmp_buf);
1151 LOGD("Find streamheader hsize2(%d)", hsize2);
1152 gst_buffer_unmap(tmp_header, &map);
1153 gst_buffer_unref(tmp_header);
1155 /* hsize1 : Identification Header (packet type 1) - fixed 30 byte */
1157 header1 = gst_buffer_new_and_alloc(hsize1);
1158 gst_buffer_fill(header1, 0, buf_data, hsize1);
1159 gst_buffer_map(header1, &map, GST_MAP_READ);
1161 /* '0x01' + 'vorbis' */
1162 if (*tmp_buf != 0x01) {
1163 LOGE("[ERROR] Invalid Caps of Stream header1");
1164 gst_buffer_unmap(header1, &map);
1165 return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
1167 gst_buffer_unmap(header1, &map);
1169 /* hsize2 : Comment Header (packet type 3) - variable byte */
1170 header2 = gst_buffer_new_and_alloc(hsize2);
1171 gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
1172 gst_buffer_map(header2, &map, GST_MAP_READ);
1174 /* '0x03' + 'vorbis' */
1175 if (*tmp_buf != 0x03) {
1176 LOGE("[ERROR] Invalid Caps of Stream header2");
1177 gst_buffer_unmap(header2, &map);
1178 return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
1180 gst_buffer_unmap(header2, &map);
1182 /* hsize3 : Setup Header (packet type 5) - variable byte */
1183 hsize3 = streamheader_size - (hsize1 + hsize2);
1184 header3 = gst_buffer_new_and_alloc(hsize3);
1185 gst_buffer_fill(header3, 0, (buf_data + (hsize1 + hsize2)), hsize3);
1186 gst_buffer_map(header3, &map, GST_MAP_READ);
1188 /* '0x05' + 'vorbis' */
1189 if (*tmp_buf != 0x05) {
1190 LOGE("[ERROR] Invalid Caps of Stream header3");
1191 gst_buffer_unmap(header3, &map);
1192 return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
1194 gst_buffer_unmap(header3, &map);
1196 LOGD("[vorbis] streamheader hsize1 (%d) + hsize2 (%d) + hsize3 (%d) = Total (%d)",
1197 hsize1, hsize2, hsize3, (hsize1 + hsize2 + hsize3));
1199 __mc_caps_buffer_set_array(*caps, "streamheader", header1, header2, header3, NULL);
1201 gst_buffer_unref(header1);
1202 gst_buffer_unref(header2);
1203 gst_buffer_unref(header3);
1204 } else if (core->codec_id == MEDIACODEC_FLAC) {
1206 * hsize1 : Stream Info (type 0) - fixed 51 byte
1207 * hsize2 : Stream Comment (type 4) - variable byte (need calculate)
1210 /* First of all, Need to fins and calculate size of hsize2 */
1211 tmp_header = gst_buffer_new_and_alloc(streamheader_size);
1212 gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
1213 gst_buffer_map(tmp_header, &map, GST_MAP_READ);
1215 hsize2 = 4 + ((tmp_buf[52] << 16) | (tmp_buf[53] << 8) | (tmp_buf[54]));
1216 LOGD("Find streamheader hsize2(%d)", hsize2);
1217 gst_buffer_unmap(tmp_header, &map);
1218 gst_buffer_unref(tmp_header);
1220 /* hsize1 : Stream Info (type 0) - fixed 51 byte */
1222 header1 = gst_buffer_new_and_alloc(hsize1);
1223 gst_buffer_fill(header1, 0, buf_data, hsize1);
1224 gst_buffer_map(header1, &map, GST_MAP_READ);
1226 /* '0x7f' + 'FLAC' */
1227 if (*tmp_buf != 0x07f) {
1228 LOGE("[ERROR] Invalid Caps of Stream header1 (Info)");
1229 gst_buffer_unmap(header1, &map);
1230 gst_buffer_unref(header1);
1231 return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
1233 gst_buffer_unmap(header1, &map);
1235 /* hsize2 : Stream Comment (type 4) - variable byte (need calculate) */
1236 header2 = gst_buffer_new_and_alloc(hsize2);
1237 gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
1238 gst_buffer_map(header2, &map, GST_MAP_READ);
1241 if (*tmp_buf != 0x84) {
1242 LOGE("[ERROR] Invalid Caps of Stream header2 (Comment)");
1243 gst_buffer_unmap(header2, &map);
1244 gst_buffer_unref(header1);
1245 gst_buffer_unref(header2);
1246 return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
1248 gst_buffer_unmap(header2, &map);
1250 LOGD("[flac] streamheader hsize1 (%d) + hsize2 (%d) = Total (%d)", hsize1, hsize2, (hsize1 + hsize2));
1251 __mc_caps_buffer_set_array(*caps, "streamheader", header1, header2, NULL);
1252 gst_buffer_unref(header1);
1253 gst_buffer_unref(header2);
1255 LOGE("Not support case of Stream header Caps");
1258 /* Update gstbuffer's data ptr and size for using previous streamheader.*/
1259 LOGD("BEFORE : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
1260 gst_buffer_remove_memory_range(buff->buffer, streamheader_size, -1);
1261 gst_buffer_set_size(buff->buffer, buf_size - streamheader_size);
1262 LOGD("AFTER : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
1269 int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, guint codecdata_size)
1271 int ret = MEDIA_PACKET_ERROR_NONE;
1272 void *buf_data = NULL;
1273 uint64_t buf_size = 0;
1274 GstBuffer *codecdata_buffer;
1276 ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
1277 if (ret != MEDIA_PACKET_ERROR_NONE) {
1278 LOGW("buffer size get fail");
1282 ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
1283 if (ret != MEDIA_PACKET_ERROR_NONE) {
1284 LOGW("buffer size get fail");
1288 LOGD("Set caps for codec_data in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
1290 /* Add the codec_data attribute to caps, if we have it */
1291 codecdata_buffer = gst_buffer_new_and_alloc(codecdata_size);
1292 gst_buffer_fill(codecdata_buffer, 0, buf_data, codecdata_size);
1294 LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size);
1296 gst_caps_set_simple(*caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
1297 gst_buffer_unref(codecdata_buffer);
1299 /* Update gstbuffer's data ptr and size for using previous codec_data..*/
1300 LOGD("BEFORE : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
1301 gst_buffer_remove_memory_range(buff->buffer, codecdata_size, -1);
1302 gst_buffer_set_size(buff->buffer, buf_size - codecdata_size);
1303 LOGD("AFTER : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
1309 int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime)
1311 if (media_format_create(&core->output_fmt) != MEDIA_FORMAT_ERROR_NONE) {
1312 LOGE("media format create failed");
1317 mc_encoder_info_t *info;
1319 info = (mc_encoder_info_t *)core->codec_info;
1322 media_format_set_video_mime(core->output_fmt, out_mime);
1323 media_format_set_video_width(core->output_fmt, info->width);
1324 media_format_set_video_height(core->output_fmt, info->height);
1325 media_format_set_video_avg_bps(core->output_fmt, info->bitrate);
1327 media_format_set_audio_mime(core->output_fmt, out_mime);
1328 media_format_set_audio_channel(core->output_fmt, info->channel);
1329 media_format_set_audio_samplerate(core->output_fmt, info->samplerate);
1330 media_format_set_audio_bit(core->output_fmt, info->bit);
1331 media_format_set_audio_avg_bps(core->output_fmt, info->bitrate);
1334 mc_decoder_info_t *info;
1336 info = (mc_decoder_info_t *)core->codec_info;
1339 media_format_set_video_mime(core->output_fmt, out_mime);
1340 media_format_set_video_width(core->output_fmt, info->width);
1341 media_format_set_video_height(core->output_fmt, info->height);
1343 media_format_set_audio_mime(core->output_fmt, out_mime);
1344 media_format_set_audio_channel(core->output_fmt, info->channel);
1345 media_format_set_audio_samplerate(core->output_fmt, info->samplerate);
1346 media_format_set_audio_bit(core->output_fmt, info->bit);
1349 return MC_ERROR_NONE;
1353 * mc_gst_core functions
1355 mc_gst_core_t *mc_gst_core_new()
1357 mc_gst_core_t *core;
1359 MEDIACODEC_FENTER();
1361 core = g_new0(mc_gst_core_t, 1);
1363 /* 0 : input, 1 : output */
1364 core->ports[0] = NULL;
1365 core->ports[1] = mc_gst_port_new(core);
1366 core->ports[1]->index = 1;
1368 core->available_queue = g_new0(mc_aqueue_t, 1);
1369 core->available_queue->input = mc_async_queue_new();
1371 g_mutex_init(&core->eos_mutex);
1372 g_cond_init(&core->eos_cond);
1373 g_mutex_init(&core->prepare_lock);
1375 core->need_feed = false;
1377 core->need_codec_data = false;
1378 core->need_sync_flag = false;
1379 core->prepare_count = 0;
1380 core->queued_count = 0;
1381 core->dequeued_count = 0;
1383 g_atomic_int_set(&core->available_queue->running, 1);
1384 core->available_queue->thread = g_thread_new("feed thread", &feed_task, core);
1386 core->bufmgr = NULL;
1388 LOGD("gst_core(%p) is created", core);
1390 MEDIACODEC_FLEAVE();
1395 void mc_gst_core_free(mc_gst_core_t *core)
1397 MEDIACODEC_FENTER();
1399 mc_aqueue_t *async_queue;
1401 async_queue = core->available_queue;
1403 _mc_gst_set_flush_input(core);
1404 mc_async_queue_disable(async_queue->input);
1406 g_atomic_int_set(&async_queue->running, 0);
1407 g_thread_join(async_queue->thread);
1409 g_mutex_clear(&core->eos_mutex);
1410 g_mutex_clear(&core->prepare_lock);
1411 g_cond_clear(&core->eos_cond);
1413 mc_async_queue_free(async_queue->input);
1415 if (core->ports[1] != NULL) {
1416 mc_gst_port_free(core->ports[1]);
1417 core->ports[1] = NULL;
1420 LOGD("gst_core(%p) is destroyed", core);
1423 MEDIACODEC_FLEAVE();
1427 * mc_gst_port functions
1429 mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
1431 MEDIACODEC_FENTER();
1433 mc_gst_port_t *port;
1435 port = g_new0(mc_gst_port_t, 1);
1437 port->num_buffers = -1;
1438 port->buffer_size = 0;
1439 port->is_allocated = 0;
1440 port->buffers = NULL;
1442 g_mutex_init(&port->mutex);
1443 g_cond_init(&port->buffer_cond);
1444 port->queue = g_queue_new();
1446 LOGD("gst_port(%p) is created", port);
1448 MEDIACODEC_FLEAVE();
1452 void mc_gst_port_free(mc_gst_port_t *port)
1454 MEDIACODEC_FENTER();
1456 g_mutex_clear(&port->mutex);
1457 g_cond_clear(&port->buffer_cond);
1458 g_queue_free(port->queue);
1460 LOGD("gst_port(%p) is freed", port);
1463 MEDIACODEC_FLEAVE();
1468 static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
1470 /*TODO remove is_hw param*/
1471 core->format = __mc_get_gst_input_format(pkt, core->is_hw);
1474 GstCaps *template_caps;
1476 pad = gst_element_get_static_pad(core->codec, "src");
1477 template_caps = gst_pad_get_pad_template_caps(pad);
1479 __mc_create_caps(core, caps, buff, codec_config);
1480 g_object_set(core->appsrc, "caps", *caps, NULL);
1482 if (gst_caps_is_subset(*caps, template_caps)) {
1483 LOGD("new caps is subset of template caps");
1487 static gpointer feed_task(gpointer data)
1489 mc_gst_core_t *core = (mc_gst_core_t *)data;
1490 int ret = MC_ERROR_NONE;
1491 bool codec_config = FALSE;
1493 media_packet_h in_buf = NULL;
1494 GstMCBuffer *buff = NULL;
1495 GstCaps *new_caps = NULL;
1496 bool initiative = true;
1498 MEDIACODEC_FENTER();
1500 while (g_atomic_int_get(&core->available_queue->running)) {
1501 LOGD("waiting for next input....");
1502 in_buf = _mc_get_input_buffer(core);
1507 if (media_packet_is_codec_config(in_buf, &codec_config) != MEDIA_PACKET_ERROR_NONE) {
1508 LOGE("media_packet_is_codec_config failed");
1512 if (media_packet_is_end_of_stream(in_buf, &eos) != MEDIA_PACKET_ERROR_NONE) {
1513 LOGE("media_packet_is_end_of_stream failed");
1517 buff = _mc_gst_media_packet_to_gstbuffer(core, &new_caps, in_buf, codec_config);
1519 LOGW("gstbuffer can't make");
1529 _mc_gst_update_caps(core, in_buf, &new_caps, buff, codec_config);
1531 pad = gst_element_get_static_pad(core->appsrc, "src");
1532 gst_pad_push_event(pad, gst_event_new_stream_start("sejun"));
1533 gst_object_unref(pad);
1535 LOGD("caps updated");
1539 ret = _mc_gst_gstbuffer_to_appsrc(core, buff);
1540 if (ret != GST_FLOW_OK) {
1541 LOGE("Failed to push gst buffer");
1548 LOGD("end of stream");
1549 gst_app_src_end_of_stream(GST_APP_SRC(core->appsrc));
1550 _mc_wait_for_eos(core);
1557 _mc_gst_set_flush_input(core);
1559 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
1560 ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
1561 (MC_INTERNAL_ERROR, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
1566 /*LOGE("status : in_buf : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", in_buf, codec_config, eos, core->encoder);*/
1572 gst_caps_unref(new_caps);
1574 LOGI("status : in_buf : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task",
1575 in_buf, codec_config, eos, core->video, core->encoder);
1576 LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder);
1578 MEDIACODEC_FLEAVE();
1583 static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data)
1585 mc_gst_core_t *core = (mc_gst_core_t *)data;
1587 LOGI("stop_feed called");
1588 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1589 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1590 (MEDIACODEC_ENOUGH_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1594 static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data)
1596 mc_gst_core_t *core = (mc_gst_core_t *)data;
1598 LOGI("start_feed called");
1600 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
1601 ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
1602 (MEDIACODEC_NEED_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
1606 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean encoder, gboolean is_hw)
1608 MEDIACODEC_FENTER();
1610 g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
1613 case MEDIACODEC_AAC:
1615 /* if set to 'CODEC_CONFIG', then It is also available case of MEDIA_FORMAT_AAC_LC (RAW) */
1616 LOGD("aac lc (adts) vtable");
1617 core->vtable = encoder ? aenc_aac_vtable : adec_aac_vtable;
1620 case MEDIACODEC_AAC_HE:
1621 case MEDIACODEC_AAC_HE_PS:
1623 LOGD("aac he v12 vtable");
1624 core->vtable = encoder ? aenc_aac_vtable : adec_aacv12_vtable;
1626 LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
1627 return MC_NOT_SUPPORTED;
1631 case MEDIACODEC_MP3:
1633 LOGD("mp3 vtable - Only support decoder");
1634 core->vtable = encoder ? aenc_vtable : adec_mp3_vtable;
1636 LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
1637 return MC_NOT_SUPPORTED;
1641 case MEDIACODEC_AMR_NB:
1643 LOGD("amrnb vtable");
1644 core->vtable = encoder ? aenc_amrnb_vtable : adec_amrnb_vtable;
1647 case MEDIACODEC_AMR_WB:
1649 LOGD("amrwb vtable - Only support decoder");
1650 core->vtable = encoder ? aenc_vtable : adec_amrwb_vtable;
1652 LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
1653 return MC_NOT_SUPPORTED;
1657 case MEDIACODEC_VORBIS:
1659 LOGD("vorbis vtable");
1660 core->vtable = encoder ? aenc_vtable : adec_vorbis_vtable;
1662 LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!");
1663 return MC_NOT_SUPPORTED;
1667 case MEDIACODEC_FLAC:
1669 LOGD("flac vtable");
1670 core->vtable = encoder ? aenc_vtable : adec_flac_vtable;
1672 LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
1673 return MC_NOT_SUPPORTED;
1677 case MEDIACODEC_WMAV1:
1678 case MEDIACODEC_WMAV2:
1679 case MEDIACODEC_WMAPRO:
1680 case MEDIACODEC_WMALSL:
1682 LOGD("wma(V1 / V2 / LSL / PRO) vtable");
1683 core->vtable = encoder ? aenc_vtable : adec_wma_vtable;
1685 LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
1686 return MC_NOT_SUPPORTED;
1690 case MEDIACODEC_H263:
1692 LOGD("h263 vtable");
1693 core->vtable = encoder ? (is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable) : is_hw ? vdec_h263_hw_vtable : vdec_h263_sw_vtable;
1696 case MEDIACODEC_MPEG4:
1698 LOGD("mpeg4 vtable");
1699 core->vtable = encoder ? (is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable) : is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable;
1703 case MEDIACODEC_H264:
1705 LOGD("h264 vtable");
1706 core->vtable = encoder ? (is_hw ? venc_h264_hw_vtable : venc_vtable) : is_hw ? vdec_h264_hw_vtable : vdec_h264_sw_vtable;
1713 return MC_ERROR_NONE;
1716 static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *buff)
1718 MEDIACODEC_FENTER();
1720 int ret = MC_ERROR_NONE;
1722 LOGD("pushed buffer to appsrc : %p, buffer of size %" G_GSIZE_FORMAT "",
1723 buff->buffer, gst_buffer_get_size(buff->buffer));
1725 ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), buff->buffer);
1730 media_packet_h _mc_get_input_buffer(mc_gst_core_t *core)
1732 LOGD("waiting for input...");
1733 return mc_async_queue_pop(core->available_queue->input);
1736 mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle)
1738 MEDIACODEC_FENTER();
1740 int ret = MC_ERROR_NONE;
1741 media_format_mimetype_e out_mime;
1742 int num_supported_codec=0;
1746 return MC_PARAM_ERROR;
1748 mediacodec_codec_type_e id;
1752 gchar *factory_name = NULL;
1753 mc_codec_map_t *codec_map;
1755 id = mc_handle->codec_id;
1756 video = mc_handle->is_video;
1757 encoder = mc_handle->is_encoder;
1758 hardware = mc_handle->is_hw;
1759 codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
1760 num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
1762 for (i = 0; i < num_supported_codec; i++){
1763 if ((id == codec_map[i].id) && (hardware == codec_map[i].hardware))
1767 if (i == num_supported_codec)
1768 return MC_NOT_SUPPORTED;
1770 factory_name = codec_map[i].type.factory_name;
1771 out_mime = codec_map[i].type.out_format;
1773 /* gst_core create */
1774 mc_gst_core_t *new_core = mc_gst_core_new();
1776 new_core->mime = codec_map[i].type.mime;
1777 new_core->is_hw = hardware;
1778 new_core->eos = false;
1779 new_core->encoder = encoder;
1780 new_core->video = video;
1781 new_core->codec_info = encoder ? (void *)&mc_handle->info.encoder : (void *)&mc_handle->info.decoder;
1782 new_core->out_mime = codec_map[i].type.out_format;
1783 new_core->codec_id = id;
1785 new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd);
1786 if (new_core->bufmgr == NULL) {
1787 LOGE("TBM initialization failed");
1791 LOGD("@%p(%p) core is initializing...v(%d)e(%d)", mc_handle, new_core, new_core->video, new_core->encoder);
1792 LOGD("factory name : %s, output_fmt : %x", factory_name, out_mime);
1794 /* create media_packet for output fmt */
1795 if ((ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime)) != MC_ERROR_NONE) {
1796 LOGE("Failed to create output pakcet");
1801 if ((ret = _mc_link_vtable(new_core, id, encoder, hardware)) != MC_ERROR_NONE) {
1802 LOGE("vtable link failed");
1806 for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++) {
1807 LOGD("copy cb function [%d]", i);
1808 if (mc_handle->user_cb[i]) {
1809 new_core->user_cb[i] = mc_handle->user_cb[i];
1810 new_core->user_data[i] = mc_handle->user_data[i];
1811 LOGD("user_cb[%d] %p, %p", i, new_core->user_cb[i], mc_handle->user_cb[i]);
1815 mc_handle->core = new_core;
1817 /* create basic core elements */
1818 ret = _mc_gst_create_pipeline(mc_handle->core, factory_name);
1820 LOGD("initialized... %d", ret);
1824 mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle)
1826 MEDIACODEC_FENTER();
1829 int ret = MC_ERROR_NONE;
1830 mc_gst_core_t *core = NULL;
1833 return MC_PARAM_ERROR;
1835 core = (mc_gst_core_t *)mc_handle->core;
1838 LOGD("@%p(%p) core is uninitializing... v(%d)e(%d)", mc_handle, core, core->video, core->encoder);
1841 _mc_send_eos_signal(core);
1844 _mc_gst_flush_buffers(core);
1847 ret = _mc_gst_destroy_pipeline(core);
1849 /* unset callback */
1850 for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER; i++) {
1851 LOGD("unset cb function [%d]", i);
1852 if (mc_handle->user_cb[i]) {
1853 core->user_cb[i] = NULL;
1854 core->user_data[i] = NULL;
1855 LOGD("user_cb[%d] %p, %p", i, core->user_cb[i], mc_handle->user_cb[i]);
1859 media_format_unref(core->output_fmt);
1861 if (core->bufmgr != NULL) {
1862 tbm_bufmgr_deinit(core->bufmgr);
1863 core->bufmgr = NULL;
1866 if(core->drm_fd != -1) {
1867 close(core->drm_fd);
1868 LOGD("close drm_fd");
1872 mc_gst_core_free(core);
1873 mc_handle->core = NULL;
1880 mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint64_t timeOutUs)
1882 MEDIACODEC_FENTER();
1884 int ret = MC_ERROR_NONE;
1885 mc_gst_core_t *core = NULL;
1889 return MC_PARAM_ERROR;
1891 core = (mc_gst_core_t *)mc_handle->core;
1893 g_get_current_time(&nowtv);
1894 g_time_val_add(&nowtv, 500 * 1000); /* usec */
1896 if (!g_cond_timed_wait(&nowtv)) {
1900 if (core->prepare_count == 0)
1901 return MEDIACODEC_ERROR_INVALID_STATE;
1904 mc_async_queue_push(core->available_queue->input, inbuf);
1906 ret = MC_INVALID_IN_BUF;
1908 LOGI("@%p v(%d)e(%d)process_input(%d)", core, core->video, core->encoder, core->queued_count);
1909 core->queued_count++;
1911 MEDIACODEC_FLEAVE();
1916 mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeOutUs)
1918 MEDIACODEC_FENTER();
1920 int ret = MC_ERROR_NONE;
1921 mc_gst_core_t *core = NULL;
1922 media_packet_h out_pkt = NULL;
1925 return MC_PARAM_ERROR;
1927 core = (mc_gst_core_t *)mc_handle->core;
1928 LOGI("@%p v(%d)e(%d) get_output", core, core->video, core->encoder);
1930 g_mutex_lock(&core->ports[1]->mutex);
1932 if (!g_queue_is_empty(core->ports[1]->queue)) {
1933 out_pkt = g_queue_pop_head(core->ports[1]->queue);
1934 LOGD("pop from output_queue : %p", out_pkt);
1936 ret = MC_OUTPUT_BUFFER_EMPTY;
1937 LOGD("output_queue is empty");
1941 g_mutex_unlock(&core->ports[1]->mutex);
1943 MEDIACODEC_FLEAVE();
1948 mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle)
1950 MEDIACODEC_FENTER();
1952 int ret = MC_ERROR_NONE;
1953 mc_gst_core_t *core = NULL;
1956 return MC_PARAM_ERROR;
1958 core = (mc_gst_core_t *)mc_handle->core;
1959 LOGI("@%p v(%d)e(%d) get_output", core, core->video, core->encoder);
1961 _mc_gst_flush_buffers(core);
1963 MEDIACODEC_FLEAVE();
1968 static gboolean __mc_gst_init_gstreamer()
1970 MEDIACODEC_FENTER();
1972 static gboolean initialized = FALSE;
1973 static const int max_argc = 50;
1975 gchar **argv = NULL;
1976 gchar **argv2 = NULL;
1982 LOGD("gstreamer already initialized.\n");
1987 argc = malloc(sizeof(int));
1988 argv = malloc(sizeof(gchar *) *max_argc);
1989 argv2 = malloc(sizeof(gchar *) *max_argc);
1991 if (!argc || !argv || !argv2)
1994 memset(argv, 0, sizeof(gchar *) *max_argc);
1995 memset(argv2, 0, sizeof(gchar *) *max_argc);
1999 argv[0] = g_strdup("media codec");
2001 /* we would not do fork for scanning plugins */
2002 argv[*argc] = g_strdup("--gst-disable-registry-fork");
2005 /* check disable registry scan */
2006 argv[*argc] = g_strdup("--gst-disable-registry-update");
2009 /* check disable segtrap */
2010 argv[*argc] = g_strdup("--gst-disable-segtrap");
2013 LOGD("initializing gstreamer with following parameter\n");
2014 LOGD("argc : %d\n", *argc);
2017 for (i = 0; i < arg_count; i++) {
2019 LOGD("argv[%d] : %s\n", i, argv2[i]);
2022 /* initializing gstreamer */
2023 if (!gst_init_check(argc, &argv, &err)) {
2024 LOGE("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
2033 for (i = 0; i < arg_count; i++) {
2034 MC_FREEIF(argv2[i]);
2044 MEDIACODEC_FLEAVE();
2050 for (i = 0; i < arg_count; i++) {
2051 LOGD("free[%d] : %s\n", i, argv2[i]);
2052 MC_FREEIF(argv2[i]);
2062 mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name)
2066 MEDIACODEC_FENTER();
2068 g_mutex_lock(&core->prepare_lock);
2069 if (core->prepare_count == 0) {
2071 if (!__mc_gst_init_gstreamer()) {
2072 LOGE("gstreamer initialize fail");
2073 g_mutex_unlock(&core->prepare_lock);
2074 return MC_NOT_INITIALIZED;
2076 core->codec = gst_element_factory_make(factory_name, NULL);
2079 LOGE("codec element create fail");
2083 LOGD("@%p v(%d)e(%d) create_pipeline", core, core->video, core->encoder);
2084 MEDIACODEC_ELEMENT_SET_STATE(core->codec, GST_STATE_READY);
2086 /* create common elements */
2087 core->pipeline = gst_pipeline_new(NULL);
2089 if (!core->pipeline) {
2090 LOGE("pipeline create fail");
2094 core->appsrc = gst_element_factory_make("appsrc", NULL);
2096 if (!core->appsrc) {
2097 LOGE("appsrc can't create");
2101 core->capsfilter = gst_element_factory_make("capsfilter", NULL);
2103 if (!core->capsfilter) {
2104 LOGE("capsfilter can't create");
2108 core->fakesink = gst_element_factory_make("fakesink", NULL);
2110 if (!core->fakesink) {
2111 LOGE("fakesink create fail");
2114 g_object_set(core->fakesink, "enable-last-sample", FALSE, NULL);
2116 /*__mc_link_elements(core);*/
2117 gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2120 gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
2122 /* connect signals, bus watcher */
2123 bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline));
2124 core->bus_whatch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core);
2125 core->thread_default = g_main_context_get_thread_default();
2127 /* set sync handler to get tag synchronously */
2128 gst_bus_set_sync_handler(bus, __mc_gst_bus_sync_callback, core, NULL);
2129 gst_object_unref(GST_OBJECT(bus));
2132 g_signal_connect(core->appsrc, "need-data", G_CALLBACK(__mc_gst_start_feed), core);
2133 g_signal_connect(core->appsrc, "enough-data", G_CALLBACK(__mc_gst_stop_feed), core);
2135 /* connect handoff */
2136 g_object_set(GST_OBJECT(core->fakesink), "signal-handoffs", TRUE, NULL);
2137 core->signal_handoff = g_signal_connect(core->fakesink, "handoff", G_CALLBACK(__mc_gst_buffer_add), core);
2139 /* set state PLAYING */
2140 MEDIACODEC_ELEMENT_SET_STATE(GST_ELEMENT_CAST(core->pipeline), GST_STATE_PLAYING);
2143 core->prepare_count++;
2144 g_mutex_unlock(&core->prepare_lock);
2146 MEDIACODEC_FLEAVE();
2148 return MC_ERROR_NONE;
2150 STATE_CHANGE_FAILED:
2154 gst_object_unref(GST_OBJECT(core->codec));
2157 gst_object_unref(GST_OBJECT(core->pipeline));
2160 gst_object_unref(GST_OBJECT(core->appsrc));
2162 if (core->capsfilter)
2163 gst_object_unref(GST_OBJECT(core->capsfilter));
2166 gst_object_unref(GST_OBJECT(core->fakesink));
2168 g_mutex_unlock(&core->prepare_lock);
2173 mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core)
2175 int ret = MC_ERROR_NONE;
2177 MEDIACODEC_FENTER();
2179 g_mutex_lock(&core->prepare_lock);
2180 core->prepare_count--;
2181 if (core->prepare_count == 0) {
2183 if (core->pipeline) {
2184 /* disconnect signal */
2185 if (core->fakesink && GST_IS_ELEMENT(core->fakesink)) {
2186 if (g_signal_handler_is_connected(core->fakesink, core->signal_handoff)) {
2187 g_signal_handler_disconnect(core->fakesink, core->signal_handoff);
2188 LOGD("handoff signal destroy");
2192 if (core->bus_whatch_id) {
2193 GSource *source = NULL;
2194 source = g_main_context_find_source_by_id(core->thread_default, core->bus_whatch_id);
2195 g_source_destroy(source);
2196 LOGD("bus_whatch_id destroy");
2199 MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL);
2201 gst_object_unref(GST_OBJECT(core->pipeline));
2205 LOGD("@%p v(%d)e(%d) destroy_pipeline : %d ", core, core->video, core->encoder, core->prepare_count);
2206 g_mutex_unlock(&core->prepare_lock);
2208 MEDIACODEC_FLEAVE();
2212 STATE_CHANGE_FAILED:
2214 gst_object_unref(GST_OBJECT(core->pipeline));
2216 LOGD("@%p v(%d)e(%d) destroy_pipeline failed", core, core->video, core->encoder);
2217 g_mutex_unlock(&core->prepare_lock);
2222 void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data)
2226 GstMapInfo map = GST_MAP_INFO_INIT;
2227 media_packet_h out_pkt = NULL;
2229 MEDIACODEC_FENTER();
2231 mc_gst_core_t *core = (mc_gst_core_t *)data;
2233 gst_buffer_ref(buffer);
2235 n = gst_buffer_n_memory(buffer);
2237 mem = gst_buffer_peek_memory(buffer, n-1);
2239 gst_memory_map(mem, &map, GST_MAP_READ);
2240 LOGD("n : %d, map.data : %p, map.size : %d", n, map.data, map.size);
2242 out_pkt = __mc_gst_make_media_packet(core, map.data, map.size);
2244 LOGI("@%p(%d) out_pkt : %p", core, core->encoder, out_pkt);
2245 gst_memory_unmap(mem, &map);
2249 media_packet_set_extra(out_pkt, buffer);
2250 media_packet_set_pts(out_pkt, GST_BUFFER_TIMESTAMP(buffer));
2252 if (core->need_codec_data) {
2253 media_packet_set_flags(out_pkt, MEDIA_PACKET_CODEC_CONFIG);
2254 core->need_codec_data = false;
2257 if (core->need_sync_flag) {
2258 media_packet_set_flags(out_pkt, MEDIA_PACKET_SYNC_FRAME);
2259 core->need_sync_flag = false;
2262 g_mutex_lock(&core->ports[1]->mutex);
2263 /* push it to output buffer queue */
2264 g_queue_push_tail(core->ports[1]->queue, out_pkt);
2266 core->dequeued_count++;
2267 LOGD("dequeued : %d", core->dequeued_count);
2268 LOGD("GST_BUFFER_TIMESTAMP = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
2270 g_mutex_unlock(&core->ports[1]->mutex);
2272 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
2273 ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
2274 (out_pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]);
2278 MEDIACODEC_FLEAVE();
2283 int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data)
2285 void *buffer = NULL;
2287 LOGD("packet finalized: %p", packet);
2288 media_packet_get_extra(packet, &buffer);
2290 gst_buffer_unref((GstBuffer *)buffer);
2292 return MEDIA_PACKET_FINALIZE;
2295 gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw)
2297 gchar *format = NULL;
2298 media_format_h fmt = NULL;
2299 media_format_mimetype_e mimetype = 0;
2301 media_packet_get_format(packet, &fmt);
2302 media_format_get_video_info(fmt, &mimetype, NULL, NULL, NULL, NULL);
2303 media_format_unref(fmt);
2304 LOGD("input packet mimetype : %x", mimetype);
2307 case MEDIA_FORMAT_I420:
2310 case MEDIA_FORMAT_NV12:
2316 case MEDIA_FORMAT_ARGB:
2322 LOGD("input packet format : %s", format);
2326 GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **caps, media_packet_h pkt, bool codec_config)
2328 int ret = MEDIA_PACKET_ERROR_NONE;
2329 GstMCBuffer *mc_buffer = NULL;
2330 void *buf_data = NULL;
2331 uint64_t buf_size = 0;
2335 ret = media_packet_get_buffer_size(pkt, &buf_size);
2336 if (ret != MEDIA_PACKET_ERROR_NONE) {
2337 LOGW("buffer size get fail");
2341 ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
2342 if (ret != MEDIA_PACKET_ERROR_NONE) {
2343 LOGW("buffer size get fail");
2347 mc_buffer = gst_mediacodec_buffer_new(core, pkt, buf_size);
2348 if (mc_buffer == NULL) {
2349 LOGW("failed to create inbuf");
2353 LOGD("pkt : %p, buf_size : %d", pkt, (int)buf_size);
2355 ret = __mc_fill_input_buffer(core, pkt, mc_buffer);
2356 if (ret != MC_ERROR_NONE) {
2357 LOGW("failed to fill inbuf");
2362 media_packet_get_pts(pkt, &pts);
2363 GST_BUFFER_PTS(mc_buffer->buffer) = pts;
2366 media_packet_get_duration(pkt, &dur);
2367 GST_BUFFER_DURATION(mc_buffer->buffer) = dur;
2372 media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size)
2374 media_packet_h pkt = NULL;
2376 __mc_fill_output_buffer(core, data, size, &pkt);
2382 gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
2384 int ret = MC_ERROR_NONE;
2385 mc_gst_core_t *core = (mc_gst_core_t *)data;
2386 LOGD("@%p v(%d)e(%d)", core, core->video, core->encoder);
2388 switch (GST_MESSAGE_TYPE(msg)) {
2390 case GST_MESSAGE_EOS:
2392 _mc_send_eos_signal(core);
2394 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
2395 LOGD("eos callback invoked");
2396 ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
2399 LOGD("End of stream\n");
2403 case GST_MESSAGE_ERROR:
2405 GError *error = NULL;
2407 gst_message_parse_error(msg, &error, NULL);
2410 LOGW("GST error message parsing failed");
2414 LOGW("Error: %s\n", error->message);
2417 if (error->domain == GST_STREAM_ERROR) {
2418 ret = __gst_handle_stream_error(core, error, msg);
2419 } else if (error->domain == GST_RESOURCE_ERROR) {
2420 ret = __gst_handle_resource_error(core, error->code);
2421 } else if (error->domain == GST_LIBRARY_ERROR) {
2422 ret = __gst_handle_library_error(core, error->code);
2423 } else if (error->domain == GST_CORE_ERROR) {
2424 ret = __gst_handle_core_error(core, error->code);
2426 LOGW("Unexpected error has occured");
2429 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
2430 ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
2431 (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
2434 g_error_free(error);
2445 static gboolean __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg)
2447 gboolean retval = false;
2449 if (!core->pipeline) {
2450 LOGE("mediacodec pipeline handle is null");
2454 switch (GST_MESSAGE_TYPE(msg)) {
2455 case GST_MESSAGE_TAG:
2456 case GST_MESSAGE_EOS:
2457 case GST_MESSAGE_ERROR:
2458 case GST_MESSAGE_WARNING:
2469 static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data)
2471 mc_gst_core_t *core = (mc_gst_core_t *)data;
2472 GstBusSyncReply reply = GST_BUS_DROP;
2474 LOGD("__mc_gst_bus_sync_callback is called");
2476 if (!core->pipeline) {
2477 LOGE("mediacodec pipeline handle is null");
2478 return GST_BUS_PASS;
2481 if (!__mc_gst_check_useful_message(core, msg)) {
2482 gst_message_unref(msg);
2483 return GST_BUS_DROP;
2486 switch (GST_MESSAGE_TYPE(msg)) {
2487 case GST_MESSAGE_EOS:
2488 case GST_MESSAGE_ERROR:
2489 __mc_gst_bus_callback(NULL, msg, core);
2490 reply = GST_BUS_DROP;
2494 reply = GST_BUS_PASS;
2498 if (reply == GST_BUS_DROP)
2499 gst_message_unref(msg);
2504 static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet_h pkt)
2506 tbm_surface_h surface = NULL;
2508 mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
2511 LOGE("output is null");
2515 MMVideoBuffer *mm_vbuffer = NULL;
2516 mm_vbuffer = (MMVideoBuffer *)malloc(sizeof(MMVideoBuffer));
2518 LOGE("Failed to alloc MMVideoBuffer");
2521 memset(mm_vbuffer, 0x00, sizeof(MMVideoBuffer));
2523 media_packet_get_tbm_surface(pkt, &surface);
2524 bo = tbm_surface_internal_get_bo(surface, 0);
2526 tbm_bo_handle handle = tbm_bo_get_handle(bo, TBM_DEVICE_CPU);
2527 #ifdef TIZEN_PROFILE_LITE
2530 tbm_bo_handle handle_fd = tbm_bo_get_handle(bo, TBM_DEVICE_MM);
2532 if (__tbm_get_physical_addr_bo(handle_fd, &phy_addr, &phy_size) == 0) {
2533 mm_vbuffer->handle.paddr[0] = (void *)phy_addr;
2534 LOGD("mm_vbuffer->paddr : %p", mm_vbuffer->handle.paddr[0]);
2536 LOGD("paddr : %p", phy_addr);
2539 mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO;
2540 mm_vbuffer->handle.bo[0] = bo;
2541 mm_vbuffer->data[0] = handle.ptr;
2542 mm_vbuffer->width[0] = enc_info->width;
2543 mm_vbuffer->height[0] = enc_info->height;
2544 mm_vbuffer->stride_width[0] = mm_vbuffer->width[0];
2545 mm_vbuffer->stride_height[0] = mm_vbuffer->height[0];
2550 static void gst_mediacodec_buffer_finalize(GstMCBuffer *mc_buffer)
2555 mc_gst_core_t *core = (mc_gst_core_t *)mc_buffer->core;
2557 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
2558 ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
2559 (mc_buffer->pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
2562 LOGD("%p buffer finalized...", mc_buffer);
2569 static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t* core, media_packet_h pkt, uint64_t size)
2571 GstMCBuffer *mc_buffer = NULL;
2573 mc_buffer = (GstMCBuffer *)malloc(sizeof(*mc_buffer));
2575 if (mc_buffer == NULL) {
2576 LOGE("malloc fail");
2580 mc_buffer->buffer = gst_buffer_new();
2581 mc_buffer->buf_size = 0;
2583 LOGD("creating buffer : %p, %p", mc_buffer, mc_buffer->buffer);
2584 mc_buffer->core = core;
2585 mc_buffer->pkt = pkt;
2590 static gint __gst_handle_core_error(mc_gst_core_t *core, int code)
2592 gint trans_err = MEDIACODEC_ERROR_NONE;
2594 g_return_val_if_fail(core, MC_PARAM_ERROR);
2597 case GST_CORE_ERROR_MISSING_PLUGIN:
2598 return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
2599 case GST_CORE_ERROR_STATE_CHANGE:
2600 case GST_CORE_ERROR_SEEK:
2601 case GST_CORE_ERROR_NOT_IMPLEMENTED:
2602 case GST_CORE_ERROR_FAILED:
2603 case GST_CORE_ERROR_TOO_LAZY:
2604 case GST_CORE_ERROR_PAD:
2605 case GST_CORE_ERROR_THREAD:
2606 case GST_CORE_ERROR_NEGOTIATION:
2607 case GST_CORE_ERROR_EVENT:
2608 case GST_CORE_ERROR_CAPS:
2609 case GST_CORE_ERROR_TAG:
2610 case GST_CORE_ERROR_CLOCK:
2611 case GST_CORE_ERROR_DISABLED:
2613 trans_err = MEDIACODEC_ERROR_INVALID_STREAM;
2620 static gint __gst_handle_library_error(mc_gst_core_t *core, int code)
2622 gint trans_err = MEDIACODEC_ERROR_NONE;
2624 g_return_val_if_fail(core, MC_PARAM_ERROR);
2627 case GST_LIBRARY_ERROR_FAILED:
2628 case GST_LIBRARY_ERROR_TOO_LAZY:
2629 case GST_LIBRARY_ERROR_INIT:
2630 case GST_LIBRARY_ERROR_SHUTDOWN:
2631 case GST_LIBRARY_ERROR_SETTINGS:
2632 case GST_LIBRARY_ERROR_ENCODE:
2634 trans_err = MEDIACODEC_ERROR_INVALID_STREAM;
2642 static gint __gst_handle_resource_error(mc_gst_core_t *core, int code)
2644 gint trans_err = MEDIACODEC_ERROR_NONE;
2646 g_return_val_if_fail(core, MC_PARAM_ERROR);
2649 case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
2650 trans_err = MEDIACODEC_ERROR_NO_FREE_SPACE;
2652 case GST_RESOURCE_ERROR_WRITE:
2653 case GST_RESOURCE_ERROR_FAILED:
2654 case GST_RESOURCE_ERROR_SEEK:
2655 case GST_RESOURCE_ERROR_TOO_LAZY:
2656 case GST_RESOURCE_ERROR_BUSY:
2657 case GST_RESOURCE_ERROR_OPEN_WRITE:
2658 case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
2659 case GST_RESOURCE_ERROR_CLOSE:
2660 case GST_RESOURCE_ERROR_SYNC:
2661 case GST_RESOURCE_ERROR_SETTINGS:
2663 trans_err = MEDIACODEC_ERROR_INTERNAL;
2670 static gint __gst_handle_stream_error(mc_gst_core_t *core, GError* error, GstMessage * message)
2672 gint trans_err = MEDIACODEC_ERROR_NONE;
2674 g_return_val_if_fail(core, MC_PARAM_ERROR);
2675 g_return_val_if_fail(error, MC_PARAM_ERROR);
2676 g_return_val_if_fail(message, MC_PARAM_ERROR);
2678 switch (error->code) {
2679 case GST_STREAM_ERROR_FAILED:
2680 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
2681 case GST_STREAM_ERROR_DECODE:
2682 case GST_STREAM_ERROR_WRONG_TYPE:
2683 case GST_STREAM_ERROR_DECRYPT:
2684 case GST_STREAM_ERROR_DECRYPT_NOKEY:
2685 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
2686 trans_err = __gst_transform_gsterror(core, message, error);
2689 case GST_STREAM_ERROR_NOT_IMPLEMENTED:
2690 case GST_STREAM_ERROR_TOO_LAZY:
2691 case GST_STREAM_ERROR_ENCODE:
2692 case GST_STREAM_ERROR_DEMUX:
2693 case GST_STREAM_ERROR_MUX:
2694 case GST_STREAM_ERROR_FORMAT:
2696 trans_err = MEDIACODEC_ERROR_INVALID_STREAM;
2703 static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage * message, GError* error)
2705 gchar *src_element_name = NULL;
2706 GstElement *src_element = NULL;
2707 GstElementFactory *factory = NULL;
2708 const gchar *klass = NULL;
2711 src_element = GST_ELEMENT_CAST(message->src);
2713 goto INTERNAL_ERROR;
2715 src_element_name = GST_ELEMENT_NAME(src_element);
2716 if (!src_element_name)
2717 goto INTERNAL_ERROR;
2719 factory = gst_element_get_factory(src_element);
2721 goto INTERNAL_ERROR;
2723 klass = gst_element_factory_get_klass(factory);
2725 goto INTERNAL_ERROR;
2727 LOGD("error code=%d, msg=%s, src element=%s, class=%s\n",
2728 error->code, error->message, src_element_name, klass);
2730 switch (error->code) {
2731 case GST_STREAM_ERROR_DECODE:
2732 return MEDIACODEC_ERROR_INVALID_STREAM;
2735 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
2736 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
2737 case GST_STREAM_ERROR_WRONG_TYPE:
2738 return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
2741 case GST_STREAM_ERROR_FAILED:
2742 return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
2749 return MEDIACODEC_ERROR_INVALID_STREAM;
2752 return MEDIACODEC_ERROR_INTERNAL;
2755 static void _mc_gst_flush_buffers(mc_gst_core_t *core)
2757 int ret = MC_ERROR_NONE;
2759 MEDIACODEC_FENTER();
2760 _mc_gst_set_flush_input(core);
2761 ret = gst_pad_push_event(core->pipeline, gst_event_new_flush_start());
2762 if (ret != MC_ERROR_NONE) {
2763 LOGE("failed to send flush_start event");
2766 ret = gst_pad_push_event(core->pipeline, gst_event_new_flush_stop(TRUE));
2767 if (ret != MC_ERROR_NONE) {
2768 LOGE("failed to send flush_stop event");
2772 MEDIACODEC_FLEAVE();
2776 static void _mc_gst_set_flush_input(mc_gst_core_t *core)
2778 media_packet_h pkt = NULL;
2780 LOGI("_mc_gst_set_flush_input is called");
2781 while (pkt != mc_async_queue_pop_forced(core->available_queue->input)) {
2782 LOGD("%p pkt is poped");
2783 if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
2784 ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
2785 (pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
2789 mc_async_queue_flush(core->available_queue->input);
2790 core->queued_count = 0;
2793 static void _mc_gst_set_flush_output(mc_gst_core_t *core)
2795 media_packet_h pkt = NULL;
2797 MEDIACODEC_FENTER();
2798 g_mutex_lock(&core->ports[1]->mutex);
2800 while(!g_queue_is_empty(core->ports[1]->queue))
2802 pkt = g_queue_pop_head(core->ports[1]->queue);
2803 LOGD("outpkt in output_queue : %p", pkt);
2805 media_packet_destroy(pkt);
2806 LOGD("outpkt destroyed");
2810 core->dequeued_count = 0;
2811 g_mutex_unlock(&core->ports[1]->mutex);
2812 MEDIACODEC_FLEAVE();
2815 #ifdef TIZEN_PROFILE_LITE
2816 int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr, int *phy_size)
2818 int tbm_bo_handle_fd;
2822 tbm_bo_handle_fd = tbm_bo_handle_fd_t.u32;
2824 int open_flags = O_RDWR;
2827 struct ion_mmu_data mmu_data;
2828 struct ion_custom_data custom_data;
2830 mmu_data.fd_buffer = tbm_bo_handle_fd;
2831 custom_data.cmd = 4;
2832 custom_data.arg = (unsigned long)&mmu_data;
2834 ion_fd = open("/dev/ion", open_flags);
2836 LOGE("[tbm_get_physical_addr_bo] ion_fd open device failed");
2839 if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
2840 LOGE("[tbm_get_physical_addr_bo] ION_IOC_CUSTOM failed");
2845 *phy_addr = mmu_data.iova_addr;
2846 *phy_size = mmu_data.iova_size;
2850 LOGW("[tbm_get_physical_addr_bo] getting physical address is failed. phy_addr = 0");
2863 * Get tiled address of position(x,y)
2866 * width of tiled[in]
2869 * height of tiled[in]
2872 * x position of tield[in]
2875 * y position of tield[in]
2878 * address of tiled data
2880 static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
2882 int pixel_x_m1, pixel_y_m1;
2884 int linear_addr0, linear_addr1, bank_addr ;
2888 pixel_x_m1 = x_size - 1;
2889 pixel_y_m1 = y_size - 1;
2891 roundup_x = ((pixel_x_m1 >> 7) + 1);
2893 x_addr = x_pos >> 2;
2895 if ((y_size <= y_pos+32) && (y_pos < y_size) &&
2896 (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
2897 linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
2898 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
2900 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
2901 bank_addr = ((x_addr >> 4) & 0x1);
2903 bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
2905 linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
2906 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
2908 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
2909 bank_addr = ((x_addr >> 4) & 0x1);
2911 bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
2914 linear_addr0 = linear_addr0 << 2;
2915 trans_addr = (linear_addr1 << 13) | (bank_addr << 11) | linear_addr0;
2921 * Converts tiled data to linear
2922 * Crops left, top, right, buttom
2923 * 1. Y of NV12T to Y of YUV420P
2924 * 2. Y of NV12T to Y of YUV420S
2925 * 3. UV of NV12T to UV of YUV420S
2927 * @param yuv420_dest
2928 * Y or UV plane address of YUV420[out]
2931 * Y or UV plane address of NV12T[in]
2933 * @param yuv420_width
2934 * Width of YUV420[in]
2936 * @param yuv420_height
2937 * Y: Height of YUV420, UV: Height/2 of YUV420[in]
2946 * Crop size of right
2949 * Crop size of buttom
2951 static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src,
2952 int yuv420_width, int yuv420_height,
2953 int left, int top, int right, int buttom)
2956 int tiled_offset = 0, tiled_offset1 = 0;
2957 int linear_offset = 0;
2958 int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
2960 temp3 = yuv420_width-right;
2962 /* real width is greater than or equal 256 */
2964 for (i = top; i < yuv420_height-buttom; i += 1) {
2970 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
2971 tiled_offset = temp4-1;
2972 temp1 = ((yuv420_width+127)>>7)<<7;
2973 tiled_offset = tiled_offset*(temp1>>6);
2974 tiled_offset = tiled_offset+temp3;
2975 tiled_offset = tiled_offset+2;
2976 temp1 = (temp3>>2)<<2;
2977 tiled_offset = tiled_offset+temp1;
2978 tiled_offset = tiled_offset<<11;
2979 tiled_offset1 = tiled_offset+2048*2;
2982 temp2 = ((yuv420_height+31)>>5)<<5;
2983 if ((i + 32) < temp2) {
2984 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
2986 temp1 = (temp1>>2)<<2;
2987 tiled_offset = temp3+temp1;
2988 temp1 = ((yuv420_width+127)>>7)<<7;
2989 tiled_offset = tiled_offset+temp4*(temp1>>6);
2990 tiled_offset = tiled_offset<<11;
2991 tiled_offset1 = tiled_offset + 2048 * 6;
2994 /* even2 fomula: x+x_block_num*y */
2995 temp1 = ((yuv420_width+127)>>7)<<7;
2996 tiled_offset = temp4*(temp1>>6);
2997 tiled_offset = tiled_offset+temp3;
2998 tiled_offset = tiled_offset<<11;
2999 tiled_offset1 = tiled_offset+2048*2;
3005 tiled_offset = tiled_offset+64*(temp1);
3006 tiled_offset1 = tiled_offset1+64*(temp1);
3007 temp2 = yuv420_width-left-right;
3008 linear_offset = temp2*(i-top);
3009 temp3 = ((j+256)>>8)<<8;
3013 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
3014 temp2 = ((left+63)>>6)<<6;
3015 temp3 = ((yuv420_width-right)>>6)<<6;
3016 if (temp2 == temp3) {
3017 temp2 = yuv420_width-right-(64-temp1);
3019 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
3020 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
3021 memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
3022 linear_offset = linear_offset+256-temp1;
3023 } else if (temp3 > 128) {
3024 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
3025 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
3026 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
3027 linear_offset = linear_offset+192-temp1;
3028 } else if (temp3 > 64) {
3029 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
3030 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
3031 linear_offset = linear_offset+128-temp1;
3032 } else if (temp3 > 0) {
3033 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
3034 linear_offset = linear_offset+64-temp1;
3037 tiled_offset = tiled_offset+temp4*2048;
3040 temp2 = yuv420_width-right-256;
3041 for (; j <= temp2; j += 256) {
3042 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3043 tiled_offset1 = tiled_offset1+temp4*2048;
3044 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3045 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
3046 tiled_offset = tiled_offset+temp4*2048;
3047 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
3048 linear_offset = linear_offset+256;
3051 tiled_offset1 = tiled_offset1+temp4*2048;
3052 temp2 = yuv420_width-right-j;
3054 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3055 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3056 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
3057 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
3058 } else if (temp2 > 128) {
3059 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3060 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
3061 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
3062 } else if (temp2 > 64) {
3063 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3064 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
3066 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3069 } else if (temp1 >= 64) {
3070 for (i = top; i < (yuv420_height-buttom); i += 1) {
3072 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3073 temp2 = ((j+64)>>6)<<6;
3075 linear_offset = temp1*(i-top);
3077 tiled_offset = tiled_offset+temp4;
3078 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3079 linear_offset = linear_offset+temp2;
3081 if ((j+64) <= temp3) {
3082 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3083 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3084 linear_offset = linear_offset+64;
3087 if ((j+64) <= temp3) {
3088 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3089 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
3090 linear_offset = linear_offset+64;
3094 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3096 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
3100 for (i = top; i < (yuv420_height-buttom); i += 1) {
3101 linear_offset = temp1*(i-top);
3102 for (j = left; j < (yuv420_width - right); j += 2) {
3103 tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
3105 tiled_offset = tiled_offset+temp4;
3106 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
3107 linear_offset = linear_offset+2;
3113 void _mc_send_eos_signal(mc_gst_core_t *core)
3115 g_mutex_lock(&core->eos_mutex);
3117 g_cond_broadcast(&core->eos_cond);
3118 g_mutex_unlock(&core->eos_mutex);
3119 LOGD("send EOS signal");
3122 void _mc_wait_for_eos(mc_gst_core_t *core)
3124 g_mutex_lock(&core->eos_mutex);
3126 LOGD("waiting for EOS");
3128 g_cond_wait(&core->eos_cond, &core->eos_mutex);
3130 LOGD("received EOS");
3131 g_mutex_unlock(&core->eos_mutex);