From: Sejun Park Date: Tue, 2 May 2017 08:27:02 +0000 (+0900) Subject: Sync with tizen_3.0 and add to control buffer overflow X-Git-Tag: submit/tizen_3.0/20170713.103716~1^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F02%2F127902%2F4;p=platform%2Fcore%2Fapi%2Fmediacodec.git Sync with tizen_3.0 and add to control buffer overflow Change-Id: Ia4d1007a9b6bc8e6cdd95cbc244b9bc621ff849b --- diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 92b4eee..98e93c0 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -127,6 +127,7 @@ struct _mc_gst_core_t { bool eos; bool eos_waiting; bool codec_config; + bool need_drain; bool need_feed; bool need_codec_data; bool need_sync_flag; @@ -165,6 +166,7 @@ int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h packet, GstMCBuff int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); +int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer); int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_packet); diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 759117c..ae66a6e 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -57,7 +57,7 @@ static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer dat static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data); static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet); static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_h packet, uint64_t size); -static void gst_mediacodec_buffer_finalize(GstMCBuffer *buffer); +static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer); static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size); static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint codecdata_size); static void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet); @@ -134,10 +134,10 @@ int(*adec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_ int(*aenc_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Encoder vtable */ &__mc_fill_packet_with_output_buffer}; -int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC LC Decoder Vtable */ +int(*adec_aac_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet, /* AAC LC Decoder Vtable */ &__mc_fill_packet_with_output_buffer}; -int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* AAC HE Decoder Vtable */ +int(*adec_aacv12_vtable[])() = {&__mc_fill_input_buffer_with_adec_packet, /* AAC HE Decoder Vtable */ &__mc_fill_packet_with_output_buffer}; int(*adec_mp3_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* MP3 Decoder Vtable */ @@ -202,7 +202,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pac if (buf_data != NULL) { gst_buffer_prepend_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, - buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); LOGD("packet data apended, %d, %d", buf_size, gst_buffer_n_memory(mcbuffer->buffer)); } return ret; @@ -229,13 +229,58 @@ int __mc_fill_input_buffer_with_packet(mc_gst_core_t *core, media_packet_h packe if (buf_data != NULL) { gst_buffer_append_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, - buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); LOGD("packet data apended"); } return ret; } +int __mc_fill_input_buffer_with_adec_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) +{ + int ret = MC_ERROR_NONE; + void *buf_data = NULL; + uint64_t buf_size = 0; + bool codec_config = FALSE; + void *codec_data = NULL; + unsigned int codec_size = 0; + + ret = media_packet_get_buffer_size(packet, &buf_size); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("buffer size get failed"); + return MC_ERROR; + } + + ret = media_packet_get_buffer_data_ptr(packet, &buf_data); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("buffer data get failed"); + return MC_ERROR; + } + + if (media_packet_is_codec_config(packet, &codec_config) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_is_codec_config failed"); + return MC_ERROR; + } + + if (buf_data != NULL) { + media_packet_get_codec_data(packet, &codec_data, &codec_size); + + if (!codec_data && codec_config) { + gst_buffer_append_memory(mcbuffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, + buf_size, NULL, NULL)); + LOGD("csd packet data apended"); + } else { + gst_buffer_append_memory(mcbuffer->buffer, + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, + buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); + LOGD("packet data apended"); + } + } + + return ret; +} + int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h packet, GstMCBuffer *mcbuffer) { int ret = MC_ERROR_NONE; @@ -335,7 +380,7 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h gst_buffer_prepend_memory(mcbuffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mcbuffer->buf_size, 0, - mcbuffer->buf_size, mcbuffer, (GDestroyNotify)gst_mediacodec_buffer_finalize)); + mcbuffer->buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); return ret; } @@ -750,15 +795,15 @@ int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint fi gst_buffer_map(mcbuffer->buffer, &map, GST_MAP_READ); memcpy(data, map.data, fixed_size); codecdata_buffer = gst_buffer_new_wrapped(data, fixed_size); - gst_buffer_unmap(mcbuffer->buffer, &map); gst_caps_set_simple(core->caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL); gst_buffer_unref(codecdata_buffer); gst_buffer_replace_memory(mcbuffer->buffer, 0, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buff_data + fixed_size , buffer_size - fixed_size, 0, - buffer_size - fixed_size, mcbuffer, NULL)); + gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, map.data + fixed_size , buffer_size - fixed_size, 0, + buffer_size - fixed_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); - LOGD("set codec data from packet: %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer)); + LOGD("after : set codec data from packet: %" G_GSIZE_FORMAT "", gst_buffer_get_size(mcbuffer->buffer)); + gst_buffer_unmap(mcbuffer->buffer, &map); } } return ret; @@ -833,6 +878,7 @@ mc_gst_core_t *mc_gst_core_new() g_mutex_init(&core->prepare_lock); g_mutex_init(&core->drain_lock); + core->need_drain = false; core->need_feed = false; core->eos = false; core->need_codec_data = false; @@ -1626,7 +1672,6 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint int ret = MC_ERROR_NONE; mc_gst_core_t *core = NULL; - gint64 end_time; if (!mc_handle) return MC_PARAM_ERROR; @@ -1635,14 +1680,10 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint g_mutex_lock(&core->drain_lock); - while (g_atomic_int_get(&core->etb_count) > MAXINUM_QNUM) { - end_time = g_get_monotonic_time() + timeOutUs; + while (g_atomic_int_get(&core->etb_count) == MAXINUM_QNUM) { LOGD("Waiting until packets are drained.."); - - if (!g_cond_wait_until(&core->buffer_cond, &core->drain_lock, end_time)) { - LOGD("time out..."); - break; - } + core->need_drain = true; + g_cond_wait(&core->buffer_cond, &core->drain_lock); } g_mutex_unlock(&core->drain_lock); @@ -2254,17 +2295,23 @@ void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet if (core && core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) { ((mc_empty_buffer_cb)core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) (packet, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]); - } - if (core) - LOGD("@v(%d)e(%d) input port emptied buffer(%d): %p", core->video, core->encoder, core->etb_count, packet); + g_mutex_lock(&core->drain_lock); + + if (core->need_drain) { + LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder); + core->need_drain = false; + g_cond_signal(&core->buffer_cond); + } + g_mutex_unlock(&core->drain_lock); + } } gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { int ret = MC_ERROR_NONE; mc_gst_core_t *core = (mc_gst_core_t *)data; - LOGD("@%p v(%d)e(%d)", core, core->video, core->encoder); + LOGD("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); switch (GST_MESSAGE_TYPE(msg)) { @@ -2310,6 +2357,16 @@ gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) else LOGW("Unexpected error has occured"); + g_mutex_lock(&core->drain_lock); + + if (core->need_drain) { + LOGD("@v(%d)e(%d) input port used----- single process_input.....", core->video, core->encoder); + core->need_drain = false; + g_cond_signal(&core->buffer_cond); + } + + g_mutex_unlock(&core->drain_lock); + if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) { ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]); @@ -2356,7 +2413,7 @@ static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, mc_gst_core_t *core = (mc_gst_core_t *)data; GstBusSyncReply reply = GST_BUS_DROP; - LOGD("__mc_gst_bus_sync_callback is called"); + LOGD("__mc_gst_bus_sync_callback is called : %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); if (!core->pipeline) { LOGE("mediacodec pipeline handle is null"); @@ -2419,6 +2476,8 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet for (i = 0; i < num_bos; i++) { mm_vbuffer->handle.bo[i] = tbm_surface_internal_get_bo(surface, i); LOGD("mm_vbuffer->handle.bo[%d] : %p", i, mm_vbuffer->handle.bo[i]); + tbm_bo_map(mm_vbuffer->handle.bo[i], TBM_DEVICE_CPU, TBM_OPTION_READ); + tbm_bo_unmap(mm_vbuffer->handle.bo[i]); } #ifdef TIZEN_PROFILE_LITE @@ -2472,13 +2531,14 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet return mm_vbuffer; } -static void gst_mediacodec_buffer_finalize(GstMCBuffer *mcbuffer) +static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer) { MEDIACODEC_FENTER(); if (!mcbuffer) return; + LOGD("============>>>>> _finalize_cb : %p, %p", mcbuffer, mcbuffer->packet); mc_gst_core_t *core = (mc_gst_core_t *)mcbuffer->core; _mc_gst_handle_input_buffer_used(core, mcbuffer->packet); @@ -2684,6 +2744,23 @@ static int _mc_gst_flush_buffers(mc_gst_core_t *core) _mc_gst_set_flush_input(core); + LOGW("Trying send flush_start .... "); + event = gst_event_new_flush_start(); + ret = gst_element_send_event(core->appsrc, event); + if (ret != TRUE) { + LOGE("failed to send Flush_Start event"); + return MC_ERROR; + } + + LOGW("Trying send flush_stop .... "); + event = gst_event_new_flush_stop(TRUE); + ret = gst_element_send_event(core->appsrc, event); + if (ret != TRUE) { + LOGE("failed to send Flush_Stop event"); + return MC_ERROR; + } + + LOGW("Trying send seek .... "); event = gst_event_new_seek(1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1); @@ -2706,17 +2783,17 @@ static void _mc_gst_set_flush_input(mc_gst_core_t *core) media_packet_h packet = NULL; MEDIACODEC_FENTER(); - LOGI("_mc_gst_set_flush_input called"); + LOGI("_mc_gst_set_flush_input called : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count); while (!mc_async_queue_is_empty(core->available_queue->input)) { packet = mc_async_queue_pop_forced(core->available_queue->input); - g_atomic_int_dec_and_test(&core->etb_count); LOGD("%p poped(%d)", packet, core->etb_count); _mc_gst_handle_input_buffer_used(core, packet); } mc_async_queue_flush(core->available_queue->input); + LOGI("_mc_gst_set_flush_input ended : input_queue_len = %d, etb_count = %d", core->available_queue->input->length, core->etb_count); MEDIACODEC_FLEAVE(); }