fixed crash when media packet is destroyed after unpreparing 52/137252/5
authorSejun Park <sejun79.park@samsung.com>
Wed, 5 Jul 2017 06:05:19 +0000 (15:05 +0900)
committerSejun Park <sejun79.park@samsung.com>
Wed, 5 Jul 2017 07:58:27 +0000 (16:58 +0900)
Change-Id: I523aa25e58411d0e0f27a8a2aaf9dd91d4c5a7a1

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

index fe5ab65..3cf9120 100644 (file)
@@ -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;
index d84b606..17b00a8 100644 (file)
@@ -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
index f3a2714..ca4994d 100644 (file)
@@ -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");