Modify setting codec data when decoding aac 97/84297/2 accepted/tizen/common/20160818.144345 accepted/tizen/ivi/20160818.231820 accepted/tizen/mobile/20160818.231642 accepted/tizen/tv/20160818.231751 accepted/tizen/wearable/20160818.231721 submit/tizen/20160818.052348
authorSejun Park <sejun79.park@samsung.com>
Thu, 18 Aug 2016 02:11:18 +0000 (11:11 +0900)
committerSejun Park <sejun79.park@samsung.com>
Thu, 18 Aug 2016 02:14:17 +0000 (11:14 +0900)
Change-Id: I9ced203947d65837bf475ee0e8028f1cb0ad9586

include/media_codec_port_gst.h
packaging/capi-media-codec.spec
src/media_codec_port.c
src/media_codec_port_gst.c
test/media_codec_test.c

index 552162d..d4bbd89 100755 (executable)
@@ -53,6 +53,8 @@ extern "C" {
 #define AAC_CODECDATA_SIZE     16
 #define WMA_CODECDATA_SIZE     64
 #define VORBIS_CODECDATA_SIZE  4096
+#define MAXINUM_QNUM   15
+#define THRESHOLD_QNUM 5
 
 /* gst port layer */
 typedef struct _mc_gst_port_t mc_gst_port_t;
@@ -110,6 +112,7 @@ struct _mc_gst_core_t {
        GMutex eos_wait_mutex;
        GMutex prepare_lock;
        GMutex drain_lock;
+       GCond buffer_cond;
        GCond eos_cond;
        GCond eos_waiting_cond;
 
index 313794b..b4a17e3 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-codec
 Summary:    A Media Codec library in Tizen Native API
-Version:    0.4.2
+Version:    0.4.3
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index edb2d20..4508f33 100755 (executable)
@@ -176,7 +176,7 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
-                       MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+                       MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
 
        mc_handle->info.decoder.width = width;
        mc_handle->info.decoder.height = height;
@@ -200,7 +200,7 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
-                       MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+                       MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
 
        mc_handle->info.encoder.width = width;
        mc_handle->info.encoder.height = height;
@@ -225,7 +225,7 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
-                       MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+                       MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
 
        mc_handle->info.decoder.samplerate = samplerate;
        mc_handle->info.decoder.channel = channel;
@@ -249,7 +249,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
-                       MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+                       MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
 
        mc_handle->info.encoder.samplerate = samplerate;
        mc_handle->info.encoder.channel = channel;
index 24980cc..d2bad4b 100755 (executable)
@@ -68,7 +68,6 @@ static gint __gst_handle_resource_error(mc_gst_core_t *core, int code);
 static gint __gst_handle_library_error(mc_gst_core_t *core, int code);
 static gint __gst_handle_core_error(mc_gst_core_t *core, int code);
 static const gchar * _mc_error_to_string(mc_ret_e err);
-static int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); /* will remove */
 
 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw);
 #ifdef TIZEN_PROFILE_LITE
@@ -78,14 +77,15 @@ static int _mc_gst_flush_buffers(mc_gst_core_t *core);
 static void _mc_gst_set_flush_input(mc_gst_core_t *core);
 static void _mc_gst_set_flush_output(mc_gst_core_t *core);
 
+#ifdef TIZEN_EXYNOS_SPECIFIC
 static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);
 static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest,
                unsigned char *nv12t_src, int yuv420_width, int yuv420_height,
                int left, int top, int right, int buttom);
+#endif
 
 static void _mc_send_eos_signal(mc_gst_core_t *core);
 static void _mc_wait_for_eos(mc_gst_core_t *core);
-
 static int _mediacodec_get_mime(mc_gst_core_t *core);
 
 /* video vtable */
@@ -291,9 +291,8 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h
                                buf_size = stride_width * stride_height;
 
                                memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size);
-                               LOGD("width is same with stride");
-                               LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size);
                                mc_buffer->buf_size += buf_size;
+                               LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size);
 
                        }
                } else {
@@ -326,7 +325,6 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h
                MMVideoBuffer *mm_video_buffer = NULL;
 
                mm_video_buffer = __mc_gst_make_tbm_buffer(core, pkt);
-               /* mm_video_buffer = core->mc_get_mm_video_buffer(pkt); */
 
                gst_buffer_prepend_memory(mc_buffer->buffer,
                                gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_video_buffer, sizeof(MMVideoBuffer), 0,
@@ -367,10 +365,9 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in
 
        g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
 
-       if (!core->is_hw) {
-
-               mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+       mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
 
+       if (!core->is_hw) {
                width = dec_info->width;
                height = dec_info->height;
                stride_width = ALIGN(width, 4);
@@ -414,94 +411,51 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in
                tbm_bo_unmap(bo[0]);
 
                tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1);
-
-               if (tsurf) {
-                       media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
-                                       (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt);
-               }
-
        } else {
-               __mc_fill_video_packet_with_mm_video_buffer(core, data, size, pkt);
-               /* tsurf = core->get_tbm_surface(data); */
-       }
-/*
-       if (tsurf) {
-               media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
-                               (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt);
-       }
-*/
-       return MC_ERROR_NONE;
-}
+               int bo_num = 0;
+               MMVideoBuffer *mm_vbuffer = NULL;
+               mm_vbuffer = (MMVideoBuffer *)data;
 
-int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
-{
-       void *pkt_data = NULL;
-       MMVideoBuffer *mm_vbuffer = NULL;
-       int i;
-       int bo_num = 0;
-
-       g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
-
-       mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info;
-       mm_vbuffer = (MMVideoBuffer *)data;
-
-       LOGD("buf_share_method %d", mm_vbuffer->type);
-
-       LOGD("a[0] : %p, a[1] : %p, p[0] : %p, p[1] : %p",
-                       mm_vbuffer->data[0], mm_vbuffer->data[1], mm_vbuffer->handle.paddr[0], mm_vbuffer->handle.paddr[1]);
-       LOGD("s[0]:%d, e[0]:%d, w[0]:%d, h[0]:%d",
-                       mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], mm_vbuffer->width[0], mm_vbuffer->height[0]);
-
-       if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) {
-               media_packet_set_buffer_size(*out_pkt, mm_vbuffer->width[0]*mm_vbuffer->height[0]*3/2);
-               media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
-
-               __csc_tiled_to_linear_crop(pkt_data, mm_vbuffer->data[0],
-                               mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], 0, 0, 0, 0);
-               __csc_tiled_to_linear_crop(pkt_data+mm_vbuffer->stride_width[0]*mm_vbuffer->stride_height[0],
-                               mm_vbuffer->data[1], mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0]/2, 0, 0, 0, 0);
-       } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_DMABUF_FD) {
-               LOGD("FD type");
-       } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
-               tbm_surface_h tsurf = NULL;
-               tbm_surface_info_s tsurf_info;
-               memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
+               if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
+                       tbm_surface_info_s tsurf_info;
+                       memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
 
-               /* create tbm surface */
-               for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) {
-                       if (mm_vbuffer->handle.bo[i]) {
-                               bo_num++;
-                               tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
+                       /* create tbm surface */
+                       for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) {
+                               if (mm_vbuffer->handle.bo[i]) {
+                                       bo_num++;
+                                       tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
+                               }
                        }
-               }
-
-               if (bo_num > 0) {
-                       tsurf_info.width = codec_info->width;
-                       tsurf_info.height = codec_info->height;
-                       tsurf_info.format = TBM_FORMAT_NV12;        /* bo_format */
-                       tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12);
-                       tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12);
-                       tsurf_info.size = 0;
-
-                       for (i = 0; i < tsurf_info.num_planes; i++) {
-                               tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
-                               tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i];
-
-                               if (i < bo_num)
-                                       tsurf_info.planes[i].offset = 0;
-                               else
-                                       tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size;
 
-                               tsurf_info.size += tsurf_info.planes[i].size;
-                               LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size);
+                       if (bo_num > 0) {
+                               tsurf_info.width = dec_info->width;
+                               tsurf_info.height = dec_info->height;
+                               tsurf_info.format = TBM_FORMAT_NV12;        /* bo_format */
+                               tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12);
+                               tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12);
+                               tsurf_info.size = 0;
+
+                               for (i = 0; i < tsurf_info.num_planes; i++) {
+                                       tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i];
+                                       tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i];
+
+                                       if (i < bo_num)
+                                               tsurf_info.planes[i].offset = 0;
+                                       else
+                                               tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size;
+
+                                       tsurf_info.size += tsurf_info.planes[i].size;
+                                       LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size);
+                               }
+                               tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num);
                        }
-                       tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num);
                }
+       }
 
-               if (tsurf) {
-                       media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
-                                       (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, out_pkt);
-               }
+       if (tsurf) {
+               media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
+                               (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt);
        }
 
        return MC_ERROR_NONE;
@@ -513,6 +467,9 @@ int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int siz
        int ret = MC_ERROR_NONE;
        g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
 
+       if (core->encoder && core->codec_id == MEDIACODEC_AAC)
+               media_format_set_audio_aac_type(core->output_fmt, FALSE);
+
        ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt);
        if (ret != MEDIA_PACKET_ERROR_NONE) {
                LOGW("media_packet_create_alloc failed");
@@ -770,6 +727,8 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *buff, guint codecd
        void *buf_data = NULL;
        uint64_t buf_size = 0;
        GstBuffer *codecdata_buffer;
+       guint8 *data;
+       GstMapInfo map;
 
        ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
        if (ret != MEDIA_PACKET_ERROR_NONE) {
@@ -786,9 +745,11 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *buff, guint codecd
        LOGD("Set caps for codec_data in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
 
        /* Add the codec_data attribute to caps, if we have it */
-       codecdata_buffer = gst_buffer_new_and_alloc(codecdata_size);
-       gst_buffer_copy_into(codecdata_buffer, buff->buffer, GST_BUFFER_COPY_MEMORY, 0, codecdata_size);
-       gst_buffer_ref(codecdata_buffer);
+       data = g_malloc0(codecdata_size);
+       gst_buffer_map(buff->buffer, &map, GST_MAP_READ);
+       memcpy(data, map.data, codecdata_size);
+       codecdata_buffer = gst_buffer_new_wrapped(data, codecdata_size);
+       gst_buffer_unmap(buff->buffer, &map);
        LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size);
 
        gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
@@ -871,6 +832,7 @@ mc_gst_core_t *mc_gst_core_new()
 
        g_mutex_init(&core->eos_mutex);
        g_cond_init(&core->eos_cond);
+       g_cond_init(&core->buffer_cond);
        g_mutex_init(&core->prepare_lock);
        g_mutex_init(&core->drain_lock);
 
@@ -912,6 +874,7 @@ void mc_gst_core_free(mc_gst_core_t *core)
        g_mutex_clear(&core->prepare_lock);
        g_mutex_clear(&core->drain_lock);
        g_cond_clear(&core->eos_cond);
+       g_cond_clear(&core->buffer_cond);
 
        mc_async_queue_free(async_queue->input);
        g_free(async_queue);
@@ -944,7 +907,6 @@ mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
        port->buffers = NULL;
 
        g_mutex_init(&port->mutex);
-       g_cond_init(&port->buffer_cond);
        port->queue = g_queue_new();
 
        LOGD("gst_port(%p) is created", port);
@@ -958,7 +920,6 @@ void mc_gst_port_free(mc_gst_port_t *port)
        MEDIACODEC_FENTER();
 
        g_mutex_clear(&port->mutex);
-       g_cond_clear(&port->buffer_cond);
        g_queue_free(port->queue);
 
        LOGD("gst_port(%p) is freed", port);
@@ -1177,7 +1138,7 @@ static gpointer feed_task(gpointer data)
                        }
 
                        pad = gst_element_get_static_pad(core->appsrc, "src");
-                       gst_pad_push_event(pad, gst_event_new_stream_start("sejun"));
+                       gst_pad_push_event(pad, gst_event_new_stream_start("start"));
                        gst_object_unref(pad);
 
                        LOGD("caps updated");
@@ -1446,6 +1407,9 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo
                if (encoder) {
                        core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable;
                        core->caps = gst_caps_new_empty_simple("video/x-raw");
+#ifdef TIZEN_PROFILE_LITE
+                       g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
+#endif
                } else {
                        if (is_hw) {
                                core->vtable = vdec_h264_hw_vtable;
@@ -1647,19 +1611,25 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint
 
        int ret = MC_ERROR_NONE;
        mc_gst_core_t *core = NULL;
-       GTimeVal nowtv;
+       gint64 end_time;
 
        if (!mc_handle)
                return MC_PARAM_ERROR;
 
        core = (mc_gst_core_t *)mc_handle->core;
 
-       g_get_current_time(&nowtv);
-       g_time_val_add(&nowtv, 500 * 1000);   /* usec */
-       /*
-          if (!g_cond_timed_wait(&nowtv)) {
-          }
-          */
+       g_mutex_lock(&core->drain_lock);
+
+       while (g_atomic_int_get(&core->etb_count) > MAXINUM_QNUM) {
+               end_time = g_get_monotonic_time() + timeOutUs * G_TIME_SPAN_MILLISECOND;
+               LOGD("Waiting until packets are drained..");
+
+               if (!g_cond_wait_until(&core->buffer_cond, &core->drain_lock, end_time)) {
+                       LOGD("time out...");
+                       break;
+               }
+       }
+       g_mutex_unlock(&core->drain_lock);
 
        if (core->prepare_count == 0)
                return MC_INVALID_STATUS;
@@ -2695,6 +2665,7 @@ int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr,
 }
 #endif
 
+#if TIZEN_EXYNOS_SPECIFIC
 /*
  * Get tiled address of position(x,y)
  *
@@ -2947,6 +2918,7 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char
                }
        }
 }
+#endif
 
 void _mc_send_eos_signal(mc_gst_core_t *core)
 {
index 698a24d..37bb551 100755 (executable)
@@ -979,7 +979,7 @@ static void _mediacodec_process_input(App *app)
                        }
                        mc_hex_dump("inbuf", tmp, 48);
 
-                       ret = mediacodec_process_input(app->mc_handle[0], pkt, -1);
+                       ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
                        if (ret != MEDIACODEC_ERROR_NONE)
                                return;