From 5e28d71938c8565f4415fb970f480bc10219e01e Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Wed, 12 Aug 2015 19:38:49 +0900 Subject: [PATCH] Change the input new_segment(start/stop) position into encodebin Change-Id: I61a8c9fa9785d711f34f04f24529afa0c9d4ba47 Signed-off-by: Gilbok Lee --- packaging/libmm-transcode.spec | 2 +- transcode/include/mm_transcode_internal.h | 3 + transcode/mm_transcode.c | 2 +- transcode/mm_transcode_pipeline.c | 20 ++++ transcode/mm_transcode_seek.c | 106 +++++++++++++++------- 5 files changed, 96 insertions(+), 37 deletions(-) diff --git a/packaging/libmm-transcode.spec b/packaging/libmm-transcode.spec index 4339df1..b54050b 100644 --- a/packaging/libmm-transcode.spec +++ b/packaging/libmm-transcode.spec @@ -1,7 +1,7 @@ Name: libmm-transcode Summary: Multimedia Framework Video Transcode Library Version: 0.9 -Release: 5 +Release: 6 Group: System/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/transcode/include/mm_transcode_internal.h b/transcode/include/mm_transcode_internal.h index 932c539..7365842 100644 --- a/transcode/include/mm_transcode_internal.h +++ b/transcode/include/mm_transcode_internal.h @@ -151,6 +151,8 @@ typedef struct _handle_encode_s GstElement *aencqueue; GstElement *encodepad; GstElement *encodevideo; + gulong video_event_probe_id; + gulong audio_event_probe_id; int encodebin_profile; } handle_encode_s; @@ -239,6 +241,7 @@ GstPadProbeReturn _mm_cb_audio_output_stream_probe(GstPad *pad, GstPadProbeInfo GstAutoplugSelectResult _mm_cb_decode_bin_autoplug_select(GstElement * element, GstPad * pad, GstCaps * caps, GstElementFactory * factory, handle_s *handle); void _mm_cb_decoder_newpad_encoder(GstElement *decodebin, GstPad *pad, handle_s *handle); GstPadProbeReturn _mm_cb_video_output_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data); +GstPadProbeReturn _mm_cb_encodebin_sinkpad_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data); gboolean _mm_cb_print_position(handle_s *handle); gboolean _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata); const gchar* _mm_check_media_type(GstCaps *caps); diff --git a/transcode/mm_transcode.c b/transcode/mm_transcode.c index 8c96256..4759bf4 100755 --- a/transcode/mm_transcode.c +++ b/transcode/mm_transcode.c @@ -321,7 +321,7 @@ mm_transcode_cancel (MMHandleType MMHandle) debug_error("unlink error"); return MM_ERROR_TRANSCODE_INTERNAL; } - + g_mutex_lock (handle->property->thread_mutex); g_cond_signal(handle->property->thread_cond); debug_log("===> send completed signal <-cancel"); g_mutex_unlock (handle->property->thread_mutex); diff --git a/transcode/mm_transcode_pipeline.c b/transcode/mm_transcode_pipeline.c index 3a4a765..1ad209d 100755 --- a/transcode/mm_transcode_pipeline.c +++ b/transcode/mm_transcode_pipeline.c @@ -230,6 +230,18 @@ _mm_cleanup_pipeline(handle_s *handle) debug_log("g_source_remove (progrss_event_id)"); } + if(handle->encodebin->audio_event_probe_id) { + g_source_remove (handle->encodebin->audio_event_probe_id); + handle->encodebin->audio_event_probe_id = 0; + debug_log("g_source_remove (audio_event_probe_id)"); + } + + if(handle->encodebin->video_event_probe_id) { + g_source_remove (handle->encodebin->video_event_probe_id); + handle->property->video_cb_probe_id = 0; + debug_log("g_source_remove (video_event_probe_id)"); + } + TRANSCODE_FREE (handle->property->mux); TRANSCODE_FREE (handle->property->venc); TRANSCODE_FREE (handle->property->aenc); @@ -729,6 +741,10 @@ _mm_encodebin_link(handle_s *handle) if (handle->encodebin->encvideopad) { debug_log("encvideopad: 0x%2x", handle->encodebin->encvideopad); gst_pad_link(handle->decoder_vidp->srcdecvideopad, handle->encodebin->encvideopad); + handle->encodebin->audio_event_probe_id = + gst_pad_add_probe (handle->encodebin->encvideopad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + _mm_cb_encodebin_sinkpad_event_probe, handle, NULL); } else { debug_error("error encvideopad"); return MM_ERROR_TRANSCODE_INTERNAL; @@ -742,6 +758,10 @@ _mm_encodebin_link(handle_s *handle) if (handle->encodebin->encaudiopad) { debug_log("encaudiopad: 0x%2x", handle->encodebin->encaudiopad); gst_pad_link(handle->decoder_audp->srcdecaudiopad, handle->encodebin->encaudiopad); + handle->encodebin->audio_event_probe_id = + gst_pad_add_probe (handle->encodebin->encaudiopad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + _mm_cb_encodebin_sinkpad_event_probe, handle, NULL); } else { debug_error("error encaudiopad"); return MM_ERROR_TRANSCODE_INTERNAL; diff --git a/transcode/mm_transcode_seek.c b/transcode/mm_transcode_seek.c index 7510d25..cb18df9 100755 --- a/transcode/mm_transcode_seek.c +++ b/transcode/mm_transcode_seek.c @@ -56,11 +56,11 @@ _mm_cb_audio_output_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer us if (current_caps) gst_caps_unref(current_caps); + } - if (handle->param->seeking) { - debug_log("[AUDIO BUFFER TIMESTAMP] ([%"G_GUINT64_FORMAT"])", start_pos_ts); - GST_BUFFER_PTS (GST_PAD_PROBE_INFO_BUFFER(info)) = start_pos_ts; - } + if (handle->param->seeking) { + /* Shifting the decoded out buffer time as the start time */ + GST_BUFFER_PTS (GST_PAD_PROBE_INFO_BUFFER(info)) -= start_pos_ts; } } return GST_PAD_PROBE_OK; @@ -91,16 +91,70 @@ _mm_cb_video_output_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer us if (current_caps) gst_caps_unref(current_caps); + } - if(handle->param->seeking) { - debug_log("[VIDEO BUFFER TIMESTAMP] ([%"G_GUINT64_FORMAT"])", start_pos_ts); - GST_BUFFER_PTS (GST_PAD_PROBE_INFO_BUFFER(info)) = start_pos_ts; - } + if(handle->param->seeking) { + /* Shifting the decoded out buffer time as the start time */ + GST_BUFFER_PTS (GST_PAD_PROBE_INFO_BUFFER(info)) -= start_pos_ts; } } return GST_PAD_PROBE_OK; } +GstPadProbeReturn +_mm_cb_encodebin_sinkpad_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) +{ + handle_s *handle = (handle_s*) user_data; + GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info); + + if (!handle) { + debug_error("[ERROR] - handle"); + return GST_PAD_PROBE_REMOVE; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return GST_PAD_PROBE_REMOVE; + } + + if (!event) { + debug_error("[ERROR] - event"); + return GST_PAD_PROBE_REMOVE; + } + + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_SEGMENT: + { + if (!handle->param->seeking) + break; + + const GstSegment *segment = NULL; + GstSegment *new_segment = NULL; + gst_event_parse_segment (event, &segment); + if (segment->format != GST_FORMAT_TIME) + break; + + new_segment = gst_segment_copy(segment); + gst_event_unref (event); + + new_segment->start = 0; + new_segment->stop = handle->param->duration * G_GINT64_CONSTANT(1000000); + + /* replace the new segment (change start/stop position) */ + GstEvent *new_event = gst_event_new_segment(new_segment); + + GST_PAD_PROBE_INFO_DATA(info) = new_event; + } + + break; + default: + break; + } + + return GST_PAD_PROBE_OK; +} + + GstAutoplugSelectResult _mm_cb_decode_bin_autoplug_select(GstElement * element, GstPad * pad, GstCaps * caps, GstElementFactory * factory, handle_s *handle) @@ -299,7 +353,9 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) gchar *debug; gst_message_parse_error (message, &err, &debug); - debug_error("[Source: %s] Error: %s", GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC (message)))), err->message); + debug_error("[Source: %s] Error: %s", + GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC (message)))), + err->message); ret = mm_transcode_cancel(MMHandle); if(ret == MM_ERROR_NONE) { @@ -418,7 +474,6 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) unlink(handle->param->outputfile); debug_log("[unlink] %s %d > %d", handle->param->outputfile, handle->param->start_pos, handle->property->total_length); } - g_mutex_lock (handle->property->thread_mutex); g_free(handle->param); debug_log("g_free (param)"); @@ -448,27 +503,6 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) return TRUE; } -static void -_mm_transcode_add_sink(handle_s *handle , GstElement* sink_elements) -{ - - if (!handle) { - debug_error("[ERROR] - handle"); - return; - } - - if (!handle->property) { - debug_error("[ERROR] - handle property"); - return; - } - - if(sink_elements) { - handle->property->sink_elements = g_list_append(handle->property->sink_elements, sink_elements); - debug_log("g_list_append"); - } - -} - static void _mm_transcode_audio_capsfilter(GstCaps *caps, handle_s *handle) { @@ -1078,6 +1112,8 @@ _mm_transcode_param_flush(handle_s *handle) handle->encodebin->encodebin_profile = 0; handle->property->AUDFLAG = 0; handle->property->VIDFLAG = 0; + handle->encodebin->audio_event_probe_id = 0; + handle->encodebin->video_event_probe_id = 0; handle->property->total_length = 0; handle->property->repeat_thread_exit = FALSE; @@ -1164,9 +1200,9 @@ _mm_transcode_seek(handle_s *handle) } if(handle->param->seek_mode == MM_SEEK_ACCURATE) { - _Flags = GST_SEEK_FLAG_ACCURATE; + _Flags = GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH; } else if(handle->param->seek_mode == MM_SEEK_INACCURATE) { - _Flags = GST_SEEK_FLAG_KEY_UNIT; + _Flags = GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_FLUSH; } if(!gst_element_seek(seekable_element, rate, GST_FORMAT_TIME, _Flags, GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, end_pos)) { @@ -1212,7 +1248,7 @@ _mm_transcode_thread(handle_s *handle) debug_error("ERROR - thread_exit_mutex is already created"); } - /*These are a communicator for thread*/ + /* These are a communicator for thread */ if(!handle->property->queue) { handle->property->queue = g_async_queue_new(); debug_log("create async queue: 0x%2x", handle->property->queue); @@ -1227,7 +1263,7 @@ _mm_transcode_thread(handle_s *handle) debug_error("thread cond is already created"); } - /*create threads*/ + /* create threads */ debug_log("create thread"); handle->property->thread = g_thread_create ((GThreadFunc)_mm_transcode_thread_repeate, (gpointer)handle, TRUE, NULL); if(!handle->property->thread) { -- 2.34.1