Update caps when info. of packet is changed. 68/69568/5 accepted/tizen/common/20160519.191325 accepted/tizen/ivi/20160519.085124 accepted/tizen/mobile/20160519.085057 accepted/tizen/tv/20160519.085038 accepted/tizen/wearable/20160519.085019 submit/tizen/20160519.011519
authorSejun Park <sejun79.park@samsung.com>
Mon, 16 May 2016 02:20:13 +0000 (11:20 +0900)
committerSejun Park <sejun79.park@samsung.com>
Tue, 17 May 2016 08:43:03 +0000 (17:43 +0900)
Change-Id: I6140d2add2a2ca09f93383a678dc0e28340b4dcb

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

index 4a396ef..eae6f9a 100755 (executable)
@@ -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;
index 379e8fa..28f5cf5 100755 (executable)
@@ -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
index a7e15af..4e94746 100755 (executable)
@@ -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;
index 76bf0b4..dbd4d24 100755 (executable)
@@ -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();
 }