Sync with tizen_3.0 and add to control buffer overflow 02/127902/4
authorSejun Park <sejun79.park@samsung.com>
Tue, 2 May 2017 08:27:02 +0000 (17:27 +0900)
committerSejun Park <sejun79.park@samsung.com>
Thu, 11 May 2017 06:03:40 +0000 (06:03 +0000)
Change-Id: Ia4d1007a9b6bc8e6cdd95cbc244b9bc621ff849b

include/media_codec_port_gst.h
src/media_codec_port_gst.c

index 92b4eee..98e93c0 100755 (executable)
@@ -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);
index 759117c..ae66a6e 100755 (executable)
@@ -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();
 }