From a13e9fd015b993f5603a6400010628322d965f04 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 5 Jul 2017 15:05:19 +0900 Subject: [PATCH] fixed crash when media packet is destroyed after unpreparing Change-Id: I523aa25e58411d0e0f27a8a2aaf9dd91d4c5a7a1 --- include/media_codec_port_gst.h | 1 - packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 107 ++++++++++++++------------------ 3 files changed, 48 insertions(+), 62 deletions(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index fe5ab65..3cf9120 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -136,7 +136,6 @@ struct _mc_gst_core_t { guint prepare_count; guint num_live_buffers; guint etb_count; - guint ftb_count; mediacodec_codec_type_e codec_id; media_format_mimetype_e out_mime; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index d84b606..17b00a8 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.6 +Version: 0.5.7 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index f3a2714..ca4994d 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -61,8 +61,8 @@ static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_ static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer); static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size); static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint codecdata_size); -static void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet); -static int __mc_gst_create_eos_packet(media_format_h fmt, media_packet_h *out_packet); +static void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer); +static int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer); static void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet); static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message); @@ -974,7 +974,6 @@ mc_gst_core_t *mc_gst_core_new() core->unprepare_flag = false; core->prepare_count = 0; core->etb_count = 0; - core->ftb_count = 0; core->codec_data = NULL; g_atomic_int_set(&core->available_queue->running, 1); @@ -2153,29 +2152,26 @@ STATE_CHANGE_FAILED: return MC_ERROR; } -void __mc_push_output_to_queue(mc_gst_core_t *core, media_packet_h out_packet) +void __mc_push_output_to_queue(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { g_mutex_lock(&core->ports[1]->mutex); /* push it to output buffer queue */ - g_queue_push_tail(core->ports[1]->queue, out_packet); + g_queue_push_tail(core->ports[1]->queue, mcbuffer->packet); g_cond_broadcast(&core->out_buffer_cond); - g_atomic_int_inc(&core->ftb_count); - GstBuffer *buffer = NULL; - media_packet_get_extra(out_packet, (void**)&buffer); - if (buffer) { - LOGD("dq : v(%d)e(%d) %d TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder, - core->ftb_count, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); + if (mcbuffer->buffer) { + LOGD("dq : v(%d)e(%d) TIMESTAMP = %"GST_TIME_FORMAT " DURATION = %"GST_TIME_FORMAT, core->video, core->encoder, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(mcbuffer->buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(mcbuffer->buffer))); } else { - LOGD("dq : v(%d)e(%d) %d ", core->video, core->encoder, core->ftb_count); + LOGD("dq : v(%d)e(%d)", core->video, core->encoder); } g_mutex_unlock(&core->ports[1]->mutex); if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) { ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) - (out_packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]); + (mcbuffer->packet, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]); } } @@ -2207,7 +2203,7 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp core->need_sync_flag = false; } - __mc_push_output_to_queue(core, mcbuffer->packet); + __mc_push_output_to_queue(core, mcbuffer); } else { gst_buffer_unref(buffer); LOGE("Failed to dequeue output packet"); @@ -2220,48 +2216,35 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data) { - void *buffer = NULL; int i = 0; guint n; GstMemory *mem; GstMapInfo map = GST_MAP_INFO_INIT; MMVideoBuffer *mm_video_buf = NULL; - GList *find; MEDIACODEC_FENTER(); GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data; - mc_gst_core_t *core = mcbuffer->core; - g_mutex_lock(&core->ports[1]->mutex); - - if ((find = g_queue_find(core->ports[1]->queue, packet))) { - LOGD("remove packet from queue"); - g_queue_remove(core->ports[1]->queue, packet); - } - - g_mutex_unlock(&core->ports[1]->mutex); + if (mcbuffer->buffer) { + n = gst_buffer_n_memory(mcbuffer->buffer); - g_atomic_int_dec_and_test(&core->ftb_count); + if (n > 1) { + mem = gst_buffer_peek_memory(mcbuffer->buffer, n-1); + gst_memory_map(mem, &map, GST_MAP_READ); + mm_video_buf = (MMVideoBuffer *)map.data; - buffer = mcbuffer->buffer; - - n = gst_buffer_n_memory(buffer); - - if (n > 1) { - mem = gst_buffer_peek_memory(buffer, n-1); - gst_memory_map(mem, &map, GST_MAP_READ); - mm_video_buf = (MMVideoBuffer *)map.data; - - if (!mm_video_buf) { - LOGW("gstbuffer map.data is null"); - } else { - for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { - if (mm_video_buf->handle.bo[i]) - tbm_bo_unref(mm_video_buf->handle.bo[i]); + if (!mm_video_buf) { + LOGW("gstbuffer map.data is null"); + } else { + for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { + if (mm_video_buf->handle.bo[i]) + tbm_bo_unref(mm_video_buf->handle.bo[i]); + } } + gst_memory_unmap(mem, &map); } - gst_memory_unmap(mem, &map); + gst_buffer_unref((GstBuffer *)mcbuffer->buffer); } if (mcbuffer->ext_mem) { @@ -2270,8 +2253,8 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * mcbuffer->ext_mem = NULL; } - gst_buffer_unref((GstBuffer *)buffer); - LOGD("@v(%d)e(%d)output port filled buffer(%d): %p", core->video, core->encoder, core->ftb_count, packet); + LOGD("output port filled buffer : %p", packet); + g_free(mcbuffer); MEDIACODEC_FLEAVE(); @@ -2398,32 +2381,34 @@ GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer) return mcbuffer; } -int __mc_gst_create_eos_packet(media_format_h fmt, media_packet_h *out_packet) +int __mc_gst_create_eos_packet(media_format_h fmt, GstMCBuffer *mcbuffer) { gint ret = MC_ERROR_NONE; - media_packet_h mediabuf = NULL; + media_packet_h packet = NULL; MEDIACODEC_FENTER(); - if (media_packet_create(fmt, NULL, NULL, &mediabuf)) { + if (media_packet_create_alloc(fmt, __mc_output_buffer_finalize_cb, mcbuffer, &packet)) { LOGE("media_packet_create_alloc failed\n"); ret = MC_ERROR; goto ERROR; } - if (media_packet_set_flags(mediabuf, MEDIA_PACKET_END_OF_STREAM)) { + if (media_packet_set_flags(packet, MEDIA_PACKET_END_OF_STREAM)) { LOGE("unable to set EOS flag\n"); ret = MC_ERROR; goto ERROR; } - *out_packet = mediabuf; + mcbuffer->buffer = NULL; + mcbuffer->ext_mem = NULL; + mcbuffer->buf_size = 0; + mcbuffer->packet = packet; MEDIACODEC_FLEAVE(); return ret; ERROR: - if (mediabuf) - media_packet_destroy(mediabuf); - *out_packet = NULL; + if (packet) + media_packet_destroy(packet); MEDIACODEC_FLEAVE(); return ret; } @@ -2450,20 +2435,23 @@ void _mc_gst_handle_input_buffer_used(mc_gst_core_t *core, media_packet_h packet gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { gint ret = MC_ERROR_NONE; + GstMCBuffer *mcbuffer = NULL; + mc_gst_core_t *core = (mc_gst_core_t *)data; - LOGD("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); + LOGI("@%p v(%d)e(%d)bus message : %s", core, core->video, core->encoder, gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: _mc_send_eos_signal(core); - media_packet_h out_packet = NULL; - if (MC_ERROR_NONE == __mc_gst_create_eos_packet(core->output_fmt, &out_packet)) { - __mc_push_output_to_queue(core, out_packet); + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(GstMCBuffer)); + if (__mc_gst_create_eos_packet(core->output_fmt, mcbuffer) == MC_ERROR_NONE) { + __mc_push_output_to_queue(core, mcbuffer); LOGD("send eos packet."); } else { LOGE("failed to create eos packet."); + g_free(mcbuffer); } if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) { @@ -2683,7 +2671,7 @@ static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer) _mc_gst_handle_input_buffer_used(core, mcbuffer->packet); - free(mcbuffer); + g_free(mcbuffer); mcbuffer = NULL; MEDIACODEC_FLEAVE(); @@ -2695,7 +2683,7 @@ static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_ { GstMCBuffer *mcbuffer = NULL; - mcbuffer = (GstMCBuffer *)malloc(sizeof(*mcbuffer)); + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(GstMCBuffer)); if (mcbuffer == NULL) { LOGE("malloc fail"); @@ -2946,8 +2934,7 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) while (!g_queue_is_empty(core->ports[1]->queue)) { packet = g_queue_pop_head(core->ports[1]->queue); - g_atomic_int_dec_and_test(&core->ftb_count); - LOGD("%p poped(%d)", packet, core->ftb_count); + LOGD("%p poped", packet); if (packet) { media_packet_destroy(packet); LOGD("outpacket destroyed"); -- 2.34.1