From fcc64519a77603c53dcfd4f98ea054323efe2492 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 16 May 2016 11:20:13 +0900 Subject: [PATCH 01/16] Update caps when info. of packet is changed. Change-Id: I6140d2add2a2ca09f93383a678dc0e28340b4dcb --- include/media_codec_port_gst.h | 4 +- packaging/capi-media-codec.spec | 4 +- src/media_codec_port.c | 9 ++- src/media_codec_port_gst.c | 132 ++++++++++++++++++++++++++++++++-------- 4 files changed, 118 insertions(+), 31 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 4a396ef..eae6f9a 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -129,8 +129,8 @@ struct _mc_gst_core_t bool unprepare_flag; unsigned int prepare_count; unsigned int num_live_buffers; - unsigned int queued_count; - unsigned int dequeued_count; + unsigned int etb_count; + unsigned int ftb_count; mediacodec_codec_type_e codec_id; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 379e8fa..28f5cf5 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -1,7 +1,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.4.0 -Release: 2 +Version: 0.4.1 +Release: 0 Group: Multimedia/API License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/src/media_codec_port.c b/src/media_codec_port.c index a7e15af..4e94746 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -205,7 +205,7 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in mc_handle->info.encoder.width = width; mc_handle->info.encoder.height = height; mc_handle->info.encoder.fps = fps; - mc_handle->info.encoder.bitrate = target_bits; + mc_handle->info.encoder.bitrate = target_bits * 1000; mc_handle->is_prepared = true; return ret; @@ -254,7 +254,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b mc_handle->info.encoder.samplerate = samplerate; mc_handle->info.encoder.channel = channel; mc_handle->info.encoder.bit = bit; - mc_handle->info.encoder.bitrate = bitrate; + mc_handle->info.encoder.bitrate = bitrate * 1000; mc_handle->is_prepared = true; @@ -333,6 +333,11 @@ int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t tim return MC_INVALID_ARG; } + if (!inbuf) { + LOGE("invaild input buffer"); + return MC_INVALID_IN_BUF; + } + switch (mc_handle->port_type) { case MEDIACODEC_PORT_TYPE_GENERAL: break; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 76bf0b4..dbd4d24 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -49,6 +49,7 @@ static mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core); static void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data); static int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data); static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config); +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, GstCaps **caps, media_packet_h pkt, bool codec_config); static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *buff); static gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw); @@ -611,7 +612,7 @@ int __mc_hw_h264enc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, "height", G_TYPE_INT, enc_info->height, "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); - g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate*1000, NULL); + g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps); @@ -631,7 +632,7 @@ int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gb "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL); + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps); @@ -651,7 +652,7 @@ int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *bu "height", G_TYPE_INT, enc_info->height, "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL); + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps); @@ -784,6 +785,7 @@ int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gbool "format", G_TYPE_STRING, "F32LE", "layout", G_TYPE_STRING, "interleaved", NULL); + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); /* +----GstAudioEncoder +----avenc_aac @@ -1298,8 +1300,6 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* return ret; } - - int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, guint codecdata_size) { int ret = MEDIA_PACKET_ERROR_NONE; @@ -1416,8 +1416,8 @@ mc_gst_core_t *mc_gst_core_new() core->need_sync_flag = false; core->unprepare_flag = false; core->prepare_count = 0; - core->queued_count = 0; - core->dequeued_count = 0; + core->etb_count = 0; + core->ftb_count = 0; g_atomic_int_set(&core->available_queue->running, 1); core->available_queue->thread = g_thread_new("feed thread", &feed_task, core); @@ -1505,6 +1505,65 @@ void mc_gst_port_free(mc_gst_port_t *port) return; } +gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) +{ + gboolean is_updated = FALSE; + + 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; + + media_format_get_video_info(fmt, NULL, &width, &height, &bitrate, NULL); + + if ((codec_info->width != width) || (codec_info->height != height)) { + LOGD("Resolution changed : %dx%d -> %dx%d",codec_info->width, codec_info->height, width, height); + codec_info->width = width; + codec_info->height = height; + is_updated = TRUE; + } + + if (core->encoder) { + mc_encoder_info_t *enc_info = (mc_decoder_info_t *)core->codec_info; + + if (enc_info->bitrate != bitrate) { + LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); + enc_info->bitrate = bitrate; + is_updated = TRUE; + } + } + } else { + int channel; + int samplerate; + int bit; + int bitrate; + + media_format_get_audio_info(fmt, NULL, &channel, &samplerate, &bit, &bitrate); + + if ((codec_info->channel != channel) || (codec_info->samplerate != samplerate) || (codec_info->bit != bit)) { + LOGD("Audio info. changed : %d -> %d, %d -> %d, %d -> %d", codec_info->channel, channel, codec_info->samplerate, samplerate, codec_info->bit, bit); + codec_info->channel = channel; + codec_info->samplerate = samplerate; + codec_info->bit = bit; + is_updated = TRUE; + } + + if (core->encoder) { + mc_encoder_info_t *enc_info = (mc_decoder_info_t *)core->codec_info; + + if (enc_info->bitrate != bitrate) { + LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); + enc_info->bitrate = bitrate; + is_updated = TRUE; + } + } + } + + return is_updated; +} + static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config) { /*TODO remove is_hw param*/ @@ -1531,6 +1590,7 @@ static gpointer feed_task(gpointer data) int ret = MC_ERROR_NONE; bool codec_config = FALSE; bool eos = FALSE; + media_format_h fmt = NULL; media_packet_h in_buf = NULL; GstMCBuffer *buff = NULL; GstCaps *new_caps = NULL; @@ -1545,6 +1605,13 @@ static gpointer feed_task(gpointer data) if (!in_buf) goto LEAVE; + media_packet_get_format(in_buf, &fmt); + if (fmt) { + if (_mc_update_packet_info(core, fmt)) + initiative = TRUE; + media_format_unref(fmt); + } + if (media_packet_is_codec_config(in_buf, &codec_config) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_is_codec_config failed"); goto ERROR; @@ -1562,7 +1629,7 @@ static gpointer feed_task(gpointer data) } if (codec_config) - initiative = true; + initiative = TRUE; if (initiative) { GstPad *pad; @@ -1919,7 +1986,7 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint */ if (core->prepare_count == 0) - return MEDIACODEC_ERROR_INVALID_STATE; + return MC_INVALID_STATUS; g_mutex_lock(&core->drain_lock); @@ -1933,8 +2000,8 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint } g_mutex_unlock(&core->drain_lock); - LOGI("@v(%d)e(%d)process_input(%d): %p", core->video, core->encoder, core->queued_count, inbuf); - core->queued_count++; + g_atomic_int_inc(&core->etb_count); + LOGI("@v(%d)e(%d)process_input(%d): %p", core->video, core->encoder, core->etb_count, inbuf); MEDIACODEC_FLEAVE(); @@ -1964,6 +2031,7 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6 ret = MC_OUTPUT_BUFFER_EMPTY; LOGD("output_queue is empty"); } + *outbuf = out_pkt; g_mutex_unlock(&core->ports[1]->mutex); @@ -2273,7 +2341,6 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp LOGI("@%p(%d) out_pkt : %p", core, core->encoder, out_pkt); gst_memory_unmap(mem, &map); - if (out_pkt) { media_packet_set_extra(out_pkt, buffer); media_packet_set_pts(out_pkt, GST_BUFFER_TIMESTAMP(buffer)); @@ -2289,11 +2356,12 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp } g_mutex_lock(&core->ports[1]->mutex); + /* push it to output buffer queue */ g_queue_push_tail(core->ports[1]->queue, out_pkt); - core->dequeued_count++; - LOGD("dequeued : %d", core->dequeued_count); + g_atomic_int_inc(&core->ftb_count); + LOGD("dequeued : %d", core->ftb_count); LOGD("GST_BUFFER_TIMESTAMP = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer))); g_mutex_unlock(&core->ports[1]->mutex); @@ -2318,8 +2386,11 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * GstMapInfo map = GST_MAP_INFO_INIT; MMVideoBuffer *mm_video_buf = NULL; + MEDIACODEC_FENTER(); + + mc_gst_core_t *core = (mc_gst_core_t *)user_data; - LOGD("packet finalized: %p", packet); + g_atomic_int_dec_and_test(&core->ftb_count); media_packet_get_extra(packet, &buffer); n = gst_buffer_n_memory(buffer); @@ -2340,6 +2411,9 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * gst_memory_unmap(mem, &map); } gst_buffer_unref((GstBuffer *)buffer); + LOGD("@v(%d)e(%d)output port filled buffer(%d): %p", core->video, core->encoder, core->ftb_count, packet); + + MEDIACODEC_FLEAVE(); return MEDIA_PACKET_FINALIZE; } @@ -2585,7 +2659,7 @@ 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); - LOGE("mm_vbuffer->handle.bo[%d] : %p", i, mm_vbuffer->handle.bo[i]); + LOGD("mm_vbuffer->handle.bo[%d] : %p", i, mm_vbuffer->handle.bo[i]); } #ifdef TIZEN_PROFILE_LITE @@ -2603,6 +2677,8 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet mm_vbuffer->height[0] = surface_info.height; mm_vbuffer->width[1] = surface_info.width; mm_vbuffer->height[1] = surface_info.height>>1; + mm_vbuffer->size[0] = surface_info.planes[0].size; + mm_vbuffer->size[1] = surface_info.planes[1].size; mm_vbuffer->stride_width[0] = surface_info.planes[0].stride; mm_vbuffer->stride_height[0] = surface_info.planes[0].size / surface_info.planes[0].stride; mm_vbuffer->stride_width[1] = surface_info.planes[1].stride; @@ -2616,20 +2692,25 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet static void gst_mediacodec_buffer_finalize(GstMCBuffer *mc_buffer) { + MEDIACODEC_FENTER(); + if (!mc_buffer) return; mc_gst_core_t *core = (mc_gst_core_t *)mc_buffer->core; + g_atomic_int_dec_and_test(&core->etb_count); if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) { ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) (mc_buffer->pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]); } - LOGD("%p(%p) buffer finalized...", mc_buffer, mc_buffer->pkt); + LOGD("@v(%d)e(%d)input port emptied buffer(%d): %p", core->video, core->encoder, core->etb_count, mc_buffer->pkt); free(mc_buffer); mc_buffer = NULL; + MEDIACODEC_FLEAVE(); + return; } @@ -2796,6 +2877,7 @@ static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage * message, switch (error->code) { case GST_STREAM_ERROR_DECODE: + case GST_STREAM_ERROR_FAILED: return MEDIACODEC_ERROR_INVALID_STREAM; break; @@ -2805,11 +2887,8 @@ static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage * message, return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT; break; - case GST_STREAM_ERROR_FAILED: - return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT; - break; - default: + return MEDIACODEC_ERROR_INTERNAL; break; } @@ -2849,10 +2928,13 @@ static void _mc_gst_set_flush_input(mc_gst_core_t *core) { media_packet_h pkt = NULL; + MEDIACODEC_FENTER(); LOGI("_mc_gst_set_flush_input is called"); while (!mc_async_queue_is_empty(core->available_queue->input)) { pkt = mc_async_queue_pop_forced(core->available_queue->input); + g_atomic_int_dec_and_test(&core->etb_count); + LOGD("%p poped(%d)", pkt, core->etb_count); if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) { ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) @@ -2861,7 +2943,7 @@ static void _mc_gst_set_flush_input(mc_gst_core_t *core) } mc_async_queue_flush(core->available_queue->input); - core->queued_count = 0; + MEDIACODEC_FLEAVE(); } static void _mc_gst_set_flush_output(mc_gst_core_t *core) @@ -2871,16 +2953,16 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) MEDIACODEC_FENTER(); g_mutex_lock(&core->ports[1]->mutex); - while (!g_queue_is_empty(core->ports[1]->queue)) { + while (!g_queue_is_empty(core->ports[1]->queue)) { pkt = g_queue_pop_head(core->ports[1]->queue); - LOGD("outpkt in output_queue : %p", pkt); + g_atomic_int_dec_and_test(&core->ftb_count); + LOGD("%p poped(%d)", pkt, core->ftb_count); if (pkt) { media_packet_destroy(pkt); LOGD("outpkt destroyed"); pkt = NULL; } } - core->dequeued_count = 0; g_mutex_unlock(&core->ports[1]->mutex); MEDIACODEC_FLEAVE(); } -- 2.7.4 From 5daa1e23466e64ed32dfa49e749338f0957aef13 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 31 May 2016 16:30:19 +0900 Subject: [PATCH 02/16] refactoring for adding backend pkg Change-Id: Ie3166abb2b1d9b600f02d5179460fc3596f2c77d --- CMakeLists.txt | 2 +- include/media_codec_port_gst.h | 216 ++++++++---------- src/media_codec_port_gst.c | 505 +++++++++++++++++++---------------------- test/media_codec_test.c | 372 +++++++++++++++++++++++------- 4 files changed, 622 insertions(+), 473 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cba697..b80b61c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ FOREACH(flag ${${fw_name}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall") +SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") IF("${ARCH}" STREQUAL "arm") diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index eae6f9a..52793e2 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -58,150 +58,134 @@ typedef struct _mc_gst_core_t mc_gst_core_t; typedef struct _GstMCBuffer GstMCBuffer; typedef enum { - BUF_SHARE_METHOD_PADDR = 0, - BUF_SHARE_METHOD_FD, - BUF_SHARE_METHOD_TIZEN_BUFFER, - BUF_SHARE_METHOD_FLUSH_BUFFER + BUF_SHARE_METHOD_PADDR = 0, + BUF_SHARE_METHOD_FD, + BUF_SHARE_METHOD_TIZEN_BUFFER, + BUF_SHARE_METHOD_FLUSH_BUFFER } buf_share_method_t; #ifdef TIZEN_PROFILE_LITE struct ion_mmu_data { - int master_id; - int fd_buffer; - unsigned long iova_addr; - size_t iova_size; + int master_id; + int fd_buffer; + unsigned long iova_addr; + size_t iova_size; }; #endif struct _mc_gst_port_t { - mc_gst_core_t *core; - unsigned int num_buffers; - unsigned int buffer_size; - unsigned int index; - bool is_allocated; - media_packet_h *buffers; - //GSem - GQueue *queue; - GMutex mutex; - GCond buffer_cond; + mc_gst_core_t *core; + unsigned int num_buffers; + unsigned int buffer_size; + unsigned int index; + bool is_allocated; + media_packet_h *buffers; + GQueue *queue; + GMutex mutex; + GCond buffer_cond; }; struct _mc_gst_core_t { - int(**vtable)(); - const char *mime; - //int format; - gchar *format; - GstElement* pipeline; - GstElement* appsrc; - GstElement* capsfilter; - GstElement* parser; - GstElement* fakesink; - GstElement* codec; - MMVideoBuffer *psimgb; - tbm_bufmgr bufmgr; - int drm_fd; - - GMainContext *thread_default; - gulong signal_handoff; - gint bus_whatch_id; - gint probe_id; - - GMutex eos_mutex; - GMutex eos_wait_mutex; - GMutex prepare_lock; - GMutex drain_lock; - GCond eos_cond; - GCond eos_waiting_cond; - - GstState state; - bool output_allocated; - bool encoder; - bool video; - bool is_hw; - bool eos; - bool eos_waiting; - bool codec_config; - 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; - - - mediacodec_codec_type_e codec_id; - media_format_mimetype_e out_mime; - media_format_h output_fmt; - mc_gst_port_t *ports[2]; - mc_bitstream_t bits; - - mc_aqueue_t *available_queue; - GQueue *output_queue; - - void *codec_info; - unsigned char codec_data[100]; - int codec_data_size; - - void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; - void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; - + int(**vtable)(); + const char *mime; + gchar *format; + GstElement* pipeline; + GstElement* appsrc; + GstElement* capsfilter; + GstElement* parser; + GstElement* fakesink; + GstElement* codec; + tbm_bufmgr bufmgr; + int drm_fd; + + GMainContext *thread_default; + gulong signal_handoff; + gint bus_whatch_id; + gint probe_id; + + GMutex eos_mutex; + GMutex eos_wait_mutex; + GMutex prepare_lock; + GMutex drain_lock; + 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_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; + + mediacodec_codec_type_e codec_id; + media_format_mimetype_e out_mime; + media_format_h output_fmt; + mc_gst_port_t *ports[2]; + mc_bitstream_t bits; + + mc_aqueue_t *available_queue; + GQueue *output_queue; + + void *codec_info; + + void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; + void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; }; struct _GstMCBuffer { - GstBuffer *buffer; - int buf_size; - mc_gst_core_t* core; - media_packet_h pkt; - bool has_imgb; + GstBuffer *buffer; + int buf_size; + mc_gst_core_t* core; + media_packet_h pkt; + bool has_imgb; }; enum { fill_inbuf, fill_outbuf, create_caps }; -//int __mc_link_elements(mc_gst_core_t *core); int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config); -//int __mc_venc_link(mc_gst_core_t *core); -//int __mc_general_link(mc_gst_core_t *core); - -int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); -int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); -int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer); +int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); +int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer); -int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); -int __mc_fill_venc_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); -int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); -int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt); +int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); +int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); +int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt); -int __mc_vdec_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_sw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_hw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_hw_h264enc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_sw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_hw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); +int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); void _mc_create_codec_map_from_ini(mc_handle_t *mc_handle, mc_codec_spec_t *spec_emul); void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index dbd4d24..0d12c63 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -68,6 +68,7 @@ static gint __gst_handle_resource_error(mc_gst_core_t *core, int code); static gint __gst_handle_library_error(mc_gst_core_t *core, int code); static gint __gst_handle_core_error(mc_gst_core_t *core, int code); static const gchar * _mc_error_to_string(mc_ret_e err); +static int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); /* will remove */ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw); #ifdef TIZEN_PROFILE_LITE @@ -88,99 +89,96 @@ static void _mc_wait_for_eos(mc_gst_core_t *core); static int _mediacodec_get_mime(mc_gst_core_t *core); /* video vtable */ -int(*vdec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_vdec_packet_with_outbuf, &__mc_vdec_caps}; -int(*venc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_venc_packet_with_outbuf, &__mc_venc_caps}; - - -int(*vdec_h264_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG H.264 Decoder Vtable */ - &__mc_fill_vdec_packet_with_outbuf, - &__mc_vdec_caps}; -int(*vdec_mpeg4_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_outbuf, - &__mc_vdec_mpeg4_caps}; -int(*venc_mpeg4_sw_vtable[])() = {&__mc_fill_inbuf_with_venc_packet, /* SPRD MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_venc_caps}; -int(*vdec_h263_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_outbuf, - &__mc_vdec_h263_caps}; -int(*venc_h263_sw_vtable[])() = {&__mc_fill_inbuf_with_venc_packet, /* SPRD MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_venc_caps}; -#ifdef TIZEN_PROFILE_LITE -int(*vdec_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD H.264 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_sprddec_caps}; -int(*venc_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD H.264 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_sprdenc_caps}; -int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD MPEG4 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_sprddec_mpeg4_caps}; -int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_sprdenc_mpeg4_caps}; -int(*vdec_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD MPEG4 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_sprddec_mpeg4_caps}; -int(*venc_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_sprdenc_mpeg4_caps}; -#else -int(*vdec_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* EXYNOS H.264 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_h264dec_caps}; -int(*venc_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* EXYNOS H.264 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_hw_h264enc_caps}; -int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* EXYNOS MPEG4 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_sprddec_mpeg4_caps}; -int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* EXYNOS MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_sprdenc_mpeg4_caps}; -int(*vdec_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* EXYNOS MPEG4 Decoder Vtable */ - &__mc_fill_video_packet_with_mm_video_buffer, - &__mc_sprddec_mpeg4_caps}; -int(*venc_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* EXYNOS MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_outbuf, - &__mc_sprdenc_mpeg4_caps}; -#endif +int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_vdec_sw_h264_caps}; +int(*venc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_venc_caps}; + + +int(*vdec_h264_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W H.264 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_sw_h264_caps}; + +int(*vdec_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W MPEG4 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_mpeg4_caps}; + +int(*vdec_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W MPEG4 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_sw_h263_caps}; + +int(*vdec_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W H.264 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_hw_h264_caps}; + +int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W MPEG4 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_mpeg4_caps}; + +int(*vdec_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W MPEG4 Decoder Vtable */ + &__mc_fill_vdec_packet_with_output_buffer, + &__mc_vdec_hw_h263_caps}; + +int(*venc_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* S/W MPEG4 Encoder Vtable */ + &__mc_fill_venc_packet_with_output_buffer, + &__mc_venc_caps}; + +int(*venc_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* S/W MPEG4 Encoder Vtable */ + &__mc_fill_venc_packet_with_output_buffer, + &__mc_venc_caps}; + +int(*venc_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W H.264 Encoder Vtable */ + &__mc_fill_venc_packet_with_output_buffer, + &__mc_venc_caps}; + +int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W MPEG4 Encoder Vtable */ + &__mc_fill_venc_packet_with_output_buffer, + &__mc_venc_caps}; + +int(*venc_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W MPEG4 Encoder Vtable */ + &__mc_fill_venc_packet_with_output_buffer, + &__mc_venc_caps}; + +int(*aenc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_aenc_caps}; +int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_adec_caps}; + +int(*aenc_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Encoder vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_aenc_aac_caps}; + +int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_aac_caps}; + +int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC HE Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_aacv12_caps}; + +int(*adec_mp3_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* MP3 Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_mp3_caps}; -/* audio vtable */ -int(*aenc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_packet_with_outbuf, &__mc_aenc_caps}; -int(*adec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_packet_with_outbuf, &__mc_adec_caps}; - -int(*aenc_aac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC LC Encoder vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_aenc_aac_caps}; -int(*adec_aac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC LC Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_aac_caps}; -int(*adec_aacv12_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC HE Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_aacv12_caps}; -int(*adec_mp3_vtable[])() = {&__mc_fill_inbuf_with_packet, /* MP3 Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_mp3_caps}; -int(*adec_amrnb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-NB Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_amrnb_caps}; -int(*adec_amrwb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-WB Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_amrwb_caps}; -int(*aenc_amrnb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-NB Encoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_aenc_amrnb_caps}; -int(*adec_vorbis_vtable[])() = {&__mc_fill_inbuf_with_packet, /* VORBIS Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_vorbis_caps}; -int(*adec_flac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FLAC Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_flac_caps}; -int(*adec_wma_vtable[])() = {&__mc_fill_inbuf_with_packet, /* WMA Decoder Vtable */ - &__mc_fill_packet_with_outbuf, - &__mc_adec_wma_caps}; +int(*adec_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-NB Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_amrnb_caps}; + +int(*adec_amrwb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-WB Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_amrwb_caps}; + +int(*aenc_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-NB Encoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_aenc_amrnb_caps}; + +int(*adec_vorbis_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* VORBIS Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_vorbis_caps}; + +int(*adec_flac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* FLAC Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_flac_caps}; + +int(*adec_wma_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* WMA Decoder Vtable */ + &__mc_fill_packet_with_output_buffer, + &__mc_adec_wma_caps}; /* @@ -229,7 +227,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt return ret; } -int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer) +int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer) { int ret = MC_ERROR_NONE; void *buf_data = NULL; @@ -257,7 +255,7 @@ int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBu return ret; } -int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer) +int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer) { int ret = MC_ERROR_NONE; void *uv_ptr = NULL; @@ -301,57 +299,67 @@ int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, Gs return MC_ERROR; } - if (width == stride_width) { - mc_buffer->buf_size += stride_width * stride_height; + if (!core->is_hw) { - for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr); - media_packet_get_video_stride_width(pkt, i, &stride_width); - media_packet_get_video_stride_height(pkt, i, &stride_height); + if (width == stride_width) { + mc_buffer->buf_size += stride_width * stride_height; - buf_size = stride_width * stride_height; + for (i = 1; i < plane_num; i++) { + media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr); + media_packet_get_video_stride_width(pkt, i, &stride_width); + media_packet_get_video_stride_height(pkt, i, &stride_height); - memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size); - LOGD("width is same with stride"); - LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); - mc_buffer->buf_size += buf_size; - - } - } else { - - for (j = 0; j < height; j++) { - memcpy(y_ptr + mc_buffer->buf_size, y_ptr + stride, width); - mc_buffer->buf_size += width; - stride += stride_width; - } + buf_size = stride_width * stride_height; - stride = 0; + memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size); + LOGD("width is same with stride"); + LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); + mc_buffer->buf_size += buf_size; - for (i = 1; i < plane_num; i++) { - media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr); - media_packet_get_video_stride_width(pkt, i, &stride_width); - media_packet_get_video_stride_height(pkt, i, &stride_height); + } + } else { - for (j = 0; j < height>>1; j++) { - memcpy(y_ptr + mc_buffer->buf_size, uv_ptr + stride, width>>1); - mc_buffer->buf_size += width>>1; + for (j = 0; j < height; j++) { + memcpy(y_ptr + mc_buffer->buf_size, y_ptr + stride, width); + mc_buffer->buf_size += width; stride += stride_width; } - memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size); - LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); - mc_buffer->buf_size += buf_size; + stride = 0; + + for (i = 1; i < plane_num; i++) { + media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr); + media_packet_get_video_stride_width(pkt, i, &stride_width); + media_packet_get_video_stride_height(pkt, i, &stride_height); + + for (j = 0; j < height>>1; j++) { + memcpy(y_ptr + mc_buffer->buf_size, uv_ptr + stride, width>>1); + mc_buffer->buf_size += width>>1; + stride += stride_width; + } + + memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size); + LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); + mc_buffer->buf_size += buf_size; + } } - } + } else { + MMVideoBuffer *mm_video_buffer = NULL; - if (y_ptr != NULL) { - gst_buffer_append_memory(mc_buffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mc_buffer->buf_size, 0, - mc_buffer->buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); - LOGD("%d plane data apended : width : %d, height : %d, size : %d", - i, stride_width, stride_height, mc_buffer->buf_size); + mm_video_buffer = __mc_gst_make_tbm_buffer(core, pkt); + /* mm_video_buffer = core->mc_get_mm_video_buffer(pkt); */ + + gst_buffer_prepend_memory(mc_buffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_video_buffer, sizeof(MMVideoBuffer), 0, + sizeof(MMVideoBuffer), mm_video_buffer, free)); + + LOGD("mm_video_buffer is appended, %d, %d", sizeof(MMVideoBuffer), gst_buffer_n_memory(mc_buffer->buffer)); } + gst_buffer_prepend_memory(mc_buffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mc_buffer->buf_size, 0, + mc_buffer->buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + return ret; } @@ -365,7 +373,7 @@ int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_pac return core->vtable[fill_outbuf](core, data, size, out_pkt); } -int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt) +int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt) { int i; int stride_width; @@ -380,57 +388,69 @@ int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - width = dec_info->width; - height = dec_info->height; - stride_width = ALIGN(width, 4); - stride_height = ALIGN(height, 4); - buf_size = stride_width * stride_height * 3 / 2; + if (!core->is_hw) { - if (buf_size > size) - return MC_ERROR; + mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); + width = dec_info->width; + height = dec_info->height; + stride_width = ALIGN(width, 4); + stride_height = ALIGN(height, 4); + buf_size = stride_width * stride_height * 3 / 2; - bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC); - if (!bo[0]) { - LOGE("bo allocation failed"); - return MC_ERROR; - } + if (buf_size > size) + return MC_ERROR; - tsurf_info.width = dec_info->width; - tsurf_info.height = dec_info->height; - tsurf_info.format = TBM_FORMAT_YVU420; - tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420); - tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420); - tsurf_info.size = 0; + memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); - for (i = 0; i < tsurf_info.num_planes; i++) { - if (i == 0) { - tsurf_info.planes[i].stride = stride_width; - tsurf_info.planes[i].size = stride_width * stride_height; - tsurf_info.planes[i].offset = 0; - tsurf_info.size = tsurf_info.planes[i].size; - } else { - tsurf_info.planes[i].stride = stride_width>>1; - tsurf_info.planes[i].size = (stride_width>>1) * (stride_height>>1); - tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size); - tsurf_info.size += tsurf_info.planes[i].size; + bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC); + if (!bo[0]) { + LOGE("bo allocation failed"); + return MC_ERROR; + } + + tsurf_info.width = dec_info->width; + tsurf_info.height = dec_info->height; + tsurf_info.format = TBM_FORMAT_YVU420; + tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420); + tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420); + tsurf_info.size = 0; + + for (i = 0; i < tsurf_info.num_planes; i++) { + if (i == 0) { + tsurf_info.planes[i].stride = stride_width; + tsurf_info.planes[i].size = stride_width * stride_height; + tsurf_info.planes[i].offset = 0; + tsurf_info.size = tsurf_info.planes[i].size; + } else { + tsurf_info.planes[i].stride = stride_width>>1; + tsurf_info.planes[i].size = (stride_width>>1) * (stride_height>>1); + tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size); + tsurf_info.size += tsurf_info.planes[i].size; + } } - } - thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE); - memcpy(thandle.ptr, data, tsurf_info.size); - tbm_bo_unmap(bo[0]); + thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE); + memcpy(thandle.ptr, data, tsurf_info.size); + tbm_bo_unmap(bo[0]); - tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1); + tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1); + if (tsurf) { + media_packet_create_from_tbm_surface(core->output_fmt, tsurf, + (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt); + } + + } else { + __mc_fill_video_packet_with_mm_video_buffer(core, data, size, pkt); + /* tsurf = core->get_tbm_surface(data); */ + } +/* if (tsurf) { media_packet_create_from_tbm_surface(core->output_fmt, tsurf, (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt); } - +*/ return MC_ERROR_NONE; } @@ -508,7 +528,7 @@ int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, return MC_ERROR_NONE; } -int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt) +int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt) { void *pkt_data = NULL; int ret = MC_ERROR_NONE; @@ -527,7 +547,7 @@ int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, medi return MC_ERROR_NONE; } -int __mc_fill_venc_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt) +int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt) { void *pkt_data = NULL; bool codec_config = FALSE; @@ -589,96 +609,43 @@ int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gbool mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; *caps = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "I420", + "format", G_TYPE_STRING, core->format, "width", G_TYPE_INT, enc_info->width, "height", G_TYPE_INT, enc_info->height, "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); - LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps); - - return MC_ERROR_NONE; -} - -int __mc_hw_h264enc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "SN12", - "width", G_TYPE_INT, enc_info->width, - "height", G_TYPE_INT, enc_info->height, - "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, - NULL); - g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); + if (core->is_hw) + g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); + else + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps); return MC_ERROR_NONE; } -int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_sw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "format", G_TYPE_STRING, "SN12", - "width", G_TYPE_INT, enc_info->width, - "height", G_TYPE_INT, enc_info->height, - "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); - - g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - - LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps); - - - return MC_ERROR_NONE; -} - -int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "SN12", - "width", G_TYPE_INT, enc_info->width, - "height", G_TYPE_INT, enc_info->height, - "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL); - - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - - LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps); - - - return MC_ERROR_NONE; -} - -int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; LOGD("%d, %d, ", dec_info->width, dec_info->height); + *caps = gst_caps_new_simple(core->mime, - "parsed", G_TYPE_BOOLEAN, TRUE, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", "width", G_TYPE_INT, dec_info->width, - "height", G_TYPE_INT, dec_info->height, NULL); + "height", G_TYPE_INT, dec_info->height, + "variant", G_TYPE_STRING, "itu", + NULL); LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); + return MC_ERROR_NONE; } -int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_hw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); @@ -699,53 +666,40 @@ int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* bu return MC_ERROR_NONE; } -int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - LOGD("%d, %d, ", dec_info->width, dec_info->height); *caps = gst_caps_new_simple(core->mime, + "mpegversion", G_TYPE_INT, 4, + "systemstream", G_TYPE_BOOLEAN, false, + "parsed", G_TYPE_BOOLEAN, TRUE, "width", G_TYPE_INT, dec_info->width, "height", G_TYPE_INT, dec_info->height, "framerate", GST_TYPE_FRACTION, 30, 1, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - - return MC_ERROR_NONE; -} - -int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "variant", G_TYPE_STRING, "itu", NULL); + NULL); LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); return MC_ERROR_NONE; } -int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; *caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, - "systemstream", G_TYPE_BOOLEAN, false, NULL); + "alignment", G_TYPE_STRING, "au", + "stream-format", G_TYPE_STRING, "byte-stream", NULL); LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); return MC_ERROR_NONE; } -int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_sw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); @@ -759,15 +713,19 @@ int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gbool return MC_ERROR_NONE; } -int __mc_vdec_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) +int __mc_vdec_hw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff,gboolean codec_config) { g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; *caps = gst_caps_new_simple(core->mime, + "parsed", G_TYPE_BOOLEAN, TRUE, "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", NULL); + "stream-format", G_TYPE_STRING, "byte-stream", + "width", G_TYPE_INT, dec_info->width, + "framerate", GST_TYPE_FRACTION, 30, 1, + "height", G_TYPE_INT, dec_info->height, NULL); LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); return MC_ERROR_NONE; @@ -820,6 +778,7 @@ int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, g "layout", G_TYPE_STRING, "interleaved", NULL); g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel); @@ -1526,7 +1485,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) } if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_decoder_info_t *)core->codec_info; + mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; if (enc_info->bitrate != bitrate) { LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); @@ -1551,7 +1510,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) } if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_decoder_info_t *)core->codec_info; + mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; if (enc_info->bitrate != bitrate) { LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); @@ -3337,7 +3296,7 @@ const gchar * _mc_error_to_string(mc_ret_e err) int _mediacodec_get_mime(mc_gst_core_t *core) { - media_format_mimetype_e mime; + media_format_mimetype_e mime = MEDIA_FORMAT_MAX; switch (core->codec_id) { case MEDIACODEC_H264: @@ -3408,8 +3367,9 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt { int curr_size; int max_size, min_size; - media_format_mimetype_e mime_format; - media_format_h *fmt_handle = NULL; + media_format_mimetype_e mime_format = MEDIA_FORMAT_MAX; + media_format_h fmt_handle = NULL; + media_packet_pool_h pool = NULL; mc_gst_core_t *core = NULL; if (!mc_handle) @@ -3417,7 +3377,7 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt core = (mc_gst_core_t *)mc_handle->core; - int ret = media_packet_pool_create(pkt_pool); + int ret = media_packet_pool_create(&pool); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_create failed"); @@ -3457,7 +3417,7 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt } } - ret = media_packet_pool_set_media_format(*pkt_pool, fmt_handle); + ret = media_packet_pool_set_media_format(pool, fmt_handle); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_set_media_format failed"); return MC_ERROR; @@ -3467,19 +3427,20 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt max_size = DEFAULT_POOL_SIZE; min_size = max_size; - ret = media_packet_pool_set_size(*pkt_pool, min_size, max_size); + ret = media_packet_pool_set_size(pool, min_size, max_size); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_set_size failed"); return MC_ERROR; } - media_packet_pool_get_size(*pkt_pool, &min_size, &max_size, &curr_size); + media_packet_pool_get_size(pool, &min_size, &max_size, &curr_size); LOGD("curr_size is %d min_size is %d and max_size is %d \n", curr_size, min_size, max_size); - ret = media_packet_pool_allocate(*pkt_pool); + ret = media_packet_pool_allocate(pool); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_allocate failed"); return MC_OUT_OF_MEMORY; } + *pkt_pool = pool; return MC_ERROR_NONE; } diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 852fa3b..46996e8 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -54,7 +55,6 @@ #define AAC_CODECDATA_SIZE 16 -static int samplebyte = DEFAULT_SAMPLEBYTE; unsigned char buf_adts[ADTS_HEADER_SIZE]; enum { @@ -132,6 +132,8 @@ struct _App { bool is_video[MAX_HANDLE]; bool is_encoder[MAX_HANDLE]; bool hardware; + bool enable_dump; + int frame; type_e type; /* video */ mediacodec_h mc_handle[MAX_HANDLE]; @@ -162,14 +164,8 @@ struct _App { App s_app; -media_format_h aenc_fmt = NULL; -media_format_h adec_fmt = NULL; -media_format_h vdec_fmt = NULL; -media_format_h venc_fmt = NULL; - -#if DUMP_OUTBUF -FILE *fp_out = NULL; -#endif +media_format_h fmt = NULL; +media_packet_pool_h pkt_pool = NULL; /* Internal Functions */ static int _create_app(void *data); @@ -177,11 +173,11 @@ static int _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); -#if DUMP_OUTBUF static void decoder_output_dump(App *app, media_packet_h pkt); -#endif +static void output_dump(App *app, media_packet_h pkt); /* */ void (*extractor)(App *app, unsigned char** data, int *size, bool *have_frame); @@ -335,12 +331,10 @@ void h263_extractor(App * app, unsigned char **data, int *size, bool * have_fram unsigned char *pH263 = app->data + app->offset; *data = pH263; int max = app->length - app->offset; - *have_frame = TRUE; while (1) { if (len >= max) { read_size = (len - 1); - *have_frame = FALSE; goto DONE; } val = pH263[len++]; @@ -371,6 +365,7 @@ void h263_extractor(App * app, unsigned char **data, int *size, bool * have_fram DONE: *size = read_size; app->offset += read_size; + *have_frame = TRUE; } void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_frame) @@ -385,7 +380,7 @@ void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_fra while (1) { if (len >= max) { - *have_frame = FALSE; + result = (len - 1); goto DONE; } @@ -435,6 +430,7 @@ 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"; #define AMR_NB_MIME_HDR_SIZE 6 @@ -529,12 +525,12 @@ void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_fram int read_size; int offset = app->length - app->offset; - read_size = ((samplebyte*app->channel)*(app->bit/8)); - + read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2); *have_frame = TRUE; + *data = app->data + app->offset; - if (offset >= read_size) + if (read_size >= offset) *size = offset; else *size = read_size; @@ -553,8 +549,9 @@ void amrenc_extractor(App *app, unsigned char **data, int *size, bool *have_fram read_size = AMRWB_PCM_INPUT_SIZE; *have_frame = TRUE; + *data = app->data + app->offset; - if (offset >= read_size) + if (read_size >= offset) *size = offset; else *size = read_size; @@ -818,7 +815,7 @@ static void _mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data) return; } #endif -int _mediacodec_set_codec(int codecid, int flag, bool *hardware) +int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) { bool encoder; media_format_mimetype_e mime = 0; @@ -890,12 +887,24 @@ int _mediacodec_set_codec(int codecid, int flag, bool *hardware) case MEDIACODEC_WMALSL: break; case MEDIACODEC_AMR_NB: - extractor = amrdec_extractor; - mime = MEDIA_FORMAT_AMR_NB; + if (encoder) { + extractor = amrenc_extractor; + mime = MEDIA_FORMAT_PCM; + app->is_amr_nb = TRUE; + } else { + extractor = amrdec_extractor; + mime = MEDIA_FORMAT_AMR_NB; + } break; case MEDIACODEC_AMR_WB: - extractor = amrdec_extractor; - mime = MEDIA_FORMAT_AMR_WB; + if (encoder) { + extractor = amrenc_extractor; + mime = MEDIA_FORMAT_PCM; + app->is_amr_nb = FALSE; + } else { + extractor = amrdec_extractor; + mime = MEDIA_FORMAT_AMR_WB; + } break; default: LOGE("NOT SUPPORTED!!!!"); @@ -904,6 +913,80 @@ int _mediacodec_set_codec(int codecid, int flag, bool *hardware) return mime; } +static void _mediacodec_process_input(App *app) +{ + int i; + bool have_frame = FALSE; + int ret; + static guint64 pts = 0L; + void *buf_data_ptr = NULL; + media_packet_h pkt = NULL; + unsigned char *tmp; + int read; + int offset; + int stride_width, stride_height; + + for (i = 0; i < app->frame; i++) { + g_print("----------read data------------\n"); + + extractor(app, &tmp, &read, &have_frame); + + if (have_frame) { + if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) { + fprintf(stderr, "media_packet_create_alloc failed\n"); + return; + } + + if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) { + fprintf(stderr, "media_packet_set_pts failed\n"); + return; + } + + 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 { + /* Y */ + media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 0, &stride_width); + media_packet_get_video_stride_height(pkt, 0, &stride_height); + + offset = stride_width*stride_height; + + memcpy(buf_data_ptr, tmp, offset); + + /* UV or U*/ + media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 1, &stride_width); + media_packet_get_video_stride_height(pkt, 1, &stride_height); + memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); + + if (app->hardware == FALSE) { + /* V */ + media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 2, &stride_width); + media_packet_get_video_stride_height(pkt, 2, &stride_height); + + offset += stride_width * stride_height; + + + memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); + } + } + mc_hex_dump("inbuf", tmp, 48); + + ret = mediacodec_process_input(app->mc_handle[0], pkt, -1); + if (ret != MEDIACODEC_ERROR_NONE) + return; + + pts += ES_DEFAULT_VIDEO_PTS_OFFSET; + } + } +} + static gboolean read_data(App *app) { guint len = 0; @@ -917,14 +1000,20 @@ static gboolean read_data(App *app) int offset; int stride_width, stride_height; + if (app->offset == 0) { + app->frame_count = 0; + app->start = clock(); + } + g_print("----------read data------------\n"); extractor(app, &tmp, &read, &have_frame); - if (app->offset >= app->length - 1) { + if (app->offset >= app->length - 4) { /* EOS */ g_print("EOS\n"); app->finish = clock(); - g_main_loop_quit(app->loop); + g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start))); + g_print("---------------------------\n"); return FALSE; } g_print("length : %d, offset : %d\n", (int)app->length, (int)app->offset); @@ -935,11 +1024,18 @@ static gboolean read_data(App *app) g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read); if (have_frame) { - if (media_packet_create_alloc(vdec_fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) { +#ifdef USE_POOL + if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) { + fprintf(stderr, "media_packet_pool_aquire_packet failed\n"); + //return TRUE; + return FALSE; + } +#else + if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) { fprintf(stderr, "media_packet_create_alloc failed\n"); return FALSE; } - +#endif if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) { fprintf(stderr, "media_packet_set_pts failed\n"); return FALSE; @@ -1011,7 +1107,12 @@ static void stop_feed(App *app) static gboolean _mediacodec_inbuf_used_cb(media_packet_h pkt, void *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 + return TRUE; } @@ -1031,19 +1132,12 @@ static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data) if (ret != MEDIACODEC_ERROR_NONE) g_print("get_output failed\n"); -#if DUMP_OUTBUF - void *data; - int buf_size; - int stride_width, stride_height; - - decoder_output_dump(app, out_pkt); - media_packet_get_buffer_data_ptr(out_pkt, &data); - media_packet_get_buffer_size(out_pkt, &buf_size); - g_print("output data : %p, size %d\n", data, (int)buf_size); - - fwrite(data, 1, buf_size, fp_out); - -#endif + if (app->enable_dump) { + if (app->type == VIDEO_DEC) + decoder_output_dump(app, out_pkt); + else + output_dump(app, out_pkt); + } app->frame_count++; @@ -1081,13 +1175,10 @@ static bool _mediacodec_eos_cb(void *user_data) return TRUE; } -static void _mediacodec_prepare(App *app) +static void _mediacodec_prepare(App *app, bool frame_all) { int ret; -#if DUMP_OUTBUF - fp_out = fopen("/tmp/codec_dump.out", "wb"); -#endif /* create instance */ ret = mediacodec_create(&app->mc_handle[0]); if (ret != MEDIACODEC_ERROR_NONE) { @@ -1102,39 +1193,38 @@ static void _mediacodec_prepare(App *app) return; } - - app->mime = _mediacodec_set_codec(app->codecid, app->flag, &app->hardware); + app->mime = _mediacodec_set_codec(app, app->codecid, app->flag, &app->hardware); /* set codec info */ - ret = media_format_create(&vdec_fmt); + 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(vdec_fmt, app->mime); - media_format_set_video_width(vdec_fmt, app->width); - media_format_set_video_height(vdec_fmt, 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); 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(vdec_fmt, app->mime); - media_format_set_video_width(vdec_fmt, app->width); - media_format_set_video_height(vdec_fmt, app->height); - media_format_set_video_avg_bps(vdec_fmt, 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); break; case AUDIO_DEC: ret = mediacodec_set_adec_info(app->mc_handle[0], app->samplerate, app->channel, app->bit); - media_format_set_audio_mime(vdec_fmt, app->mime); - media_format_set_audio_channel(vdec_fmt, app->channel); - media_format_set_audio_samplerate(vdec_fmt, app->samplerate); - media_format_set_audio_bit(vdec_fmt, 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); 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(vdec_fmt, app->mime); - media_format_set_audio_channel(vdec_fmt, app->channel); - media_format_set_audio_samplerate(vdec_fmt, app->samplerate); - media_format_set_audio_bit(vdec_fmt, 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); break; default: g_print("invaild type\n"); @@ -1149,7 +1239,8 @@ static void _mediacodec_prepare(App *app) /* set callback */ mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, NULL); mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app); - mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_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_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL); @@ -1160,17 +1251,44 @@ static void _mediacodec_prepare(App *app) return; } - app->frame_count = 0; - app->start = clock(); - g_main_loop_run(app->loop); - - g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start))); - g_print("---------------------------\n"); +/* 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"); + return; + } return; } +static void _mediacodec_unprepare(App *app) +{ + mediacodec_unprepare(app->mc_handle[0]); +} + +static void _mediacodec_destroy(App *app) +{ +#ifdef USE_POOL + if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) { + + fprintf(stderr, "media_packet_pool_deallocatet failed\n"); + g_print("PKT POOL deallocation failed \n"); + return; + } + g_print("PKT POOL deallocated! \n"); + + if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) { + + fprintf(stderr, " media_packet_pool_destroy failed\n"); + g_print("PKT POOL destroy failed \n"); + return; + } + g_print("PKT POOL destroyed! \n"); +#endif + mediacodec_destroy(app->mc_handle[0]); +} + static void input_filepath(char *filename, App *app) { GError *error = NULL; @@ -1191,12 +1309,10 @@ static void input_filepath(char *filename, App *app) return; } -void quit_program() +void quit_program(App *app) { -#if DUMP_OUTBUF - if (fp_out) - fclose(fp_out); -#endif + media_format_unref(fmt); + g_main_loop_quit(app->loop); elm_exit(); } @@ -1216,12 +1332,14 @@ void _interpret_main_menu(char *cmd, App *app) else if (strncmp(cmd, "o", 1) == 0) g_menu_state = CURRENT_STATUS_GET_OUTPUT; else if (strncmp(cmd, "q", 1) == 0) - quit_program(); + quit_program(app); else g_print("unknown menu \n"); } else if (len == 2) { if (strncmp(cmd, "pr", 2) == 0) - _mediacodec_prepare(app); + _mediacodec_prepare(app, 0); + else if (strncmp(cmd, "pa", 2) == 0) + _mediacodec_prepare(app, 1); else if (strncmp(cmd, "sc", 2) == 0) g_menu_state = CURRENT_STATUS_SET_CODEC; else if (strncmp(cmd, "vd", 2) == 0) @@ -1234,7 +1352,19 @@ void _interpret_main_menu(char *cmd, App *app) g_menu_state = CURRENT_STATUS_SET_AENC_INFO; else if (strncmp(cmd, "pi", 2) == 0) g_menu_state = CURRENT_STATUS_PROCESS_INPUT; - else + else if (strncmp(cmd, "un", 2) == 0) + _mediacodec_unprepare(app); + else if (strncmp(cmd, "dt", 2) == 0) + _mediacodec_destroy(app); + else if (strncmp(cmd, "dp", 2) == 0) { + if(!app->enable_dump) { + app->enable_dump = TRUE; + g_print("dump enabled\n"); + } else { + app->enable_dump = FALSE; + g_print("dump disabled\n"); + } + } else display_sub_basic(); } else { g_print("unknown menu \n"); @@ -1448,6 +1578,8 @@ static void interpret(char *cmd, App *app) break; case CURRENT_STATUS_PROCESS_INPUT: { + app->frame = atoi(cmd); + _mediacodec_process_input(app); reset_menu_state(); } break; @@ -1475,14 +1607,15 @@ static void display_sub_basic() g_print("ve. Set venc info \n"); g_print("ad. Set adec info \t"); g_print("ae. Set aenc info \n"); - g_print("pr. Prepare \t\t"); - g_print("pi. Process input \n"); + g_print("pr. Prepare \t"); + g_print("pa. Prepare and process all\t\t"); + g_print("pi. process input with num\n"); g_print("o. Get output \t\t"); g_print("rb. Reset output buffer \n"); - g_print("pa. Process all frames \n"); g_print("un. Unprepare \t\t"); g_print("dt. Destroy \t\t"); - g_print("q. quite test suite \t"); + g_print("q. quite test suite \n"); + g_print("dp. enable dump \n"); g_print("\n"); g_print("=========================================================================================\n"); } @@ -1512,10 +1645,13 @@ int main(int argc, char *argv[]) g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, app); + displaymenu(); app->loop = g_main_loop_new(NULL, TRUE); app->timer = g_timer_new(); + //app->frame_count = 0; + g_main_loop_run(app->loop); + - displaymenu(); ops.data = app; @@ -1558,7 +1694,6 @@ void mc_hex_dump(char *desc, void *addr, int len) printf(" %s\n", buff); } -#if DUMP_OUTBUF static void decoder_output_dump(App *app, media_packet_h pkt) { void *temp; @@ -1608,4 +1743,73 @@ static void decoder_output_dump(App *app, media_packet_h pkt) fclose(fp); } -#endif + +/** + * Add ADTS header at the beginning of each and every AAC packet. + * This is needed as MediaCodec encoder generates a packet of raw AAC data. + * Note the packetLen must count in the ADTS header itself. + **/ +void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen) { + int profile = 2; //AAC LC (0x01) + int freqIdx = 3; //48KHz (0x03) + int chanCfg = 2; //CPE (0x02) + + if (app->samplerate == 96000) freqIdx = 0; + else if (app->samplerate == 88200) freqIdx = 1; + else if (app->samplerate == 64000) freqIdx = 2; + else if (app->samplerate == 48000) freqIdx = 3; + else if (app->samplerate == 44100) freqIdx = 4; + else if (app->samplerate == 32000) freqIdx = 5; + else if (app->samplerate == 24000) freqIdx = 6; + else if (app->samplerate == 22050) freqIdx = 7; + else if (app->samplerate == 16000) freqIdx = 8; + else if (app->samplerate == 12000) freqIdx = 9; + else if (app->samplerate == 11025) freqIdx = 10; + else if (app->samplerate == 8000) freqIdx = 11; + + if ((app->channel == 1) || (app->channel == 2)) + chanCfg = app->channel; + + // fill in ADTS data + buffer[0] = (char)0xFF; + buffer[1] = (char)0xF1; + buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2)); + buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11)); + buffer[4] = (char)((packetLen&0x7FF) >> 3); + buffer[5] = (char)(((packetLen&7)<<5) + 0x1F); + buffer[6] = (char)0xFC; +} + +static void output_dump(App *app, media_packet_h pkt) +{ + void *temp; + uint64_t buf_size; + char filename[100] = {0}; + FILE *fp = NULL; + int ret = 0; + char adts[100] = {0, }; + + sprintf(filename, "/tmp/dec_output_dump_%d.out", app->type); + fp = fopen(filename, "ab"); + + media_packet_get_buffer_data_ptr(pkt, &temp); + media_packet_get_buffer_size(pkt, &buf_size); + g_print("output data : %p, size %d\n", temp, (int)buf_size); + + if (buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) { + 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 (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 */ + write_amr_header = 0; + } + + fwrite(temp, (int)buf_size, 1, fp); + + g_print("codec dec output dumped!!%d\n", ret); + fclose(fp); + +} -- 2.7.4 From 077a3cf2a743a5b8fce4e14b5f9946f1c3cf64ad Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 3 Jun 2016 15:15:00 +0900 Subject: [PATCH 03/16] Fixed build error when compling with 64bit Change-Id: I797f3e70800584e879999eea3ab3a7e3d17aee7c --- test/media_codec_test.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 46996e8..15f10bb 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -117,9 +117,9 @@ struct _App { GMappedFile *file; guint8 *data; - gsize length; - guint64 offset; - guint obj; + gint length; + gint offset; + gint obj; GTimer *timer; long start; @@ -1016,7 +1016,7 @@ static gboolean read_data(App *app) g_print("---------------------------\n"); return FALSE; } - g_print("length : %d, offset : %d\n", (int)app->length, (int)app->offset); + g_print("length : %d, offset : %d\n", app->length, app->offset); if (app->offset + len > app->length) len = app->length - app->offset; @@ -1304,7 +1304,7 @@ static void input_filepath(char *filename, App *app) app->length = g_mapped_file_get_length(app->file); app->data = (guint8 *)g_mapped_file_get_contents(app->file); app->offset = 0; - g_print("len : %d, offset : %d, obj : %d", app->length, (int)app->offset, app->obj); + g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj); return; } -- 2.7.4 From 4661b7b1d1e279af46e87a26df89d95dea07474f Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 10 Jun 2016 13:06:49 +0900 Subject: [PATCH 04/16] fix memory corruption which was not malloed Change-Id: Icb24bf83d8b3fade1124ad1a6327181c4f8d6055 --- 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 0d12c63..40e9315 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -1281,7 +1281,7 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *bu LOGD("Set caps for codec_data in mime : %s and codec_id (0x%x)", core->mime, core->codec_id); /* Add the codec_data attribute to caps, if we have it */ - codecdata_buffer = gst_buffer_new(); + codecdata_buffer = gst_buffer_new_and_alloc(codecdata_size); gst_buffer_copy_into(codecdata_buffer, buff->buffer, GST_BUFFER_COPY_MEMORY, 0, codecdata_size); gst_buffer_ref(codecdata_buffer); LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size); -- 2.7.4 From 39a8119d7c392a708dddf758f87152a05bca0ac5 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 10 Jun 2016 13:29:52 +0900 Subject: [PATCH 05/16] move ini paring func. to mediacodec_port Change-Id: I7717353245573132d26d034dd64c9278891f5f3d --- include/media_codec_ini.h | 52 +++++++++++++-------- include/media_codec_port.h | 4 ++ src/media_codec_ini.c | 114 +++------------------------------------------ src/media_codec_port.c | 96 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 126 deletions(-) diff --git a/include/media_codec_ini.h b/include/media_codec_ini.h index 75553dc..b51404e 100755 --- a/include/media_codec_ini.h +++ b/include/media_codec_ini.h @@ -19,6 +19,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { @@ -34,32 +36,42 @@ extern "C" { #define MEDIA_CODEC_MAX_VIDEO_CODEC 100 #define MEDIA_CODEC_MAX_AUDIO_CODEC 100 +typedef struct _codec_list_t codec_list_t; +typedef struct _codec_info_t codec_info_t; +typedef struct _codec_t codec_t; +typedef struct _mc_ini_t mc_ini_t; + +struct _codec_list_t { + gchar cname[MEDIA_CODEC_INI_MAX_STRLEN]; + mediacodec_codec_type_e ctype; +}; typedef enum { - GST_PORT = 0, - FFMPEG_PORT, - CUSTOM_PORT, + GST_PORT = 0, + FFMPEG_PORT, + CUSTOM_PORT, } port_mode; -typedef struct { - gchar name[MEDIA_CODEC_INI_MAX_STRLEN]; - gchar mime[MEDIA_CODEC_INI_MAX_STRLEN]; - gchar format[MEDIA_CODEC_INI_MAX_STRLEN]; -} codec_info_t; +struct _codec_info_t { + gchar name[MEDIA_CODEC_INI_MAX_STRLEN]; + gchar mime[MEDIA_CODEC_INI_MAX_STRLEN]; + gchar format[MEDIA_CODEC_INI_MAX_STRLEN]; +}; -typedef struct { - gint codec_id; - codec_info_t codec_info[MEDIA_CODEC_MAX_CODEC_ROLE]; -} codec_t; +struct _codec_t { + gint codec_id; + codec_info_t codec_info[MEDIA_CODEC_MAX_CODEC_ROLE]; +}; /* @ mark means the item has tested */ -typedef struct __mc_ini { - port_mode port_type; - /* general */ - gchar port_name[MEDIA_CODEC_INI_MAX_STRLEN]; - codec_t codec[MEDIA_CODEC_MAX_CODEC_TYPE]; -} mc_ini_t; +struct _mc_ini_t { + int codec_list; + port_mode port_type; + /* general */ + gchar port_name[MEDIA_CODEC_INI_MAX_STRLEN]; + codec_t codec[MEDIA_CODEC_MAX_CODEC_TYPE]; +}; /*Default sink ini values*/ /* General*/ @@ -68,7 +80,7 @@ typedef struct __mc_ini { /* FIXIT : need smarter way to generate default ini file. */ /* FIXIT : finally, it should be an external file */ #define MEDIA_CODEC_DEFAULT_INI \ - "\ +"\ [general] \n\ \n\ ;Add general config parameters here\n\ @@ -96,6 +108,8 @@ media_codec_port = GST_PORT \n\ " int mc_ini_load(mc_ini_t *ini); +media_format_mimetype_e _mc_convert_media_format_str_to_int(char *sformat); + #ifdef __cplusplus } diff --git a/include/media_codec_port.h b/include/media_codec_port.h index 5d3975c..e31dfd8 100755 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -257,6 +257,10 @@ int mc_unset_buffer_status_cb(MMHandleType mediacodec); int mc_set_supported_codec_cb(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data); int _mediacodec_foreach_supported_codec(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data); +void _mc_create_codec_map_from_ini(mc_handle_t *mc_handle, mc_codec_spec_t *spec_emul); +void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); +void _mc_create_encoder_map_from_ini(mc_handle_t *mc_handle); + #ifdef __cplusplus } #endif diff --git a/src/media_codec_ini.c b/src/media_codec_ini.c index 79d5ccc..1bc2c86 100755 --- a/src/media_codec_ini.c +++ b/src/media_codec_ini.c @@ -48,11 +48,6 @@ #define CNAME_SIZE 512 -typedef struct { - gchar cname[MEDIA_CODEC_INI_MAX_STRLEN]; - mediacodec_codec_type_e ctype; -} codec_list_t; - static codec_list_t general_codec_list[] = { {"h261", MEDIACODEC_H261}, {"h263", MEDIACODEC_H263}, @@ -302,7 +297,10 @@ int mc_ini_load(mc_ini_t *ini) int i = 0; dictionary *dict = NULL; - static const int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]); + /* get ini values */ + memset(ini, 0, sizeof(mc_ini_t)); + + ini->codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]); _mc_ini_check_ini_status(); @@ -325,14 +323,12 @@ int mc_ini_load(mc_ini_t *ini) #endif } - /* get ini values */ - memset(ini, 0, sizeof(mc_ini_t)); if (dict) {/* if dict is available */ /* general */ MEDIA_CODEC_INI_GET_STRING(dict, ini->port_name, "port_in_use:media_codec_port", DEFAULT_PORT); /* codec */ - for (i = 0; i < codec_list; i++) { + for (i = 0; i < ini->codec_list; i++) { memset(cname, 0x00, CNAME_SIZE); snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname); int len = strlen(cname); @@ -351,7 +347,7 @@ int mc_ini_load(mc_ini_t *ini) LOGW("failed to load ini. using hardcoded default\n"); /* general */ snprintf(ini->port_name, sizeof(ini->port_name), "%s", DEFAULT_PORT); - for (i = 0; i < codec_list; i++) { + for (i = 0; i < ini->codec_list; i++) { MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[0].name, DEFAULT_HW_DECODER_NAME); MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[0].mime, DEFAULT_HW_DECODER_MIME); MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[0].format, DEFAULT_HW_DECODER_FORMAT); @@ -379,7 +375,7 @@ int mc_ini_load(mc_ini_t *ini) } LOGD("The port is set to [%s] [%d]\n", ini->port_name, ini->port_type); - for (i = 0; i < codec_list; i++) { + for (i = 0; i < ini->codec_list; i++) { memset(cname, 0x00, CNAME_SIZE); snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname); int len = strlen(cname); @@ -449,100 +445,4 @@ static gboolean _generate_default_ini(void) return TRUE; } #endif - -void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec) -{ - int indx = 0, count = 0; - int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]); - for (indx = 0; indx < codec_list; indx++) { - if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) { - mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id; - mediacodec->decoder_map[count].hardware = 1; /* hardware */ - mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[0].name; - mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[0].mime; - mediacodec->decoder_map[count].type.out_format = - _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[0].format); - count++; - } - - if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) { - mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id; - mediacodec->decoder_map[count].hardware = 0; /* software */ - mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[2].name; - mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[2].mime; - mediacodec->decoder_map[count].type.out_format = - _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[2].format); - count++; - } - } - mediacodec->num_supported_decoder = count; - return; - -} - -void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec) -{ - int indx = 0, count = 0; - int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]); - - for (indx = 0; indx < codec_list; indx++) { - if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) { - mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id; - mediacodec->encoder_map[count].hardware = 1; - mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[1].name; - mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[1].mime; - mediacodec->encoder_map[count].type.out_format = - _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[1].format); - count++; - } - - if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) { - mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id; - mediacodec->encoder_map[count].hardware = 0; - mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[3].name; - mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[3].mime; - mediacodec->encoder_map[count].type.out_format = - _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[3].format); - count++; - } - } - mediacodec->num_supported_encoder = count; - return; - -} -void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul) -{ - int indx = 0, count = 0; - int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]); - for (indx = 0; indx < codec_list; indx++) { - if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) { - spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; - spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW; - spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; - count++; - } - if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) { - spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; - spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW; - spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; - count++; - } - if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) { - spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; - spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW; - spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; - count++; - } - if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) { - spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; - spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW; - spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; - count++; - } - } - - mediacodec->num_supported_codecs = count; - return; -} - #endif /* #ifdef _MEDIA_CODEC_INI_C_ */ diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 4e94746..468efde 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -749,5 +749,101 @@ int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool) return ret; } +void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec) +{ + int indx = 0, count = 0; + int codec_list = mediacodec->ini.codec_list; + for (indx = 0; indx < codec_list; indx++) { + if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) { + mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id; + mediacodec->decoder_map[count].hardware = 1; /* hardware */ + mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[0].name; + mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[0].mime; + mediacodec->decoder_map[count].type.out_format = + _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[0].format); + count++; + } + + if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) { + mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id; + mediacodec->decoder_map[count].hardware = 0; /* software */ + mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[2].name; + mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[2].mime; + mediacodec->decoder_map[count].type.out_format = + _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[2].format); + count++; + } + } + mediacodec->num_supported_decoder = count; + return; + +} + +void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec) +{ + int indx = 0, count = 0; + int codec_list = mediacodec->ini.codec_list; + + for (indx = 0; indx < codec_list; indx++) { + if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) { + mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id; + mediacodec->encoder_map[count].hardware = 1; + mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[1].name; + mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[1].mime; + mediacodec->encoder_map[count].type.out_format = + _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[1].format); + count++; + } + + if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) { + mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id; + mediacodec->encoder_map[count].hardware = 0; + mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[3].name; + mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[3].mime; + mediacodec->encoder_map[count].type.out_format = + _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[3].format); + count++; + } + } + mediacodec->num_supported_encoder = count; + return; + +} +void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul) +{ + int indx = 0, count = 0; + int codec_list = mediacodec->ini.codec_list; + + for (indx = 0; indx < codec_list; indx++) { + if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) { + spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; + spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW; + spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; + count++; + } + if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) { + spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; + spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW; + spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; + count++; + } + if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) { + spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; + spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW; + spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; + count++; + } + if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) { + spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id; + spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW; + spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST; + count++; + } + } + + mediacodec->num_supported_codecs = count; + LOGE("supported codecs :%d", count); + return; +} -- 2.7.4 From 6b4f14aec33a1f5c77b0c8500dc9c5e5512799b9 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 13 Jun 2016 19:29:15 +0900 Subject: [PATCH 06/16] modify to create caps Change-Id: I1e2bb1060f52ba767a6b7f45ab2e1b7044631cd5 --- doc/media_codec_doc.h | 2 +- include/media_codec.h | 132 +++--- include/media_codec_bitstream.h | 101 +++-- include/media_codec_port.h | 170 ++++---- include/media_codec_port_gst.h | 74 ++-- include/media_codec_private.h | 114 +++--- include/media_codec_queue.h | 34 +- include/media_codec_spec_emul.h | 31 +- include/media_codec_util.h | 41 +- src/media_codec.c | 4 +- src/media_codec_port.c | 2 +- src/media_codec_port_gst.c | 862 ++++++++++++++-------------------------- test/media_codec_test.c | 77 ++-- 13 files changed, 652 insertions(+), 992 deletions(-) diff --git a/doc/media_codec_doc.h b/doc/media_codec_doc.h index 28971c8..03bed18 100644 --- a/doc/media_codec_doc.h +++ b/doc/media_codec_doc.h @@ -39,4 +39,4 @@ * */ -#endif // __TIZEN_MEDIA_CODEC_DOC_H__ +#endif /* __TIZEN_MEDIA_CODEC_DOC_H__ */ diff --git a/include/media_codec.h b/include/media_codec.h index 011d5ba..b6fa990 100755 --- a/include/media_codec.h +++ b/include/media_codec.h @@ -48,89 +48,85 @@ typedef struct mediacodec_s *mediacodec_h; * @remarks If this codec is to be used as an encoder or decoder, the codec flag must be set to #MEDIACODEC_ENCODER or * #MEDIACODEC_DECODER. If user doesn't set optional flag, default flags will be set to #MEDIACODEC_SUPPORT_TYPE_SW. */ -typedef enum -{ - MEDIACODEC_ENCODER = 0x1, /**< This flag is for using the encoder */ - MEDIACODEC_DECODER = 0x2, /**< This flag is for using the decoder */ - MEDIACODEC_SUPPORT_TYPE_HW = 0x4, /**< This is an optional flag for using the h/w codec */ - MEDIACODEC_SUPPORT_TYPE_SW = 0x8, /**< This is an optional flag for using the s/w codec */ +typedef enum { + MEDIACODEC_ENCODER = 0x1, /**< This flag is for using the encoder */ + MEDIACODEC_DECODER = 0x2, /**< This flag is for using the decoder */ + MEDIACODEC_SUPPORT_TYPE_HW = 0x4, /**< This is an optional flag for using the h/w codec */ + MEDIACODEC_SUPPORT_TYPE_SW = 0x8, /**< This is an optional flag for using the s/w codec */ } mediacodec_support_type_e; /** * @brief Enumerations of media codec type * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ -typedef enum -{ - MEDIACODEC_NONE = 0x0, /**< NONE*/ - MEDIACODEC_L16 = 0x1010, /**< L16*/ - MEDIACODEC_ALAW = 0x1020, /**< ALAW*/ - MEDIACODEC_ULAW = 0x1030, /**< ULAW*/ - MEDIACODEC_AMR = 0x1040, /**< MEDIACDEC_AMR indicates AMR-NB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_AMR_NB = 0x1040, /**< AMR-NB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_AMR_WB = 0x1041, /**< AMR-WB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_G729 = 0x1050, /**< G729*/ - MEDIACODEC_AAC = 0x1060, /**< MEDIACDEC_AAC indicates AAC-LC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_AAC_LC = 0x1060, /**< AAC-LC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_AAC_HE = 0x1061, /**< HE-AAC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_AAC_HE_PS = 0x1062, /**< HE-AAC-PS (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_MP3 = 0x1070, /**< MP3*/ - MEDIACODEC_VORBIS = 0x1080, /**< VORBIS (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_FLAC = 0x1090, /**< FLAC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_WMAV1 = 0x10A0, /**< WMA version 1 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_WMAV2 = 0x10A1, /**< WMA version 2 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_WMAPRO = 0x10A2, /**< WMA Professional (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_WMALSL = 0x10A3, /**< WMA Lossless (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - - MEDIACODEC_H261 = 0x2010, /**< H.261*/ - MEDIACODEC_H263 = 0x2020, /**< H.263*/ - MEDIACODEC_H264 = 0x2030, /**< H.264*/ - MEDIACODEC_MJPEG = 0x2040, /**< MJPEG*/ - MEDIACODEC_MPEG1 = 0x2050, /**< MPEG1*/ - MEDIACODEC_MPEG2 = 0x2060, /**< MPEG2*/ - MEDIACODEC_MPEG4 = 0x2070, /**< MPEG4*/ - MEDIACODEC_HEVC = 0x2080, /**< HEVC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_VP8 = 0x2090, /**< VP8 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_VP9 = 0x20A0, /**< VP9 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_VC1 = 0x20B0, /**< VC1 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ +typedef enum { + MEDIACODEC_NONE = 0x0, /**< NONE*/ + MEDIACODEC_L16 = 0x1010, /**< L16*/ + MEDIACODEC_ALAW = 0x1020, /**< ALAW*/ + MEDIACODEC_ULAW = 0x1030, /**< ULAW*/ + MEDIACODEC_AMR = 0x1040, /**< MEDIACDEC_AMR indicates AMR-NB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_AMR_NB = 0x1040, /**< AMR-NB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_AMR_WB = 0x1041, /**< AMR-WB (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_G729 = 0x1050, /**< G729*/ + MEDIACODEC_AAC = 0x1060, /**< MEDIACDEC_AAC indicates AAC-LC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_AAC_LC = 0x1060, /**< AAC-LC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_AAC_HE = 0x1061, /**< HE-AAC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_AAC_HE_PS = 0x1062, /**< HE-AAC-PS (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_MP3 = 0x1070, /**< MP3*/ + MEDIACODEC_VORBIS = 0x1080, /**< VORBIS (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_FLAC = 0x1090, /**< FLAC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_WMAV1 = 0x10A0, /**< WMA version 1 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_WMAV2 = 0x10A1, /**< WMA version 2 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_WMAPRO = 0x10A2, /**< WMA Professional (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_WMALSL = 0x10A3, /**< WMA Lossless (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + + MEDIACODEC_H261 = 0x2010, /**< H.261*/ + MEDIACODEC_H263 = 0x2020, /**< H.263*/ + MEDIACODEC_H264 = 0x2030, /**< H.264*/ + MEDIACODEC_MJPEG = 0x2040, /**< MJPEG*/ + MEDIACODEC_MPEG1 = 0x2050, /**< MPEG1*/ + MEDIACODEC_MPEG2 = 0x2060, /**< MPEG2*/ + MEDIACODEC_MPEG4 = 0x2070, /**< MPEG4*/ + MEDIACODEC_HEVC = 0x2080, /**< HEVC (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_VP8 = 0x2090, /**< VP8 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_VP9 = 0x20A0, /**< VP9 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_VC1 = 0x20B0, /**< VC1 (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ } mediacodec_codec_type_e; /** * @brief Enumeration of media codec error * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ -typedef enum -{ - MEDIACODEC_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - MEDIACODEC_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - MEDIACODEC_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - MEDIACODEC_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ - MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ - MEDIACODEC_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ - MEDIACODEC_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIACODEC | 0x01, /**< Invalid state */ - MEDIACODEC_ERROR_INVALID_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x02, /**< Invalid input buffer */ - MEDIACODEC_ERROR_INVALID_OUTBUFFER = TIZEN_ERROR_MEDIACODEC | 0x03, /**< Invalid output buffer */ - MEDIACODEC_ERROR_INTERNAL = TIZEN_ERROR_MEDIACODEC | 0x04, /**< Internal error */ - MEDIACODEC_ERROR_NOT_INITIALIZED = TIZEN_ERROR_MEDIACODEC | 0x05, /**< Not initialized mediacodec */ - MEDIACODEC_ERROR_INVALID_STREAM = TIZEN_ERROR_MEDIACODEC | 0x06, /**< Invalid stream */ - MEDIACODEC_ERROR_CODEC_NOT_FOUND = TIZEN_ERROR_MEDIACODEC | 0x07, /**< Not supported format */ - MEDIACODEC_ERROR_DECODE = TIZEN_ERROR_MEDIACODEC | 0x08, /**< Error while decoding data */ - MEDIACODEC_ERROR_NO_FREE_SPACE = TIZEN_ERROR_MEDIACODEC | 0x09, /**< Out of storage */ - MEDIACODEC_ERROR_STREAM_NOT_FOUND = TIZEN_ERROR_MEDIACODEC | 0x0a, /**< Cannot find stream */ - MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT = TIZEN_ERROR_MEDIACODEC | 0x0b, /**< Not supported format */ - MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE = TIZEN_ERROR_MEDIACODEC | 0x0c, /**< Not available buffer */ - MEDIACODEC_ERROR_OVERFLOW_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x0d, /**< Overflow input buffer (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ - MEDIACODEC_ERROR_RESOURCE_OVERLOADED = TIZEN_ERROR_MEDIACODEC | 0x0e, /**< Exceed the instance limits (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ +typedef enum { + MEDIACODEC_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + MEDIACODEC_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + MEDIACODEC_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MEDIACODEC_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + MEDIACODEC_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + MEDIACODEC_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIACODEC | 0x01, /**< Invalid state */ + MEDIACODEC_ERROR_INVALID_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x02, /**< Invalid input buffer */ + MEDIACODEC_ERROR_INVALID_OUTBUFFER = TIZEN_ERROR_MEDIACODEC | 0x03, /**< Invalid output buffer */ + MEDIACODEC_ERROR_INTERNAL = TIZEN_ERROR_MEDIACODEC | 0x04, /**< Internal error */ + MEDIACODEC_ERROR_NOT_INITIALIZED = TIZEN_ERROR_MEDIACODEC | 0x05, /**< Not initialized mediacodec */ + MEDIACODEC_ERROR_INVALID_STREAM = TIZEN_ERROR_MEDIACODEC | 0x06, /**< Invalid stream */ + MEDIACODEC_ERROR_CODEC_NOT_FOUND = TIZEN_ERROR_MEDIACODEC | 0x07, /**< Not supported format */ + MEDIACODEC_ERROR_DECODE = TIZEN_ERROR_MEDIACODEC | 0x08, /**< Error while decoding data */ + MEDIACODEC_ERROR_NO_FREE_SPACE = TIZEN_ERROR_MEDIACODEC | 0x09, /**< Out of storage */ + MEDIACODEC_ERROR_STREAM_NOT_FOUND = TIZEN_ERROR_MEDIACODEC | 0x0a, /**< Cannot find stream */ + MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT = TIZEN_ERROR_MEDIACODEC | 0x0b, /**< Not supported format */ + MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE = TIZEN_ERROR_MEDIACODEC | 0x0c, /**< Not available buffer */ + MEDIACODEC_ERROR_OVERFLOW_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x0d, /**< Overflow input buffer (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_ERROR_RESOURCE_OVERLOADED = TIZEN_ERROR_MEDIACODEC | 0x0e, /**< Exceed the instance limits (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ } mediacodec_error_e; /** * @brief Enumeration of buffer status * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ -typedef enum -{ - MEDIACODEC_NEED_DATA, - MEDIACODEC_ENOUGH_DATA +typedef enum { + MEDIACODEC_NEED_DATA, + MEDIACODEC_ENOUGH_DATA } mediacodec_status_e; /** @@ -358,7 +354,7 @@ int mediacodec_unprepare(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation * @retval #MEDIACODEC_ERROR_OVERFLOW_INBUFFER Overflow inputbuffer */ -int mediacodec_process_input (mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs); +int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs); /** * @brief Gets the decoded or encoded packet from the output queue. @@ -374,7 +370,7 @@ int mediacodec_process_input (mediacodec_h mediacodec, media_packet_h inbuf, uin * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation */ -int mediacodec_get_output (mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs); +int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs); /** * @brief Flushes both input and output buffers. @@ -384,7 +380,7 @@ int mediacodec_get_output (mediacodec_h mediacodec, media_packet_h *outbuf, uint * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter */ -int mediacodec_flush_buffers (mediacodec_h mediacodec); +int mediacodec_flush_buffers(mediacodec_h mediacodec); /** * @brief set empty buffer callback the media codec for process, asynchronously. diff --git a/include/media_codec_bitstream.h b/include/media_codec_bitstream.h index 44329ba..e8af1af 100755 --- a/include/media_codec_bitstream.h +++ b/include/media_codec_bitstream.h @@ -22,61 +22,56 @@ typedef struct _mc_bitstream_t mc_bitstream_t; -typedef enum -{ - NAL_SLICE_NO_PARTITIONING = 1, - NAL_SLICE_PART_A, - NAL_SLICE_PART_B, - NAL_SLICE_PART_C, - NAL_SLICE_IDR, - NAL_SEI, - NAL_SEQUENCE_PARAMETER_SET, - NAL_PICTURE_PARAMETER_SET, - NAL_PICTURE_DELIMITER, - NAL_END_OF_SEQUENCE, - NAL_END_OF_STREAM, - NAL_FILLER_DATA, - NAL_PREFIX_SVC = 14 +typedef enum { + NAL_SLICE_NO_PARTITIONING = 1, + NAL_SLICE_PART_A, + NAL_SLICE_PART_B, + NAL_SLICE_PART_C, + NAL_SLICE_IDR, + NAL_SEI, + NAL_SEQUENCE_PARAMETER_SET, + NAL_PICTURE_PARAMETER_SET, + NAL_PICTURE_DELIMITER, + NAL_END_OF_SEQUENCE, + NAL_END_OF_STREAM, + NAL_FILLER_DATA, + NAL_PREFIX_SVC = 14 } mc_nal_unit_type_e; -enum -{ - MC_EXIST_SPS = 1 << 0, - MC_EXIST_PPS = 1 << 1, - MC_EXIST_IDR = 1 << 2, - MC_EXIST_SLICE = 1 << 3, +enum { + MC_EXIST_SPS = 1 << 0, + MC_EXIST_PPS = 1 << 1, + MC_EXIST_IDR = 1 << 2, + MC_EXIST_SLICE = 1 << 3, - MC_VALID_HEADER = ( MC_EXIST_SPS | MC_EXIST_PPS ), - MC_VALID_FIRST_SLICE = ( MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR ) + MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS), + MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR) }; #define CHECK_VALID_PACKET(state, expected_state) \ - ((state & (expected_state)) == (expected_state)) - -static const unsigned int mask[33] = -{ - 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, - 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, - 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, - 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, - 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, - 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, - 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, - 0xffffffff + ((state & (expected_state)) == (expected_state)) + +static const unsigned int mask[33] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff }; -struct _mc_bitstream_t -{ - unsigned char *data; - unsigned int numBytes; - unsigned int bytePos; - unsigned int buffer; - unsigned int dataBitPos; - unsigned int bitcnt; +struct _mc_bitstream_t { + unsigned char *data; + unsigned int numBytes; + unsigned int bytePos; + unsigned int buffer; + unsigned int dataBitPos; + unsigned int bitcnt; }; - #ifdef __cplusplus extern "C" { #endif @@ -84,28 +79,26 @@ extern "C" { #define MC_READ16B(x) ((((const unsigned char*)(x))[0] << 8) | ((const unsigned char*)(x))[1]) #define MC_READ32B(x) ((((const unsigned char*)(x))[0] << 24) | \ - (((const unsigned char*)(x))[1] << 16) | \ - (((const unsigned char*)(x))[2] << 8) | \ - ((const unsigned char*)(x))[3]) + (((const unsigned char*)(x))[1] << 16) | \ + (((const unsigned char*)(x))[2] << 8) | \ + ((const unsigned char*)(x))[3]) void mc_init_bits(mc_bitstream_t *stream, unsigned char *data, int size); short mc_show_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData); -short mc_read_bits( mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData ); -short mc_byte_align( mc_bitstream_t *stream ); +short mc_read_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData); +short mc_byte_align(mc_bitstream_t *stream); bool _mc_is_voss(unsigned char *buf, int size, int *codec_size); bool _mc_is_ivop(unsigned char *p, int size, int pos); bool _mc_is_vop(unsigned char *p, int size, int pos); - int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height); -unsigned int __mc_bytestream_to_nal( unsigned char* data, int size ); -int _mc_check_h264_bytestream ( unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice); +unsigned int __mc_bytestream_to_nal(unsigned char* data, int size); +int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice); int _mc_check_valid_h263_frame(unsigned char *p, int size); bool _mc_check_h263_out_bytestream(unsigned char *p, int buf_length, bool* need_sync_flag); int _mc_check_mpeg4_out_bytestream(unsigned char *buf, int buf_length, bool* need_codec_data, bool *need_sync_flag); - #ifdef __cplusplus } #endif diff --git a/include/media_codec_port.h b/include/media_codec_port.h index e31dfd8..2b7ec12 100755 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -43,16 +43,17 @@ #define GET_IS_DECODER(x) CHECK_BIT(x, 1) #define GET_IS_HW(x) CHECK_BIT(x, 2) #define GET_IS_SW(x) CHECK_BIT(x, 3) - -//#define GET_IS_OMX(x) CHECK_BIT(x, 4) -//#define GET_IS_GEN(x) CHECK_BIT(x, 5) +/* +#define GET_IS_OMX(x) CHECK_BIT(x, 4) +#define GET_IS_GEN(x) CHECK_BIT(x, 5) +*/ #if 1 #define MEDIACODEC_FENTER(); #define MEDIACODEC_FLEAVE(); #else -#define MEDIACODEC_FENTER(); LOGW("%s Enter",__FUNCTION__); -#define MEDIACODEC_FLEAVE(); LOGW("%s Exit",__FUNCTION__); +#define MEDIACODEC_FENTER(); LOGW("%s Enter", __FUNCTION__); +#define MEDIACODEC_FLEAVE(); LOGW("%s Exit", __FUNCTION__); #endif /*--------------------------------------------------------------------------- @@ -61,8 +62,7 @@ /** * @brief Enumerations of media codec port's retrun value */ -typedef enum -{ +typedef enum { MC_ERROR_NONE = 0, MC_ERROR = -1, /**< codec happens error */ MC_MEMORY_ERROR = -2, /**< codec memory is not enough */ @@ -112,100 +112,94 @@ typedef void (*mc_buffer_status_cb)(mediacodec_status_e status, void *user_data) typedef void (*mc_supported_codec_cb)(mediacodec_codec_type_e codec_type, void *user_data); typedef enum { - _MEDIACODEC_EVENT_TYPE_COMPLETE, - _MEDIACODEC_EVENT_TYPE_EMPTYBUFFER, - _MEDIACODEC_EVENT_TYPE_FILLBUFFER, - _MEDIACODEC_EVENT_TYPE_ERROR, - _MEDIACODEC_EVENT_TYPE_EOS, - _MEDIACODEC_EVENT_TYPE_BUFFER_STATUS, - _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER, - _MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC, - _MEDIACODEC_EVENT_TYPE_NUM + _MEDIACODEC_EVENT_TYPE_COMPLETE, + _MEDIACODEC_EVENT_TYPE_EMPTYBUFFER, + _MEDIACODEC_EVENT_TYPE_FILLBUFFER, + _MEDIACODEC_EVENT_TYPE_ERROR, + _MEDIACODEC_EVENT_TYPE_EOS, + _MEDIACODEC_EVENT_TYPE_BUFFER_STATUS, + _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER, + _MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC, + _MEDIACODEC_EVENT_TYPE_NUM } _mediacodec_event_e; -typedef enum _mc_codec_port_type_e -{ - CODEC_PORT_TYPE_GENERAL, - CODEC_PORT_TYPE_OMX, - CODEC_PORT_TYPE_GST, - CODEC_PORT_TYPE_MAX, +typedef enum _mc_codec_port_type_e { + CODEC_PORT_TYPE_GENERAL, + CODEC_PORT_TYPE_OMX, + CODEC_PORT_TYPE_GST, + CODEC_PORT_TYPE_MAX, } mc_codec_port_type_e; -typedef enum _mc_vendor_e -{ - MC_VENDOR_DEFAULT, - MC_VENDOR_SLSI_SEC, - MC_VENDOR_SLSI_EXYNOS, - MC_VENDOR_QCT, - MC_VENDOR_SPRD +typedef enum _mc_vendor_e { + MC_VENDOR_DEFAULT, + MC_VENDOR_SLSI_SEC, + MC_VENDOR_SLSI_EXYNOS, + MC_VENDOR_QCT, + MC_VENDOR_SPRD } mc_vendor_e; -struct _mc_decoder_info_t -{ - int width; - int height; - int actwidth; - int actheight; +struct _mc_decoder_info_t { + int width; + int height; + int actwidth; + int actheight; - int samplerate; - int channel; - int bit; + int samplerate; + int channel; + int bit; }; -struct _mc_encoder_info_t -{ - int width; - int height; - int bitrate; - int format; - int fps; - int qp_min; - int qp_max; - int vbvbuffer_size; - int level; - int profile; - - int samplerate; - int channel; - int bit; +struct _mc_encoder_info_t { + int width; + int height; + int bitrate; + int format; + int fps; + int qp_min; + int qp_max; + int vbvbuffer_size; + int level; + int profile; + + int samplerate; + int channel; + int bit; }; /* Codec Private data */ -struct _mc_handle_t -{ - int state; /**< mc current state */ - bool is_encoder; - bool is_video; - bool is_hw; - bool is_prepared; - - GList *supported_codecs; - mediacodec_port_type_e port_type; - mediacodec_codec_type_e codec_id; - mc_vendor_e vendor; - - void *ports[2]; - void *core; - - union - { - mc_decoder_info_t decoder; - mc_encoder_info_t encoder; - } info; - - /* for process done cb */ - void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; - void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; - - mc_codec_map_t encoder_map[MEDIA_CODEC_MAX_CODEC_TYPE]; - mc_codec_map_t decoder_map[MEDIA_CODEC_MAX_CODEC_TYPE]; - - int num_supported_codecs; - int num_supported_decoder; - int num_supported_encoder; - - mc_ini_t ini; +struct _mc_handle_t { + int state; /**< mc current state */ + bool is_encoder; + bool is_video; + bool is_hw; + bool is_prepared; + + GList *supported_codecs; + mediacodec_port_type_e port_type; + mediacodec_codec_type_e codec_id; + mc_vendor_e vendor; + + void *ports[2]; + void *core; + + union { + mc_decoder_info_t decoder; + mc_encoder_info_t encoder; + } info; + + /* for process done cb */ + void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; + void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; + + mc_codec_map_t encoder_map[MEDIA_CODEC_MAX_CODEC_TYPE]; + mc_codec_map_t decoder_map[MEDIA_CODEC_MAX_CODEC_TYPE]; + + int num_supported_codecs; + int num_supported_decoder; + int num_supported_encoder; + + mc_ini_t ini; }; /*=========================================================================================== diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 52793e2..552162d 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -36,21 +36,23 @@ extern "C" { #endif #define GST_INIT_STRUCTURE(param) \ - memset(&(param), 0, sizeof(param)); - -#define MEDIACODEC_ELEMENT_SET_STATE( x_element, x_state ) \ - do { \ - LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \ - if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \ - { \ - LOGE("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \ - goto STATE_CHANGE_FAILED; \ - } \ - } while (0) + memset(&(param), 0, sizeof(param)); + +#define MEDIACODEC_ELEMENT_SET_STATE(x_element, x_state) \ + do { \ + LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME(x_element)); \ + if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(x_element, x_state)) { \ + LOGE("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME(x_element)); \ + goto STATE_CHANGE_FAILED; \ + } \ + } while (0) #define SCMN_IMGB_MAX_PLANE 4 #define TBM_API_CHANGE #define DEFAULT_POOL_SIZE 20 +#define AAC_CODECDATA_SIZE 16 +#define WMA_CODECDATA_SIZE 64 +#define VORBIS_CODECDATA_SIZE 4096 /* gst port layer */ typedef struct _mc_gst_port_t mc_gst_port_t; @@ -73,8 +75,7 @@ struct ion_mmu_data { }; #endif -struct _mc_gst_port_t -{ +struct _mc_gst_port_t { mc_gst_core_t *core; unsigned int num_buffers; unsigned int buffer_size; @@ -86,17 +87,17 @@ struct _mc_gst_port_t GCond buffer_cond; }; -struct _mc_gst_core_t -{ +struct _mc_gst_core_t { int(**vtable)(); const char *mime; gchar *format; - GstElement* pipeline; - GstElement* appsrc; - GstElement* capsfilter; - GstElement* parser; - GstElement* fakesink; - GstElement* codec; + GstElement *pipeline; + GstElement *appsrc; + GstElement *capsfilter; + GstElement *parser; + GstElement *fakesink; + GstElement *codec; + GstCaps *caps; tbm_bufmgr bufmgr; int drm_fd; @@ -143,8 +144,7 @@ struct _mc_gst_core_t void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; }; -struct _GstMCBuffer -{ +struct _GstMCBuffer { GstBuffer *buffer; int buf_size; mc_gst_core_t* core; @@ -152,11 +152,10 @@ struct _GstMCBuffer bool has_imgb; }; -enum { fill_inbuf, fill_outbuf, create_caps }; +enum { fill_inbuf, fill_outbuf }; int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); -int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config); int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff); int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer); @@ -165,31 +164,6 @@ int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int siz int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt); -int __mc_vdec_sw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_hw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_sw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_hw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); - -void _mc_create_codec_map_from_ini(mc_handle_t *mc_handle, mc_codec_spec_t *spec_emul); -void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); -void _mc_create_encoder_map_from_ini(mc_handle_t *mc_handle); mc_gst_core_t *mc_gst_core_new(); void mc_gst_core_free(mc_gst_core_t *core); diff --git a/include/media_codec_private.h b/include/media_codec_private.h index c703087..dc5d663 100755 --- a/include/media_codec_private.h +++ b/include/media_codec_private.h @@ -34,89 +34,85 @@ extern "C" { #define LOG_TAG "TIZEN_N_MEDIACODEC" -#define MEDIACODEC_CHECK_CONDITION(condition,error,msg) \ - if(condition) {} else \ - { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \ +#define MEDIACODEC_CHECK_CONDITION(condition, error, msg) \ + if (condition) {} else \ + {LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); return error; }; \ #define MEDIACODEC_INSTANCE_CHECK(mediacodec) \ - MEDIACODEC_CHECK_CONDITION(mediacodec != NULL, MEDIACODEC_ERROR_INVALID_PARAMETER,"MEDIACODEC_ERROR_INVALID_PARAMETER") + MEDIACODEC_CHECK_CONDITION(mediacodec != NULL, MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER") -#define MEDIACODEC_STATE_CHECK(mediacodec,expected_state) \ - MEDIACODEC_CHECK_CONDITION(mediacodec->state == expected_state,MEDIACODEC_ERROR_INVALID_STATE,"MEDIACODEC_ERROR_INVALID_STATE") +#define MEDIACODEC_STATE_CHECK(mediacodec, expected_state) \ + MEDIACODEC_CHECK_CONDITION(mediacodec->state == expected_state, MEDIACODEC_ERROR_INVALID_STATE, "MEDIACODEC_ERROR_INVALID_STATE") #define MEDIACODEC_NULL_ARG_CHECK(arg) \ - MEDIACODEC_CHECK_CONDITION(arg != NULL,MEDIACODEC_ERROR_INVALID_PARAMETER,"MEDIACODEC_ERROR_INVALID_PARAMETER") + MEDIACODEC_CHECK_CONDITION(arg != NULL, MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER") #define MEDIACODEC_SUPPORT_CHECK(arg) \ - MEDIACODEC_CHECK_CONDITION(arg != false, MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE, "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE") + MEDIACODEC_CHECK_CONDITION(arg != false, MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE, "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE") /** * @brief Enumeration of media codec state * @since_tizen 2.3 */ -typedef enum -{ - MEDIACODEC_STATE_NONE = 0, /**< Media codec is not created */ - MEDIACODEC_STATE_IDLE, /**< Media codec is created, but not prepared */ - MEDIACODEC_STATE_READY, /**< Media codec is ready to process */ - MEDIACODEC_STATE_EXCUTE, /**< Media codec is executing media */ +typedef enum { + MEDIACODEC_STATE_NONE = 0, /**< Media codec is not created */ + MEDIACODEC_STATE_IDLE, /**< Media codec is created, but not prepared */ + MEDIACODEC_STATE_READY, /**< Media codec is ready to process */ + MEDIACODEC_STATE_EXCUTE, /**< Media codec is executing media */ } mediacodec_state_e; -typedef enum -{ - MEDIACODEC_SUPPORT_TYPE_OMX = 0x10, /**< This is optional flag for using openmax il */ - MEDIACODEC_SUPPORT_TYPE_GEN = 0x20 /**< This is optional flag for using general codec */ +typedef enum { + MEDIACODEC_SUPPORT_TYPE_OMX = 0x10, /**< This is optional flag for using openmax il */ + MEDIACODEC_SUPPORT_TYPE_GEN = 0x20 /**< This is optional flag for using general codec */ } mediacodec_internal_support_type_e; -typedef enum -{ - MEDIACODEC_PORT_TYPE_GENERAL, - MEDIACODEC_PORT_TYPE_OMX, - MEDIACODEC_PORT_TYPE_GST, - MEDIACODEC_PORT_TYPE_MAX, +typedef enum { + MEDIACODEC_PORT_TYPE_GENERAL, + MEDIACODEC_PORT_TYPE_OMX, + MEDIACODEC_PORT_TYPE_GST, + MEDIACODEC_PORT_TYPE_MAX, } mediacodec_port_type_e; /** * @brief Media Codec's format for configuring codec. */ typedef struct _mediacodecformat_s { - // Video - int fps; - int height; - int width; - float aspect; - bool vfr; - int level; - int profile; - - // Audio - int channels; - int samplerate; - int bitrate; - - // Codec Extra Data - void * extradata; - unsigned int extrasize; + /* Video */ + int fps; + int height; + int width; + float aspect; + bool vfr; + int level; + int profile; + + /* Audio */ + int channels; + int samplerate; + int bitrate; + + /* Codec Extra Data */ + void * extradata; + unsigned int extrasize; } mediacodec_format_s; typedef struct _mediacodec_s { - MMHandleType mc_handle; - int state; - bool is_omx; - char *m_mime; - - mediacodec_input_buffer_used_cb empty_buffer_cb; - void* empty_buffer_cb_userdata; - mediacodec_output_buffer_available_cb fill_buffer_cb; - void* fill_buffer_cb_userdata; - mediacodec_error_cb error_cb; - void* error_cb_userdata; - mediacodec_eos_cb eos_cb; - void* eos_cb_userdata; - mediacodec_buffer_status_cb buffer_status_cb; - void* buffer_status_cb_userdata; - mediacodec_supported_codec_cb supported_codec_cb; - void* supported_codec_cb_userdata; - + MMHandleType mc_handle; + int state; + bool is_omx; + char *m_mime; + + mediacodec_input_buffer_used_cb empty_buffer_cb; + void* empty_buffer_cb_userdata; + mediacodec_output_buffer_available_cb fill_buffer_cb; + void* fill_buffer_cb_userdata; + mediacodec_error_cb error_cb; + void* error_cb_userdata; + mediacodec_eos_cb eos_cb; + void* eos_cb_userdata; + mediacodec_buffer_status_cb buffer_status_cb; + void* buffer_status_cb_userdata; + mediacodec_supported_codec_cb supported_codec_cb; + void* supported_codec_cb_userdata; } mediacodec_s; bool __mediacodec_state_validate(mediacodec_h mediacodec, mediacodec_state_e threshold); diff --git a/include/media_codec_queue.h b/include/media_codec_queue.h index 5242997..cc8fe24 100755 --- a/include/media_codec_queue.h +++ b/include/media_codec_queue.h @@ -24,37 +24,29 @@ extern "C" { #endif typedef struct _async_queue { - GMutex mutex; - GCond condition; - GList *head; - GList *tail; - guint length; - gboolean enabled; + GMutex mutex; + GCond condition; + GList *head; + GList *tail; + guint length; + gboolean enabled; } async_queue_t; typedef struct _mc_aqueue { - GThread *thread; - gint running; - async_queue_t *input; - async_queue_t *output; + GThread *thread; + gint running; + async_queue_t *input; + async_queue_t *output; } mc_aqueue_t; async_queue_t *mc_async_queue_new(); - void mc_async_queue_free(async_queue_t *async_queue); - void mc_async_queue_push(async_queue_t *async_queue, gpointer data); - -gpointer mc_async_queue_pop_forced (async_queue_t * async_queue); - +gpointer mc_async_queue_pop_forced(async_queue_t *async_queue); gpointer mc_async_queue_pop(async_queue_t *async_queue); - -void mc_async_queue_disable (async_queue_t *async_queue); - -void mc_async_queue_enable (async_queue_t *async_queue); - +void mc_async_queue_disable(async_queue_t *async_queue); +void mc_async_queue_enable(async_queue_t *async_queue); void mc_async_queue_flush(async_queue_t *async_queue); - gboolean mc_async_queue_is_empty(async_queue_t *async_queue); #ifdef __cplusplus diff --git a/include/media_codec_spec_emul.h b/include/media_codec_spec_emul.h index 3ba2129..4fc7f6f 100755 --- a/include/media_codec_spec_emul.h +++ b/include/media_codec_spec_emul.h @@ -23,32 +23,29 @@ extern "C" { #include -enum { DECODER, ENCODER }; -enum { SOFTWARE, HARDWARE }; +enum {DECODER, ENCODER}; +enum {SOFTWARE, HARDWARE}; typedef struct _mc_codec_spec_t mc_codec_spec_t; typedef struct _mc_codec_map_t mc_codec_map_t; typedef struct _mc_codec_type_t mc_codec_type_t; -struct _mc_codec_spec_t -{ - mediacodec_codec_type_e codec_id; - mediacodec_support_type_e codec_type; - mediacodec_port_type_e port_type; +struct _mc_codec_spec_t { + mediacodec_codec_type_e codec_id; + mediacodec_support_type_e codec_type; + mediacodec_port_type_e port_type; }; -struct _mc_codec_type_t -{ - char *factory_name; - char *mime; - media_format_mimetype_e out_format; +struct _mc_codec_type_t { + char *factory_name; + char *mime; + media_format_mimetype_e out_format; }; -struct _mc_codec_map_t -{ - mediacodec_codec_type_e id; - bool hardware; - mc_codec_type_t type; +struct _mc_codec_map_t { + mediacodec_codec_type_e id; + bool hardware; + mc_codec_type_t type; }; diff --git a/include/media_codec_util.h b/include/media_codec_util.h index d88b889..988a54a 100755 --- a/include/media_codec_util.h +++ b/include/media_codec_util.h @@ -21,34 +21,31 @@ #include #include #include -//#include #ifdef __cplusplus extern "C" { #endif -typedef enum -{ - CODEC_RET_SUCCESS = 0, - CODEC_RET_FAIL = -1, - CODEC_RET_NOT_SUPPORT = -2, - CODEC_RET_INVALID_ARG = -3, - CODEC_RET_INVALID_CONFIG = -4, - CODEC_RET_CORRUPTED_BS = -5, - CODEC_RET_SMALL_IMG_BUF = -6, - CODEC_RET_HW_ERROR = -7, - CODEC_RET_NOT_AVAILABLE = -8, - CODEC_RET_NOT_EXPECTED = -9, - CODEC_RET_UNKNOWN_ERR = -100, +typedef enum { + CODEC_RET_SUCCESS = 0, + CODEC_RET_FAIL = -1, + CODEC_RET_NOT_SUPPORT = -2, + CODEC_RET_INVALID_ARG = -3, + CODEC_RET_INVALID_CONFIG = -4, + CODEC_RET_CORRUPTED_BS = -5, + CODEC_RET_SMALL_IMG_BUF = -6, + CODEC_RET_HW_ERROR = -7, + CODEC_RET_NOT_AVAILABLE = -8, + CODEC_RET_NOT_EXPECTED = -9, + CODEC_RET_UNKNOWN_ERR = -100, } CodecRet; typedef struct _mc_sem_t mc_sem_t; -struct _mc_sem_t -{ - GCond cond; - GMutex mutex; - int counter; +struct _mc_sem_t { + GCond cond; + GMutex mutex; + int counter; }; mc_sem_t *mc_sem_new(); @@ -59,9 +56,9 @@ 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; + if (x) \ + g_free(x); \ + x = NULL; #ifdef __cplusplus } diff --git a/src/media_codec.c b/src/media_codec.c index 0bfcaf2..c8d6e20 100755 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -490,12 +490,12 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo } -int mediacodec_get_packet_pool(mediacodec_h mediacodec,media_packet_pool_h *pkt_pool) +int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool) { MEDIACODEC_INSTANCE_CHECK(mediacodec); mediacodec_s *handle = (mediacodec_s *)mediacodec; MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY); - int ret = mc_get_packet_pool(handle->mc_handle,pkt_pool); + int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool); if (ret != MEDIACODEC_ERROR_NONE) return MEDIACODEC_ERROR_INVALID_OPERATION; diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 468efde..edb2d20 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -739,7 +739,7 @@ int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool) break; case MEDIACODEC_PORT_TYPE_GST: - ret = mc_gst_get_packet_pool(mc_handle, pool); + ret = mc_gst_get_packet_pool(mc_handle, pool); break; default: diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 40e9315..9e82cb4 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -48,9 +48,9 @@ static mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name static mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core); static void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data); static int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data); -static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config); +static int _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer* buff, bool codec_config); 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, GstCaps **caps, media_packet_h pkt, bool codec_config); +static GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h pkt, bool codec_config); static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *buff); 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); @@ -59,8 +59,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 pkt); static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t* core, media_packet_h pkt, uint64_t size); static void gst_mediacodec_buffer_finalize(GstMCBuffer *buffer); -static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint streamheader_size); -static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint codecdata_size); +static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer*buff, guint streamheader_size); +static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer*buff, guint codecdata_size); static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message); static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, GError *error); @@ -89,96 +89,75 @@ static void _mc_wait_for_eos(mc_gst_core_t *core); static int _mediacodec_get_mime(mc_gst_core_t *core); /* video vtable */ -int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_vdec_sw_h264_caps}; -int(*venc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_venc_caps}; +int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; +int(*venc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; int(*vdec_h264_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W H.264 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_sw_h264_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*vdec_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_mpeg4_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*vdec_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* S/W MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_sw_h263_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*vdec_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W H.264 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_hw_h264_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_mpeg4_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*vdec_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* H/W MPEG4 Decoder Vtable */ - &__mc_fill_vdec_packet_with_output_buffer, - &__mc_vdec_hw_h263_caps}; + &__mc_fill_vdec_packet_with_output_buffer}; int(*venc_mpeg4_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* S/W MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_output_buffer, - &__mc_venc_caps}; + &__mc_fill_venc_packet_with_output_buffer}; int(*venc_h263_sw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* S/W MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_output_buffer, - &__mc_venc_caps}; + &__mc_fill_venc_packet_with_output_buffer}; int(*venc_h264_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W H.264 Encoder Vtable */ - &__mc_fill_venc_packet_with_output_buffer, - &__mc_venc_caps}; + &__mc_fill_venc_packet_with_output_buffer}; int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_output_buffer, - &__mc_venc_caps}; + &__mc_fill_venc_packet_with_output_buffer}; int(*venc_h263_hw_vtable[])() = {&__mc_fill_input_buffer_with_venc_packet, /* H/W MPEG4 Encoder Vtable */ - &__mc_fill_venc_packet_with_output_buffer, - &__mc_venc_caps}; + &__mc_fill_venc_packet_with_output_buffer}; -int(*aenc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_aenc_caps}; -int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer, &__mc_adec_caps}; +int(*aenc_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; +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_aenc_aac_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_aac_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC HE Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_aacv12_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_mp3_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* MP3 Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_mp3_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-NB Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_amrnb_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_amrwb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-WB Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_amrwb_caps}; + &__mc_fill_packet_with_output_buffer}; int(*aenc_amrnb_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AMR-NB Encoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_aenc_amrnb_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_vorbis_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* VORBIS Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_vorbis_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_flac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* FLAC Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_flac_caps}; + &__mc_fill_packet_with_output_buffer}; int(*adec_wma_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* WMA Decoder Vtable */ - &__mc_fill_packet_with_output_buffer, - &__mc_adec_wma_caps}; + &__mc_fill_packet_with_output_buffer}; /* @@ -593,480 +572,6 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in return ret; } -/* - * create_caps virtual functions - */ - -int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config) -{ - return core->vtable[create_caps](core, caps, buff, codec_config); -} - -int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, core->format, - "width", G_TYPE_INT, enc_info->width, - "height", G_TYPE_INT, enc_info->height, - "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, - NULL); - - if (core->is_hw) - g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); - else - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - - LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps); - - return MC_ERROR_NONE; -} - -int __mc_vdec_sw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - LOGD("%d, %d, ", dec_info->width, dec_info->height); - - *caps = gst_caps_new_simple(core->mime, - "width", G_TYPE_INT, dec_info->width, - "height", G_TYPE_INT, dec_info->height, - "variant", G_TYPE_STRING, "itu", - NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - - return MC_ERROR_NONE; -} - -int __mc_vdec_hw_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - LOGD("%d, %d, ", dec_info->width, dec_info->height); - - *caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, - "width", G_TYPE_INT, dec_info->width, - "height", G_TYPE_INT, dec_info->height, - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - - return MC_ERROR_NONE; -} - -int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, - "systemstream", G_TYPE_BOOLEAN, false, - "parsed", G_TYPE_BOOLEAN, TRUE, - "width", G_TYPE_INT, dec_info->width, - "height", G_TYPE_INT, dec_info->height, - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - return MC_ERROR_NONE; -} - -int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - return MC_ERROR_NONE; -} - -int __mc_vdec_sw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - return MC_ERROR_NONE; -} - -int __mc_vdec_hw_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff,gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "parsed", G_TYPE_BOOLEAN, TRUE, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", - "width", G_TYPE_INT, dec_info->width, - "framerate", GST_TYPE_FRACTION, 30, 1, - "height", G_TYPE_INT, dec_info->height, NULL); - - LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height); - return MC_ERROR_NONE; -} - -int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, enc_info->samplerate, - "channels", G_TYPE_INT, enc_info->channel, - "format", G_TYPE_STRING, "F32LE", - "layout", G_TYPE_STRING, "interleaved", NULL); - - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - /* - +----GstAudioEncoder - +----avenc_aac - - Element Properties: -compliance : Adherence of the encoder to the specifications -flags: readable, writable -Enum "GstFFMpegCompliance" Default: 0, "normal" -(2): verystrict - Strictly conform to older spec -(1): strict - Strictly conform to current spec -(0): normal - Normal behavior -(-1): unofficial - Allow unofficial extensions -(-2): experimental - Allow nonstandardized experimental things -*/ - g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, enc_info->samplerate, - "channels", G_TYPE_INT, enc_info->channel, - "format", G_TYPE_STRING, "F32LE", - "layout", G_TYPE_STRING, "interleaved", NULL); - - g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, enc_info->samplerate, - "channels", G_TYPE_INT, enc_info->channel, - "format", G_TYPE_STRING, "S16LE", - "layout", G_TYPE_STRING, "interleaved", - NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - int ret = MC_ERROR_NONE; - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)"); - *caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, 4, - "stream-format", G_TYPE_STRING, "adts", - "rate", G_TYPE_INT, dec_info->samplerate, - "channels", G_TYPE_INT, dec_info->channel, - NULL); - - if (codec_config && (!core->encoder)) { - guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/ - ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_codecdata failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} - -int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config) -{ - int ret = MC_ERROR_NONE; - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)"); - *caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, 4, - "stream-format", G_TYPE_STRING, "adts", - "rate", G_TYPE_INT, dec_info->samplerate, - "channels", G_TYPE_INT, dec_info->channel, - NULL); - - if (codec_config && (!core->encoder)) { - guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/ - ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_codecdata failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} - -int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - int ret = MC_ERROR_NONE; - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE and _PS - MP4/M4A case)"); - *caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, /*TODO : need adding version /profile*/ - "framed", G_TYPE_BOOLEAN, TRUE, - "stream-format", G_TYPE_STRING, "raw", - "channels", G_TYPE_INT, dec_info->channel, - "rate", G_TYPE_INT, dec_info->samplerate, - NULL); - - if (codec_config && (!core->encoder)) { - guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/ - ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_codecdata failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} - -int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, 1, /* To-Do : plz check */ - "mpegaudioversion", G_TYPE_INT, 1, /* To-Do : plz check */ - "layer", G_TYPE_INT, 3, /* To-Do : plz check */ - "rate", G_TYPE_INT, dec_info->samplerate, - "channels", G_TYPE_INT, dec_info->channel, - NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, 8000, - "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */ - NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, 16000, - "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */ - NULL); - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return MC_ERROR_NONE; -} - -int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - int ret = MC_ERROR_NONE; - - *caps = gst_caps_new_simple(core->mime, - "channels", G_TYPE_INT, dec_info->channel, - "rate", G_TYPE_INT, dec_info->samplerate, - /* FIXME - Insert 'Stream Header' */ - NULL); - - LOGD(" ----- VORBIS Need Additional Caps -----------"); - /* - * Need to extract from each Stream header ... or - * Need to get Demuxer's Caps from each Stream heade - */ - if (codec_config && (!core->encoder)) { - guint streamheader_size = 4096; /* VORBIS_CODECDATA_SIZE = 4096 */ - ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_streamheader failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} - -int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - int ret = MC_ERROR_NONE; - - *caps = gst_caps_new_simple(core->mime, - "channels", G_TYPE_INT, dec_info->channel, - "rate", G_TYPE_INT, dec_info->samplerate, - "framed", G_TYPE_BOOLEAN, TRUE, - /* FIXME - Insert More Info */ - NULL); - - LOGD(" ----- FLAC Need Additional Caps -----------"); - /* - * Need to extract from each Stream header ... or - * Need to get Demuxer's Caps from each Stream heade - */ - if (codec_config && (!core->encoder)) { - guint streamheader_size = 4096; /* FLAC_CODECDATA_SIZE = 4096 */ - ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_streamheader failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} - -int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, gboolean codec_config) -{ - int ret = MC_ERROR_NONE; - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - /* - * Need to extract from Stream Type Specific ... or - * Need to get Demuxer's Caps from Stream Type Specific - */ - guint16 format_tag = 0; - gint wma_version = 0; - gint block_align = 1024; /*FIXME : Need checking */ - gint bitrate = 128000; /*FIXME : Need checking */ - - LOGD(" ----- WMA Need Additional Caps -----------"); - if (core->codec_id == MEDIACODEC_WMAV1) { - format_tag = 352; /* 0x160 */ - wma_version = 1; - } else if (core->codec_id == MEDIACODEC_WMAV2) { - format_tag = 353; /* 0x161 */ - wma_version = 2; - } else if (core->codec_id == MEDIACODEC_WMAPRO) { - format_tag = 354; /* 0x162 */ - wma_version = 3; - } else if (core->codec_id == MEDIACODEC_WMALSL) { - format_tag = 355; /* 0x163 */ - wma_version = 3; - } else { - LOGE("Not support WMA format"); - } - - *caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, dec_info->samplerate, - "channels", G_TYPE_INT, dec_info->channel, - "bitrate", G_TYPE_INT, bitrate, - "depth", G_TYPE_INT, dec_info->bit, - /* FIXME - Need More Info */ - "wmaversion", G_TYPE_INT, wma_version, - "format_tag", G_TYPE_INT, format_tag, - "block_align", G_TYPE_INT, block_align, - NULL); - - if (codec_config && (!core->encoder)) { - guint codecdata_size = 64; /* WMA_CODECDATA_SIZE = 64 */ - ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size); - if (ret != MC_ERROR_NONE) { - LOGW("__mc_set_caps_codecdata failed"); - return ret; - } - } - - LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel); - - return ret; -} static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * name, GstBuffer * buf, ...) { @@ -1102,7 +607,7 @@ static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * nam return caps; } -int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint streamheader_size) +int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer*buff, guint streamheader_size) { int ret = MEDIA_PACKET_ERROR_NONE; void *buf_data = NULL; @@ -1191,7 +696,7 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* LOGD("[vorbis] streamheader hsize1 (%d) + hsize2 (%d) + hsize3 (%d) = Total (%d)", hsize1, hsize2, hsize3, (hsize1 + hsize2 + hsize3)); - __mc_gst_caps_set_buffer_array(*caps, "streamheader", header1, header2, header3, NULL); + __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, header3, NULL); gst_buffer_unref(header1); gst_buffer_unref(header2); @@ -1243,7 +748,7 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* gst_buffer_unmap(header2, &map); LOGD("[flac] streamheader hsize1 (%d) + hsize2 (%d) = Total (%d)", hsize1, hsize2, (hsize1 + hsize2)); - __mc_gst_caps_set_buffer_array(*caps, "streamheader", header1, header2, NULL); + __mc_gst_caps_set_buffer_array(core->caps, "streamheader", header1, header2, NULL); gst_buffer_unref(header1); gst_buffer_unref(header2); } else { @@ -1259,7 +764,7 @@ int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* return ret; } -int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, guint codecdata_size) +int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *buff, guint codecdata_size) { int ret = MEDIA_PACKET_ERROR_NONE; void *buf_data = NULL; @@ -1286,7 +791,7 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *bu gst_buffer_ref(codecdata_buffer); LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size); - gst_caps_set_simple(*caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL); + gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL); gst_buffer_unref(codecdata_buffer); /* Update gstbuffer's data ptr and size for using previous codec_data..*/ @@ -1478,7 +983,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) media_format_get_video_info(fmt, NULL, &width, &height, &bitrate, NULL); if ((codec_info->width != width) || (codec_info->height != height)) { - LOGD("Resolution changed : %dx%d -> %dx%d",codec_info->width, codec_info->height, width, height); + LOGD("Resolution changed : %dx%d -> %dx%d", codec_info->width, codec_info->height, width, height); codec_info->width = width; codec_info->height = height; is_updated = TRUE; @@ -1488,7 +993,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; if (enc_info->bitrate != bitrate) { - LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); + LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); enc_info->bitrate = bitrate; is_updated = TRUE; } @@ -1513,7 +1018,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; if (enc_info->bitrate != bitrate) { - LOGD("Bitrate changed : %d -> %d",enc_info->bitrate, bitrate); + LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); enc_info->bitrate = bitrate; is_updated = TRUE; } @@ -1523,24 +1028,97 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) return is_updated; } -static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config) +static int _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer* buff, bool codec_config) { - /*TODO remove is_hw param*/ - core->format = __mc_get_gst_input_format(pkt, core->is_hw); + MEDIACODEC_FENTER(); + + g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); + + int ret = MC_ERROR_NONE; + + if (core->video) { + if (core->encoder) { + mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - GstPad *pad = NULL; - GstCaps *template_caps; + core->format = __mc_get_gst_input_format(pkt, core->is_hw); + gst_caps_set_simple(core->caps, + "format", G_TYPE_STRING, core->format, + "width", G_TYPE_INT, enc_info->width, + "height", G_TYPE_INT, enc_info->height, + "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, + NULL); - pad = gst_element_get_static_pad(core->codec, "src"); - template_caps = gst_pad_get_pad_template_caps(pad); + if (g_object_class_find_property(G_OBJECT_GET_CLASS(core->codec), "bitrate")) + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); + else + g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); + + } else { + mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - __mc_create_caps(core, caps, buff, codec_config); - g_object_set(core->appsrc, "caps", *caps, NULL); + gst_caps_set_simple(core->caps, + "width", G_TYPE_INT, dec_info->width, + "height", G_TYPE_INT, dec_info->height, + NULL); + } + } else { + if (core->encoder) { + mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; + + gst_caps_set_simple(core->caps, + "rate", G_TYPE_INT, enc_info->samplerate, + "channels", G_TYPE_INT, enc_info->channel, + NULL); + g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); + } else { + mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; + + gst_caps_set_simple(core->caps, + "rate", G_TYPE_INT, dec_info->samplerate, + "channels", G_TYPE_INT, dec_info->channel, + NULL); + + if (codec_config) { + switch (core->codec_id) { + case MEDIACODEC_AAC: + case MEDIACODEC_AAC_HE: + case MEDIACODEC_AAC_HE_PS: + ret = __mc_set_caps_codecdata(core, buff, AAC_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) { + LOGW("__mc_set_caps_codecdata failed"); + return ret; + } + break; + case MEDIACODEC_WMAV1: + case MEDIACODEC_WMAV2: + case MEDIACODEC_WMAPRO: + case MEDIACODEC_WMALSL: + ret = __mc_set_caps_codecdata(core, buff, WMA_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) { + LOGW("__mc_set_caps_codecdata failed"); + return ret; + } + break; + case MEDIACODEC_VORBIS: + case MEDIACODEC_FLAC: + ret = __mc_set_caps_streamheader(core, buff, VORBIS_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) { + LOGW("__mc_set_caps_streamheader failed"); + return ret; + } + break; + default: + LOGD("doesn't need to set codecdata"); + break; - if (gst_caps_is_subset(*caps, template_caps)) - LOGD("new caps is subset of template caps"); + } + } + } + } + g_object_set(core->appsrc, "caps", core->caps, NULL); - gst_object_unref(pad); + MEDIACODEC_FLEAVE(); + return ret; } static gpointer feed_task(gpointer data) @@ -1552,7 +1130,6 @@ static gpointer feed_task(gpointer data) media_format_h fmt = NULL; media_packet_h in_buf = NULL; GstMCBuffer *buff = NULL; - GstCaps *new_caps = NULL; bool initiative = true; MEDIACODEC_FENTER(); @@ -1581,7 +1158,7 @@ static gpointer feed_task(gpointer data) goto ERROR; } - buff = _mc_gst_media_packet_to_gstbuffer(core, &new_caps, in_buf, codec_config); + buff = _mc_gst_media_packet_to_gstbuffer(core, in_buf, codec_config); if (!buff) { LOGW("gstbuffer can't make"); goto ERROR; @@ -1593,7 +1170,11 @@ static gpointer feed_task(gpointer data) if (initiative) { GstPad *pad; - _mc_gst_update_caps(core, in_buf, &new_caps, buff, codec_config); + ret = _mc_gst_update_caps(core, in_buf, buff, codec_config); + if (ret != MC_ERROR_NONE) { + LOGE("failed to update caps"); + goto ERROR; + } pad = gst_element_get_static_pad(core->appsrc, "src"); gst_pad_push_event(pad, gst_event_new_stream_start("sejun")); @@ -1635,9 +1216,6 @@ LEAVE: } - if (new_caps) - gst_caps_unref(new_caps); - LOGI("status : in_buf : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task", in_buf, codec_config, eos, core->video, core->encoder); LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder); @@ -1680,51 +1258,103 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo case MEDIACODEC_AAC: /* if set to 'CODEC_CONFIG', then It is also available case of MEDIA_FORMAT_AAC_LC (RAW) */ LOGD("aac lc (adts) vtable"); - core->vtable = encoder ? aenc_aac_vtable : adec_aac_vtable; + 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 { + LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)"); + + core->vtable = adec_aac_vtable; + core->caps = gst_caps_new_simple(core->mime, + "framed", G_TYPE_BOOLEAN, TRUE, + "mpegversion", G_TYPE_INT, 4, + "stream-format", G_TYPE_STRING, "adts", + NULL); + } break; case MEDIACODEC_AAC_HE: case MEDIACODEC_AAC_HE_PS: LOGD("aac he v12 vtable"); - core->vtable = encoder ? aenc_aac_vtable : adec_aacv12_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE and _PS - MP4/M4A case)"); + core->vtable = adec_aacv12_vtable; + core->caps = gst_caps_new_simple(core->mime, + "mpegversion", G_TYPE_INT, 4, /*TODO : need adding version /profile*/ + "framed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, "raw", + NULL); } break; case MEDIACODEC_MP3: LOGD("mp3 vtable - Only support decoder"); - core->vtable = encoder ? aenc_vtable : adec_mp3_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + core->vtable = adec_mp3_vtable; + core->caps = gst_caps_new_simple(core->mime, + "framed", G_TYPE_BOOLEAN, TRUE, + "mpegversion", G_TYPE_INT, 1, /* To-Do : plz check */ + "mpegaudioversion", G_TYPE_INT, 1, /* To-Do : plz check */ + "layer", G_TYPE_INT, 3, /* To-Do : plz check */ + NULL); } break; case MEDIACODEC_AMR_NB: LOGD("amrnb vtable"); - core->vtable = encoder ? aenc_amrnb_vtable : adec_amrnb_vtable; + if (encoder) { + core->vtable = aenc_amrnb_vtable; + core->caps = gst_caps_new_simple(core->mime, + "format", G_TYPE_STRING, "S16LE", + "layout", G_TYPE_STRING, "interleaved", + NULL); + + } else { + core->vtable = adec_amrnb_vtable; + core->caps = gst_caps_new_simple(core->mime, + "rate", G_TYPE_INT, 8000, + NULL); + } break; case MEDIACODEC_AMR_WB: LOGD("amrwb vtable - Only support decoder"); - core->vtable = encoder ? aenc_vtable : adec_amrwb_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + core->vtable = adec_amrwb_vtable; + core->caps = gst_caps_new_simple(core->mime, + "rate", G_TYPE_INT, 16000, + NULL); } break; case MEDIACODEC_VORBIS: LOGD("vorbis vtable"); - core->vtable = encoder ? aenc_vtable : adec_vorbis_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + core->vtable = adec_vorbis_vtable; + core->caps = gst_caps_new_empty_simple("audio/x-vorbis"); } break; case MEDIACODEC_FLAC: LOGD("flac vtable"); - core->vtable = encoder ? aenc_vtable : adec_flac_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + core->vtable = adec_flac_vtable; + core->caps = gst_caps_new_simple(core->mime, + "framed", G_TYPE_BOOLEAN, TRUE, + /* FIXME - Insert More Info */ + NULL); } break; case MEDIACODEC_WMAV1: @@ -1732,28 +1362,112 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo case MEDIACODEC_WMAPRO: case MEDIACODEC_WMALSL: LOGD("wma(V1 / V2 / LSL / PRO) vtable"); - core->vtable = encoder ? aenc_vtable : adec_wma_vtable; if (encoder) { LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; + } else { + mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; + + core->vtable = adec_wma_vtable; + + /* + * Need to extract from Stream Type Specific ... or + * Need to get Demuxer's Caps from Stream Type Specific + */ + guint16 format_tag = 0; + gint wma_version = 0; + gint block_align = 1024; /*FIXME : Need checking */ + gint bitrate = 128000; /*FIXME : Need checking */ + + LOGD(" ----- WMA Need Additional Caps -----------"); + if (core->codec_id == MEDIACODEC_WMAV1) { + format_tag = 352; /* 0x160 */ + wma_version = 1; + } else if (core->codec_id == MEDIACODEC_WMAV2) { + format_tag = 353; /* 0x161 */ + wma_version = 2; + } else if (core->codec_id == MEDIACODEC_WMAPRO) { + format_tag = 354; /* 0x162 */ + wma_version = 3; + } else if (core->codec_id == MEDIACODEC_WMALSL) { + format_tag = 355; /* 0x163 */ + wma_version = 3; + } else { + LOGE("Not support WMA format"); + } + + core->caps = gst_caps_new_simple(core->mime, + "bitrate", G_TYPE_INT, bitrate, + "depth", G_TYPE_INT, dec_info->bit, + /* FIXME - Need More Info */ + "wmaversion", G_TYPE_INT, wma_version, + "format_tag", G_TYPE_INT, format_tag, + "block_align", G_TYPE_INT, block_align, + NULL); } break; case MEDIACODEC_H263: LOGD("h263 vtable"); - core->vtable = encoder ? (is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable) : is_hw ? vdec_h263_hw_vtable : vdec_h263_sw_vtable; + if (encoder) { + core->vtable = is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable; + core->caps = gst_caps_new_empty_simple("video/x-raw"); + } else { + if (is_hw) { + core->vtable = vdec_h263_hw_vtable; + core->caps = gst_caps_new_simple(core->mime, + "mpegversion", G_TYPE_INT, 4, + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } else { + core->vtable = vdec_h263_sw_vtable; + core->caps = gst_caps_new_simple(core->mime, + "variant", G_TYPE_STRING, "itu", + NULL); + } + } break; case MEDIACODEC_MPEG4: LOGD("mpeg4 vtable"); - core->vtable = encoder ? (is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable) : is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable; - + if (encoder) { + core->vtable = is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable; + core->caps = gst_caps_new_empty_simple("video/x-raw"); + } else { + core->vtable = is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable; + core->caps = gst_caps_new_simple(core->mime, + "mpegversion", G_TYPE_INT, 4, + "systemstream", G_TYPE_BOOLEAN, false, + "parsed", G_TYPE_BOOLEAN, TRUE, + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } break; case MEDIACODEC_H264: LOGD("h264 vtable"); - core->vtable = encoder ? (is_hw ? venc_h264_hw_vtable : venc_vtable) : is_hw ? vdec_h264_hw_vtable : vdec_h264_sw_vtable; + if (encoder) { + core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable; + core->caps = gst_caps_new_empty_simple("video/x-raw"); + } else { + if (is_hw) { + core->vtable = vdec_h264_hw_vtable; + core->caps = gst_caps_new_simple(core->mime, + "parsed", G_TYPE_BOOLEAN, TRUE, + "alignment", G_TYPE_STRING, "au", + "stream-format", G_TYPE_STRING, "byte-stream", + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } else { + core->vtable = vdec_h264_sw_vtable; + core->caps = gst_caps_new_simple(core->mime, + "alignment", G_TYPE_STRING, "au", + "stream-format", G_TYPE_STRING, "byte-stream", NULL); + } + } break; default: break; } + /* set caps */ + g_object_set(core->appsrc, "caps", core->caps, NULL); return MC_ERROR_NONE; } @@ -1842,12 +1556,6 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) return ret; } - /* link vtable */ - if ((ret = _mc_link_vtable(new_core, id, encoder, hardware)) != MC_ERROR_NONE) { - LOGE("vtable link failed"); - return ret; - } - for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++) { LOGD("copy cb function [%d]", i); if (mc_handle->user_cb[i]) { @@ -1860,7 +1568,16 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) mc_handle->core = new_core; /* create basic core elements */ - ret = _mc_gst_create_pipeline(mc_handle->core, factory_name); + if ((ret = _mc_gst_create_pipeline(mc_handle->core, factory_name) != MC_ERROR_NONE)) { + LOGE("failed to create pipeline"); + return ret; + } + + /* link vtable */ + if ((ret = _mc_link_vtable(mc_handle->core, id, encoder, hardware)) != MC_ERROR_NONE) { + LOGE("vtable link failed"); + return ret; + } LOGD("initialized... %d", ret); return ret; @@ -2195,6 +1912,7 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) /* set state PLAYING */ MEDIACODEC_ELEMENT_SET_STATE(GST_ELEMENT_CAST(core->pipeline), GST_STATE_PLAYING); + } core->prepare_count++; g_mutex_unlock(&core->prepare_lock); @@ -2255,6 +1973,10 @@ mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core) MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(core->pipeline)); + if (core->caps) { + gst_caps_unref(core->caps); + core->caps = NULL; + } } } @@ -2408,7 +2130,7 @@ gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw) return format; } -GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **caps, media_packet_h pkt, bool codec_config) +GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, media_packet_h pkt, bool codec_config) { int ret = MEDIA_PACKET_ERROR_NONE; GstMCBuffer *mc_buffer = NULL; diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 15f10bb..698a24d 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -129,8 +129,8 @@ struct _App { int codecid; int flag; - bool is_video[MAX_HANDLE]; - bool is_encoder[MAX_HANDLE]; + bool is_video; + bool is_encoder; bool hardware; bool enable_dump; int frame; @@ -821,6 +821,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) media_format_mimetype_e mime = 0; encoder = GET_IS_ENCODER(flag) ? 1 : 0; *hardware = GET_IS_HW(flag) ? 1 : 0; + app->is_encoder = encoder; switch (codecid) { case MEDIACODEC_H264: @@ -1027,7 +1028,6 @@ static gboolean read_data(App *app) #ifdef USE_POOL if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) { fprintf(stderr, "media_packet_pool_aquire_packet failed\n"); - //return TRUE; return FALSE; } #else @@ -1253,8 +1253,7 @@ static void _mediacodec_prepare(App *app, bool frame_all) /* get packet pool instance */ - ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool); - + 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"); return; @@ -1357,7 +1356,7 @@ void _interpret_main_menu(char *cmd, App *app) else if (strncmp(cmd, "dt", 2) == 0) _mediacodec_destroy(app); else if (strncmp(cmd, "dp", 2) == 0) { - if(!app->enable_dump) { + if (!app->enable_dump) { app->enable_dump = TRUE; g_print("dump enabled\n"); } else { @@ -1648,7 +1647,6 @@ int main(int argc, char *argv[]) displaymenu(); app->loop = g_main_loop_new(NULL, TRUE); app->timer = g_timer_new(); - //app->frame_count = 0; g_main_loop_run(app->loop); @@ -1749,35 +1747,36 @@ static void decoder_output_dump(App *app, media_packet_h pkt) * This is needed as MediaCodec encoder generates a packet of raw AAC data. * Note the packetLen must count in the ADTS header itself. **/ -void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen) { - int profile = 2; //AAC LC (0x01) - int freqIdx = 3; //48KHz (0x03) - int chanCfg = 2; //CPE (0x02) - - if (app->samplerate == 96000) freqIdx = 0; - else if (app->samplerate == 88200) freqIdx = 1; - else if (app->samplerate == 64000) freqIdx = 2; - else if (app->samplerate == 48000) freqIdx = 3; - else if (app->samplerate == 44100) freqIdx = 4; - else if (app->samplerate == 32000) freqIdx = 5; - else if (app->samplerate == 24000) freqIdx = 6; - else if (app->samplerate == 22050) freqIdx = 7; - else if (app->samplerate == 16000) freqIdx = 8; - else if (app->samplerate == 12000) freqIdx = 9; - else if (app->samplerate == 11025) freqIdx = 10; - else if (app->samplerate == 8000) freqIdx = 11; - - if ((app->channel == 1) || (app->channel == 2)) - chanCfg = app->channel; - - // fill in ADTS data - buffer[0] = (char)0xFF; - buffer[1] = (char)0xF1; - buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2)); - buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11)); - buffer[4] = (char)((packetLen&0x7FF) >> 3); - buffer[5] = (char)(((packetLen&7)<<5) + 0x1F); - buffer[6] = (char)0xFC; +void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen) +{ + int profile = 2; /* AAC LC (0x01) */ + int freqIdx = 3; /* 48KHz (0x03) */ + int chanCfg = 2; /* CPE (0x02) */ + + if (app->samplerate == 96000) freqIdx = 0; + else if (app->samplerate == 88200) freqIdx = 1; + else if (app->samplerate == 64000) freqIdx = 2; + else if (app->samplerate == 48000) freqIdx = 3; + else if (app->samplerate == 44100) freqIdx = 4; + else if (app->samplerate == 32000) freqIdx = 5; + else if (app->samplerate == 24000) freqIdx = 6; + else if (app->samplerate == 22050) freqIdx = 7; + else if (app->samplerate == 16000) freqIdx = 8; + else if (app->samplerate == 12000) freqIdx = 9; + else if (app->samplerate == 11025) freqIdx = 10; + else if (app->samplerate == 8000) freqIdx = 11; + + if ((app->channel == 1) || (app->channel == 2)) + chanCfg = app->channel; + + /* fill in ADTS data */ + buffer[0] = (char)0xFF; + buffer[1] = (char)0xF1; + buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2)); + buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11)); + buffer[4] = (char)((packetLen&0x7FF) >> 3); + buffer[5] = (char)(((packetLen&7)<<5) + 0x1F); + buffer[6] = (char)0xFC; } static void output_dump(App *app, media_packet_h pkt) @@ -1796,13 +1795,13 @@ static void output_dump(App *app, media_packet_h pkt) media_packet_get_buffer_size(pkt, &buf_size); g_print("output data : %p, size %d\n", temp, (int)buf_size); - if (buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) { + if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) { 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 (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__); + 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 */ write_amr_header = 0; } -- 2.7.4 From 3efa2b42062b95657582e4196ee5ebf70442c37c Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 22 Jun 2016 14:56:13 +0900 Subject: [PATCH 07/16] Add duration when output is dequeued Change-Id: I7f4fc091def3c65a92f446acd1392f6b15a9d060 --- packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 28f5cf5..313794b 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -1,6 +1,6 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.4.1 +Version: 0.4.2 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 9e82cb4..2608cb2 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2025,6 +2025,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp if (out_pkt) { media_packet_set_extra(out_pkt, buffer); media_packet_set_pts(out_pkt, GST_BUFFER_TIMESTAMP(buffer)); + media_packet_set_duration(out_pkt, GST_BUFFER_DURATION(buffer)); if (core->need_codec_data) { media_packet_set_flags(out_pkt, MEDIA_PACKET_CODEC_CONFIG); @@ -2042,8 +2043,8 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp g_queue_push_tail(core->ports[1]->queue, out_pkt); g_atomic_int_inc(&core->ftb_count); - LOGD("dequeued : %d", core->ftb_count); - LOGD("GST_BUFFER_TIMESTAMP = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer))); + LOGD("dq : %d TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, + core->ftb_count, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); g_mutex_unlock(&core->ports[1]->mutex); -- 2.7.4 From 774a6adb640c5498dabbc77f86942d19e774eea6 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 22 Jun 2016 17:41:21 +0900 Subject: [PATCH 08/16] fix svace issue Change-Id: Idbe126b029ee94cf5477cf9f15d7a7516a054d0d --- 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 2608cb2..24980cc 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2044,7 +2044,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp g_atomic_int_inc(&core->ftb_count); LOGD("dq : %d TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, - core->ftb_count, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); + core->ftb_count, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); g_mutex_unlock(&core->ports[1]->mutex); -- 2.7.4 From 40a406e0bb3d8886cf383429b8c3fcfdf8bf9226 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 18 Aug 2016 11:11:18 +0900 Subject: [PATCH 09/16] Modify setting codec data when decoding aac Change-Id: I9ced203947d65837bf475ee0e8028f1cb0ad9586 --- include/media_codec_port_gst.h | 3 + packaging/capi-media-codec.spec | 2 +- src/media_codec_port.c | 8 +- src/media_codec_port_gst.c | 174 +++++++++++++++++----------------------- test/media_codec_test.c | 2 +- 5 files changed, 82 insertions(+), 107 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 552162d..d4bbd89 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -53,6 +53,8 @@ extern "C" { #define AAC_CODECDATA_SIZE 16 #define WMA_CODECDATA_SIZE 64 #define VORBIS_CODECDATA_SIZE 4096 +#define MAXINUM_QNUM 15 +#define THRESHOLD_QNUM 5 /* gst port layer */ typedef struct _mc_gst_port_t mc_gst_port_t; @@ -110,6 +112,7 @@ struct _mc_gst_core_t { GMutex eos_wait_mutex; GMutex prepare_lock; GMutex drain_lock; + GCond buffer_cond; GCond eos_cond; GCond eos_waiting_cond; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 313794b..b4a17e3 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -1,6 +1,6 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.4.2 +Version: 0.4.3 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port.c b/src/media_codec_port.c index edb2d20..4508f33 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -176,7 +176,7 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height) return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder, - MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER"); + MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); mc_handle->info.decoder.width = width; mc_handle->info.decoder.height = height; @@ -200,7 +200,7 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder, - MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER"); + MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); mc_handle->info.encoder.width = width; mc_handle->info.encoder.height = height; @@ -225,7 +225,7 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder, - MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER"); + MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); mc_handle->info.decoder.samplerate = samplerate; mc_handle->info.decoder.channel = channel; @@ -249,7 +249,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder, - MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER"); + MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); mc_handle->info.encoder.samplerate = samplerate; mc_handle->info.encoder.channel = channel; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 24980cc..d2bad4b 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -68,7 +68,6 @@ static gint __gst_handle_resource_error(mc_gst_core_t *core, int code); static gint __gst_handle_library_error(mc_gst_core_t *core, int code); static gint __gst_handle_core_error(mc_gst_core_t *core, int code); static const gchar * _mc_error_to_string(mc_ret_e err); -static int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt); /* will remove */ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw); #ifdef TIZEN_PROFILE_LITE @@ -78,14 +77,15 @@ static int _mc_gst_flush_buffers(mc_gst_core_t *core); static void _mc_gst_set_flush_input(mc_gst_core_t *core); static void _mc_gst_set_flush_output(mc_gst_core_t *core); +#ifdef TIZEN_EXYNOS_SPECIFIC static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos); static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height, int left, int top, int right, int buttom); +#endif static void _mc_send_eos_signal(mc_gst_core_t *core); static void _mc_wait_for_eos(mc_gst_core_t *core); - static int _mediacodec_get_mime(mc_gst_core_t *core); /* video vtable */ @@ -291,9 +291,8 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h buf_size = stride_width * stride_height; memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size); - LOGD("width is same with stride"); - LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); mc_buffer->buf_size += buf_size; + LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size); } } else { @@ -326,7 +325,6 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h MMVideoBuffer *mm_video_buffer = NULL; mm_video_buffer = __mc_gst_make_tbm_buffer(core, pkt); - /* mm_video_buffer = core->mc_get_mm_video_buffer(pkt); */ gst_buffer_prepend_memory(mc_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_video_buffer, sizeof(MMVideoBuffer), 0, @@ -367,10 +365,9 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - if (!core->is_hw) { - - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; + mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; + if (!core->is_hw) { width = dec_info->width; height = dec_info->height; stride_width = ALIGN(width, 4); @@ -414,94 +411,51 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in tbm_bo_unmap(bo[0]); tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1); - - if (tsurf) { - media_packet_create_from_tbm_surface(core->output_fmt, tsurf, - (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt); - } - } else { - __mc_fill_video_packet_with_mm_video_buffer(core, data, size, pkt); - /* tsurf = core->get_tbm_surface(data); */ - } -/* - if (tsurf) { - media_packet_create_from_tbm_surface(core->output_fmt, tsurf, - (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt); - } -*/ - return MC_ERROR_NONE; -} + int bo_num = 0; + MMVideoBuffer *mm_vbuffer = NULL; + mm_vbuffer = (MMVideoBuffer *)data; -int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt) -{ - void *pkt_data = NULL; - MMVideoBuffer *mm_vbuffer = NULL; - int i; - int bo_num = 0; - - g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - - mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info; - mm_vbuffer = (MMVideoBuffer *)data; - - LOGD("buf_share_method %d", mm_vbuffer->type); - - LOGD("a[0] : %p, a[1] : %p, p[0] : %p, p[1] : %p", - mm_vbuffer->data[0], mm_vbuffer->data[1], mm_vbuffer->handle.paddr[0], mm_vbuffer->handle.paddr[1]); - LOGD("s[0]:%d, e[0]:%d, w[0]:%d, h[0]:%d", - mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], mm_vbuffer->width[0], mm_vbuffer->height[0]); - - if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) { - media_packet_set_buffer_size(*out_pkt, mm_vbuffer->width[0]*mm_vbuffer->height[0]*3/2); - media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data); - - __csc_tiled_to_linear_crop(pkt_data, mm_vbuffer->data[0], - mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], 0, 0, 0, 0); - __csc_tiled_to_linear_crop(pkt_data+mm_vbuffer->stride_width[0]*mm_vbuffer->stride_height[0], - mm_vbuffer->data[1], mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0]/2, 0, 0, 0, 0); - } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_DMABUF_FD) { - LOGD("FD type"); - } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { - tbm_surface_h tsurf = NULL; - tbm_surface_info_s tsurf_info; - memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); + if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { + tbm_surface_info_s tsurf_info; + memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); - /* create tbm surface */ - for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { - if (mm_vbuffer->handle.bo[i]) { - bo_num++; - tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; + /* create tbm surface */ + for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { + if (mm_vbuffer->handle.bo[i]) { + bo_num++; + tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; + } } - } - - if (bo_num > 0) { - tsurf_info.width = codec_info->width; - tsurf_info.height = codec_info->height; - tsurf_info.format = TBM_FORMAT_NV12; /* bo_format */ - tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12); - tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12); - tsurf_info.size = 0; - - for (i = 0; i < tsurf_info.num_planes; i++) { - tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; - tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i]; - - if (i < bo_num) - tsurf_info.planes[i].offset = 0; - else - tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size; - tsurf_info.size += tsurf_info.planes[i].size; - LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size); + if (bo_num > 0) { + tsurf_info.width = dec_info->width; + tsurf_info.height = dec_info->height; + tsurf_info.format = TBM_FORMAT_NV12; /* bo_format */ + tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12); + tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12); + tsurf_info.size = 0; + + for (i = 0; i < tsurf_info.num_planes; i++) { + tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; + tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i]; + + if (i < bo_num) + tsurf_info.planes[i].offset = 0; + else + tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size; + + tsurf_info.size += tsurf_info.planes[i].size; + LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size); + } + tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num); } - tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num); } + } - if (tsurf) { - media_packet_create_from_tbm_surface(core->output_fmt, tsurf, - (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, out_pkt); - } + if (tsurf) { + media_packet_create_from_tbm_surface(core->output_fmt, tsurf, + (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt); } return MC_ERROR_NONE; @@ -513,6 +467,9 @@ int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int siz int ret = MC_ERROR_NONE; g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); + if (core->encoder && core->codec_id == MEDIACODEC_AAC) + media_format_set_audio_aac_type(core->output_fmt, FALSE); + ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); @@ -770,6 +727,8 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *buff, guint codecd void *buf_data = NULL; uint64_t buf_size = 0; GstBuffer *codecdata_buffer; + guint8 *data; + GstMapInfo map; ret = media_packet_get_buffer_size(buff->pkt, &buf_size); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -786,9 +745,11 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *buff, guint codecd LOGD("Set caps for codec_data in mime : %s and codec_id (0x%x)", core->mime, core->codec_id); /* Add the codec_data attribute to caps, if we have it */ - codecdata_buffer = gst_buffer_new_and_alloc(codecdata_size); - gst_buffer_copy_into(codecdata_buffer, buff->buffer, GST_BUFFER_COPY_MEMORY, 0, codecdata_size); - gst_buffer_ref(codecdata_buffer); + data = g_malloc0(codecdata_size); + gst_buffer_map(buff->buffer, &map, GST_MAP_READ); + memcpy(data, map.data, codecdata_size); + codecdata_buffer = gst_buffer_new_wrapped(data, codecdata_size); + gst_buffer_unmap(buff->buffer, &map); LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size); gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL); @@ -871,6 +832,7 @@ mc_gst_core_t *mc_gst_core_new() g_mutex_init(&core->eos_mutex); g_cond_init(&core->eos_cond); + g_cond_init(&core->buffer_cond); g_mutex_init(&core->prepare_lock); g_mutex_init(&core->drain_lock); @@ -912,6 +874,7 @@ void mc_gst_core_free(mc_gst_core_t *core) g_mutex_clear(&core->prepare_lock); g_mutex_clear(&core->drain_lock); g_cond_clear(&core->eos_cond); + g_cond_clear(&core->buffer_cond); mc_async_queue_free(async_queue->input); g_free(async_queue); @@ -944,7 +907,6 @@ mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core) port->buffers = NULL; g_mutex_init(&port->mutex); - g_cond_init(&port->buffer_cond); port->queue = g_queue_new(); LOGD("gst_port(%p) is created", port); @@ -958,7 +920,6 @@ void mc_gst_port_free(mc_gst_port_t *port) MEDIACODEC_FENTER(); g_mutex_clear(&port->mutex); - g_cond_clear(&port->buffer_cond); g_queue_free(port->queue); LOGD("gst_port(%p) is freed", port); @@ -1177,7 +1138,7 @@ static gpointer feed_task(gpointer data) } pad = gst_element_get_static_pad(core->appsrc, "src"); - gst_pad_push_event(pad, gst_event_new_stream_start("sejun")); + gst_pad_push_event(pad, gst_event_new_stream_start("start")); gst_object_unref(pad); LOGD("caps updated"); @@ -1446,6 +1407,9 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo if (encoder) { core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable; core->caps = gst_caps_new_empty_simple("video/x-raw"); +#ifdef TIZEN_PROFILE_LITE + g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); +#endif } else { if (is_hw) { core->vtable = vdec_h264_hw_vtable; @@ -1647,19 +1611,25 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint int ret = MC_ERROR_NONE; mc_gst_core_t *core = NULL; - GTimeVal nowtv; + gint64 end_time; if (!mc_handle) return MC_PARAM_ERROR; core = (mc_gst_core_t *)mc_handle->core; - g_get_current_time(&nowtv); - g_time_val_add(&nowtv, 500 * 1000); /* usec */ - /* - if (!g_cond_timed_wait(&nowtv)) { - } - */ + g_mutex_lock(&core->drain_lock); + + while (g_atomic_int_get(&core->etb_count) > MAXINUM_QNUM) { + end_time = g_get_monotonic_time() + timeOutUs * G_TIME_SPAN_MILLISECOND; + LOGD("Waiting until packets are drained.."); + + if (!g_cond_wait_until(&core->buffer_cond, &core->drain_lock, end_time)) { + LOGD("time out..."); + break; + } + } + g_mutex_unlock(&core->drain_lock); if (core->prepare_count == 0) return MC_INVALID_STATUS; @@ -2695,6 +2665,7 @@ int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr, } #endif +#if TIZEN_EXYNOS_SPECIFIC /* * Get tiled address of position(x,y) * @@ -2947,6 +2918,7 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char } } } +#endif void _mc_send_eos_signal(mc_gst_core_t *core) { diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 698a24d..37bb551 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -979,7 +979,7 @@ static void _mediacodec_process_input(App *app) } mc_hex_dump("inbuf", tmp, 48); - ret = mediacodec_process_input(app->mc_handle[0], pkt, -1); + ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000); if (ret != MEDIACODEC_ERROR_NONE) return; -- 2.7.4 From d9445c9a05caa3fa67493b4147e739d34dd9a749 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 23 Aug 2016 13:54:18 +0900 Subject: [PATCH 10/16] Added test suite for camera preview Change-Id: Ic60e48e994bf7b1f79c14934572319eb7007d093 --- packaging/capi-media-codec.spec | 1 + test/CMakeLists.txt | 2 +- test/media_codec_test.c | 115 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 3 deletions(-) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index b4a17e3..94a969c 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -12,6 +12,7 @@ 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) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d6a1257..d3e0022 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) +pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera) 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 37bb551..2da9c6f 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -135,6 +136,7 @@ struct _App { bool enable_dump; int frame; type_e type; + camera_h camera_handle; /* video */ mediacodec_h mc_handle[MAX_HANDLE]; guint width; @@ -844,7 +846,7 @@ int _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware) break; case MEDIACODEC_H263: if (encoder) { - extractor = h263_extractor; + extractor = yuv_extractor; mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; } else { extractor = h263_extractor; @@ -1261,6 +1263,108 @@ static void _mediacodec_prepare(App *app, bool frame_all) return; } +static 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) +{ + /* release input encoded packet */ + media_packet_destroy(pkt); +} + +static void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data) +{ + App *app = (App*)user_data; + + mediacodec_h media_codec_handle = app->mc_handle[1]; + media_packet_h output_buf = NULL; + mediacodec_get_output(media_codec_handle, &output_buf, 0); + /* decode encoded camera preview */ + 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) +{ + App *app = (App*)user_data; + + mediacodec_h media_codec_handle = app->mc_handle[0]; + media_packet_h output_buf = NULL; + + mediacodec_get_output(media_codec_handle, &output_buf, 0); + + if (app->enable_dump) + decoder_output_dump(app, output_buf); + + media_packet_destroy(output_buf); +} + +static void _media_packet_preview_cb(media_packet_h packet, void *user_data) +{ + App *app = user_data; + g_mutex_lock(&app->lock); + mediacodec_process_input(app->mc_handle[1], packet, 0); + g_mutex_unlock(&app->lock); + + return; +} + +static void _mediacodec_camera_start(App *app) +{ + int default_format = CAMERA_PIXEL_FORMAT_NV12; + app->width = 640; + app->height = 480; + app->hardware = TRUE; + + /*create decoder instance and setup */ + mediacodec_create(&app->mc_handle[0]); + mediacodec_set_codec(app->mc_handle[0], MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW); + mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height); + /* set callback */ + mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_dec_input_buffer_used_cb, NULL); + mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_dec_output_buffer_available_cb, app); + mediacodec_prepare(app->mc_handle[0]); + + /*create encoder instance and setup */ + mediacodec_create(&app->mc_handle[1]); + mediacodec_set_codec(app->mc_handle[1], MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW); + mediacodec_set_venc_info(app->mc_handle[1], app->width, app->height, 30, 1000); + /* set callback */ + mediacodec_set_input_buffer_used_cb(app->mc_handle[1], _mediacodec_enc_input_buffer_used_cb, NULL); + mediacodec_set_output_buffer_available_cb(app->mc_handle[1], _mediacodec_enc_output_buffer_available_cb, app); + mediacodec_prepare(app->mc_handle[1]); + + /* create camera instance and setup and then start preview */ + camera_create(CAMERA_DEVICE_CAMERA0, &app->camera_handle); + camera_set_media_packet_preview_cb(app->camera_handle, _media_packet_preview_cb, app); + camera_get_preview_format(app->camera_handle, &default_format); + camera_set_preview_format(app->camera_handle, default_format); + camera_set_preview_resolution(app->camera_handle, app->width, app->height); + camera_set_display(app->camera_handle, CAMERA_DISPLAY_TYPE_NONE, NULL); + camera_start_preview(app->camera_handle); + + return; +} + + +static void _mediacodec_camera_stop(App *app) +{ + camera_state_e camera_state = CAMERA_STATE_NONE; + + camera_get_state(app->camera_handle, &camera_state); + camera_stop_preview(app->camera_handle); + camera_destroy(app->camera_handle); + + mediacodec_unprepare(app->mc_handle[0]); + mediacodec_unprepare(app->mc_handle[1]); + mediacodec_destroy(app->mc_handle[0]); + mediacodec_destroy(app->mc_handle[1]); + return; +} + static void _mediacodec_unprepare(App *app) { mediacodec_unprepare(app->mc_handle[0]); @@ -1355,6 +1459,10 @@ void _interpret_main_menu(char *cmd, App *app) _mediacodec_unprepare(app); else if (strncmp(cmd, "dt", 2) == 0) _mediacodec_destroy(app); + 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, "dp", 2) == 0) { if (!app->enable_dump) { app->enable_dump = TRUE; @@ -1613,8 +1721,11 @@ static void display_sub_basic() g_print("rb. Reset output buffer \n"); g_print("un. Unprepare \t\t"); g_print("dt. Destroy \t\t"); - g_print("q. quite test suite \n"); + g_print("q. quit test suite \n"); g_print("dp. enable dump \n"); + g_print("-----------------------------------------------------------------------------------------\n"); + g_print("cr. camera preview -> encoder -> decoder\n"); + g_print("ct. quit camera test\n"); g_print("\n"); g_print("=========================================================================================\n"); } -- 2.7.4 From 6835c2b4e62b2fbfd6e580104b67d1c0350a4cbc Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 23 Aug 2016 17:59:41 +0900 Subject: [PATCH 11/16] Fixed align issue when using s/w codec Change-Id: I051be3f7f783bef6d1ade8fb1fa865228fe1bd64 --- src/media_codec_port_gst.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index d2bad4b..5e38462 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -33,7 +33,6 @@ #include #endif -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) /* * Internal Implementation */ @@ -370,13 +369,10 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in if (!core->is_hw) { width = dec_info->width; height = dec_info->height; - stride_width = ALIGN(width, 4); - stride_height = ALIGN(height, 4); + stride_width = GST_ROUND_UP_4(width); + stride_height = GST_ROUND_UP_2(height); buf_size = stride_width * stride_height * 3 / 2; - if (buf_size > size) - return MC_ERROR; - memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC); @@ -399,8 +395,8 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in tsurf_info.planes[i].offset = 0; tsurf_info.size = tsurf_info.planes[i].size; } else { - tsurf_info.planes[i].stride = stride_width>>1; - tsurf_info.planes[i].size = (stride_width>>1) * (stride_height>>1); + tsurf_info.planes[i].stride = GST_ROUND_UP_4(GST_ROUND_UP_2(width)/2); + tsurf_info.planes[i].size = GST_ROUND_UP_4(GST_ROUND_UP_2(width)/2) * (GST_ROUND_UP_2(height)/2); tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size); tsurf_info.size += tsurf_info.planes[i].size; } @@ -2022,6 +2018,9 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) (out_pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]); } + } else { + gst_buffer_unref(buffer); + LOGE("Failed to dequeue output packet"); } MEDIACODEC_FLEAVE(); -- 2.7.4 From 5c02c9fd8884297589a05ecb4515851b5a9082cd Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 19 Sep 2016 18:33:04 +0900 Subject: [PATCH 12/16] fix issue when bitrate is not set with media packet Change-Id: I7ed942a8ee3d5ea9eab1c72c13e247ba2553e980 --- include/media_codec_port_gst.h | 1 + src/media_codec_port_gst.c | 43 ++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index d4bbd89..ffcff60 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -113,6 +113,7 @@ struct _mc_gst_core_t { GMutex prepare_lock; GMutex drain_lock; GCond buffer_cond; + GCond out_buffer_cond; GCond eos_cond; GCond eos_waiting_cond; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 5e38462..22359a4 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -829,6 +829,7 @@ mc_gst_core_t *mc_gst_core_new() g_mutex_init(&core->eos_mutex); g_cond_init(&core->eos_cond); g_cond_init(&core->buffer_cond); + g_cond_init(&core->out_buffer_cond); g_mutex_init(&core->prepare_lock); g_mutex_init(&core->drain_lock); @@ -871,6 +872,7 @@ void mc_gst_core_free(mc_gst_core_t *core) g_mutex_clear(&core->drain_lock); g_cond_clear(&core->eos_cond); g_cond_clear(&core->buffer_cond); + g_cond_clear(&core->out_buffer_cond); mc_async_queue_free(async_queue->input); g_free(async_queue); @@ -949,9 +951,9 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) if (core->encoder) { mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - if (enc_info->bitrate != bitrate) { + if (bitrate != 0 && enc_info->bitrate != bitrate * 1000) { LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); - enc_info->bitrate = bitrate; + enc_info->bitrate = bitrate * 1000; is_updated = TRUE; } } @@ -974,9 +976,9 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) if (core->encoder) { mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - if (enc_info->bitrate != bitrate) { + if (bitrate != 0 && enc_info->bitrate != bitrate * 1000) { LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); - enc_info->bitrate = bitrate; + enc_info->bitrate = bitrate * 1000; is_updated = TRUE; } } @@ -1617,7 +1619,7 @@ 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 * G_TIME_SPAN_MILLISECOND; + end_time = g_get_monotonic_time() + timeOutUs; LOGD("Waiting until packets are drained.."); if (!g_cond_wait_until(&core->buffer_cond, &core->drain_lock, end_time)) { @@ -1657,24 +1659,34 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6 int ret = MC_ERROR_NONE; mc_gst_core_t *core = NULL; media_packet_h out_pkt = NULL; + gint64 end_time = -1; + gboolean signalled; + + end_time = g_get_monotonic_time() + timeOutUs; if (!mc_handle) return MC_PARAM_ERROR; core = (mc_gst_core_t *)mc_handle->core; - LOGI("@%p v(%d)e(%d) get_output", core, core->video, core->encoder); g_mutex_lock(&core->ports[1]->mutex); - if (!g_queue_is_empty(core->ports[1]->queue)) { + if (!g_queue_is_empty(core->ports[1]->queue)) + signalled = TRUE; + else { + LOGD("no buffer, wait for signal"); + signalled = g_cond_wait_until(&core->out_buffer_cond, &core->ports[1]->mutex, end_time); + } + + if (signalled) out_pkt = g_queue_pop_head(core->ports[1]->queue); - LOGD("pop from output_queue : %p", out_pkt); - } else { + else { + LOGW("Failed to get buffer"); ret = MC_OUTPUT_BUFFER_EMPTY; - LOGD("output_queue is empty"); } *outbuf = out_pkt; + LOGI("@%p v(%d)e(%d) got buffer :%p", core, core->video, core->encoder, out_pkt); g_mutex_unlock(&core->ports[1]->mutex); @@ -2007,6 +2019,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp /* push it to output buffer queue */ g_queue_push_tail(core->ports[1]->queue, out_pkt); + g_cond_broadcast(&core->out_buffer_cond); g_atomic_int_inc(&core->ftb_count); LOGD("dq : %d TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, @@ -2036,11 +2049,21 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * GstMemory *mem; GstMapInfo map = GST_MAP_INFO_INIT; MMVideoBuffer *mm_video_buf = NULL; + GList *find; MEDIACODEC_FENTER(); mc_gst_core_t *core = (mc_gst_core_t *)user_data; + 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); + g_atomic_int_dec_and_test(&core->ftb_count); media_packet_get_extra(packet, &buffer); -- 2.7.4 From e7d8a5c7ace73c940623293bdbeab2ee1557703b Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 29 Sep 2016 19:04:20 +0900 Subject: [PATCH 13/16] modify align for I420 format Change-Id: I8f8c9d69bb211790e5b6cb09c89284212a0d8332 --- src/media_codec_port_gst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 22359a4..d97c686 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -370,7 +370,7 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in width = dec_info->width; height = dec_info->height; stride_width = GST_ROUND_UP_4(width); - stride_height = GST_ROUND_UP_2(height); + stride_height = height; buf_size = stride_width * stride_height * 3 / 2; memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); @@ -395,8 +395,8 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in tsurf_info.planes[i].offset = 0; tsurf_info.size = tsurf_info.planes[i].size; } else { - tsurf_info.planes[i].stride = GST_ROUND_UP_4(GST_ROUND_UP_2(width)/2); - tsurf_info.planes[i].size = GST_ROUND_UP_4(GST_ROUND_UP_2(width)/2) * (GST_ROUND_UP_2(height)/2); + tsurf_info.planes[i].stride = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2); + tsurf_info.planes[i].size = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2) * (height / 2); tsurf_info.planes[i].offset = (tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size); tsurf_info.size += tsurf_info.planes[i].size; } -- 2.7.4 From c315770f57585c18054d5ee78b7cf0643346957f Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 5 Oct 2016 15:23:48 +0900 Subject: [PATCH 14/16] fixed not to retrieve supporting codec type Change-Id: Ifdf164336a2c6156fea2c9a147e6a9045c186a45 --- src/media_codec_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 4508f33..76e49cc 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -428,6 +428,7 @@ int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec LOGE("fail invaild param\n"); return MC_INVALID_ARG; } + codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map; num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder; @@ -437,7 +438,6 @@ int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec *support_type |= MEDIACODEC_SUPPORT_TYPE_HW; else *support_type |= MEDIACODEC_SUPPORT_TYPE_SW; - break; } } -- 2.7.4 From c8b396024865b0d7be734e0f7339508c2524fa3c Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 14 Oct 2016 17:48:44 +0900 Subject: [PATCH 15/16] modify to fill yuv data in test suite Change-Id: I5c9339c89f029e66639d79019303a69334bfd94a --- include/media_codec_port_gst.h | 2 +- src/media_codec_port_gst.c | 25 +++++++-- test/media_codec_test.c | 115 +++++++++++++++++++++++++++++------------ 3 files changed, 106 insertions(+), 36 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index ffcff60..3da69a8 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -49,7 +49,7 @@ extern "C" { #define SCMN_IMGB_MAX_PLANE 4 #define TBM_API_CHANGE -#define DEFAULT_POOL_SIZE 20 +#define DEFAULT_POOL_SIZE 13 #define AAC_CODECDATA_SIZE 16 #define WMA_CODECDATA_SIZE 64 #define VORBIS_CODECDATA_SIZE 4096 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index d97c686..1590169 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2308,6 +2308,7 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet int num_bos; tbm_surface_h surface = NULL; tbm_surface_info_s surface_info; + tbm_bo_handle handle_bo; if (!pkt) { LOGE("output is null"); @@ -2357,6 +2358,24 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet mm_vbuffer->stride_height[0] = surface_info.planes[0].size / surface_info.planes[0].stride; mm_vbuffer->stride_width[1] = surface_info.planes[1].stride; mm_vbuffer->stride_height[1] = surface_info.planes[1].size / surface_info.planes[1].stride; + + if (mm_vbuffer->handle.bo[0]) { + handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_CPU); + mm_vbuffer->data[0]= handle_bo.ptr; + + handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); + mm_vbuffer->handle.dmabuf_fd[0]= handle_bo.u32; + } + + if (mm_vbuffer->handle.bo[1]) { + handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[1], TBM_DEVICE_CPU); + mm_vbuffer->data[1]= handle_bo.ptr; + + handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[1], TBM_DEVICE_MM); + mm_vbuffer->handle.dmabuf_fd[1]= handle_bo.u32; + } else { + mm_vbuffer->data[1] = mm_vbuffer->data[0] + mm_vbuffer->stride_width[0] * mm_vbuffer->stride_height[0]; + } mm_vbuffer->plane_num = 2; LOGD("size[0] : %d, size[1] : %d, bo[0] :%p, bo[1] :%p", mm_vbuffer->size[0], mm_vbuffer->size[1], mm_vbuffer->handle.bo[0], mm_vbuffer->handle.bo[1]); @@ -3150,14 +3169,14 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt return MC_ERROR; } - media_packet_pool_get_size(pool, &min_size, &max_size, &curr_size); - LOGD("curr_size is %d min_size is %d and max_size is %d \n", curr_size, min_size, max_size); - ret = media_packet_pool_allocate(pool); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_pool_allocate failed"); return MC_OUT_OF_MEMORY; } + media_packet_pool_get_size(pool, &min_size, &max_size, &curr_size); + LOGD("curr_size is %d min_size is %d and max_size is %d \n", curr_size, min_size, max_size); + *pkt_pool = pool; return MC_ERROR_NONE; } diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 2da9c6f..949f4ef 100755 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -55,6 +55,7 @@ ((state & (expected_state)) == (expected_state)) #define AAC_CODECDATA_SIZE 16 +#define USE_POOL 1 unsigned char buf_adts[ADTS_HEADER_SIZE]; @@ -926,8 +927,9 @@ static void _mediacodec_process_input(App *app) media_packet_h pkt = NULL; unsigned char *tmp; int read; + int size; int offset; - int stride_width, stride_height; + int stride_width; for (i = 0; i < app->frame; i++) { g_print("----------read data------------\n"); @@ -935,10 +937,17 @@ static void _mediacodec_process_input(App *app) extractor(app, &tmp, &read, &have_frame); if (have_frame) { - if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) { - fprintf(stderr, "media_packet_create_alloc failed\n"); - return; - } +#ifdef USE_POOL + if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) { + fprintf(stderr, "media_packet_pool_aquire_packet failed\n"); + return; + } +#else + if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) { + fprintf(stderr, "media_packet_create_alloc failed\n"); + return; + } +#endif if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) { fprintf(stderr, "media_packet_set_pts failed\n"); @@ -955,28 +964,47 @@ static void _mediacodec_process_input(App *app) /* Y */ media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); - media_packet_get_video_stride_height(pkt, 0, &stride_height); + offset = app->width*app->height; + + for (i = 0; i < app->height; i++) { + memcpy(buf_data_ptr, tmp, app->width); + buf_data_ptr += stride_width; + tmp += app->width; + } - offset = stride_width*stride_height; + if (app->hardware == TRUE) { + media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 1, &stride_width); + size = app->width * app->height / 2; - memcpy(buf_data_ptr, tmp, offset); + for (i = 0; i< app->height / 2; i++) { + memcpy(buf_data_ptr, tmp, app->width); + buf_data_ptr += stride_width; + tmp += app->width; + } + } else { + /* U */ + media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 1, &stride_width); + size = (app->width>>1) * (app->height>>1); - /* UV or U*/ - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); - media_packet_get_video_stride_width(pkt, 1, &stride_width); - media_packet_get_video_stride_height(pkt, 1, &stride_height); - memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); + for (i = 0; i < app->height/2; i++) { + memcpy(buf_data_ptr, tmp, app->width/2); + buf_data_ptr += stride_width; + tmp += app->width/2; + } - if (app->hardware == FALSE) { /* V */ media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); - media_packet_get_video_stride_height(pkt, 2, &stride_height); + offset += size; - offset += stride_width * stride_height; + for (i = 0; i < app->height/2; i++) { + memcpy(buf_data_ptr, tmp, app->width/2); + buf_data_ptr += stride_width; + tmp += app->width/2; + } - - memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); } } mc_hex_dump("inbuf", tmp, 48); @@ -999,9 +1027,11 @@ static gboolean read_data(App *app) void *buf_data_ptr = NULL; media_packet_h pkt = NULL; unsigned char *tmp; + int i; int read; + int size; int offset; - int stride_width, stride_height; + int stride_width; if (app->offset == 0) { app->frame_count = 0; @@ -1043,6 +1073,7 @@ static gboolean read_data(App *app) return FALSE; } + if (app->type != VIDEO_ENC) { media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr); media_packet_set_buffer_size(pkt, (uint64_t)read); @@ -1053,28 +1084,48 @@ static gboolean read_data(App *app) /* Y */ media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); - media_packet_get_video_stride_height(pkt, 0, &stride_height); + offset = app->width*app->height; + + for (i = 0; i < app->height; i++) { + memcpy(buf_data_ptr, tmp, app->width); + buf_data_ptr += stride_width; + tmp += app->width; + } + + if (app->hardware == TRUE) { + media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 1, &stride_width); + size = app->width * app->height>>1; - offset = stride_width*stride_height; + for (i = 0; i < app->height>>1; i++) { + memcpy(buf_data_ptr, tmp, app->width); + buf_data_ptr += stride_width; + tmp += app->width; + } - memcpy(buf_data_ptr, tmp, offset); + } else { + /* U */ + media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); + media_packet_get_video_stride_width(pkt, 1, &stride_width); + size = (app->width>>1) * (app->height>>1); - /* UV or U*/ - media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr); - media_packet_get_video_stride_width(pkt, 1, &stride_width); - media_packet_get_video_stride_height(pkt, 1, &stride_height); - memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); + for (i = 0; i < app->height/2; i++) { + memcpy(buf_data_ptr, tmp, app->width>>1); + buf_data_ptr += stride_width; + tmp += (app->width>>1); + } - if (app->hardware == FALSE) { /* V */ media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); - media_packet_get_video_stride_height(pkt, 2, &stride_height); - - offset += stride_width * stride_height; + offset += size; + for (i = 0; i < app->height/2; i++) { + memcpy(buf_data_ptr, tmp, app->width>>1); + buf_data_ptr += stride_width; + tmp += (app->width>>1); + } - memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height); } } mc_hex_dump("inbuf", tmp, 48); -- 2.7.4 From 0405e0f52514a2db61cdaffad50a88393356cc49 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 20 Oct 2016 14:38:45 +0900 Subject: [PATCH 16/16] Modify packet pool size Change-Id: Ie9b4e37040e836cacb137aac9c39203920c9796e --- include/media_codec_port_gst.h | 3 ++- src/media_codec_port_gst.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 3da69a8..56e28f2 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -49,7 +49,8 @@ extern "C" { #define SCMN_IMGB_MAX_PLANE 4 #define TBM_API_CHANGE -#define DEFAULT_POOL_SIZE 13 +#define DEFAULT_DEC_POOL_SIZE 20 +#define DEFAULT_ENC_POOL_SIZE 13 #define AAC_CODECDATA_SIZE 16 #define WMA_CODECDATA_SIZE 64 #define VORBIS_CODECDATA_SIZE 4096 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 1590169..3f181e3 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -3160,7 +3160,7 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt } /* will use default size temporarily */ - max_size = DEFAULT_POOL_SIZE; + max_size = core->encoder ? DEFAULT_ENC_POOL_SIZE : DEFAULT_DEC_POOL_SIZE; min_size = max_size; ret = media_packet_pool_set_size(pool, min_size, max_size); -- 2.7.4