From 9eb4807f1fef0bd18ae11264ef79498371cf62ac Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 25 Apr 2017 16:29:09 +0900 Subject: [PATCH 01/16] fixed build error and unresolved svace issues in unified version Change-Id: Idab4be2138bc8581eb4af0e3401ee9adad6f9a21 --- include/media_codec_port_gst.h | 3 ++- src/media_codec_port_gst.c | 10 +++++++--- test/media_codec_test.c | 14 ++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index d0aa50d..92b4eee 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -62,6 +62,7 @@ extern "C" { typedef struct _mc_gst_port_t mc_gst_port_t; typedef struct _mc_gst_core_t mc_gst_core_t; typedef struct _GstMCBuffer GstMCBuffer; +typedef struct _ion_mmu_data_t ion_mmu_data_t; typedef enum { BUF_SHARE_METHOD_PADDR = 0, @@ -71,7 +72,7 @@ typedef enum { } buf_share_method_t; #ifdef TIZEN_PROFILE_LITE -struct ion_mmu_data { +struct _ion_mmu_data_t { int master_id; int fd_buffer; unsigned long iova_addr; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index cb8f751..95fac10 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2425,6 +2425,11 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet int phy_addr = 0; int phy_size = 0; tbm_bo_handle handle_fd = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); + if (handle_fd == NULL) { + LOGE("Invaild bo handle"); + return NULL; + } + if (__tbm_get_physical_addr_bo(handle_fd, &phy_addr, &phy_size) == 0) { mm_vbuffer->handle.paddr[0] = (void *)phy_addr; LOGD("mm_vbuffer->paddr : %p", mm_vbuffer->handle.paddr[0]); @@ -2743,11 +2748,10 @@ int __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_ int open_flags = O_RDWR; int ion_fd = -1; - struct ion_mmu_data mmu_data; + ion_mmu_data_t mmu_data; struct ion_custom_data custom_data; - memset(&mmu_data, 0x0, sizeof(ion_mmu_data)); - memset(&custom_data, 0x0, sizeof(ion_custom_data)); + memset(&mmu_data, 0x0, sizeof(ion_mmu_data_t)); mmu_data.fd_buffer = handle_bo.u32; custom_data.cmd = 4; diff --git a/test/media_codec_test.c b/test/media_codec_test.c index e94e011..1f6096c 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -639,11 +639,6 @@ void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_fram return; } else { layer = 4 - ((header >> 17) & 0x3); - - if (layer < 1) { - *have_frame = FALSE; - return; - } } /* if it's an invalid bitrate */ @@ -783,6 +778,13 @@ void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, b read_size = readsize; app->offset += header_size + readsize; + if (app->offset > app->length) { + read_size = 0; + *have_frame = FALSE; + g_print("[FAIL] offset error \n"); + return; + } + } else { read_size = 0; g_print("[FAIL] Not found aac frame sync. \n"); @@ -1762,7 +1764,7 @@ static void interpret(char *cmd, App *app) { app->frame = atoi(cmd); - if (app->frame > 0) + if (app->frame > 0 && app->frame < 10) _mediacodec_process_input(app); reset_menu_state(); } -- 2.7.4 From 86060365022fb3ea999589d66356832d8fda0c0f Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 25 Apr 2017 20:40:26 +0900 Subject: [PATCH 02/16] modify checking null Change-Id: I4f84db66ff439bbdad845da2af532c09afaeea44 --- src/media_codec_port_gst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 95fac10..759117c 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2425,7 +2425,7 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet int phy_addr = 0; int phy_size = 0; tbm_bo_handle handle_fd = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); - if (handle_fd == NULL) { + if (handle_fd.ptr == NULL) { LOGE("Invaild bo handle"); return NULL; } -- 2.7.4 From bb4a4aa75c0dff0943bedac3a689d2876540ffc2 Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Mon, 10 Apr 2017 11:45:02 +0300 Subject: [PATCH 03/16] fixed build with -fno-common ASan build failed with variables redefinition. Change-Id: I61bab52f3e82745c5d8551fb9c1458e1fbdc7007 Signed-off-by: Slava Barinov --- src/media_codec_port.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 83b618f..f2afd34 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -25,9 +25,7 @@ #include #include #include - -mc_ini_t mc_ini; -mc_codec_spec_t spec_emul[MEDIA_CODEC_MAX_CODEC_TYPE]; +#include int mc_create(MMHandleType *mediacodec) { -- 2.7.4 From f5f5583413922963709c9a19736c33e1169eaf49 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 2 May 2017 17:27:02 +0900 Subject: [PATCH 04/16] Sync with tizen_3.0 and add to control buffer overflow Change-Id: Ia4d1007a9b6bc8e6cdd95cbc244b9bc621ff849b --- include/media_codec_port_gst.h | 2 + src/media_codec_port_gst.c | 129 ++++++++++++++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 26 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 92b4eee..98e93c0 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -127,6 +127,7 @@ struct _mc_gst_core_t { bool eos; bool eos_waiting; bool codec_config; + bool need_drain; bool need_feed; bool need_codec_data; bool need_sync_flag; @@ -165,6 +166,7 @@ int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuff int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); +int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 759117c..ae66a6e 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -57,7 +57,7 @@ static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer dat static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data); static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet); static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_h packet, uint64_t size); -static void gst_mediacodec_buffer_finalize(GstMCBuffer *buffer); +static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer); static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size); static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint codecdata_size); static void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet); @@ -134,10 +134,10 @@ int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_ int(*aenc_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Encoder vtable */ &__mc_fill_packet_with_output_buffer}; -int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Decoder Vtable */ +int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet, /* AAC LC Decoder Vtable */ &__mc_fill_packet_with_output_buffer}; -int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC HE Decoder Vtable */ +int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet, /* AAC HE Decoder Vtable */ &__mc_fill_packet_with_output_buffer}; int(*adec_mp3_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* MP3 Decoder Vtable */ @@ -202,7 +202,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pac if (buf_data != NULL) { gst_buffer_prepend_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, - buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); LOGD("packet data apended, %d, %d", buf_size, gst_buffer_n_memory(mcbuffer->buffer)); } return ret; @@ -229,13 +229,58 @@ int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packe if (buf_data != NULL) { gst_buffer_append_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, - buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); LOGD("packet data apended"); } return ret; } +int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) +{ + int ret = MC_ERROR_NONE; + void *buf_data = NULL; + uint64_t buf_size = 0; + bool codec_config = FALSE; + void *codec_data = NULL; + unsigned int codec_size = 0; + + ret = media_packet_get_buffer_size(packet, &buf_size); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("buffer size get failed"); + return MC_ERROR; + } + + ret = media_packet_get_buffer_data_ptr(packet, &buf_data); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("buffer data get failed"); + return MC_ERROR; + } + + if (media_packet_is_codec_config(packet, &codec_config) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_is_codec_config failed"); + return MC_ERROR; + } + + if (buf_data != NULL) { + media_packet_get_codec_data(packet, &codec_data, &codec_size); + + if (!codec_data && codec_config) { + gst_buffer_append_memory(mcbuffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, + buf_size, NULL, NULL)); + LOGD("csd packet data apended"); + } else { + gst_buffer_append_memory(mcbuffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); + LOGD("packet data apended"); + } + } + + return ret; +} + int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { int ret = MC_ERROR_NONE; @@ -335,7 +380,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h gst_buffer_prepend_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mcbuffer->buf_size, 0, - mcbuffer->buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + mcbuffer->buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); return ret; } @@ -750,15 +795,15 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint fi gst_buffer_map(mcbuffer->buffer, &map, GST_MAP_READ); memcpy(data, map.data, fixed_size); codecdata_buffer = gst_buffer_new_wrapped(data, fixed_size); - gst_buffer_unmap(mcbuffer->buffer, &map); gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL); gst_buffer_unref(codecdata_buffer); gst_buffer_replace_memory(mcbuffer->buffer, 0, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buff_data + fixed_size , buffer_size - fixed_size, 0, - buffer_size - fixed_size, mcbuffer, NULL)); + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, map.data + fixed_size , buffer_size - fixed_size, 0, + buffer_size - fixed_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); - LOGD("set codec data from packet: %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer)); + LOGD("after : set codec data from packet: %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer)); + gst_buffer_unmap(mcbuffer->buffer, &map); } } return ret; @@ -833,6 +878,7 @@ mc_gst_core_t *mc_gst_core_new() g_mutex_init(&core->prepare_lock); g_mutex_init(&core->drain_lock); + core->need_drain = false; core->need_feed = false; core->eos = false; core->need_codec_data = false; @@ -1626,7 +1672,6 @@ 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; - gint64 end_time; if (!mc_handle) return MC_PARAM_ERROR; @@ -1635,14 +1680,10 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint g_mutex_lock(&core->drain_lock); - while (g_atomic_int_get(&core->etb_count) > MAXINUM_QNUM) { - end_time = g_get_monotonic_time() + timeOutUs; + while (g_atomic_int_get(&core->etb_count) == MAXINUM_QNUM) { LOGD("Waiting until packets are drained.."); - - if (!g_cond_wait_until(&core->buffer_cond, &core->drain_lock, end_time)) { - LOGD("time out..."); - break; - } + core->need_drain = true; + g_cond_wait(&core->buffer_cond, &core->drain_lock); } g_mutex_unlock(&core->drain_lock); @@ -2254,17 +2295,23 @@ void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet if (core && core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) { ((mc_empty_buffer_cb)core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) (packet, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]); - } - if (core) - LOGD("@v(%d)e(%d) input port emptied buffer(%d): %p", core->video, core->encoder, core->etb_count, packet); + g_mutex_lock(&core->drain_lock); + + if (core->need_drain) { + LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder); + core->need_drain = false; + g_cond_signal(&core->buffer_cond); + } + g_mutex_unlock(&core->drain_lock); + } } gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { int ret = MC_ERROR_NONE; mc_gst_core_t *core = (mc_gst_core_t *)data; - LOGD("@%p v(%d)e(%d)", core, core->video, core->encoder); + LOGD("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); switch (GST_MESSAGE_TYPE(msg)) { @@ -2310,6 +2357,16 @@ gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) else LOGW("Unexpected error has occured"); + g_mutex_lock(&core->drain_lock); + + if (core->need_drain) { + LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder); + core->need_drain = false; + g_cond_signal(&core->buffer_cond); + } + + g_mutex_unlock(&core->drain_lock); + if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) { ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]); @@ -2356,7 +2413,7 @@ static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, mc_gst_core_t *core = (mc_gst_core_t *)data; GstBusSyncReply reply = GST_BUS_DROP; - LOGD("__mc_gst_bus_sync_callback is called"); + LOGD("__mc_gst_bus_sync_callback is called : %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); if (!core->pipeline) { LOGE("mediacodec pipeline handle is null"); @@ -2419,6 +2476,8 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet for (i = 0; i < num_bos; i++) { mm_vbuffer->handle.bo[i] = tbm_surface_internal_get_bo(surface, i); LOGD("mm_vbuffer->handle.bo[%d] : %p", i, mm_vbuffer->handle.bo[i]); + tbm_bo_map(mm_vbuffer->handle.bo[i], TBM_DEVICE_CPU, TBM_OPTION_READ); + tbm_bo_unmap(mm_vbuffer->handle.bo[i]); } #ifdef TIZEN_PROFILE_LITE @@ -2472,13 +2531,14 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet return mm_vbuffer; } -static void gst_mediacodec_buffer_finalize(GstMCBuffer *mcbuffer) +static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer) { MEDIACODEC_FENTER(); if (!mcbuffer) return; + LOGD("============>>>>> _finalize_cb : %p, %p", mcbuffer, mcbuffer->packet); mc_gst_core_t *core = (mc_gst_core_t *)mcbuffer->core; _mc_gst_handle_input_buffer_used(core, mcbuffer->packet); @@ -2684,6 +2744,23 @@ static int _mc_gst_flush_buffers(mc_gst_core_t *core) _mc_gst_set_flush_input(core); + LOGW("Trying send flush_start .... "); + event = gst_event_new_flush_start(); + ret = gst_element_send_event(core->appsrc, event); + if (ret != TRUE) { + LOGE("failed to send Flush_Start event"); + return MC_ERROR; + } + + LOGW("Trying send flush_stop .... "); + event = gst_event_new_flush_stop(TRUE); + ret = gst_element_send_event(core->appsrc, event); + if (ret != TRUE) { + LOGE("failed to send Flush_Stop event"); + return MC_ERROR; + } + + LOGW("Trying send seek .... "); event = gst_event_new_seek(1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1); @@ -2706,17 +2783,17 @@ static void _mc_gst_set_flush_input(mc_gst_core_t *core) media_packet_h packet = NULL; MEDIACODEC_FENTER(); - LOGI("_mc_gst_set_flush_input called"); + LOGI("_mc_gst_set_flush_input called : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count); while (!mc_async_queue_is_empty(core->available_queue->input)) { packet = mc_async_queue_pop_forced(core->available_queue->input); - g_atomic_int_dec_and_test(&core->etb_count); LOGD("%p poped(%d)", packet, core->etb_count); _mc_gst_handle_input_buffer_used(core, packet); } mc_async_queue_flush(core->available_queue->input); + LOGI("_mc_gst_set_flush_input ended : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count); MEDIACODEC_FLEAVE(); } -- 2.7.4 From 48b40d4ffd885b8a9444fa9e1b2140cd4c9b2a30 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 19 May 2017 17:20:10 +0900 Subject: [PATCH 05/16] Added audioconvert for supporting 16bit pcm when running audio encoder Change-Id: Ifc30775dc202210669112a677b64cb4147e7213e --- include/media_codec_port_gst.h | 3 + packaging/capi-media-codec.spec | 2 +- src/media_codec_ini.c | 3 + src/media_codec_port.c | 2 +- src/media_codec_port_gst.c | 155 ++++++++++++++++++++++++++++++++++++---- test/media_codec_test.c | 12 ++-- 6 files changed, 156 insertions(+), 21 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 98e93c0..84ff576 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -98,6 +98,7 @@ struct _mc_gst_core_t { gchar *format; GstElement *pipeline; GstElement *appsrc; + GstElement *audioconvert; GstElement *capsfilter; GstElement *parser; GstElement *fakesink; @@ -147,6 +148,7 @@ struct _mc_gst_core_t { GQueue *output_queue; void *codec_info; + GstBuffer *codec_data; void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; @@ -170,6 +172,7 @@ int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); +int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *packet); diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 6b69fe1..c58bbf9 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.3 +Version: 0.5.4 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_ini.c b/src/media_codec_ini.c index 1bc2c86..676ae83 100755 --- a/src/media_codec_ini.c +++ b/src/media_codec_ini.c @@ -227,6 +227,9 @@ media_format_mimetype_e _mc_convert_media_format_str_to_int(char *sformat) } else if (!strcmp(sformat, "PCM")) { iformat = MEDIA_FORMAT_PCM; goto endf; + } else if (!strcmp(sformat, "PCM_F32LE")) { + iformat = MEDIA_FORMAT_PCM_F32LE; + goto endf; } else if (!strcmp(sformat, "H261")) { iformat = MEDIA_FORMAT_H261; goto endf; diff --git a/src/media_codec_port.c b/src/media_codec_port.c index f2afd34..48760d6 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -682,7 +682,7 @@ int _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, { int ret = MEDIACODEC_NONE; int i; - int index; + int index = 0; gboolean codec[CODEC_NR_ITEMS] = {0,}; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index ae66a6e..9e93383 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,8 @@ 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 const gchar * _mc_bit_to_string(int bit); +static int _mc_get_support_bit_from_format(media_format_mimetype_e format); 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 @@ -88,7 +91,7 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, 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); +static int _mc_get_mime(mc_gst_core_t *core); /* video vtable */ int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; @@ -132,7 +135,7 @@ int(*aenc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_ int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; int(*aenc_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Encoder vtable */ - &__mc_fill_packet_with_output_buffer}; + &__mc_fill_aenc_packet_with_output_buffer}; int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet, /* AAC LC Decoder Vtable */ &__mc_fill_packet_with_output_buffer}; @@ -571,6 +574,63 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in return ret; } +int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet) +{ + int ret = MC_ERROR_NONE; + GstPad *pad; + GstCaps *peercaps; + const GValue *codec_data = NULL; + void *packet_data = NULL; + GstMapInfo map; + guint8 *ptr; + gsize len; + + 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_packet); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("media_packet_create_alloc failed"); + return MC_ERROR; + } + + media_packet_set_buffer_size(*out_packet, size); + media_packet_get_buffer_data_ptr(*out_packet, &packet_data); + memcpy(packet_data, data, size); + + if (!core->codec_data) { + pad = gst_element_get_static_pad(core->fakesink, "sink"); + peercaps = gst_pad_get_current_caps(pad); + if (peercaps) { + GstStructure *s; + if (gst_caps_is_empty(peercaps)) { + gst_caps_unref(peercaps); + gst_object_unref(pad); + LOGW("Empty caps"); + return ret; + } + + s = gst_caps_get_structure(peercaps, 0); + codec_data = gst_structure_get_value(s, "codec_data"); + core->codec_data = GST_BUFFER(g_value_dup_boxed(codec_data)); + gst_caps_unref(peercaps); + } + gst_object_unref(pad); + LOGD("codec data set"); + } + + if (core->codec_data) { + gst_buffer_map(core->codec_data, &map, GST_MAP_READ); + ptr = map.data; + len = map.size; + media_packet_set_codec_data(*out_packet, ptr, len); + gst_buffer_unmap(core->codec_data, &map); + } + + return ret; +} static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * name, GstBuffer * buf, ...) { @@ -827,10 +887,13 @@ int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, m media_format_set_video_height(core->output_fmt, info->height); media_format_set_video_avg_bps(core->output_fmt, info->bitrate); } else { + int support_bit = 0; + support_bit = _mc_get_support_bit_from_format(out_mime); + media_format_set_audio_mime(core->output_fmt, out_mime); media_format_set_audio_channel(core->output_fmt, info->channel); media_format_set_audio_samplerate(core->output_fmt, info->samplerate); - media_format_set_audio_bit(core->output_fmt, info->bit); + media_format_set_audio_bit(core->output_fmt, support_bit); media_format_set_audio_avg_bps(core->output_fmt, info->bitrate); } } else { @@ -887,6 +950,7 @@ mc_gst_core_t *mc_gst_core_new() core->prepare_count = 0; core->etb_count = 0; core->ftb_count = 0; + core->codec_data = NULL; g_atomic_int_set(&core->available_queue->running, 1); core->available_queue->thread = g_thread_new("feed thread", &feed_task, core); @@ -923,6 +987,9 @@ void mc_gst_core_free(mc_gst_core_t *core) mc_async_queue_free(async_queue->input); g_free(async_queue); + if (core->codec_data) + gst_buffer_unref(core->codec_data); + if (core->ports[1] != NULL) { mc_gst_port_free(core->ports[1]); core->ports[1] = NULL; @@ -1077,6 +1144,7 @@ static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; gst_caps_set_simple(core->caps, + "format", G_TYPE_STRING, _mc_bit_to_string(enc_info->bit), "rate", G_TYPE_INT, enc_info->samplerate, "channels", G_TYPE_INT, enc_info->channel, NULL); @@ -1280,7 +1348,6 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo if (encoder) { core->vtable = aenc_aac_vtable; core->caps = gst_caps_new_simple(core->mime, - "format", G_TYPE_STRING, "F32LE", "layout", G_TYPE_STRING, "interleaved", NULL); g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); } else { @@ -1903,6 +1970,15 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) goto ERROR; } + if (!core->video && core->encoder) { + core->audioconvert = gst_element_factory_make("audioconvert", NULL); + + if (!core->audioconvert) { + LOGE("capsfilter can't create"); + goto ERROR; + } + } + core->capsfilter = gst_element_factory_make("capsfilter", NULL); if (!core->capsfilter) { @@ -1919,12 +1995,22 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) g_object_set(core->fakesink, "enable-last-sample", FALSE, NULL); /*__mc_link_elements(core);*/ - gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL); + if (!core->video && core->encoder) { + gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->audioconvert, core->codec, core->fakesink, NULL); - /* link elements */ - if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL))) { - LOGE("gst_element_link_many is failed"); - goto ERROR; + /* link elements */ + if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->audioconvert, core->codec, core->fakesink, NULL))) { + LOGE("gst_element_link_many is failed"); + goto ERROR; + } + } else { + gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL); + + /* link elements */ + if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL))) { + LOGE("gst_element_link_many is failed"); + goto ERROR; + } } /* connect signals, bus watcher */ @@ -1971,6 +2057,9 @@ ERROR: if (core->capsfilter) gst_object_unref(GST_OBJECT(core->capsfilter)); + if (core->audioconvert) + gst_object_unref(GST_OBJECT(core->audioconvert)); + if (core->fakesink) gst_object_unref(GST_OBJECT(core->fakesink)); @@ -3185,7 +3274,47 @@ const gchar * _mc_error_to_string(mc_ret_e err) } } -int _mediacodec_get_mime(mc_gst_core_t *core) +const gchar * _mc_bit_to_string(int bit) +{ + switch (bit) { + case 16: + return "S16LE"; + case 32: + return "F32LE"; + default: + return "NULL"; + + } +} + +int _mc_get_support_bit_from_format(media_format_mimetype_e format) +{ + int bit = 0; + + switch (format) { + case MEDIA_FORMAT_PCM_S16LE: + case MEDIA_FORMAT_PCM_S16BE: + case MEDIA_FORMAT_PCM_U16LE: + case MEDIA_FORMAT_PCM_U16BE: + bit = 16; + break; + case MEDIA_FORMAT_PCM_S32LE: + case MEDIA_FORMAT_PCM_S32BE: + case MEDIA_FORMAT_PCM_U32LE: + case MEDIA_FORMAT_PCM_U32BE: + case MEDIA_FORMAT_PCM_F32LE: + case MEDIA_FORMAT_PCM_F32BE: + bit = 32; + break; + default: + LOGE("NOT SUPPORTED!!!!"); + break; + } + + return bit; +} + +int _mc_get_mime(mc_gst_core_t *core) { media_format_mimetype_e mime = MEDIA_FORMAT_MAX; @@ -3212,14 +3341,14 @@ int _mediacodec_get_mime(mc_gst_core_t *core) break; case MEDIACODEC_AAC: if (core->encoder) - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /*FIXME need to change PCM supported by chipset */ else mime = MEDIA_FORMAT_AAC; break; case MEDIACODEC_AAC_HE: if (core->encoder) - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to change PCM supported by chipset */ else mime = MEDIA_FORMAT_AAC_HE; @@ -3281,7 +3410,7 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pac return MC_ERROR; } - mime_format = _mediacodec_get_mime(core); + mime_format = _mc_get_mime(core); if (core->video) { if (core->encoder) { diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 1f6096c..67f0f68 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -873,7 +873,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) case MEDIACODEC_AAC: if (encoder) { extractor = aacenc_extractor; - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ } else { extractor = aacdec_extractor; mime = MEDIA_FORMAT_AAC; @@ -882,7 +882,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) case MEDIACODEC_AAC_HE: if (encoder) { extractor = aacenc_extractor; - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ } else { extractor = extract_input_aacdec_m4a_test; mime = MEDIA_FORMAT_AAC_HE; @@ -909,7 +909,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) case MEDIACODEC_AMR_NB: if (encoder) { extractor = amrenc_extractor; - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ app->is_amr_nb = TRUE; } else { extractor = amrdec_extractor; @@ -919,7 +919,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) case MEDIACODEC_AMR_WB: if (encoder) { extractor = amrenc_extractor; - mime = MEDIA_FORMAT_PCM; + mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ app->is_amr_nb = FALSE; } else { extractor = amrdec_extractor; @@ -1244,10 +1244,10 @@ static bool _mediacodec_eos_cb(void *user_data) return TRUE; } -void _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) +gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) { g_print("codec type : %x %s\n", codec_type, codec_type_to_string(codec_type)); - return; + return TRUE; } static void _mediacodec_prepare(App *app, bool frame_all) -- 2.7.4 From 69dd0f486e53d400c726bf18b94d23026ccfeb87 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 9 Jun 2017 12:38:10 +0900 Subject: [PATCH 06/16] removed unused code Change-Id: Ieca797efb30634bcfd742caba63434074a70406d --- include/media_codec.h | 0 include/media_codec_bitstream.h | 0 include/media_codec_ini.h | 0 include/media_codec_internal.h | 0 include/media_codec_port.h | 0 include/media_codec_port_gst.h | 0 include/media_codec_private.h | 0 include/media_codec_queue.h | 0 include/media_codec_spec_emul.h | 0 include/media_codec_util.h | 10 +- src/media_codec.c | 0 src/media_codec_bitstream.c | 0 src/media_codec_ini.c | 0 src/media_codec_internal.c | 0 src/media_codec_port.c | 0 src/media_codec_port_gst.c | 0 src/media_codec_queue.c | 0 src/media_codec_util.c | 0 test/media_codec_test.c | 403 ++++++++++++++++------------------------ 19 files changed, 166 insertions(+), 247 deletions(-) mode change 100755 => 100644 include/media_codec.h mode change 100755 => 100644 include/media_codec_bitstream.h mode change 100755 => 100644 include/media_codec_ini.h mode change 100755 => 100644 include/media_codec_internal.h mode change 100755 => 100644 include/media_codec_port.h mode change 100755 => 100644 include/media_codec_port_gst.h mode change 100755 => 100644 include/media_codec_private.h mode change 100755 => 100644 include/media_codec_queue.h mode change 100755 => 100644 include/media_codec_spec_emul.h mode change 100755 => 100644 include/media_codec_util.h mode change 100755 => 100644 src/media_codec.c mode change 100755 => 100644 src/media_codec_bitstream.c mode change 100755 => 100644 src/media_codec_ini.c mode change 100755 => 100644 src/media_codec_internal.c mode change 100755 => 100644 src/media_codec_port.c mode change 100755 => 100644 src/media_codec_port_gst.c mode change 100755 => 100644 src/media_codec_queue.c mode change 100755 => 100644 src/media_codec_util.c mode change 100755 => 100644 test/media_codec_test.c diff --git a/include/media_codec.h b/include/media_codec.h old mode 100755 new mode 100644 diff --git a/include/media_codec_bitstream.h b/include/media_codec_bitstream.h old mode 100755 new mode 100644 diff --git a/include/media_codec_ini.h b/include/media_codec_ini.h old mode 100755 new mode 100644 diff --git a/include/media_codec_internal.h b/include/media_codec_internal.h old mode 100755 new mode 100644 diff --git a/include/media_codec_port.h b/include/media_codec_port.h old mode 100755 new mode 100644 diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h old mode 100755 new mode 100644 diff --git a/include/media_codec_private.h b/include/media_codec_private.h old mode 100755 new mode 100644 diff --git a/include/media_codec_queue.h b/include/media_codec_queue.h old mode 100755 new mode 100644 diff --git a/include/media_codec_spec_emul.h b/include/media_codec_spec_emul.h old mode 100755 new mode 100644 diff --git a/include/media_codec_util.h b/include/media_codec_util.h old mode 100755 new mode 100644 index 988a54a..5dde410 --- a/include/media_codec_util.h +++ b/include/media_codec_util.h @@ -55,10 +55,12 @@ void mc_sem_up(mc_sem_t *sem); void mc_hex_dump(char *desc, void *addr, int len); -#define MC_FREEIF(x) \ - if (x) \ - g_free(x); \ - x = NULL; +#define MC_FREEIF(x) \ + do { \ + if (x) \ + g_free(x); \ + x = NULL; \ + } while(0) #ifdef __cplusplus } diff --git a/src/media_codec.c b/src/media_codec.c old mode 100755 new mode 100644 diff --git a/src/media_codec_bitstream.c b/src/media_codec_bitstream.c old mode 100755 new mode 100644 diff --git a/src/media_codec_ini.c b/src/media_codec_ini.c old mode 100755 new mode 100644 diff --git a/src/media_codec_internal.c b/src/media_codec_internal.c old mode 100755 new mode 100644 diff --git a/src/media_codec_port.c b/src/media_codec_port.c old mode 100755 new mode 100644 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c old mode 100755 new mode 100644 diff --git a/src/media_codec_queue.c b/src/media_codec_queue.c old mode 100755 new mode 100644 diff --git a/src/media_codec_util.c b/src/media_codec_util.c old mode 100755 new mode 100644 diff --git a/test/media_codec_test.c b/test/media_codec_test.c old mode 100755 new mode 100644 index 67f0f68..9c35563 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -58,7 +60,7 @@ #define AAC_CODECDATA_SIZE 16 #define USE_POOL 1 -unsigned char buf_adts[ADTS_HEADER_SIZE]; +guint8 buf_adts[ADTS_HEADER_SIZE]; enum { MC_EXIST_SPS = 1 << 0, @@ -125,18 +127,18 @@ struct _App { gint obj; GTimer *timer; - long start; - long finish; - long process_time; - int frame_count; - - int codecid; - int flag; - bool is_video; - bool is_encoder; - bool hardware; - bool enable_dump; - int frame; + glong start; + glong finish; + glong process_time; + gint frame_count; + + gint codecid; + gint flag; + gboolean is_video; + gboolean is_encoder; + gboolean hardware; + gboolean enable_dump; + gint frame; type_e type; camera_h camera_handle; /* video */ @@ -152,7 +154,7 @@ struct _App { guint channel; guint bit; guint bitrate; - bool is_amr_nb; + gboolean is_amr_nb; /* Render */ @@ -172,24 +174,24 @@ media_format_h fmt = NULL; media_packet_pool_h pkt_pool = NULL; /* Internal Functions */ -static int _create_app(void *data); -static int _terminate_app(void *data); +static gint _create_app(void *data); +static gint _terminate_app(void *data); static void displaymenu(void); static void display_sub_basic(); static void _mediacodec_unprepare(App *app); /* For debugging */ -static void mc_hex_dump(char *desc, void *addr, int len); +static void mc_hex_dump(char *desc, void *addr, gint len); static void decoder_output_dump(App *app, media_packet_h pkt); static void output_dump(App *app, media_packet_h pkt); /* */ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id); -void (*extractor)(App *app, unsigned char** data, int *size, bool *have_frame); +void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data); -int g_menu_state = CURRENT_STATUS_MAINMENU; +gint g_menu_state = CURRENT_STATUS_MAINMENU; -static int _create_app(void *data) +static gint _create_app(void *data) { g_print("My app is going alive!\n"); App *app = (App*)data; @@ -198,7 +200,7 @@ static int _create_app(void *data) return 0; } -static int _terminate_app(void *data) +static gint _terminate_app(void *data) { g_print("My app is going gone!\n"); App *app = (App*)data; @@ -231,18 +233,18 @@ static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000}, {11025, 12000, 8000} }; -void h264_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void h264_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data) { - unsigned char val, zero_count; - unsigned char *pNal = app->data + app->offset; - int max = app->length - app->offset; - int index = 0; - int nal_unit_type = 0; - bool init; - bool slice; - bool idr; - static int state; - int read; + guint8 val, zero_count; + guint8 *pNal = app->data + app->offset; + gint max = app->length - app->offset; + gint index = 0; + gint nal_unit_type = 0; + gboolean init; + gboolean slice; + gboolean idr; + static gint state; + gint read; zero_count = 0; @@ -328,12 +330,12 @@ DONE: app->offset += read; } -void h263_extractor(App * app, unsigned char **data, int *size, bool * have_frame) +void h263_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data) { int len = 0; int read_size = 1, state = 1, bStart = 0; - unsigned char val; - unsigned char *pH263 = app->data + app->offset; + guint8 val; + guint8 *pH263 = app->data + app->offset; *data = pH263; int max = app->length - app->offset; @@ -373,13 +375,13 @@ void h263_extractor(App * app, unsigned char **data, int *size, bool * have_fram *have_frame = TRUE; } -void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_frame) +void mpeg4_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data) { int len = 0; int result = 0; int state = 1, bType = 0; - unsigned char val; - unsigned char *pMpeg4 = app->data + app->offset; + guint8 val; + guint8 *pMpeg4 = app->data + app->offset; *data = pMpeg4; int max = app->length - app->offset; @@ -435,20 +437,20 @@ void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_fra * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits **/ -int write_amr_header = 1; /* write magic number for AMR Header at one time */ -static const char AMR_header[] = "#!AMR\n"; -static const char AMRWB_header[] = "#!AMR-WB\n"; +gint write_amr_header = 1; /* write magic number for AMR Header at one time */ +static const gchar AMR_header[] = "#!AMR\n"; +static const gchar AMRWB_header[] = "#!AMR-WB\n"; #define AMR_NB_MIME_HDR_SIZE 6 #define AMR_WB_MIME_HDR_SIZE 9 -static const int block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; -static const int block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 }; +static const gint block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; +static const gint block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 }; -int *blocksize_tbl; -void amrdec_extractor(App * app, unsigned char **data, int *size, bool * have_frame) +gint *blocksize_tbl; +void amrdec_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data) { - int readsize = 0, mode_temp; - unsigned int fsize, mode; - unsigned char *pAmr = app->data + app->offset; + gint readsize = 0, mode_temp; + gint fsize, mode; + guint8 *pAmr = app->data + app->offset; /* change the below one to frame count */ if (app->offset == 0) { if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) { @@ -484,10 +486,10 @@ void amrdec_extractor(App * app, unsigned char **data, int *size, bool * have_fr *have_frame = TRUE; } -void nv12_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void nv12_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data) { - int yuv_size; - int offset = app->length - app->offset; + gint yuv_size; + gint offset = app->length - app->offset; yuv_size = app->width * app->height * 3 / 2; @@ -497,16 +499,18 @@ void nv12_extractor(App *app, unsigned char **data, int *size, bool *have_frame) *have_frame = TRUE; *data = app->data + app->offset; - if (offset >= yuv_size) + if (yuv_size >= offset) *size = offset; else *size = yuv_size; + + app->offset += *size; } -void yuv_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void yuv_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data) { - int yuv_size; - int offset = app->length - app->offset; + gint yuv_size; + gint offset = app->length - app->offset; yuv_size = app->width * app->height * 3 / 2; @@ -522,13 +526,12 @@ void yuv_extractor(App *app, unsigned char **data, int *size, bool *have_frame) *size = yuv_size; app->offset += *size; - } -void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data) { - int read_size; - int offset = app->length - app->offset; + gint read_size; + gint offset = app->length - app->offset; read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2); @@ -543,10 +546,10 @@ void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_fram app->offset += *size; } -void amrenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void amrenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data) { - int read_size; - int offset = app->length - app->offset; + gint read_size; + gint offset = app->length - app->offset; if (app->is_amr_nb) read_size = AMRNB_PCM_INPUT_SIZE; @@ -569,11 +572,11 @@ void amrenc_extractor(App *app, unsigned char **data, int *size, bool *have_fram * (case of (LC profile) ADTS format) * codec_data : Don't need **/ -void aacdec_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void aacdec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data) { int read_size; int offset = app->length - app->offset; - unsigned char *pData = app->data + app->offset; + guint8 *pData = app->data + app->offset; if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) { read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5); @@ -591,17 +594,16 @@ void aacdec_extractor(App *app, unsigned char **data, int *size, bool *have_fram *size = read_size; app->offset += *size; - } -void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_frame) +void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data) { - int read_size; + gint read_size; guint header; guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0; guint hdr_bitrate = 0, sf = 0; - int offset = app->length - app->offset; - unsigned char *pData = app->data + app->offset; + gint offset = app->length - app->offset; + guint8 *pData = app->data + app->offset; header = GST_READ_UINT32_BE(pData); @@ -693,117 +695,11 @@ void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_fram app->offset += *size; } -#if 1 -void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, bool * have_frame) -{ - int readsize = 0, read_size = 0; - unsigned int header_size = ADTS_HEADER_SIZE; - unsigned char buffer[100000]; - unsigned char codecdata[AAC_CODECDATA_SIZE] = { 0, }; - int offset = app->length - app->offset; - unsigned char *pData = app->data + app->offset; - /* - * It is not support full parsing MP4 container box. - * So It MUST start as RAW valid frame sequence. - * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER. - */ - - /* change the below one later */ - if (app->offset == 0) { - /* - * CAUTION : Codec data is needed only once in first time - * Codec data is made(or extracted) by MP4 demuxer in 'esds' box. - * So I use this data (byte) as hard coding for temporary our testing. - */ -#if 1 - /* - * The codec_data data is according to AudioSpecificConfig, - * ISO/IEC 14496-3, 1.6.2.1 - * - * below example is test for using "test.aac" or "TestSample-AAC-LC.m4a" - * case : M4A - LC profile - * codec_data=(buffer)119056e5000000000000000000000000 - * savs aac decoder get codec_data. size: 16 (Tag size : 5 byte) - * - codec data: profile : 2 - * - codec data: samplrate: 48000 - * - codec data: channels : 2 - */ - /* 2 bytes are mandatory */ - codecdata[0] = 0x11; /* ex) (5bit) 2 (LC) / (4bit) 3 (48khz)*/ - codecdata[1] = 0x90; /* ex) (4bit) 2 (2ch) */ - /* othter bytes are (optional) epconfig information */ - codecdata[2] = 0x56; - codecdata[3] = 0xE5; - codecdata[4] = 0x00; -#else - /* - * below example is test for using "TestSample-EAAC+.m4a" - * - * case : M4A - HE-AAC v1 and v2 profile - * codec_data=(buffer)138856e5a54880000000000000000000 - * savs aac decoder get codec_data. size: 16 (Tag size : 7 byte) - * - codec data: profile : 2 - * - codec data: samplrate: 22050 - * - codec data: channels : 1 - */ - /* 2 bytes are mandatory */ - codecdata[0] = 0x13; /* ex) (5bit) 2 (LC) / (4bit) 9 (22khz) */ - codecdata[1] = 0x88; /* ex) (4bit) 1 (1ch) */ - /* othter bytes are (optional) epconfig information */ - codecdata[2] = 0x56; - codecdata[3] = 0xE5; - codecdata[4] = 0xA5; - codecdata[5] = 0x48; - codecdata[6] = 0x80; -#endif - - memcpy(buffer, codecdata, AAC_CODECDATA_SIZE); - if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) { - read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5); - } else { - read_size = 0; - g_print("[FAIL] Not found aac frame sync.....\n"); - } - readsize = read_size - header_size; - memcpy(buffer + AAC_CODECDATA_SIZE, pData + 7, readsize); - read_size = readsize + AAC_CODECDATA_SIZE; /* return combination of (codec_data + raw_data) */ - app->offset += header_size + readsize; - goto DONE; - } - - if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) { - read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5); - readsize = read_size - header_size; - memcpy(buffer, pData + 7, readsize); /* Make only RAW data, so exclude header 7 bytes */ - read_size = readsize; - app->offset += header_size + readsize; - - if (app->offset > app->length) { - read_size = 0; - *have_frame = FALSE; - g_print("[FAIL] offset error \n"); - return; - } - - } else { - read_size = 0; - g_print("[FAIL] Not found aac frame sync. \n"); - } - DONE: - *data = buffer; - *have_frame = TRUE; - if (read_size >= offset) - *size = offset; - else - *size = read_size; -} -#endif - /** * Extract Input data for AAC encoder **/ /* - void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame) + void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame) { int read_size; int offset = app->length - app->offset; @@ -824,19 +720,9 @@ void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, b app->offset += *size; } */ -#if 0 -static void _mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data) -{ - if (pkt != NULL) { - g_print("Used input buffer = %p\n", pkt); - media_packet_destroy(pkt); - } - return; -} -#endif -int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) +int _configure(App *app, int codecid, int flag, gboolean *hardware) { - bool encoder; + gboolean encoder; media_format_mimetype_e mime = 0; encoder = GET_IS_ENCODER(flag) ? 1 : 0; *hardware = GET_IS_HW(flag) ? 1 : 0; @@ -883,9 +769,6 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) if (encoder) { extractor = aacenc_extractor; mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ - } else { - extractor = extract_input_aacdec_m4a_test; - mime = MEDIA_FORMAT_AAC_HE; } break; case MEDIACODEC_AAC_HE_PS: @@ -935,22 +818,23 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) static void _mediacodec_process_input(App *app) { - int i; - bool have_frame = FALSE; - int ret; + gint i; + gboolean have_frame = FALSE; + gint ret; static guint64 pts = 0L; void *buf_data_ptr = NULL; media_packet_h pkt = NULL; - unsigned char *tmp; - int read; - int size; - int offset; - int stride_width; + guint8 *tmp; + gint read; + gint size; + gint offset; + gint stride_width; + gboolean codec_config = FALSE; for (i = 0; i < app->frame; i++) { g_print("----------read data------------\n"); - extractor(app, &tmp, &read, &have_frame); + extractor(app, &tmp, &read, &have_frame, &codec_config); if (have_frame) { #ifdef USE_POOL @@ -973,7 +857,6 @@ static void _mediacodec_process_input(App *app) if (app->type != VIDEO_ENC) { media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr); media_packet_set_buffer_size(pkt, (uint64_t)read); - memcpy(buf_data_ptr, tmp, read); g_print("tmp:%p, read:%d\n", tmp, read); } else { @@ -1037,17 +920,18 @@ static void _mediacodec_process_input(App *app) static gboolean read_data(App *app) { guint len = 0; - bool have_frame = FALSE; - int ret; + gboolean have_frame = FALSE; + gboolean codec_config = FALSE; + gint ret; static guint64 pts = 0L; void *buf_data_ptr = NULL; media_packet_h pkt = NULL; - unsigned char *tmp; - int i; - int read; - int size; - int offset; - int stride_width; + guint8 *tmp; + gint i; + gint read; + gint size; + gint offset; + gint stride_width; if (app->offset == 0) { app->frame_count = 0; @@ -1055,7 +939,7 @@ static gboolean read_data(App *app) } g_print("----------read data------------\n"); - extractor(app, &tmp, &read, &have_frame); + extractor(app, &tmp, &read, &have_frame, &codec_config); if (app->offset >= app->length - 4) { /* EOS */ @@ -1185,7 +1069,7 @@ static gboolean _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data) return TRUE; } -static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) +static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) { media_packet_h out_pkt = NULL; int ret; @@ -1220,7 +1104,7 @@ static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) return TRUE; } -static bool _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data) +static gboolean _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data) { g_print("_mediacodec_buffer_status_cb %d\n", status); @@ -1234,12 +1118,12 @@ static bool _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_ return TRUE; } -static bool _mediacodec_error_cb(mediacodec_error_e error, void *user_data) +static gboolean _mediacodec_error_cb(mediacodec_error_e error, void *user_data) { return TRUE; } -static bool _mediacodec_eos_cb(void *user_data) +static gboolean _mediacodec_eos_cb(void *user_data) { return TRUE; } @@ -1250,7 +1134,7 @@ gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) return TRUE; } -static void _mediacodec_prepare(App *app, bool frame_all) +static void _mediacodec_prepare(App *app, gboolean frame_all) { int ret; @@ -1271,7 +1155,8 @@ static void _mediacodec_prepare(App *app, bool frame_all) return; } - app->mime = _mediacodec_set_codec(app, app->codecid, app->flag, &app->hardware); + /* get mime and link to each codec parser */ + app->mime = _configure(app, app->codecid, app->flag, &app->hardware); /* set codec info */ ret = media_format_create(&fmt); @@ -1332,7 +1217,7 @@ static void _mediacodec_prepare(App *app, bool frame_all) } -/* get packet pool instance */ + /* get packet pool instance */ ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool); if (ret != MEDIA_PACKET_ERROR_NONE) { g_print("mediacodec_get_packet_pool failed\n"); @@ -1493,7 +1378,7 @@ void quit_program(App *app) { media_format_unref(fmt); g_main_loop_quit(app->loop); - elm_exit(); + exit(0); } @@ -1505,7 +1390,7 @@ void reset_menu_state() void _interpret_main_menu(char *cmd, App *app) { - int len = strlen(cmd); + gint len = strlen(cmd); if (len == 1) { if (strncmp(cmd, "a", 1) == 0) g_menu_state = CURRENT_STATUS_FILENAME; @@ -1619,8 +1504,11 @@ gboolean timeout_menu_display(void* data) } -static void interpret(char *cmd, App *app) +static void interpret(char *cmd) { + App *app = &s_app; + gint tmp = 0; + switch (g_menu_state) { case CURRENT_STATUS_MAINMENU: _interpret_main_menu(cmd, app); @@ -1631,9 +1519,8 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_SET_CODEC: { - int tmp; - static int cnt = 0; - char **ptr = NULL; + static gint cnt = 0; + gchar **ptr = NULL; switch (cnt) { case 0: tmp = atoi(cmd); @@ -1662,7 +1549,7 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_SET_VDEC_INFO: { - static int cnt = 0; + static gint cnt = 0; switch (cnt) { case 0: app->width = atoi(cmd); @@ -1682,7 +1569,7 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_SET_VENC_INFO: { - static int cnt = 0; + static gint cnt = 0; switch (cnt) { case 0: app->width = atoi(cmd); @@ -1710,7 +1597,7 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_SET_ADEC_INFO: { - static int cnt = 0; + static gint cnt = 0; switch (cnt) { case 0: app->samplerate = atoi(cmd); @@ -1737,20 +1624,48 @@ static void interpret(char *cmd, App *app) static int cnt = 0; switch (cnt) { case 0: - app->samplerate = atoi(cmd); + tmp = atoi(cmd); + + if (tmp <= 0 || tmp > 96000) { + g_print("Invalid value\n"); + reset_menu_state(); + break; + } + app->samplerate = tmp; cnt++; break; case 1: - app->channel = atoi(cmd); + tmp = atoi(cmd); + + if (tmp <= 0 || tmp > 6) { + g_print("Invalid value\n"); + reset_menu_state(); + break; + } + app->channel = tmp; cnt++; break; case 2: - app->bit = atoi(cmd); + tmp = atoi(cmd); + + if (tmp <= 0 || tmp > 32) { + g_print("Invalid value\n"); + reset_menu_state(); + break; + } + app->bit = tmp; cnt++; break; case 3: - app->bitrate = atoi(cmd); + tmp = atoi(cmd); + + if (tmp <= 0 || tmp > INT_MAX) { + g_print("Invalid value\n"); + reset_menu_state(); + break; + } app->type = AUDIO_ENC; + app->bitrate = tmp; reset_menu_state(); cnt = 0; @@ -1762,10 +1677,16 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_PROCESS_INPUT: { - app->frame = atoi(cmd); + tmp = atoi(cmd); + + if (tmp <= 0 || tmp > INT_MAX) { + g_print("Invalid value\n"); + reset_menu_state(); + break; + } + app->frame = tmp; - if (app->frame > 0 && app->frame < 10) - _mediacodec_process_input(app); + _mediacodec_process_input(app); reset_menu_state(); } break; @@ -1814,33 +1735,29 @@ gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data) gchar buf[MAX_STRING_LEN]; gsize read; GError *error = NULL; - App *context = (App*)data; g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error); buf[read] = '\0'; g_strstrip(buf); - interpret(buf, context); + interpret(buf); return TRUE; } int main(int argc, char *argv[]) { - App *app = &s_app; - GIOChannel *stdin_channel; stdin_channel = g_io_channel_unix_new(0); g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, app); + g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL); + App *app = &s_app; displaymenu(); app->loop = g_main_loop_new(NULL, TRUE); app->timer = g_timer_new(); g_main_loop_run(app->loop); - - ops.data = app; return appcore_efl_main(PACKAGE, &argc, &argv, &ops); @@ -1848,11 +1765,11 @@ int main(int argc, char *argv[]) -void mc_hex_dump(char *desc, void *addr, int len) +void mc_hex_dump(char *desc, void *addr, gint len) { int i; - unsigned char buff[17]; - unsigned char *pc = (unsigned char *)addr; + guint8 buff[17]; + guint8 *pc = (guint8 *)addr; if (desc != NULL) g_print("%s:\n", desc); -- 2.7.4 From fa0614f96adabea984e403471519b3fc2faef5f6 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 19 Jun 2017 11:37:30 +0900 Subject: [PATCH 07/16] Added tc for integration test Change-Id: I13d0659212d3ef8e2022a6ddb9e5319e3f58986e --- packaging/capi-media-codec.spec | 3 +- test/CMakeLists.txt | 2 +- test/media_codec_test.c | 611 +++++++++++++++++++++++++++++++++++----- 3 files changed, 543 insertions(+), 73 deletions(-) mode change 100755 => 100644 packaging/capi-media-codec.spec diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec old mode 100755 new mode 100644 index c58bbf9..8b18995 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.4 +Version: 0.5.5 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -23,6 +23,7 @@ BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) BuildRequires: pkgconfig(gstreamer-app-1.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(capi-mediademuxer) %description A Media Codec library in Tizen Native API diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d3e0022..754b501 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(../include/headers) link_directories(${CMAKE_SOURCE_DIR}/../) INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera) +pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera capi-mediademuxer) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 9c35563..bb61c69 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -31,6 +31,7 @@ #include #include #include +#include #define PACKAGE "media_codec_test" #define MAX_HANDLE 4 @@ -58,7 +59,7 @@ ((state & (expected_state)) == (expected_state)) #define AAC_CODECDATA_SIZE 16 -#define USE_POOL 1 +#define USE_POOL 0 guint8 buf_adts[ADTS_HEADER_SIZE]; @@ -90,6 +91,7 @@ enum { CURRENT_STATUS_GET_OUTPUT, CURRENT_STATUS_RESET_OUTPUT_BUFFER, CURRENT_STATUS_SET_SIZE, + CURRENT_STATUS_AUTO_TEST, }; typedef enum { @@ -119,6 +121,8 @@ typedef enum { struct _App { GMainLoop *loop; guint sourceid; + guint audio_id; + guint video_id; GMappedFile *file; guint8 *data; @@ -141,6 +145,20 @@ struct _App { gint frame; type_e type; camera_h camera_handle; + + GThread *thread; + GCond thread_cond; + GMutex thread_mutex; + GMutex eos_mutex; + GCond eos_cond; + GCond dst_eos_cond; + gint demux_eos; + gint codec_eos; + gint suspend; + gchar filepath[256]; + /* demuxer */ + mediademuxer_h demuxer; + media_format_h format[MAX_HANDLE]; /* video */ mediacodec_h mc_handle[MAX_HANDLE]; guint width; @@ -148,6 +166,7 @@ struct _App { guint fps; guint target_bits; media_format_mimetype_e mime; + gint video_track; /* Audio */ guint samplerate; @@ -155,7 +174,7 @@ struct _App { guint bit; guint bitrate; gboolean is_amr_nb; - + gint audio_track; /* Render */ guint w; @@ -166,6 +185,11 @@ struct _App { Ecore_Pipe *pipe; GList *packet_list; GMutex lock; + + gint etb; + gint ftb; + gint ebd; + gint fbd; }; App s_app; @@ -174,24 +198,28 @@ media_format_h fmt = NULL; media_packet_pool_h pkt_pool = NULL; /* Internal Functions */ -static gint _create_app(void *data); -static gint _terminate_app(void *data); -static void displaymenu(void); -static void display_sub_basic(); - -static void _mediacodec_unprepare(App *app); +gint _create_app(void *data); +gint _terminate_app(void *data); +void displaymenu(void); +void display_sub_basic(); + +void _mediacodec_unprepare(App *app); +void _mediacodec_destroy(App *app); +void _mediacodec_auto_test(App *app, char *path); +void input_filepath(char *filename, App *app); /* For debugging */ -static void mc_hex_dump(char *desc, void *addr, gint len); -static void decoder_output_dump(App *app, media_packet_h pkt); -static void output_dump(App *app, media_packet_h pkt); +void mc_hex_dump(char *desc, void *addr, gint len); +void decoder_output_dump(App *app, media_packet_h pkt); +void output_dump(App *app, media_packet_h pkt); /* */ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id); void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data); gint g_menu_state = CURRENT_STATUS_MAINMENU; +void demuxer_error_cb(mediademuxer_error_e error, void *user_data); -static gint _create_app(void *data) +gint _create_app(void *data) { g_print("My app is going alive!\n"); App *app = (App*)data; @@ -200,7 +228,7 @@ static gint _create_app(void *data) return 0; } -static gint _terminate_app(void *data) +gint _terminate_app(void *data) { g_print("My app is going gone!\n"); App *app = (App*)data; @@ -816,7 +844,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware) return mime; } -static void _mediacodec_process_input(App *app) +void _mediacodec_process_input(App *app) { gint i; gboolean have_frame = FALSE; @@ -917,7 +945,7 @@ static void _mediacodec_process_input(App *app) } } -static gboolean read_data(App *app) +gboolean read_data(App *app) { guint len = 0; gboolean have_frame = FALSE; @@ -1040,7 +1068,100 @@ static gboolean read_data(App *app) return TRUE; } -static void start_feed(App *app) +void av_feed_suspend(App *app) +{ + g_mutex_lock(&app->thread_mutex); + app->suspend = 1; + g_print("suspend thread\n"); + g_mutex_unlock(&app->thread_mutex); +} + +void av_feed_resume(App *app) +{ + g_mutex_lock(&app->thread_mutex); + app->suspend = 0; + g_print("resume thread\n"); + g_cond_broadcast(&app->thread_cond); + g_mutex_unlock(&app->thread_mutex); +} + +gpointer av_feed_thread(gpointer data) +{ + App *app = (App *)data; + int ret = 0; + gint track = -1; + + media_packet_h packet = NULL; + track = app->audio_track; + + while (1) { + g_mutex_lock(&app->thread_mutex); + + while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex); + + g_mutex_unlock(&app->thread_mutex); + + if (app->demux_eos == 1) { + g_print("got eos!!!\n"); + break; + } + + ret = mediademuxer_read_sample(app->demuxer, track, &packet); + if (ret != MEDIACODEC_ERROR_NONE) + return NULL; + + ret = mediacodec_process_input(app->mc_handle[track], packet, 0); + if (ret != MEDIACODEC_ERROR_NONE) + return NULL; + + app->etb++; + + } + + return NULL; +} + +gboolean feed_audio(App *app) +{ + gint ret = 0; + gint track = -1; + + media_packet_h packet = NULL; + track = app->audio_track; + + g_print("read audio sample!!!\n"); + ret = mediademuxer_read_sample(app->demuxer, track, &packet); + if (ret != MEDIACODEC_ERROR_NONE) + return FALSE; + + ret = mediacodec_process_input(app->mc_handle[track], packet, 0); + if (ret != MEDIACODEC_ERROR_NONE) + return FALSE; + + return TRUE; +} + +gboolean feed_video(App *app) +{ + gint ret = 0; + gint track = -1; + + media_packet_h packet = NULL; + track = app->video_track; + + g_print("read video sample!!!\n"); + ret = mediademuxer_read_sample(app->demuxer, track, &packet); + if (ret != MEDIACODEC_ERROR_NONE) + return FALSE; + + ret = mediacodec_process_input(app->mc_handle[track], packet, 0); + if (ret != MEDIACODEC_ERROR_NONE) + return FALSE; + + return TRUE; +} + +void start_feed(App *app) { if (app->sourceid == 0) { app->sourceid = g_idle_add((GSourceFunc)read_data, app); @@ -1048,7 +1169,7 @@ static void start_feed(App *app) } } -static void stop_feed(App *app) +void stop_feed(App *app) { if (app->sourceid != 0) { g_source_remove(app->sourceid); @@ -1057,19 +1178,86 @@ static void stop_feed(App *app) } } -static gboolean _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data) +void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data) { + App *app = (App *)user_data; + g_print("_mediacodec_inbuf_used_cb!!!\n"); #ifdef USE_POOL media_packet_pool_release_packet(pkt_pool, pkt); #else media_packet_destroy(pkt); #endif + app->ebd++; - return TRUE; + return; } -static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) +void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data) +{ + media_packet_h out_pkt = NULL; + int ret; + + App *app = (App*)user_data; + + g_print("_audio_outbuf_available_cb\n"); + + g_mutex_lock(&app->lock); + + ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0); + + if (ret != MEDIACODEC_ERROR_NONE) + g_print("get_output failed\n"); + + if (app->enable_dump) + output_dump(app, out_pkt); + + app->frame_count++; + app->fbd++; + + + g_mutex_unlock(&app->lock); + + media_packet_destroy(out_pkt); + out_pkt = NULL; + g_print("done\n"); + + return; +} + +void _video_outbuf_available_cb(media_packet_h pkt, void *user_data) +{ + media_packet_h out_pkt = NULL; + int ret; + + App *app = (App*)user_data; + + g_print("_video_outbuf_available_cb\n"); + + g_mutex_lock(&app->lock); + + ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0); + + if (ret != MEDIACODEC_ERROR_NONE) + g_print("get_output failed\n"); + + if (app->enable_dump) + decoder_output_dump(app, out_pkt); + + app->frame_count++; + app->fbd++; + + + g_mutex_unlock(&app->lock); + + media_packet_destroy(out_pkt); + out_pkt = NULL; + g_print("done\n"); + + return; +} + +void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) { media_packet_h out_pkt = NULL; int ret; @@ -1093,6 +1281,7 @@ static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_d } app->frame_count++; + app->fbd++; g_mutex_unlock(&app->lock); @@ -1101,10 +1290,10 @@ static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_d out_pkt = NULL; g_print("done\n"); - return TRUE; + return; } -static gboolean _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data) +void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data) { g_print("_mediacodec_buffer_status_cb %d\n", status); @@ -1115,17 +1304,58 @@ static gboolean _mediacodec_buffer_status_cb(mediacodec_status_e status, void *u else if (status == MEDIACODEC_ENOUGH_DATA) stop_feed(app); - return TRUE; + return; } -static gboolean _mediacodec_error_cb(mediacodec_error_e error, void *user_data) +void _av_buffer_status_cb(mediacodec_status_e status, void *user_data) { - return TRUE; + g_print("_av_buffer_status_cb %d\n", status); + + App *app = (App*)user_data; + + if (status == MEDIACODEC_NEED_DATA) + av_feed_resume(app); + else if (status == MEDIACODEC_ENOUGH_DATA) + av_feed_suspend(app); + + return; } -static gboolean _mediacodec_eos_cb(void *user_data) +void _mediacodec_error_cb(mediacodec_error_e error, void *user_data) { - return TRUE; + return; +} + +void demuxer_error_cb(mediademuxer_error_e error, void *user_data) +{ + g_print("Got Error %d from Mediademuxer\n", error); + return; +} + +void _mediacodec_eos_cb(void *user_data) +{ + App *app = (App *)user_data; + + g_print("mediacodec eos\n"); + g_mutex_lock(&app->eos_mutex); + app->codec_eos = 1; + g_mutex_unlock(&app->eos_mutex); + g_cond_broadcast(&app->dst_eos_cond); + return; +} + +void _mediademuxer_eos_cb(int track, void *user_data) +{ + App *app = (App *)user_data; + + g_print("eos track : %d\n", track); + av_feed_suspend(app); + g_print("suspended\n"); + app->demux_eos = 1; + av_feed_resume(app); + g_cond_broadcast(&app->eos_cond); + + return; } gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) @@ -1134,7 +1364,7 @@ gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) return TRUE; } -static void _mediacodec_prepare(App *app, gboolean frame_all) +void _mediacodec_prepare(App *app, gboolean frame_all) { int ret; @@ -1206,7 +1436,7 @@ static void _mediacodec_prepare(App *app, gboolean frame_all) mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app); if (frame_all) mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app); - mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, NULL); + mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app); mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL); /* prepare */ @@ -1228,20 +1458,20 @@ static void _mediacodec_prepare(App *app, gboolean frame_all) return; } -static void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data) +void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data) { /* release input raw packet */ media_packet_destroy(pkt); } /* this callback is called when the input buffer for codec has done to use */ -static void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data) +void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data) { /* release input encoded packet */ media_packet_destroy(pkt); } -static void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data) +void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data) { App *app = (App*)user_data; @@ -1252,7 +1482,7 @@ static void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void mediacodec_process_input(app->mc_handle[0], output_buf, 0); } -static void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data) +void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data) { App *app = (App*)user_data; @@ -1267,7 +1497,7 @@ static void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void media_packet_destroy(output_buf); } -static void _media_packet_preview_cb(media_packet_h packet, void *user_data) +void _media_packet_preview_cb(media_packet_h packet, void *user_data) { App *app = user_data; g_mutex_lock(&app->lock); @@ -1277,7 +1507,7 @@ static void _media_packet_preview_cb(media_packet_h packet, void *user_data) return; } -static void _mediacodec_camera_start(App *app) +void _mediacodec_camera_start(App *app) { int default_format = CAMERA_PIXEL_FORMAT_NV12; app->width = 640; @@ -1315,7 +1545,7 @@ static void _mediacodec_camera_start(App *app) } -static void _mediacodec_camera_stop(App *app) +void _mediacodec_camera_stop(App *app) { camera_state_e camera_state = CAMERA_STATE_NONE; @@ -1330,12 +1560,230 @@ static void _mediacodec_camera_stop(App *app) return; } -static void _mediacodec_unprepare(App *app) +void _mediacodec_auto_test(App *app, char *path) +{ + gint ret = 0; + gint num_tracks = 0; + gint track = 0; + gint width = 0; + gint height = 0; + gint channel = 0; + gint samplerate = 0; + gint bit = 0; + media_format_type_e formattype; + media_format_mimetype_e video_mime; + media_format_mimetype_e audio_mime; + gint codec_mask = 0xFFF0; + gint codec_id; + app->demux_eos = 0; + app->codec_eos = 0; + app->etb = 0; + app->ebd = 0; + app->ftb = 0; + app->fbd = 0; + + ret = mediademuxer_create(&app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to create demuxer\n"); + return; + } + + ret = mediademuxer_set_data_source(app->demuxer, path); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to mediademuxer_set_data_source\n"); + return; + } + + ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to mediademuxer_set_error_cb\n"); + return; + } + + mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app); + + ret = mediademuxer_prepare(app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to prepare\n"); + return; + } + + + ret = mediademuxer_get_track_count(app->demuxer, &num_tracks); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to get track\n"); + return; + } + + for (track = 0; track < num_tracks; track++) { + ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to get track info\n"); + return; + } + + media_format_get_type(app->format[track], &formattype); + + if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) { + app->audio_track = track; + app->type = AUDIO_DEC; + media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL); + + mediademuxer_select_track(app->demuxer, track); + + ret = mediacodec_create(&app->mc_handle[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to create mediacocec\n"); + return; + } + + codec_id = audio_mime & codec_mask; + g_print("auido codec_id : %x\n", codec_id); + + ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to set codec\n"); + return; + } + + ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to set adec info\n"); + return; + } + + mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app); + mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app); + mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app); + mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app); + mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL); + + } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) { + app->video_track = track; + app->type = VIDEO_DEC; + media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL); + + mediademuxer_select_track(app->demuxer, track); + + ret = mediacodec_create(&app->mc_handle[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to create mediacocec\n"); + return; + } + + app->width = width; + app->height = height; + + codec_id = video_mime & codec_mask; + g_print("video codec_id : %x\n", codec_id); + + ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to set codec\n"); + return; + } + + ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to set vdec info\n"); + return; + } + + mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app); + mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app); + mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app); + mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app); + mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL); + } + } + + ret = mediademuxer_start(app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to start mediademuxer\n"); + return; + } + + track = app->is_video ? app->video_track : app->audio_track; + ret = mediacodec_prepare(app->mc_handle[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to prepare mediacodec\n"); + return; + } + + g_cond_init(&app->thread_cond); + g_cond_init(&app->eos_cond); + g_cond_init(&app->dst_eos_cond); + g_mutex_init(&app->thread_mutex); + g_mutex_init(&app->eos_mutex); + + app->thread = g_thread_new("feed thread", &av_feed_thread, app); + app->start = clock(); + + g_mutex_lock(&app->eos_mutex); + while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex); + g_mutex_unlock(&app->eos_mutex); + g_print("now try to destroy thread!!\n"); + g_thread_join(app->thread); + app->finish = clock(); + + ret = mediademuxer_stop(app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to stop mediademuxer\n"); + return; + } + + ret = mediademuxer_unselect_track(app->demuxer, track); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to unselect mediademuxer\n"); + return; + } + + ret = mediacodec_unprepare(app->mc_handle[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to unprepare mediacodec\n"); + return; + } + + ret = mediacodec_destroy(app->mc_handle[track]); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to destroy mediacodec\n"); + return; + } + + ret = mediademuxer_unprepare(app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to unprepare mediademuxer\n"); + return; + } + + ret = mediademuxer_destroy(app->demuxer); + if (ret != MEDIACODEC_ERROR_NONE) { + g_print("failed to destroy mediademuxer\n"); + return; + } + + g_cond_clear(&app->thread_cond); + g_cond_clear(&app->eos_cond); + g_cond_clear(&app->dst_eos_cond); + g_mutex_clear(&app->thread_mutex); + g_mutex_clear(&app->eos_mutex); + + g_print("resources are released!!!\n\n\n"); + g_print("-----------------------------------------------------\n"); + g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd); + g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd); + g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start))); + g_print("-----------------------------------------------------\n"); + + return; +} + +void _mediacodec_unprepare(App *app) { mediacodec_unprepare(app->mc_handle[0]); } -static void _mediacodec_destroy(App *app) +void _mediacodec_destroy(App *app) { #ifdef USE_POOL if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) { @@ -1354,7 +1802,7 @@ static void _mediacodec_destroy(App *app) mediacodec_destroy(app->mc_handle[0]); } -static void input_filepath(char *filename, App *app) +void input_filepath(char *filename, App *app) { GError *error = NULL; @@ -1379,7 +1827,6 @@ void quit_program(App *app) media_format_unref(fmt); g_main_loop_quit(app->loop); exit(0); - } void reset_menu_state() @@ -1425,6 +1872,8 @@ void _interpret_main_menu(char *cmd, App *app) _mediacodec_camera_start(app); else if (strncmp(cmd, "ct", 2) == 0) _mediacodec_camera_stop(app); + else if (strncmp(cmd, "au", 2) == 0) + g_menu_state = CURRENT_STATUS_AUTO_TEST; else if (strncmp(cmd, "dp", 2) == 0) { if (!app->enable_dump) { app->enable_dump = TRUE; @@ -1442,7 +1891,7 @@ void _interpret_main_menu(char *cmd, App *app) return; } -static void displaymenu(void) +void displaymenu(void) { if (g_menu_state == CURRENT_STATUS_MAINMENU) { display_sub_basic(); @@ -1491,6 +1940,8 @@ static void displaymenu(void) g_print("*** input dec process number\n"); } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) { g_print("*** input get output buffer number\n"); + } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) { + g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n"); } else { g_print("*** unknown status.\n"); } @@ -1503,8 +1954,7 @@ gboolean timeout_menu_display(void* data) return FALSE; } - -static void interpret(char *cmd) +void interpret(char *cmd) { App *app = &s_app; gint tmp = 0; @@ -1660,7 +2110,7 @@ static void interpret(char *cmd) tmp = atoi(cmd); if (tmp <= 0 || tmp > INT_MAX) { - g_print("Invalid value\n"); + g_print(";;Invalid value\n"); reset_menu_state(); break; } @@ -1695,14 +2145,34 @@ static void interpret(char *cmd) reset_menu_state(); } break; - default: - break; + case CURRENT_STATUS_AUTO_TEST: + { + int len; + static int cnt = 0; + switch (cnt) { + case 0: + len = strlen(cmd); + strncpy(app->filepath, cmd, len + 1); + g_print("%s, %d\n", app->filepath, len); + cnt++; + break; + case 1: + app->is_video = atoi(cmd) ? 1 : 0; + _mediacodec_auto_test(app, app->filepath); + reset_menu_state(); + cnt = 0; + break; + default: + break; + } + } + break; } g_timeout_add(100, timeout_menu_display, 0); } -static void display_sub_basic() +void display_sub_basic() { g_print("\n"); g_print("=========================================================================================\n"); @@ -1725,6 +2195,7 @@ static void display_sub_basic() g_print("dp. enable dump \n"); g_print("-----------------------------------------------------------------------------------------\n"); g_print("cr. camera preview -> encoder -> decoder\n"); + g_print("au. interlocking with mediademuxer\n"); g_print("ct. quit camera test\n"); g_print("\n"); g_print("=========================================================================================\n"); @@ -1744,27 +2215,6 @@ gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data) return TRUE; } -int main(int argc, char *argv[]) -{ - GIOChannel *stdin_channel; - stdin_channel = g_io_channel_unix_new(0); - g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL); - - App *app = &s_app; - - displaymenu(); - app->loop = g_main_loop_new(NULL, TRUE); - app->timer = g_timer_new(); - g_main_loop_run(app->loop); - - ops.data = app; - - return appcore_efl_main(PACKAGE, &argc, &argv, &ops); -} - - - void mc_hex_dump(char *desc, void *addr, gint len) { int i; @@ -1799,7 +2249,7 @@ void mc_hex_dump(char *desc, void *addr, gint len) g_print(" %s\n", buff); } -static void decoder_output_dump(App *app, media_packet_h pkt) +void decoder_output_dump(App *app, media_packet_h pkt) { void *temp; int i = 0; @@ -1886,7 +2336,7 @@ void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen) buffer[6] = (char)0xFC; } -static void output_dump(App *app, media_packet_h pkt) +void output_dump(App *app, media_packet_h pkt) { void *temp; uint64_t buf_size; @@ -1906,7 +2356,7 @@ static void output_dump(App *app, media_packet_h pkt) add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE)); fwrite(&adts, 1, ADTS_HEADER_SIZE, fp); g_print("adts appended\n"); - } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) { + } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) { /* This is used only AMR encoder case for adding AMR masic header in only first frame */ g_print("%s - AMR_header write in first frame\n", __func__); fwrite(&AMR_header[0], 1, sizeof(AMR_header) - 1, fp); /* AMR-NB magic number */ @@ -1982,5 +2432,24 @@ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id) default: return "NONE"; } + return "NONE"; } +int main(int argc, char *argv[]) +{ + GIOChannel *stdin_channel; + stdin_channel = g_io_channel_unix_new(0); + g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL); + + App *app = &s_app; + + displaymenu(); + app->loop = g_main_loop_new(NULL, TRUE); + app->timer = g_timer_new(); + g_main_loop_run(app->loop); + + ops.data = app; + + return appcore_efl_main(PACKAGE, &argc, &argv, &ops); +} -- 2.7.4 From 4f3a8c1b2a61cd5fee437ee51a48cce804d3ecf1 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 22 Jun 2017 17:57:28 +0900 Subject: [PATCH 08/16] 1.flxible memory allocation using external memory 2.removed setting extra data with media packet Change-Id: I775cc19791d0b51cb46ae9c379293b9cc8a41e51 --- include/media_codec_port_gst.h | 67 ++++---- packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 353 +++++++++++++++++++++++----------------- test/media_codec_test.c | 3 +- 4 files changed, 238 insertions(+), 187 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 84ff576..fe5ab65 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -73,8 +73,8 @@ typedef enum { #ifdef TIZEN_PROFILE_LITE struct _ion_mmu_data_t { - int master_id; - int fd_buffer; + gint master_id; + gint fd_buffer; unsigned long iova_addr; size_t iova_size; }; @@ -82,10 +82,10 @@ struct _ion_mmu_data_t { struct _mc_gst_port_t { mc_gst_core_t *core; - unsigned int num_buffers; - unsigned int buffer_size; - unsigned int index; - bool is_allocated; + guint num_buffers; + guint buffer_size; + guint index; + gboolean is_allocated; media_packet_h *buffers; GQueue *queue; GMutex mutex; @@ -93,8 +93,8 @@ struct _mc_gst_port_t { }; struct _mc_gst_core_t { - int(**vtable)(); - const char *mime; + gint(**vtable)(); + const gchar *mime; gchar *format; GstElement *pipeline; GstElement *appsrc; @@ -105,11 +105,11 @@ struct _mc_gst_core_t { GstElement *codec; GstCaps *caps; tbm_bufmgr bufmgr; - int drm_fd; + gint drm_fd; GMainContext *thread_default; gulong signal_handoff; - gint bus_whatch_id; + gint bus_watch_id; gint probe_id; GMutex eos_mutex; @@ -121,22 +121,22 @@ struct _mc_gst_core_t { GCond eos_cond; GCond eos_waiting_cond; - bool output_allocated; - bool encoder; - bool video; - bool is_hw; - bool eos; - bool eos_waiting; - bool codec_config; - bool need_drain; - bool need_feed; - bool need_codec_data; - bool need_sync_flag; - bool unprepare_flag; - unsigned int prepare_count; - unsigned int num_live_buffers; - unsigned int etb_count; - unsigned int ftb_count; + gboolean output_allocated; + gboolean encoder; + gboolean video; + gboolean is_hw; + gboolean eos; + gboolean eos_waiting; + gboolean codec_config; + gboolean need_drain; + gboolean need_feed; + gboolean need_codec_data; + gboolean need_sync_flag; + gboolean unprepare_flag; + guint prepare_count; + guint num_live_buffers; + guint etb_count; + guint ftb_count; mediacodec_codec_type_e codec_id; media_format_mimetype_e out_mime; @@ -156,25 +156,26 @@ struct _mc_gst_core_t { struct _GstMCBuffer { GstBuffer *buffer; - int buf_size; + gint buf_size; mc_gst_core_t* core; media_packet_h packet; - bool has_imgb; + void *ext_mem; + gboolean has_tbm; }; enum { fill_inbuf, fill_outbuf }; int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); -int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); +int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer); int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); -int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); -int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); -int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); -int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *packet); +int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer); +int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer); +int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer); +int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer); mc_gst_core_t *mc_gst_core_new(); void mc_gst_core_free(mc_gst_core_t *core); diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 8b18995..d84b606 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.5 +Version: 0.5.6 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 9e93383..f3a2714 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -53,7 +53,7 @@ static gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt); static GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h packet, bool codec_config); static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer); static gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw); -static media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size); +static GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer); static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data); static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data); static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet); @@ -175,11 +175,10 @@ int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuff int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { - int ret = MC_ERROR_NONE; - + gint ret = MC_ERROR_NONE; + uint64_t buf_size = 0; MMVideoBuffer *mm_vbuffer = NULL; void *buf_data = NULL; - uint64_t buf_size = 0; ret = media_packet_get_buffer_size(packet, &buf_size); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -213,7 +212,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pac int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { - int ret = MC_ERROR_NONE; + gint ret = MC_ERROR_NONE; void *buf_data = NULL; uint64_t buf_size = 0; @@ -241,12 +240,12 @@ int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packe int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { - int ret = MC_ERROR_NONE; - void *buf_data = NULL; + gint ret = MC_ERROR_NONE; uint64_t buf_size = 0; + unsigned int codec_size = 0; bool codec_config = FALSE; + void *buf_data = NULL; void *codec_data = NULL; - unsigned int codec_size = 0; ret = media_packet_get_buffer_size(packet, &buf_size); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -286,18 +285,17 @@ int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { - int ret = MC_ERROR_NONE; - void *uv_ptr = NULL; - void *y_ptr = NULL; - int buf_size = 0; - int stride_width; - int stride_height; - int width; - int height; + gint ret = MC_ERROR_NONE; + gint i; + gint j; + gint stride = 0; + gint buf_size = 0; + gint stride_width; + gint stride_height; + gint width; + gint height; uint32_t plane_num; - int i; - int j; - int stride = 0; + void *planes[2]; mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; @@ -310,7 +308,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h return MC_ERROR; } - ret = media_packet_get_video_plane_data_ptr(packet, 0, &y_ptr); + ret = media_packet_get_video_plane_data_ptr(packet, 0, &planes[0]); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_get_video_plane_data_ptr failed"); return MC_ERROR; @@ -333,20 +331,20 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h mcbuffer->buf_size += stride_width * stride_height; for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(packet, i, &uv_ptr); + media_packet_get_video_plane_data_ptr(packet, i, &planes[1]); media_packet_get_video_stride_width(packet, i, &stride_width); media_packet_get_video_stride_height(packet, i, &stride_height); buf_size = stride_width * stride_height; - memcpy(y_ptr + mcbuffer->buf_size, uv_ptr, buf_size); + memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size); mcbuffer->buf_size += buf_size; LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size); } } else { for (j = 0; j < height; j++) { - memcpy(y_ptr + mcbuffer->buf_size, y_ptr + stride, width); + memcpy(planes[0] + mcbuffer->buf_size, planes[0] + stride, width); mcbuffer->buf_size += width; stride += stride_width; } @@ -354,17 +352,17 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h stride = 0; for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(packet, i, &uv_ptr); + media_packet_get_video_plane_data_ptr(packet, i, &planes[1]); media_packet_get_video_stride_width(packet, i, &stride_width); media_packet_get_video_stride_height(packet, i, &stride_height); for (j = 0; j < height>>1; j++) { - memcpy(y_ptr + mcbuffer->buf_size, uv_ptr + stride, width>>1); + memcpy(planes[0] + mcbuffer->buf_size, planes[1] + stride, width>>1); mcbuffer->buf_size += width>>1; stride += stride_width; } - memcpy(y_ptr + mcbuffer->buf_size, uv_ptr, buf_size); + memcpy(planes[0] + mcbuffer->buf_size, planes[1], buf_size); LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mcbuffer->buf_size); mcbuffer->buf_size += buf_size; } @@ -382,7 +380,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h } gst_buffer_prepend_memory(mcbuffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mcbuffer->buf_size, 0, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, planes[0], mcbuffer->buf_size, 0, mcbuffer->buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); return ret; @@ -393,12 +391,12 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h * fill_outbuf virtual functions */ -int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet) +int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer) { - return core->vtable[fill_outbuf](core, data, size, out_packet); + return core->vtable[fill_outbuf](core, data, size, mcbuffer); } -int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *packet) +int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer) { int i; int stride_width; @@ -406,10 +404,11 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in uint32_t width; uint32_t height; uint32_t buf_size; - tbm_surface_h tsurf = NULL; tbm_surface_info_s tsurf_info; tbm_bo bo[MM_VIDEO_BUFFER_PLANE_MAX]; tbm_bo_handle thandle; + tbm_surface_h tsurf = NULL; + media_packet_h packet = NULL; g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); @@ -500,41 +499,54 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in if (tsurf) { media_packet_create_from_tbm_surface(core->output_fmt, tsurf, - (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, packet); + (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, mcbuffer, &packet); + mcbuffer->packet = packet; } return MC_ERROR_NONE; } -int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet) +int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer) { + gint ret = MC_ERROR_NONE; + gchar *ext_mem = NULL; + gint mem_size = 0; void *packet_data = NULL; - int ret = MC_ERROR_NONE; + media_packet_h packet = NULL; + 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_packet); + mem_size = GST_ROUND_UP_4(size); + ext_mem = g_malloc0(mem_size); + + ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); return MC_ERROR; } + mcbuffer->packet = packet; + mcbuffer->ext_mem = ext_mem; - media_packet_set_buffer_size(*out_packet, size); - media_packet_get_buffer_data_ptr(*out_packet, &packet_data); + media_packet_set_buffer_size(packet, size); + media_packet_get_buffer_data_ptr(packet, &packet_data); memcpy(packet_data, data, size); return MC_ERROR_NONE; } -int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet) +int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer) { - void *packet_data = NULL; + gint ret = MC_ERROR_NONE; bool codec_config = FALSE; bool sync_flag = FALSE; bool slice = FALSE; - int ret = MC_ERROR_NONE; + gint mem_size = 0; + gchar *ext_mem = NULL; + void *packet_data = NULL; + media_packet_h packet = NULL; g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); @@ -558,14 +570,19 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in } LOGD("codec_config : %d, sync_flag : %d, slice : %d", codec_config, sync_flag, slice); - ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_packet); + mem_size = GST_ROUND_UP_4(size); + ext_mem = g_malloc0(mem_size); + + ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); return MC_ERROR; } + mcbuffer->packet = packet; + mcbuffer->ext_mem = ext_mem; - media_packet_set_buffer_size(*out_packet, size); - media_packet_get_buffer_data_ptr(*out_packet, &packet_data); + media_packet_set_buffer_size(packet, size); + media_packet_get_buffer_data_ptr(packet, &packet_data); memcpy(packet_data, data, size); core->need_sync_flag = sync_flag ? 1 : 0; @@ -574,30 +591,38 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in return ret; } -int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet) +int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, GstMCBuffer *mcbuffer) { int ret = MC_ERROR_NONE; + gint mem_size = 0; GstPad *pad; GstCaps *peercaps; - const GValue *codec_data = NULL; - void *packet_data = NULL; GstMapInfo map; guint8 *ptr; gsize len; + gchar *ext_mem = NULL; + const GValue *codec_data = NULL; + void *packet_data = NULL; + media_packet_h packet = NULL; 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_packet); + mem_size = GST_ROUND_UP_4(size); + ext_mem = g_malloc0(mem_size); + + ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); return MC_ERROR; } + mcbuffer->packet = packet; + mcbuffer->ext_mem = ext_mem; - media_packet_set_buffer_size(*out_packet, size); - media_packet_get_buffer_data_ptr(*out_packet, &packet_data); + media_packet_set_buffer_size(packet, size); + media_packet_get_buffer_data_ptr(packet, &packet_data); memcpy(packet_data, data, size); if (!core->codec_data) { @@ -625,7 +650,7 @@ int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in gst_buffer_map(core->codec_data, &map, GST_MAP_READ); ptr = map.data; len = map.size; - media_packet_set_codec_data(*out_packet, ptr, len); + media_packet_set_codec_data(packet, ptr, len); gst_buffer_unmap(core->codec_data, &map); } @@ -668,14 +693,14 @@ static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * nam int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size) { - int ret = MEDIA_PACKET_ERROR_NONE; - void *buf_data = NULL; + gint ret = MEDIA_PACKET_ERROR_NONE; uint64_t buf_size = 0; GstBuffer *header1, *header2, *header3; guint hsize1, hsize2, hsize3; GstBuffer *tmp_header; - guint8 *tmp_buf = NULL; GstMapInfo map; + void *buf_data = NULL; + guint8 *tmp_buf = NULL; ret = media_packet_get_buffer_size(mcbuffer->packet, &buf_size); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -825,12 +850,12 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint fixed_size) { - int ret = MC_ERROR_NONE; - void *codec_data = NULL; - unsigned int codec_data_size = 0; + gint ret = MC_ERROR_NONE; + uint32_t codec_data_size = 0; + GstMapInfo map; GstBuffer *codecdata_buffer; guint8 *data = NULL; - GstMapInfo map; + void *codec_data = NULL; media_packet_get_codec_data(mcbuffer->packet, &codec_data, &codec_data_size); @@ -1048,9 +1073,9 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info; if (core->video) { - int width = 0; - int height = 0; - int bitrate = 0; + gint width = 0; + gint height = 0; + gint bitrate = 0; media_format_get_video_info(fmt, NULL, &width, &height, &bitrate, NULL); @@ -1071,10 +1096,10 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) } } } else { - int channel; - int samplerate; - int bit; - int bitrate; + gint channel; + gint samplerate; + gint bit; + gint bitrate; media_format_get_audio_info(fmt, NULL, &channel, &samplerate, &bit, &bitrate); @@ -1199,17 +1224,18 @@ static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool static gpointer feed_task(gpointer data) { - mc_gst_core_t *core = (mc_gst_core_t *)data; - int ret = MC_ERROR_NONE; + gint ret = MC_ERROR_NONE; bool codec_config = FALSE; bool eos = FALSE; + bool initiative = TRUE; media_format_h fmt = NULL; media_packet_h in_buf = NULL; GstMCBuffer *mcbuffer = NULL; - bool initiative = true; MEDIACODEC_FENTER(); + mc_gst_core_t *core = (mc_gst_core_t *)data; + while (g_atomic_int_get(&core->available_queue->running)) { LOGD("waiting for next input...."); in_buf = _mc_get_input_buffer(core); @@ -1561,19 +1587,22 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo /* set caps */ g_object_set(core->appsrc, "caps", core->caps, NULL); + MEDIACODEC_FLEAVE(); + return MC_ERROR_NONE; } -static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer) +static gint _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { - MEDIACODEC_FENTER(); + gint ret = MC_ERROR_NONE; - int ret = MC_ERROR_NONE; + MEDIACODEC_FENTER(); + ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer); LOGD("pushed buffer to appsrc : %p, buffer of size %" G_GSIZE_FORMAT "", mcbuffer->buffer, gst_buffer_get_size(mcbuffer->buffer)); - ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer); + MEDIACODEC_FLEAVE(); return ret; } @@ -1672,6 +1701,8 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) } LOGD("initialized... %d", ret); + MEDIACODEC_FLEAVE(); + return ret; } @@ -1730,6 +1761,8 @@ mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle) } } + MEDIACODEC_FLEAVE(); + return ret; } @@ -1779,14 +1812,13 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeOutUs) { - MEDIACODEC_FENTER(); - - int ret = MC_ERROR_NONE; - mc_gst_core_t *core = NULL; - media_packet_h out_packet = NULL; + gint ret = MC_ERROR_NONE; gint64 end_time = -1; gboolean signalled; + mc_gst_core_t *core = NULL; + media_packet_h out_packet = NULL; + MEDIACODEC_FENTER(); end_time = g_get_monotonic_time() + timeOutUs; if (!mc_handle) @@ -1822,11 +1854,11 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6 mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle) { - MEDIACODEC_FENTER(); - - int ret = MC_ERROR_NONE; + gint ret = MC_ERROR_NONE; mc_gst_core_t *core = NULL; + MEDIACODEC_FENTER(); + if (!mc_handle) return MC_PARAM_ERROR; @@ -1844,14 +1876,14 @@ static gboolean __mc_gst_init_gstreamer() { MEDIACODEC_FENTER(); + gint i = 0; + gint arg_count = 0; static gboolean initialized = FALSE; static const int max_argc = 50; gint *argc = NULL; gchar **argv = NULL; gchar **argv2 = NULL; GError *err = NULL; - int i = 0; - int arg_count = 0; if (initialized) { LOGD("gstreamer already initialized.\n"); @@ -2015,7 +2047,7 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) /* connect signals, bus watcher */ bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline)); - core->bus_whatch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core); + core->bus_watch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core); core->thread_default = g_main_context_get_thread_default(); /* set sync handler to get tag synchronously */ @@ -2087,11 +2119,11 @@ mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core) } } - if (core->bus_whatch_id) { + if (core->bus_watch_id) { GSource *source = NULL; - source = g_main_context_find_source_by_id(core->thread_default, core->bus_whatch_id); + source = g_main_context_find_source_by_id(core->thread_default, core->bus_watch_id); g_source_destroy(source); - LOGD("bus_whatch_id destroy"); + LOGD("bus_watch_id destroy"); } MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL); @@ -2149,10 +2181,7 @@ void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet) void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data) { - guint n; - GstMemory *mem; - GstMapInfo map = GST_MAP_INFO_INIT; - media_packet_h out_packet = NULL; + GstMCBuffer *mcbuffer = NULL; MEDIACODEC_FENTER(); @@ -2160,34 +2189,25 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp gst_buffer_ref(buffer); - n = gst_buffer_n_memory(buffer); - - mem = gst_buffer_peek_memory(buffer, n-1); - - gst_memory_map(mem, &map, GST_MAP_READ); - LOGD("n : %d, map.data : %p, map.size : %d", n, map.data, map.size); + mcbuffer = __mc_gst_make_media_packet(core, buffer); - out_packet = __mc_gst_make_media_packet(core, map.data, map.size); + LOGI("@%p(%d) out_packet : %p", core, core->encoder, mcbuffer->packet); - LOGI("@%p(%d) out_packet : %p", core, core->encoder, out_packet); - gst_memory_unmap(mem, &map); - - if (out_packet) { - media_packet_set_extra(out_packet, buffer); - media_packet_set_pts(out_packet, GST_BUFFER_TIMESTAMP(buffer)); - media_packet_set_duration(out_packet, GST_BUFFER_DURATION(buffer)); + if (mcbuffer->packet) { + media_packet_set_pts(mcbuffer->packet, GST_BUFFER_TIMESTAMP(buffer)); + media_packet_set_duration(mcbuffer->packet, GST_BUFFER_DURATION(buffer)); if (core->need_codec_data) { - media_packet_set_flags(out_packet, MEDIA_PACKET_CODEC_CONFIG); + media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_CODEC_CONFIG); core->need_codec_data = false; } if (core->need_sync_flag) { - media_packet_set_flags(out_packet, MEDIA_PACKET_SYNC_FRAME); + media_packet_set_flags(mcbuffer->packet, MEDIA_PACKET_SYNC_FRAME); core->need_sync_flag = false; } - __mc_push_output_to_queue(core, out_packet); + __mc_push_output_to_queue(core, mcbuffer->packet); } else { gst_buffer_unref(buffer); LOGE("Failed to dequeue output packet"); @@ -2210,7 +2230,8 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * MEDIACODEC_FENTER(); - mc_gst_core_t *core = (mc_gst_core_t *)user_data; + GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data; + mc_gst_core_t *core = mcbuffer->core; g_mutex_lock(&core->ports[1]->mutex); @@ -2222,7 +2243,8 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * g_mutex_unlock(&core->ports[1]->mutex); g_atomic_int_dec_and_test(&core->ftb_count); - media_packet_get_extra(packet, &buffer); + + buffer = mcbuffer->buffer; n = gst_buffer_n_memory(buffer); @@ -2241,6 +2263,13 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * } gst_memory_unmap(mem, &map); } + + if (mcbuffer->ext_mem) { + g_free(mcbuffer->ext_mem); + LOGD("freed external memory"); + mcbuffer->ext_mem = NULL; + } + gst_buffer_unref((GstBuffer *)buffer); LOGD("@v(%d)e(%d)output port filled buffer(%d): %p", core->video, core->encoder, core->ftb_count, packet); @@ -2282,12 +2311,12 @@ gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw) GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h packet, bool codec_config) { - int ret = MEDIA_PACKET_ERROR_NONE; - GstMCBuffer *mcbuffer = NULL; - void *buf_data = NULL; + gint ret = MEDIA_PACKET_ERROR_NONE; uint64_t buf_size = 0; uint64_t pts = 0; uint64_t dur = 0; + void *buf_data = NULL; + GstMCBuffer *mcbuffer = NULL; ret = media_packet_get_buffer_size(packet, &buf_size); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -2332,25 +2361,47 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet return mcbuffer; } -media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size) +GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer) { - int ret = MEDIA_PACKET_ERROR_NONE; - media_packet_h packet = NULL; + gint ret = MEDIA_PACKET_ERROR_NONE; + guint n; + GstMemory *mem; + GstMapInfo map = GST_MAP_INFO_INIT; + GstMCBuffer *mcbuffer = NULL; + + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(*mcbuffer)); + + if (mcbuffer == NULL) { + LOGE("malloc fail"); + return NULL; + } + + n = gst_buffer_n_memory(buffer); - ret = __mc_fill_output_buffer(core, data, size, &packet); + mem = gst_buffer_peek_memory(buffer, n-1); + + gst_memory_map(mem, &map, GST_MAP_READ); + + mcbuffer->buffer = buffer; + mcbuffer->core = core; + mcbuffer->buf_size = map.size; + + LOGD("n : %d, map.data : %p, map.size : %d", n, map.data, map.size); + ret = __mc_fill_output_buffer(core, map.data, map.size, mcbuffer); if (ret != MC_ERROR_NONE) { LOGW("failed to fill outbuf: %s (ox%08x)", _mc_error_to_string(ret), ret); + gst_memory_unmap(mem, &map); return NULL; } + gst_memory_unmap(mem, &map); - - return packet; + return mcbuffer; } int __mc_gst_create_eos_packet(media_format_h fmt, media_packet_h *out_packet) { + gint ret = MC_ERROR_NONE; media_packet_h mediabuf = NULL; - int ret = MC_ERROR_NONE; MEDIACODEC_FENTER(); if (media_packet_create(fmt, NULL, NULL, &mediabuf)) { @@ -2398,7 +2449,7 @@ void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { - int ret = MC_ERROR_NONE; + gint ret = MC_ERROR_NONE; mc_gst_core_t *core = (mc_gst_core_t *)data; LOGD("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); @@ -2475,11 +2526,11 @@ gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) static gboolean __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg) { - gboolean retval = false; + gboolean retval = FALSE; if (!core->pipeline) { LOGE("mediacodec pipeline handle is null"); - return true; + return TRUE; } switch (GST_MESSAGE_TYPE(msg)) { @@ -2487,10 +2538,10 @@ static gboolean __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *m case GST_MESSAGE_EOS: case GST_MESSAGE_ERROR: case GST_MESSAGE_WARNING: - retval = true; + retval = TRUE; break; default: - retval = false; + retval = FALSE; break; } @@ -2534,8 +2585,8 @@ static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet) { - int i; - int num_bos; + gint i; + gint num_bos; tbm_surface_h surface = NULL; tbm_surface_info_s surface_info; tbm_bo_handle handle_bo; @@ -2555,7 +2606,7 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet media_packet_get_tbm_surface(packet, &surface); num_bos = tbm_surface_internal_get_num_bos(surface); - int err = tbm_surface_get_info((tbm_surface_h)surface, &surface_info); + gint err = tbm_surface_get_info((tbm_surface_h)surface, &surface_info); if (err != TBM_SURFACE_ERROR_NONE) { LOGE("get tbm surface is failed"); free(mm_vbuffer); @@ -2570,8 +2621,8 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet } #ifdef TIZEN_PROFILE_LITE - int phy_addr = 0; - int phy_size = 0; + gint phy_addr = 0; + gint phy_size = 0; tbm_bo_handle handle_fd = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); if (handle_fd.ptr == NULL) { LOGE("Invaild bo handle"); @@ -2824,7 +2875,7 @@ INTERNAL_ERROR: return MEDIACODEC_ERROR_INTERNAL; } -static int _mc_gst_flush_buffers(mc_gst_core_t *core) +static gint _mc_gst_flush_buffers(mc_gst_core_t *core) { gboolean ret = FALSE; GstEvent *event = NULL; @@ -2908,11 +2959,11 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) } #ifdef TIZEN_PROFILE_LITE -int __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_size) +gint __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_size) { - int ret = 0; - int open_flags = O_RDWR; - int ion_fd = -1; + gint ret = 0; + gint open_flags = O_RDWR; + gint ion_fd = -1; ion_mmu_data_t mmu_data; struct ion_custom_data custom_data; @@ -2969,13 +3020,13 @@ int __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_ * @return * address of tiled data */ -static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) +static gint __tile_4x2_read(gint x_size, gint y_size, gint x_pos, gint y_pos) { - int pixel_x_m1, pixel_y_m1; - int roundup_x; - int linear_addr0, linear_addr1, bank_addr ; - int x_addr; - int trans_addr; + gint pixel_x_m1, pixel_y_m1; + gint roundup_x; + gint linear_addr0, linear_addr1, bank_addr ; + gint x_addr; + gint trans_addr; pixel_x_m1 = x_size - 1; pixel_y_m1 = y_size - 1; @@ -3040,14 +3091,14 @@ static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) * @param buttom * Crop size of buttom */ -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) +static void __csc_tiled_to_linear_crop(gchar *yuv420_dest, gchar *nv12t_src, + gint yuv420_width, gint yuv420_height, + gint left, int top, gint right, gint buttom) { - int i, j; - int tiled_offset = 0, tiled_offset1 = 0; - int linear_offset = 0; - int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0; + gint i, j; + gint tiled_offset = 0, tiled_offset1 = 0; + gint linear_offset = 0; + gint temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0; temp3 = yuv420_width-right; temp1 = temp3-left; @@ -3289,7 +3340,7 @@ const gchar * _mc_bit_to_string(int bit) int _mc_get_support_bit_from_format(media_format_mimetype_e format) { - int bit = 0; + gint bit = 0; switch (format) { case MEDIA_FORMAT_PCM_S16LE: @@ -3385,8 +3436,9 @@ int _mc_get_mime(mc_gst_core_t *core) mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *packet_pool) { - int curr_size; - int max_size, min_size; + gint ret = MC_ERROR_NONE; + gint curr_size; + gint max_size, min_size; media_format_mimetype_e mime_format = MEDIA_FORMAT_MAX; media_format_h fmt_handle = NULL; media_packet_pool_h pool = NULL; @@ -3397,8 +3449,7 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pac core = (mc_gst_core_t *)mc_handle->core; - int ret = media_packet_pool_create(&pool); - + ret = media_packet_pool_create(&pool); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_create failed"); return MC_ERROR; diff --git a/test/media_codec_test.c b/test/media_codec_test.c index bb61c69..b0e0bbd 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -59,7 +59,6 @@ ((state & (expected_state)) == (expected_state)) #define AAC_CODECDATA_SIZE 16 -#define USE_POOL 0 guint8 buf_adts[ADTS_HEADER_SIZE]; @@ -1432,7 +1431,7 @@ void _mediacodec_prepare(App *app, gboolean frame_all) /* set callback */ g_print("supported codec lists\n"); mediacodec_foreach_supported_codec(app->mc_handle[0], (mediacodec_supported_codec_cb)_foreach_cb, app); - mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, NULL); + mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, app); mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app); if (frame_all) mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app); -- 2.7.4 From a13e9fd015b993f5603a6400010628322d965f04 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 5 Jul 2017 15:05:19 +0900 Subject: [PATCH 09/16] fixed crash when media packet is destroyed after unpreparing Change-Id: I523aa25e58411d0e0f27a8a2aaf9dd91d4c5a7a1 --- include/media_codec_port_gst.h | 1 - packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 107 ++++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 62 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index fe5ab65..3cf9120 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -136,7 +136,6 @@ struct _mc_gst_core_t { guint prepare_count; guint num_live_buffers; guint etb_count; - guint ftb_count; mediacodec_codec_type_e codec_id; media_format_mimetype_e out_mime; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index d84b606..17b00a8 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.6 +Version: 0.5.7 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index f3a2714..ca4994d 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -61,8 +61,8 @@ static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_ static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer); static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size); static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint codecdata_size); -static void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet); -static int __mc_gst_create_eos_packet(media_format_h fmt, media_packet_h *out_packet); +static void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer); +static int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer); static void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet); static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message); @@ -974,7 +974,6 @@ mc_gst_core_t *mc_gst_core_new() core->unprepare_flag = false; core->prepare_count = 0; core->etb_count = 0; - core->ftb_count = 0; core->codec_data = NULL; g_atomic_int_set(&core->available_queue->running, 1); @@ -2153,29 +2152,26 @@ STATE_CHANGE_FAILED: return MC_ERROR; } -void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet) +void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { g_mutex_lock(&core->ports[1]->mutex); /* push it to output buffer queue */ - g_queue_push_tail(core->ports[1]->queue, out_packet); + g_queue_push_tail(core->ports[1]->queue, mcbuffer->packet); g_cond_broadcast(&core->out_buffer_cond); - g_atomic_int_inc(&core->ftb_count); - GstBuffer *buffer = NULL; - media_packet_get_extra(out_packet, (void**)&buffer); - if (buffer) { - LOGD("dq : v(%d)e(%d) %d TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder, - core->ftb_count, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); + if (mcbuffer->buffer) { + LOGD("dq : v(%d)e(%d) TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(mcbuffer->buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(mcbuffer->buffer))); } else { - LOGD("dq : v(%d)e(%d) %d ", core->video, core->encoder, core->ftb_count); + LOGD("dq : v(%d)e(%d)", core->video, core->encoder); } g_mutex_unlock(&core->ports[1]->mutex); if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) { ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) - (out_packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]); + (mcbuffer->packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]); } } @@ -2207,7 +2203,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp core->need_sync_flag = false; } - __mc_push_output_to_queue(core, mcbuffer->packet); + __mc_push_output_to_queue(core, mcbuffer); } else { gst_buffer_unref(buffer); LOGE("Failed to dequeue output packet"); @@ -2220,48 +2216,35 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data) { - void *buffer = NULL; int i = 0; guint n; GstMemory *mem; GstMapInfo map = GST_MAP_INFO_INIT; MMVideoBuffer *mm_video_buf = NULL; - GList *find; MEDIACODEC_FENTER(); GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data; - mc_gst_core_t *core = mcbuffer->core; - g_mutex_lock(&core->ports[1]->mutex); - - if ((find = g_queue_find(core->ports[1]->queue, packet))) { - LOGD("remove packet from queue"); - g_queue_remove(core->ports[1]->queue, packet); - } - - g_mutex_unlock(&core->ports[1]->mutex); + if (mcbuffer->buffer) { + n = gst_buffer_n_memory(mcbuffer->buffer); - g_atomic_int_dec_and_test(&core->ftb_count); + if (n > 1) { + mem = gst_buffer_peek_memory(mcbuffer->buffer, n-1); + gst_memory_map(mem, &map, GST_MAP_READ); + mm_video_buf = (MMVideoBuffer *)map.data; - buffer = mcbuffer->buffer; - - n = gst_buffer_n_memory(buffer); - - if (n > 1) { - mem = gst_buffer_peek_memory(buffer, n-1); - gst_memory_map(mem, &map, GST_MAP_READ); - mm_video_buf = (MMVideoBuffer *)map.data; - - if (!mm_video_buf) { - LOGW("gstbuffer map.data is null"); - } else { - for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { - if (mm_video_buf->handle.bo[i]) - tbm_bo_unref(mm_video_buf->handle.bo[i]); + if (!mm_video_buf) { + LOGW("gstbuffer map.data is null"); + } else { + for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { + if (mm_video_buf->handle.bo[i]) + tbm_bo_unref(mm_video_buf->handle.bo[i]); + } } + gst_memory_unmap(mem, &map); } - gst_memory_unmap(mem, &map); + gst_buffer_unref((GstBuffer *)mcbuffer->buffer); } if (mcbuffer->ext_mem) { @@ -2270,8 +2253,8 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * mcbuffer->ext_mem = NULL; } - gst_buffer_unref((GstBuffer *)buffer); - LOGD("@v(%d)e(%d)output port filled buffer(%d): %p", core->video, core->encoder, core->ftb_count, packet); + LOGD("output port filled buffer : %p", packet); + g_free(mcbuffer); MEDIACODEC_FLEAVE(); @@ -2398,32 +2381,34 @@ GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer) return mcbuffer; } -int __mc_gst_create_eos_packet(media_format_h fmt, media_packet_h *out_packet) +int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer) { gint ret = MC_ERROR_NONE; - media_packet_h mediabuf = NULL; + media_packet_h packet = NULL; MEDIACODEC_FENTER(); - if (media_packet_create(fmt, NULL, NULL, &mediabuf)) { + if (media_packet_create_alloc(fmt, __mc_output_buffer_finalize_cb, mcbuffer, &packet)) { LOGE("media_packet_create_alloc failed\n"); ret = MC_ERROR; goto ERROR; } - if (media_packet_set_flags(mediabuf, MEDIA_PACKET_END_OF_STREAM)) { + if (media_packet_set_flags(packet, MEDIA_PACKET_END_OF_STREAM)) { LOGE("unable to set EOS flag\n"); ret = MC_ERROR; goto ERROR; } - *out_packet = mediabuf; + mcbuffer->buffer = NULL; + mcbuffer->ext_mem = NULL; + mcbuffer->buf_size = 0; + mcbuffer->packet = packet; MEDIACODEC_FLEAVE(); return ret; ERROR: - if (mediabuf) - media_packet_destroy(mediabuf); - *out_packet = NULL; + if (packet) + media_packet_destroy(packet); MEDIACODEC_FLEAVE(); return ret; } @@ -2450,20 +2435,23 @@ void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { gint ret = MC_ERROR_NONE; + GstMCBuffer *mcbuffer = NULL; + mc_gst_core_t *core = (mc_gst_core_t *)data; - LOGD("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); + LOGI("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: _mc_send_eos_signal(core); - media_packet_h out_packet = NULL; - if (MC_ERROR_NONE == __mc_gst_create_eos_packet(core->output_fmt, &out_packet)) { - __mc_push_output_to_queue(core, out_packet); + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(GstMCBuffer)); + if (__mc_gst_create_eos_packet(core->output_fmt, mcbuffer) == MC_ERROR_NONE) { + __mc_push_output_to_queue(core, mcbuffer); LOGD("send eos packet."); } else { LOGE("failed to create eos packet."); + g_free(mcbuffer); } if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) { @@ -2683,7 +2671,7 @@ static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer) _mc_gst_handle_input_buffer_used(core, mcbuffer->packet); - free(mcbuffer); + g_free(mcbuffer); mcbuffer = NULL; MEDIACODEC_FLEAVE(); @@ -2695,7 +2683,7 @@ static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_ { GstMCBuffer *mcbuffer = NULL; - mcbuffer = (GstMCBuffer *)malloc(sizeof(*mcbuffer)); + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(GstMCBuffer)); if (mcbuffer == NULL) { LOGE("malloc fail"); @@ -2946,8 +2934,7 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) while (!g_queue_is_empty(core->ports[1]->queue)) { packet = g_queue_pop_head(core->ports[1]->queue); - g_atomic_int_dec_and_test(&core->ftb_count); - LOGD("%p poped(%d)", packet, core->ftb_count); + LOGD("%p poped", packet); if (packet) { media_packet_destroy(packet); LOGD("outpacket destroyed"); -- 2.7.4 From 989a02973e6a78aafea7553642935baafedffa81 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 10 Jul 2017 15:25:19 +0900 Subject: [PATCH 10/16] Added new API for configuration via media format Change-Id: I03b67183493b9c1e97136c0c213ad6234901fe7f --- include/media_codec.h | 148 ++++++++++++++++++++++++++++----------------- include/media_codec_port.h | 2 + src/media_codec.c | 16 +++++ src/media_codec_port.c | 116 +++++++++++++++++++++++++++++++++++ test/media_codec_test.c | 52 +++++++++++++--- 5 files changed, 270 insertions(+), 64 deletions(-) diff --git a/include/media_codec.h b/include/media_codec.h index b6fa990..8e6aa3c 100644 --- a/include/media_codec.h +++ b/include/media_codec.h @@ -133,8 +133,8 @@ typedef enum { * @brief Called when the input buffer(pkt) used up. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details It will be invoked when mediacodec has used input buffer. - * @param[in] pkt The media packet handle - * @param[in] user_data The user data passed from the callback registration function + * @param[in] pkt The media packet handle + * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when input buffer process completed if you register this callback using mediacodec_set_input_buffer_used_cb(). * @see mediacodec_set_input_buffer_used_cb() * @see mediacodec_unset_input_buffer_used_cb() @@ -145,8 +145,8 @@ typedef void (*mediacodec_input_buffer_used_cb)(media_packet_h pkt, void *user_d * @brief Called when the output buffer is available. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details It will be invoked when mediacodec has output buffer. - * @param[in] pkt The media packet handle - * @param[in] user_data The user data passed from the callback registration function + * @param[in] pkt The media packet handle + * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when mediacodec process completed(had output buffer) if you register this callback using mediacodec_set_fill_buffer_cb(). * @see mediacodec_set_output_buffer_available_cb() * @see mediacodec_unset_output_buffer_available_cb() @@ -157,7 +157,7 @@ typedef void (*mediacodec_output_buffer_available_cb)(media_packet_h pkt, void * * @brief Called when the error has occured * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details It will be invoked when the error has occured. - * @param[in] error_code The error code + * @param[in] error_code The error code * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when the error has occured if you register this callback using mediacodec_set_error_cb(). * @see mediacodec_set_error_cb() @@ -169,7 +169,7 @@ typedef void (*mediacodec_error_cb)(mediacodec_error_e error, void *user_data); * @brief Called when there is no data to decode/encode * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details It will be invoked when the end-of-stream is reached. - * @param[in] user_data The user data passed from the callback registration function + * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when the eos event generate if you register this callback using mediacodec_set_eos_cb(). * @see mediacodec_set_eos_cb() * @see mediacodec_unset_eos_cb() @@ -181,7 +181,7 @@ typedef void (*mediacodec_eos_cb)(void *user_data); * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @details It is recommended that the application stops calling mediacodec_process_input() when MEDIACODEC_ENOUGH_DATA * is invoked. - * @param[in] user_data The user data passed from the callback registration function + * @param[in] user_data The user data passed from the callback registration function * @see mediacodec_set_buffer_status_cb() * @see mediacodec_unset_buffer_status_cb() */ @@ -206,7 +206,7 @@ typedef bool (*mediacodec_supported_codec_cb)(mediacodec_codec_type_e codec_type * the mediacodec cannot guarantee proper operation because of limited resources, like * audio or display device. * - * @param[out] mediacodec A new handle to mediacodec + * @param[out] mediacodec A new handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -221,7 +221,7 @@ int mediacodec_create(mediacodec_h *mediacodec); * @remarks To completely shutdown the mediacodec operation, call this function with a valid player handle from any * mediacodec * - * @param[in] mediacodec The handle to mediacodec to be destroyed. + * @param[in] mediacodec The handle to mediacodec to be destroyed. * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -252,9 +252,9 @@ int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_ /** * @brief Sets the default info for the video decoder * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] width The width for video decoding. - * @param[in] height The height for video decoding. + * @param[in] mediacodec The handle to mediacodec + * @param[in] width The width for video decoding. + * @param[in] height The height for video decoding. * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -284,10 +284,10 @@ int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int /** * @brief Sets the default info for the audio decoder * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] samplerate The samplerate for audio decoding. - * @param[in] channel The channels for audio decoding. - * @param[in] bit The bits resolution for audio decoding. + * @param[in] mediacodec The handle to mediacodec + * @param[in] samplerate The samplerate for audio decoding. + * @param[in] channel The channels for audio decoding. + * @param[in] bit The bits resolution for audio decoding. * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -297,12 +297,12 @@ int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit); /** - * @brief Sets the default info for the audio encdoer + * @brief Sets the default info for the audio encoder * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] samplerate The samplerate for audio encoding. - * @param[in] channel The channels for audio encoding. - * @param[in] bit The bits resolution for audio encoding. + * @param[in] mediacodec The handle to mediacodec + * @param[in] samplerate The samplerate for audio encoding. + * @param[in] channel The channels for audio encoding. + * @param[in] bit The bits resolution for audio encoding. * @param[in] bitrate The bitrate for audio encoding. * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -313,9 +313,47 @@ int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channe int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate); /** + * @brief Sets the codec type and codec default info via media format. + * @details Sets the value via media format instead of mediacodec_set_codec(), mediacodec_set_venc_info(), + * mediacodec_set_vdec_info(), mediacodec_set_aenc_info(), and mediacodec_set_adec_info(). + * @since_tizen 4.0 + * @remarks When using the @a format parameter from the output of the media demuxer, you can use media format via media_packet_get_format(). + * Otherwise, you must set the following values after creating media format. + * Set the audio or video codec type via media_format_set_video_mime() or media_format_set_audio_mime(). + * For video decoding, width, height must be set via media_format_set_video_width() and media_format_set_video_height(). + * For video encoding, width, height, target bitrate, and frame rate must be set via media_format_set_video_avg_bps() and media_format_set_video_frame_rate(). + * For audio decoding, samplerate, channel, and bit must be set via media_format_set_audio_samplerate(), media_format_set_audio_channel() and media_format_set_audio_bit(). + * For audio encoding, samplerate, channel, bit, and bitrate must be set via media_format_set_audio_avg_bps().\n + * If this codec is to be used as a decoder, pass the #MEDIACODEC_DECODER flag. + * If this codec is to be used as an encoder, pass the #MEDIACODEC_ENCODER flag.\n + * The software codec is used as default setting (#MEDIACODEC_SUPPORT_TYPE_SW) if user doesn't set hardware flag. + * If you wants to use h/w decoder, you needs to pass the #MEDIACODEC_DECODER | #MEDIACODEC_SUPPORT_TYPE_HW. + * @param[in] mediacodec The mediacodec handle + * @param[in] format The #media_format_h of input data + * @param[in] flags The encoding/decoding scheme, + * values of #mediacodec_support_type_e combined with bitwise 'or' + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIACODEC_ERROR_NONE Successful + * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_CODEC_NOT_FOUND Unsupported codec + * @pre The media format has been created and the required values for configuration have been set. + * @see media_format_set_video_mime() + * @see media_format_set_audio_mime() + * @see media_format_set_video_width() + * @see media_format_set_video_height() + * @see media_format_set_video_avg_bps() + * @see media_format_set_video_frame_rate() + * @see media_format_set_audio_channel() + * @see media_format_set_audio_samplerate() + * @see media_format_set_audio_bit() + * @see media_format_set_audio_avg_bps() + */ +int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format_h format, int flags); + +/** * @brief Prepares @a mediacodec for encoding/decoding. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -330,7 +368,7 @@ int mediacodec_prepare(mediacodec_h mediacodec); /** * @brief Unprepares @a mediacodec for encoding/decoding. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -341,10 +379,10 @@ int mediacodec_unprepare(mediacodec_h mediacodec); /** * @brief Decodes/Encodes a packet. The function passed undecoded/unencoded packet to the input queue and decode/encode a - * frame sequentially. + * frame sequentially. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] inbuf The current input format for the decoder/encoder + * @param[in] mediacodec The handle to mediacodec + * @param[in] inbuf The current input format for the decoder/encoder * @param[in] timeOutUs The timeout in microseconds. \n * The input buffer wait up to "timeOutUs" microseconds. * @return @c 0 on success, otherwise a negative error value @@ -359,9 +397,9 @@ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint /** * @brief Gets the decoded or encoded packet from the output queue. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[out] outbuf The current output of the decoder/encoder. this function passed decoded/encoded frame to output - * queue. + * @param[in] mediacodec The handle to mediacodec + * @param[out] outbuf The current output of the decoder/encoder. + * this function passed decoded/encoded frame to output queue. * @param[in] timeOutUs The timeout in microseconds. \n * The input buffer wait up to "timeOutUs" microseconds. * @return @c 0 on success, otherwise a negative error value @@ -375,7 +413,7 @@ int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint6 /** * @brief Flushes both input and output buffers. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -385,8 +423,8 @@ int mediacodec_flush_buffers(mediacodec_h mediacodec); /** * @brief set empty buffer callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to register + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -401,7 +439,7 @@ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_inpu /** * @brief unset input buffer used callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -412,8 +450,8 @@ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec); /** * @brief set output buffer available callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to register + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -428,7 +466,7 @@ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacode /** * @brief unset output buffer available callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -439,8 +477,8 @@ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec); /** * @brief set error callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to register + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -455,7 +493,7 @@ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callbac /** * @brief unset error callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -466,8 +504,8 @@ int mediacodec_unset_error_cb(mediacodec_h mediacodec); /** * @brief set eos callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to register + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -482,7 +520,7 @@ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, v /** * @brief unset eos callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -493,8 +531,8 @@ int mediacodec_unset_eos_cb(mediacodec_h mediacodec); /** * @brief Registers a callback function to be invoked when the mediacodec needs more data or has enough data. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to register + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful @@ -509,7 +547,7 @@ int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_s /** * @brief Unregisters the callback function. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @param[in] mediacodec The handle to mediacodec + * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -519,9 +557,9 @@ int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec); /** * @brief Retrieves all supported codecs by invoking callback function once for each supported codecs. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] callback The callback function to invoke - * @param[in] user_data The user data to be passed to the callback function + * @param[in] mediacodec The handle to mediacodec + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -532,10 +570,10 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo /** * @brief Verifies whether encoding can be performed with codec_type or not. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @param[in] mediacodec The handle to mediacodec - * @param[in] codec_type The identifier of the codec type of the encoder. - * @param[in] encoder Whether the encoder or decoder : (@c true = encoder, @c false = decoder). - * @param[out] support_type (@c MEDIACODEC_SUPPORT_TYPE_HW = mediacodec can be performed with hardware codec, @c MEDIACODEC_SUPPORT_TYPE_SW = mediacodec can be performed with software codec) + * @param[in] mediacodec The handle to mediacodec + * @param[in] codec_type The identifier of the codec type of the encoder. + * @param[in] encoder Whether the encoder or decoder : (@c true = encoder, @c false = decoder). + * @param[out] support_type (@c MEDIACODEC_SUPPORT_TYPE_HW = mediacodec can be performed with hardware codec, @c MEDIACODEC_SUPPORT_TYPE_SW = mediacodec can be performed with software codec) * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter @@ -563,11 +601,11 @@ int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type /** * @brief Gets the media packet pool allocated for recycling media packets. * @details The user can get the pool allocated with the number of packets are required to be used in codecs.\n - * It is recomended to use media packet pool for better stability and performance. + * It is recomended to use media packet pool for better stability and performance. * @since_tizen 3.0 * @remarks The @a pool should be released using media_packet_pool_deallocate() and destroyed using media_packet_pool_destroy(). - * @param[in] mediacodec The mediacodec handle - * @param[out] pool The allocated pool handle + * @param[in] mediacodec The mediacodec handle + * @param[out] pool The allocated pool handle * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter diff --git a/include/media_codec_port.h b/include/media_codec_port.h index 30937c2..f704059 100644 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -253,6 +253,8 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int bit); int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit, int bitrate); +int mc_configure(MMHandleType mediacodec, media_format_h format, int flags); + int mc_prepare(MMHandleType mediacodec); int mc_unprepare(MMHandleType mediacodec); diff --git a/src/media_codec.c b/src/media_codec.c index 45d9454..2d8c848 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -253,6 +253,22 @@ int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channe } } +int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format_h format, int flags) +{ + MEDIACODEC_INSTANCE_CHECK(mediacodec); + mediacodec_s *handle = (mediacodec_s *)mediacodec; + MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE); + + int ret = mc_configure(handle->mc_handle, format, flags); + + if (ret != MEDIACODEC_ERROR_NONE) { + return __convert_error_code(ret, (char *)__FUNCTION__); + } else { + handle->state = MEDIACODEC_STATE_IDLE; + return MEDIACODEC_ERROR_NONE; + } +} + int mediacodec_prepare(mediacodec_h mediacodec) { MEDIACODEC_INSTANCE_CHECK(mediacodec); diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 48760d6..4edb261 100644 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -257,6 +257,122 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b return ret; } +int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) +{ + int ret = MC_ERROR_NONE; + mc_handle_t *mc_handle = (mc_handle_t *) mediacodec; + int i; + const int codec_mask = 0xFFF0; + int codec_id = 0; + int channel = 0; + int samplerate = 0; + int bit = 0; + int bitrate = 0; + int width = 0; + int height = 0; + int fps = 0; + media_format_type_e type; + media_format_mimetype_e mimetype; + + if (!mc_handle) { + LOGE("fail invaild param"); + return MC_INVALID_ARG; + } + + if (media_format_get_type(format, &type) != MEDIA_FORMAT_ERROR_NONE) { + LOGE("failed to retrieve type"); + return MC_INVALID_ARG; + } + + if (type == MEDIA_FORMAT_AUDIO) { + media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &bitrate); + + if (GET_IS_ENCODER(flags)) { + if ((samplerate <= 0) || (channel <= 0) || (bit <= 0) || (bitrate <= 0)) { + LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d, bitrate : %d", + samplerate, channel, bit, bitrate); + return MC_PARAM_ERROR; + } + + mc_handle->info.encoder.samplerate = samplerate; + mc_handle->info.encoder.channel = channel; + mc_handle->info.encoder.bit = bit; + mc_handle->info.encoder.bitrate = bitrate * 1000; + } else if (GET_IS_DECODER(flags)) { + if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) { + LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d", + samplerate, channel, bit); + return MC_PARAM_ERROR; + } + mc_handle->info.decoder.samplerate = samplerate; + mc_handle->info.decoder.channel = channel; + mc_handle->info.decoder.bit = bit; + } else { + LOGE("either an encoder or a decoder must be set"); + return MC_PARAM_ERROR; + } + } else if (type == MEDIA_FORMAT_VIDEO) { + media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL); + media_format_get_video_frame_rate(format, &fps); + + if (GET_IS_ENCODER(flags)) { + if ((width <= 0) || (height <= 0) || (bitrate <= 0) || (fps <= 0)) { + LOGE("invalid pram is set : width : %d, height : %d, bitrate : %d, fps : %d", + width, height, bitrate, fps); + return MC_PARAM_ERROR; + } + + mc_handle->info.encoder.width = width; + mc_handle->info.encoder.height = height; + mc_handle->info.encoder.fps = fps; + mc_handle->info.encoder.bitrate = bitrate * 1000; + } else if (GET_IS_DECODER(flags)) { + if ((width <= 0) || (height <= 0)) { + LOGE("invalid pram is set : width : %d, height : %d", + width, height); + return MC_PARAM_ERROR; + } + + mc_handle->info.decoder.width = width; + mc_handle->info.decoder.height = height; + } else { + LOGE("either an encoder or a decoder must be set"); + return MC_PARAM_ERROR; + } + } else { + LOGE("invalid format type is set"); + return MC_PARAM_ERROR; + } + + if (!GET_IS_HW(flags) && !GET_IS_SW(flags)) + flags |= MEDIACODEC_SUPPORT_TYPE_SW; + + codec_id = mimetype & codec_mask; + + for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) { + if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type)) + break; + } + LOGD("support_list : %d, i : %d", mc_handle->ini->num_supported_codecs, i); + + if (i == mc_handle->ini->num_supported_codecs) + return MC_CODEC_NOT_FOUND; + + mc_handle->port_type = spec_emul[i].port_type; + + mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0; + mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0; + mc_handle->codec_id = codec_id; + mc_handle->is_video = CHECK_BIT(codec_id, 13); + + mc_handle->is_prepared = true; + + LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d", + mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video); + + return ret; +} + int mc_prepare(MMHandleType mediacodec) { int ret = MC_ERROR_NONE; diff --git a/test/media_codec_test.c b/test/media_codec_test.c index b0e0bbd..505dede 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -747,7 +747,7 @@ void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, app->offset += *size; } */ -int _configure(App *app, int codecid, int flag, gboolean *hardware) +int _configure(App *app, int codecid, int flag, gboolean *hardware, media_format_mimetype_e *codec_mime) { gboolean encoder; media_format_mimetype_e mime = 0; @@ -760,6 +760,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware) if (encoder) { extractor = yuv_extractor; mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + *codec_mime = MEDIA_FORMAT_H264_SP; } else { extractor = h264_extractor; mime = MEDIA_FORMAT_H264_SP; @@ -769,6 +770,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware) if (encoder) { extractor = yuv_extractor; mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + *codec_mime = MEDIA_FORMAT_MPEG4_SP; } else { extractor = mpeg4_extractor; mime = MEDIA_FORMAT_MPEG4_SP; @@ -778,15 +780,17 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware) if (encoder) { extractor = yuv_extractor; mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + *codec_mime = MEDIA_FORMAT_H263; } else { extractor = h263_extractor; - mime = MEDIA_FORMAT_H263P; + mime = MEDIA_FORMAT_H263; } break; case MEDIACODEC_AAC: if (encoder) { extractor = aacenc_extractor; mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ + *codec_mime = MEDIA_FORMAT_AAC; } else { extractor = aacdec_extractor; mime = MEDIA_FORMAT_AAC; @@ -796,6 +800,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware) if (encoder) { extractor = aacenc_extractor; mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ + *codec_mime = MEDIA_FORMAT_AAC_HE; } break; case MEDIACODEC_AAC_HE_PS: @@ -1366,6 +1371,8 @@ gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) void _mediacodec_prepare(App *app, gboolean frame_all) { int ret; + media_format_mimetype_e codec_mime; + media_format_h codec_format; g_print("supported codec lists -internal-\n"); mediacodec_foreach_supported_codec_static((mediacodec_supported_codec_cb)_foreach_cb, app); @@ -1376,47 +1383,74 @@ void _mediacodec_prepare(App *app, gboolean frame_all) g_print("mediacodec_create failed\n"); return; } - +#if 0 /* set codec */ ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag); if (ret != MEDIACODEC_ERROR_NONE) { g_print("mediacodec_set_codec failed\n"); return; } - +#endif /* get mime and link to each codec parser */ - app->mime = _configure(app, app->codecid, app->flag, &app->hardware); + app->mime = _configure(app, app->codecid, app->flag, &app->hardware, &codec_mime); /* set codec info */ ret = media_format_create(&fmt); switch (app->type) { case VIDEO_DEC: - ret = mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height); media_format_set_video_mime(fmt, app->mime); media_format_set_video_width(fmt, app->width); media_format_set_video_height(fmt, app->height); + + ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag); + if (ret != MEDIACODEC_ERROR_NONE) + g_print("mediacodec_configure failed\n"); break; case VIDEO_ENC: - ret = mediacodec_set_venc_info(app->mc_handle[0], app->width, app->height, app->fps, app->target_bits); media_format_set_video_mime(fmt, app->mime); media_format_set_video_width(fmt, app->width); media_format_set_video_height(fmt, app->height); media_format_set_video_avg_bps(fmt, app->target_bits); + + media_format_create(&codec_format); + media_format_set_video_mime(codec_format, codec_mime); + media_format_set_video_width(codec_format, app->width); + media_format_set_video_height(codec_format, app->height); + media_format_set_video_avg_bps(codec_format, app->target_bits); + media_format_set_video_frame_rate(codec_format, app->fps); + + ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag); + if (ret != MEDIACODEC_ERROR_NONE) + g_print("mediacodec_configure failed\n"); + media_format_unref(codec_format); break; case AUDIO_DEC: - ret = mediacodec_set_adec_info(app->mc_handle[0], app->samplerate, app->channel, app->bit); media_format_set_audio_mime(fmt, app->mime); media_format_set_audio_channel(fmt, app->channel); media_format_set_audio_samplerate(fmt, app->samplerate); media_format_set_audio_bit(fmt, app->bit); + + ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag); + if (ret != MEDIACODEC_ERROR_NONE) + g_print("mediacodec_configure failed\n"); break; case AUDIO_ENC: - ret = mediacodec_set_aenc_info(app->mc_handle[0], app->samplerate, app->channel, app->bit, app->bitrate); media_format_set_audio_mime(fmt, app->mime); media_format_set_audio_channel(fmt, app->channel); media_format_set_audio_samplerate(fmt, app->samplerate); media_format_set_audio_bit(fmt, app->bit); + + media_format_create(&codec_format); + media_format_set_audio_mime(codec_format, codec_mime); + media_format_set_audio_channel(codec_format, app->channel); + media_format_set_audio_samplerate(codec_format, app->samplerate); + media_format_set_audio_bit(codec_format, app->bit); + + ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag); + if (ret != MEDIACODEC_ERROR_NONE) + g_print("mediacodec_set_configure failed\n"); + media_format_unref(codec_format); break; default: g_print("invaild type\n"); -- 2.7.4 From cedd73c46c0d9c9211475788ef2f4271348defb9 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 18 Jul 2017 19:12:02 +0900 Subject: [PATCH 11/16] Increase MAXINUM_QNUM due to error callback invocation problem Change-Id: Ie4edc97f8e2a9e9c9764a1278f5204585548fe37 --- include/media_codec_port_gst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 3cf9120..626f9ad 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -55,7 +55,7 @@ extern "C" { #define AAC_CODECDATA_SIZE 16 #define WMA_CODECDATA_SIZE 64 #define VORBIS_CODECDATA_SIZE 4096 -#define MAXINUM_QNUM 15 +#define MAXINUM_QNUM 20 #define THRESHOLD_QNUM 5 /* gst port layer */ -- 2.7.4 From 501a4b43a944e14b66319f4d3a741b874b36082d Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 21 Jul 2017 17:34:25 +0900 Subject: [PATCH 12/16] Removed cyclic dependency with mediademuxer Change-Id: I7e2354284d14959fb2aece3fb815cadd29098ce2 --- packaging/capi-media-codec.spec | 2 -- test/CMakeLists.txt | 2 +- test/media_codec_test.c | 46 ++++++++++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 17 deletions(-) mode change 100755 => 100644 test/CMakeLists.txt diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 17b00a8..7196071 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -16,14 +16,12 @@ BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(capi-media-tool) -BuildRequires: pkgconfig(capi-media-camera) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(gstreamer-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) BuildRequires: pkgconfig(gstreamer-app-1.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(iniparser) -BuildRequires: pkgconfig(capi-mediademuxer) %description A Media Codec library in Tizen Native API diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt old mode 100755 new mode 100644 index 754b501..d6a1257 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(../include/headers) link_directories(${CMAKE_SOURCE_DIR}/../) INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera capi-mediademuxer) +pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 505dede..5eca332 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -25,19 +25,18 @@ #include #include #include -#include #include #include #include #include #include +#ifdef TIZEN_FEATURE_INTEGRATION +#include #include +#endif #define PACKAGE "media_codec_test" #define MAX_HANDLE 4 -#if 0 -#define DUMP_OUTBUF 1 -#endif #define TEST_FILE_SIZE (10 * 1024 * 1024) #define MAX_STRING_LEN 256 @@ -143,7 +142,11 @@ struct _App { gboolean enable_dump; gint frame; type_e type; + +#ifdef TIZEN_FEATURE_INTEGRATION camera_h camera_handle; + mediademuxer_h demuxer; +#endif GThread *thread; GCond thread_cond; @@ -156,7 +159,6 @@ struct _App { gint suspend; gchar filepath[256]; /* demuxer */ - mediademuxer_h demuxer; media_format_h format[MAX_HANDLE]; /* video */ mediacodec_h mc_handle[MAX_HANDLE]; @@ -216,7 +218,6 @@ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id); void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data); gint g_menu_state = CURRENT_STATUS_MAINMENU; -void demuxer_error_cb(mediademuxer_error_e error, void *user_data); gint _create_app(void *data) { @@ -1089,6 +1090,7 @@ void av_feed_resume(App *app) g_mutex_unlock(&app->thread_mutex); } +#ifdef TIZEN_FEATURE_INTEGRATION gpointer av_feed_thread(gpointer data) { App *app = (App *)data; @@ -1164,6 +1166,7 @@ gboolean feed_video(App *app) return TRUE; } +#endif void start_feed(App *app) { @@ -1330,11 +1333,6 @@ void _mediacodec_error_cb(mediacodec_error_e error, void *user_data) return; } -void demuxer_error_cb(mediademuxer_error_e error, void *user_data) -{ - g_print("Got Error %d from Mediademuxer\n", error); - return; -} void _mediacodec_eos_cb(void *user_data) { @@ -1348,6 +1346,13 @@ void _mediacodec_eos_cb(void *user_data) return; } +#ifdef TIZEN_FEATURE_INTEGRATION +void demuxer_error_cb(mediademuxer_error_e error, void *user_data) +{ + g_print("Got Error %d from Mediademuxer\n", error); + return; +} + void _mediademuxer_eos_cb(int track, void *user_data) { App *app = (App *)user_data; @@ -1361,6 +1366,7 @@ void _mediademuxer_eos_cb(int track, void *user_data) return; } +#endif gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) { @@ -1540,6 +1546,7 @@ void _media_packet_preview_cb(media_packet_h packet, void *user_data) return; } +#ifdef TIZEN_FEATURE_INTEGRATION void _mediacodec_camera_start(App *app) { int default_format = CAMERA_PIXEL_FORMAT_NV12; @@ -1592,7 +1599,9 @@ void _mediacodec_camera_stop(App *app) mediacodec_destroy(app->mc_handle[1]); return; } +#endif +#ifdef TIZEN_FEATURE_INTEGRATION void _mediacodec_auto_test(App *app, char *path) { gint ret = 0; @@ -1810,6 +1819,7 @@ void _mediacodec_auto_test(App *app, char *path) return; } +#endif void _mediacodec_unprepare(App *app) { @@ -1901,12 +1911,14 @@ void _interpret_main_menu(char *cmd, App *app) _mediacodec_unprepare(app); else if (strncmp(cmd, "dt", 2) == 0) _mediacodec_destroy(app); +#ifdef TIZEN_FEATURE_INTEGRATION else if (strncmp(cmd, "cr", 2) == 0) _mediacodec_camera_start(app); else if (strncmp(cmd, "ct", 2) == 0) _mediacodec_camera_stop(app); else if (strncmp(cmd, "au", 2) == 0) g_menu_state = CURRENT_STATUS_AUTO_TEST; +#endif else if (strncmp(cmd, "dp", 2) == 0) { if (!app->enable_dump) { app->enable_dump = TRUE; @@ -1973,8 +1985,10 @@ void displaymenu(void) g_print("*** input dec process number\n"); } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) { g_print("*** input get output buffer number\n"); +#ifdef TIZEN_FEATURE_INTEGRATION } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) { g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n"); +#endif } else { g_print("*** unknown status.\n"); } @@ -2142,7 +2156,7 @@ void interpret(char *cmd) case 3: tmp = atoi(cmd); - if (tmp <= 0 || tmp > INT_MAX) { + if (tmp <= 0 || tmp >= INT_MAX) { g_print(";;Invalid value\n"); reset_menu_state(); break; @@ -2162,7 +2176,7 @@ void interpret(char *cmd) { tmp = atoi(cmd); - if (tmp <= 0 || tmp > INT_MAX) { + if (tmp <= 0 || tmp >= 10) { g_print("Invalid value\n"); reset_menu_state(); break; @@ -2178,6 +2192,7 @@ void interpret(char *cmd) reset_menu_state(); } break; +#ifdef TIZEN_FEATURE_INTEGRATION case CURRENT_STATUS_AUTO_TEST: { int len; @@ -2200,6 +2215,7 @@ void interpret(char *cmd) } } break; +#endif } g_timeout_add(100, timeout_menu_display, 0); @@ -2226,10 +2242,12 @@ void display_sub_basic() g_print("dt. Destroy \t\t"); g_print("q. quit test suite \n"); g_print("dp. enable dump \n"); +#ifdef TIZEN_FEATURE_INTEGRATION g_print("-----------------------------------------------------------------------------------------\n"); g_print("cr. camera preview -> encoder -> decoder\n"); - g_print("au. interlocking with mediademuxer\n"); + g_print("au. integration test with mediademuxer\n"); g_print("ct. quit camera test\n"); +#endif g_print("\n"); g_print("=========================================================================================\n"); } -- 2.7.4 From 2655f967eee1a76605b351a8303660039873e450 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 3 Aug 2017 14:08:19 +0900 Subject: [PATCH 13/16] Added tc for verifying mediamuxer Change-Id: Id25024ce9dd66404e8c5603f58bd285e6fc373de --- packaging/capi-media-codec.spec | 3 ++ src/media_codec_port_gst.c | 6 +++ test/CMakeLists.txt | 2 + test/media_codec_test.c | 86 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 7196071..ff08340 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -22,6 +22,9 @@ BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) BuildRequires: pkgconfig(gstreamer-app-1.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(iniparser) +#BuildRequires: pkgconfig(capi-media-camera) +#BuildRequires: pkgconfig(capi-mediademuxer) +#BuildRequires: pkgconfig(capi-mediamuxer) %description A Media Codec library in Tizen Native API diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index ca4994d..83ab219 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2191,6 +2191,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp if (mcbuffer->packet) { media_packet_set_pts(mcbuffer->packet, GST_BUFFER_TIMESTAMP(buffer)); + media_packet_set_dts(mcbuffer->packet, GST_BUFFER_DTS(buffer)); media_packet_set_duration(mcbuffer->packet, GST_BUFFER_DURATION(buffer)); if (core->need_codec_data) { @@ -2297,6 +2298,7 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet gint ret = MEDIA_PACKET_ERROR_NONE; uint64_t buf_size = 0; uint64_t pts = 0; + uint64_t dts = 0; uint64_t dur = 0; void *buf_data = NULL; GstMCBuffer *mcbuffer = NULL; @@ -2333,6 +2335,10 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet return NULL; } + /* dts */ + media_packet_get_pts(packet, &dts); + GST_BUFFER_DTS(mcbuffer->buffer) = dts; + /* pts */ media_packet_get_pts(packet, &pts); GST_BUFFER_PTS(mcbuffer->buffer) = pts; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d6a1257..de10cdc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,12 +7,14 @@ link_directories(${CMAKE_SOURCE_DIR}/../) INCLUDE(FindPkgConfig) pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary) +#pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera capi-mediademuxer capi-mediamuxer) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pie") +#add_definitions(-DTIZEN_FEATURE_INTEGRATION) aux_source_directory(. sources) FOREACH(src ${sources}) GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 5eca332..80e6c60 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -33,6 +33,7 @@ #ifdef TIZEN_FEATURE_INTEGRATION #include #include +#include #endif #define PACKAGE "media_codec_test" @@ -140,12 +141,14 @@ struct _App { gboolean is_encoder; gboolean hardware; gboolean enable_dump; + gboolean enable_muxer; gint frame; type_e type; #ifdef TIZEN_FEATURE_INTEGRATION camera_h camera_handle; mediademuxer_h demuxer; + mediamuxer_h muxer; #endif GThread *thread; @@ -167,6 +170,7 @@ struct _App { guint fps; guint target_bits; media_format_mimetype_e mime; + gint track; gint video_track; /* Audio */ @@ -1286,7 +1290,13 @@ void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) else output_dump(app, out_pkt); } - +#ifdef TIZEN_FEATURE_INTEGRATION + if (app->enable_muxer) { + if (mediamuxer_write_sample(app->muxer, app->track, out_pkt) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_write_sample failed\n"); + g_print("write sample!!!\n"); + } +#endif app->frame_count++; app->fbd++; @@ -1366,6 +1376,29 @@ void _mediademuxer_eos_cb(int track, void *user_data) return; } + +void _mediamuxer_eos_cb(void *user_data) +{ + if (user_data == NULL) { + g_print("invalid param"); + return; + } + + App *app = (App *)user_data; + + g_print("muxer eos\n"); + + if (mediamuxer_stop(app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print(" mediamuxer_stop failed\n"); + + if (mediamuxer_unprepare(app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print(" mediamuxer_unprepare failed\n"); + + if (mediamuxer_destroy(app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print(" mediamuxer_destory failed\n"); + + g_print("mediamuxer destroyed\n"); +} #endif gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data) @@ -1452,6 +1485,7 @@ void _mediacodec_prepare(App *app, gboolean frame_all) media_format_set_audio_channel(codec_format, app->channel); media_format_set_audio_samplerate(codec_format, app->samplerate); media_format_set_audio_bit(codec_format, app->bit); + media_format_set_audio_avg_bps(codec_format, app->bitrate); ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag); if (ret != MEDIACODEC_ERROR_NONE) @@ -1485,6 +1519,36 @@ void _mediacodec_prepare(App *app, gboolean frame_all) return; } +#ifdef TIZEN_FEATURE_INTEGRATION + if (app->enable_muxer) { + if (mediamuxer_create(&app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_create failed\n"); + + if (mediamuxer_set_data_sink(app->muxer, "/tmp/muxtest.mp4", MEDIAMUXER_CONTAINER_FORMAT_MP4) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_set_data_sink failed\n"); + + media_format_create(&app->format[0]); + if (app->type == AUDIO_ENC) + media_format_set_audio_mime(app->format[0], codec_mime); + else if (app->type == VIDEO_ENC) + media_format_set_video_mime(app->format[0], codec_mime); + else + g_print("invalid format\n"); + + if (mediamuxer_set_eos_cb(app->muxer, _mediamuxer_eos_cb, app) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_set_eos_cb failed\n"); + + if (mediamuxer_add_track(app->muxer, app->format[0], &app->track) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_add_track failed\n"); + + if (mediamuxer_prepare(app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_prepare failed\n"); + + if (mediamuxer_start(app->muxer) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_start failed\n"); + } +#endif + /* get packet pool instance */ ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool); @@ -1828,6 +1892,10 @@ void _mediacodec_unprepare(App *app) void _mediacodec_destroy(App *app) { + if (app == NULL) { + g_print("invalid param"); + return; + } #ifdef USE_POOL if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) { @@ -1843,6 +1911,12 @@ void _mediacodec_destroy(App *app) g_print("media packet pool destroyed! \n"); #endif mediacodec_destroy(app->mc_handle[0]); +#ifdef TIZEN_FEATURE_INTEGRATION + if (app->enable_muxer) { + if (mediamuxer_close_track(app->muxer, app->track) != MEDIAMUXER_ERROR_NONE) + g_print("mediamuxer_close_track failed\n"); + } +#endif } void input_filepath(char *filename, App *app) @@ -1918,6 +1992,15 @@ void _interpret_main_menu(char *cmd, App *app) _mediacodec_camera_stop(app); else if (strncmp(cmd, "au", 2) == 0) g_menu_state = CURRENT_STATUS_AUTO_TEST; + else if (strncmp(cmd, "mp", 2) == 0) { + if (!app->enable_muxer) { + app->enable_muxer = TRUE; + g_print("muxer enabled\n"); + } else { + app->enable_dump = FALSE; + g_print("dump disabled\n"); + } + } #endif else if (strncmp(cmd, "dp", 2) == 0) { if (!app->enable_dump) { @@ -2243,6 +2326,7 @@ void display_sub_basic() g_print("q. quit test suite \n"); g_print("dp. enable dump \n"); #ifdef TIZEN_FEATURE_INTEGRATION + g_print("mp. enable muxer \n"); g_print("-----------------------------------------------------------------------------------------\n"); g_print("cr. camera preview -> encoder -> decoder\n"); g_print("au. integration test with mediademuxer\n"); -- 2.7.4 From e5fd50a816f292ff3ca5d3b4c0e9f3eb7400f396 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 7 Aug 2017 13:14:21 +0900 Subject: [PATCH 14/16] fixed pvs issues Change-Id: I25db77a3ab066ea0a82c963a54af08021f20ae91 --- src/media_codec_port_gst.c | 7 ++++--- test/media_codec_test.c | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 83ab219..daa574f 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2421,7 +2421,10 @@ ERROR: void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet) { - g_atomic_int_dec_and_test(&core->etb_count); + if (core) { + g_atomic_int_dec_and_test(&core->etb_count); + LOGD("@v(%d)e(%d) input port used(%d)----- ", core->video, core->encoder, core->etb_count); + } if (core && core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) { ((mc_empty_buffer_cb)core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) @@ -2863,8 +2866,6 @@ static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, G break; } - return MEDIACODEC_ERROR_INVALID_STREAM; - INTERNAL_ERROR: return MEDIACODEC_ERROR_INTERNAL; } diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 80e6c60..005d4f3 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -855,7 +855,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware, media_forma void _mediacodec_process_input(App *app) { - gint i; + gint i, j; gboolean have_frame = FALSE; gint ret; static guint64 pts = 0L; @@ -902,7 +902,7 @@ void _mediacodec_process_input(App *app) media_packet_get_video_stride_width(pkt, 0, &stride_width); offset = app->width*app->height; - for (i = 0; i < app->height; i++) { + for (j = 0; j < app->height; j++) { memcpy(buf_data_ptr, tmp, app->width); buf_data_ptr += stride_width; tmp += app->width; @@ -913,7 +913,7 @@ void _mediacodec_process_input(App *app) media_packet_get_video_stride_width(pkt, 1, &stride_width); size = app->width * app->height / 2; - for (i = 0; i < app->height / 2; i++) { + for (j = 0; j < app->height / 2; j++) { memcpy(buf_data_ptr, tmp, app->width); buf_data_ptr += stride_width; tmp += app->width; @@ -924,7 +924,7 @@ void _mediacodec_process_input(App *app) media_packet_get_video_stride_width(pkt, 1, &stride_width); size = (app->width>>1) * (app->height>>1); - for (i = 0; i < app->height/2; i++) { + for (j = 0; j < app->height/2; j++) { memcpy(buf_data_ptr, tmp, app->width/2); buf_data_ptr += stride_width; tmp += app->width/2; @@ -935,7 +935,7 @@ void _mediacodec_process_input(App *app) media_packet_get_video_stride_width(pkt, 2, &stride_width); offset += size; - for (i = 0; i < app->height/2; i++) { + for (j = 0; j < app->height/2; j++) { memcpy(buf_data_ptr, tmp, app->width/2); buf_data_ptr += stride_width; tmp += app->width/2; -- 2.7.4 From f6fb6ae0689cb5a51115e0b32191eb61d231d2d2 Mon Sep 17 00:00:00 2001 From: Praveen R Jadhav Date: Mon, 28 Aug 2017 09:38:51 +0530 Subject: [PATCH 15/16] Pointers changed to guint8 type in order to calculate offset properly Change-Id: I4344a8b3623c44a22282439d61c733ecf23ef307 --- src/media_codec_port_gst.c | 12 ++++++------ test/media_codec_test.c | 34 +++++++++++++++++----------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index daa574f..c639c02 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -295,7 +295,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h gint width; gint height; uint32_t plane_num; - void *planes[2]; + guint8 *planes[2]; mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; @@ -308,7 +308,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h return MC_ERROR; } - ret = media_packet_get_video_plane_data_ptr(packet, 0, &planes[0]); + ret = media_packet_get_video_plane_data_ptr(packet, 0, (void **)&planes[0]); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_get_video_plane_data_ptr failed"); return MC_ERROR; @@ -331,7 +331,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h mcbuffer->buf_size += stride_width * stride_height; for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(packet, i, &planes[1]); + media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]); media_packet_get_video_stride_width(packet, i, &stride_width); media_packet_get_video_stride_height(packet, i, &stride_height); @@ -352,7 +352,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h stride = 0; for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(packet, i, &planes[1]); + media_packet_get_video_plane_data_ptr(packet, i, (void **)&planes[1]); media_packet_get_video_stride_width(packet, i, &stride_width); media_packet_get_video_stride_height(packet, i, &stride_height); @@ -699,7 +699,7 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint guint hsize1, hsize2, hsize3; GstBuffer *tmp_header; GstMapInfo map; - void *buf_data = NULL; + guint8 *buf_data = NULL; guint8 *tmp_buf = NULL; ret = media_packet_get_buffer_size(mcbuffer->packet, &buf_size); @@ -708,7 +708,7 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint return ret; } - ret = media_packet_get_buffer_data_ptr(mcbuffer->packet, &buf_data); + ret = media_packet_get_buffer_data_ptr(mcbuffer->packet, (void **)&buf_data); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("buffer data get failed"); return ret; diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 005d4f3..64491d5 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -859,7 +859,7 @@ void _mediacodec_process_input(App *app) gboolean have_frame = FALSE; gint ret; static guint64 pts = 0L; - void *buf_data_ptr = NULL; + guint8 *buf_data_ptr = NULL; media_packet_h pkt = NULL; guint8 *tmp; gint read; @@ -892,13 +892,13 @@ void _mediacodec_process_input(App *app) } if (app->type != VIDEO_ENC) { - media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr); + media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr); media_packet_set_buffer_size(pkt, (uint64_t)read); memcpy(buf_data_ptr, tmp, read); g_print("tmp:%p, read:%d\n", tmp, read); } else { /* Y */ - media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); offset = app->width*app->height; @@ -909,7 +909,7 @@ void _mediacodec_process_input(App *app) } if (app->hardware == TRUE) { - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); size = app->width * app->height / 2; @@ -920,7 +920,7 @@ void _mediacodec_process_input(App *app) } } else { /* U */ - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); size = (app->width>>1) * (app->height>>1); @@ -931,7 +931,7 @@ void _mediacodec_process_input(App *app) } /* V */ - media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); offset += size; @@ -961,7 +961,7 @@ gboolean read_data(App *app) gboolean codec_config = FALSE; gint ret; static guint64 pts = 0L; - void *buf_data_ptr = NULL; + guint8 *buf_data_ptr = NULL; media_packet_h pkt = NULL; guint8 *tmp; gint i; @@ -1012,14 +1012,14 @@ gboolean read_data(App *app) if (app->type != VIDEO_ENC) { - media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr); + media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr); media_packet_set_buffer_size(pkt, (uint64_t)read); memcpy(buf_data_ptr, tmp, read); g_print("tmp:%p, read:%d\n", tmp, read); } else { /* Y */ - media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); offset = app->width*app->height; @@ -1030,7 +1030,7 @@ gboolean read_data(App *app) } if (app->hardware == TRUE) { - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); size = app->width * app->height>>1; @@ -1042,7 +1042,7 @@ gboolean read_data(App *app) } else { /* U */ - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); size = (app->width>>1) * (app->height>>1); @@ -1053,7 +1053,7 @@ gboolean read_data(App *app) } /* V */ - media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr); + media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); offset += size; @@ -2386,7 +2386,7 @@ void mc_hex_dump(char *desc, void *addr, gint len) void decoder_output_dump(App *app, media_packet_h pkt) { - void *temp; + guint8 *temp; int i = 0; int stride_width, stride_height; gchar filename[100] = {0}; @@ -2396,7 +2396,7 @@ void decoder_output_dump(App *app, media_packet_h pkt) g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height); fp = fopen(filename, "ab"); - media_packet_get_video_plane_data_ptr(pkt, 0, &temp); + media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&temp); media_packet_get_video_stride_width(pkt, 0, &stride_width); media_packet_get_video_stride_height(pkt, 0, &stride_height); g_print("stride : %d, %d\n", stride_width, stride_height); @@ -2407,21 +2407,21 @@ void decoder_output_dump(App *app, media_packet_h pkt) } if (app->hardware == TRUE) { - media_packet_get_video_plane_data_ptr(pkt, 1, &temp); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp); media_packet_get_video_stride_width(pkt, 1, &stride_width); for (i = 0; i < app->height/2; i++) { ret = fwrite(temp, app->width, 1, fp); temp += stride_width; } } else { - media_packet_get_video_plane_data_ptr(pkt, 1, &temp); + media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp); media_packet_get_video_stride_width(pkt, 1, &stride_width); for (i = 0; i < app->height/2; i++) { ret = fwrite(temp, app->width/2, 1, fp); temp += stride_width; } - media_packet_get_video_plane_data_ptr(pkt, 2, &temp); + media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&temp); media_packet_get_video_stride_width(pkt, 2, &stride_width); for (i = 0; i < app->height/2; i++) { ret = fwrite(temp, app->width/2, 1, fp); -- 2.7.4 From 2b5ff1e1ee365b801a1e5baa44ba825f6893a556 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 4 Sep 2017 18:13:53 +0900 Subject: [PATCH 16/16] Removed TM1 kernel dependency Change-Id: Ie02972ac83881534744efd2e51e811348d5709f6 --- include/media_codec_port_gst.h | 9 ----- packaging/capi-media-codec.spec | 90 +---------------------------------------- src/media_codec_port_gst.c | 69 ------------------------------- 3 files changed, 2 insertions(+), 166 deletions(-) mode change 100644 => 100755 packaging/capi-media-codec.spec diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 626f9ad..4373b7b 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -71,15 +71,6 @@ typedef enum { BUF_SHARE_METHOD_FLUSH_BUFFER } buf_share_method_t; -#ifdef TIZEN_PROFILE_LITE -struct _ion_mmu_data_t { - gint master_id; - gint fd_buffer; - unsigned long iova_addr; - size_t iova_size; -}; -#endif - struct _mc_gst_port_t { mc_gst_core_t *core; guint num_buffers; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec old mode 100644 new mode 100755 index ff08340..d1871f2 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -29,21 +29,7 @@ BuildRequires: pkgconfig(iniparser) %description A Media Codec library in Tizen Native API -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -%package extension-TM1 -Summary: Extension for mobile TM1 -Requires: %{name} = %{version}-%{release} -#!BuildIgnore: kernel-headers -BuildConflicts: linux-glibc-devel -BuildRequires: kernel-headers-3.10-sc7730 - -%description extension-TM1 -A Media Codec library in Tizen Native API Extension for mobile TM1 -%endif -%endif + %package devel @@ -59,40 +45,8 @@ Requires: %{name} = %{version}-%{release} %build -%if 0%{?sec_build_binary_debug_enable} -export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" -export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" -export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" -%endif -%ifarch %{arm} -export CFLAGS="$CFLAGS -DENABLE_FFMPEG_CODEC" -%endif export CFLAGS="$CFLAGS -DSYSCONFDIR=\\\"%{_sysconfdir}\\\"" -export CFLAGS_DEFAULT="$CFLAGS" - -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -# extension-TM1 -export CFLAGS="$CFLAGS_DEFAULT -DTIZEN_PROFILE_LITE" - -MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -%cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} - -make %{?jobs:-j%jobs} - -mkdir -p tm1 - -%make_install -ls -al %{buildroot}%{_libdir}/libcapi-media-codec.so.* -cp -a %{buildroot}%{_libdir}/libcapi-media-codec.so.* tm1/ - -%endif -%endif -# common -export CFLAGS="$CFLAGS_DEFAULT" MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} @@ -106,44 +60,6 @@ cp test/media_codec_test %{buildroot}/usr/bin %make_install - -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -# extension-TM1 -pushd tm1 -for FILE in libcapi-media-codec.so.*; do mv "$FILE" "%{buildroot}%{_libdir}/$FILE.tm1"; done -popd - -%post extension-TM1 -pushd %{_libdir} -for FILE in libcapi-media-codec.so.*.tm1; do mv "$FILE" "${FILE%.tm1}"; done -popd -/sbin/ldconfig - -%preun extension-TM1 -case "$1" in - 0) - # This is an un-installation. - pushd %{_libdir} - for FILE in libcapi-media-codec.so.*; do mv "$FILE" "${FILE%.tm1}"; done - popd - /sbin/ldconfig - ;; - 1) - # This is an upgrade. - # Do nothing. - : - ;; -esac - -%files extension-TM1 -%manifest capi-media-codec.manifest -%{_libdir}/libcapi-media-codec.so.*.tm1 -%endif -%endif - %post /sbin/ldconfig @@ -153,9 +69,7 @@ esac %files %manifest capi-media-codec.manifest %{_libdir}/libcapi-media-codec.so.* -%ifarch %{arm} -%exclude %{_libdir}/libcapi-media-codec.so.*.tm1 -%endif + %license LICENSE.APLv2 /usr/bin/* #%{_bindir}/* diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index c639c02..27663cf 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -28,12 +28,6 @@ #include #include -#ifdef TIZEN_PROFILE_LITE -#include -#include -#include -#endif - /* * Internal Implementation */ @@ -75,9 +69,6 @@ static const gchar * _mc_bit_to_string(int bit); static int _mc_get_support_bit_from_format(media_format_mimetype_e format); 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 -static int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr, int *phy_size); -#endif 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); @@ -1558,9 +1549,7 @@ 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; @@ -2617,21 +2606,6 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet tbm_bo_unmap(mm_vbuffer->handle.bo[i]); } -#ifdef TIZEN_PROFILE_LITE - gint phy_addr = 0; - gint phy_size = 0; - tbm_bo_handle handle_fd = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); - if (handle_fd.ptr == NULL) { - LOGE("Invaild bo handle"); - return NULL; - } - - if (__tbm_get_physical_addr_bo(handle_fd, &phy_addr, &phy_size) == 0) { - mm_vbuffer->handle.paddr[0] = (void *)phy_addr; - LOGD("mm_vbuffer->paddr : %p", mm_vbuffer->handle.paddr[0]); - } -#endif - mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO; mm_vbuffer->width[0] = surface_info.width; mm_vbuffer->height[0] = surface_info.height; @@ -2952,49 +2926,6 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) MEDIACODEC_FLEAVE(); } -#ifdef TIZEN_PROFILE_LITE -gint __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_size) -{ - gint ret = 0; - gint open_flags = O_RDWR; - gint ion_fd = -1; - - ion_mmu_data_t mmu_data; - struct ion_custom_data custom_data; - - memset(&mmu_data, 0x0, sizeof(ion_mmu_data_t)); - - mmu_data.fd_buffer = handle_bo.u32; - custom_data.cmd = 4; - custom_data.arg = (unsigned long)&mmu_data; - - ion_fd = open("/dev/ion", open_flags); - if (ion_fd < 0) - LOGE("[tbm_get_physical_addr_bo] ion_fd open device failed"); - - if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) { - LOGE("[tbm_get_physical_addr_bo] ION_IOC_CUSTOM failed"); - ret = -1; - } - - if (!ret) { - *phy_addr = mmu_data.iova_addr; - *phy_size = mmu_data.iova_size; - } else { - *phy_addr = 0; - *phy_size = 0; - LOGW("[tbm_get_physical_addr_bo] getting physical address is failed. phy_addr = 0"); - } - - if (ion_fd != -1) { - close(ion_fd); - ion_fd = -1; - } - - return 0; -} -#endif - #if TIZEN_EXYNOS_SPECIFIC /* * Get tiled address of position(x,y) -- 2.7.4