From: fscherry Date: Thu, 10 Nov 2016 11:39:58 +0000 (+0900) Subject: RVU Service LiveStreaming Optimization X-Git-Tag: accepted/tizen/3.0/common/20161216.123750~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b8ca0545b54ebe0c8f16f77db8a0fe06d5513d7;p=platform%2Fupstream%2Fgstreamer.git RVU Service LiveStreaming Optimization Change-Id: I74868b743064b3b447b1f1de01873b54bc82d88d Signed-off-by: fscherry --- diff --git a/packaging/gstreamer.spec b/packaging/gstreamer.spec index fd01353..5b9d887 100644 --- a/packaging/gstreamer.spec +++ b/packaging/gstreamer.spec @@ -73,6 +73,7 @@ export CFLAGS="%{optflags} \ -DTIZEN_FEATURE_QUEUE_MODIFICATION\ %if "%{?profile}" == "tv" -DTIZEN_PROFILE_TV\ + -DRVU_LIVESTREAMING_OPTIMIZATION\ %endif -fno-strict-aliasing" diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index 84e87b5..425654c 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -122,6 +122,16 @@ */ typedef struct _GstSingleQueue GstSingleQueue; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch*/ +enum +{ + SQ_VIDEO_STREAM = 0, + SQ_AUDIO_STREAM, + SQ_OTHER_STREAM +}; +#endif + struct _GstSingleQueue { /* unique identifier of the queue */ @@ -172,6 +182,11 @@ struct _GstSingleQueue GCond query_handled; gboolean last_query; GstQuery *last_handled_query; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : update buffering percent*/ + gint sq_stream_type; + GstClockTime cur_time_of_begin_buffering; +#endif }; @@ -189,6 +204,10 @@ struct _GstMultiQueueItem guint32 posid; gboolean is_query; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + /*RVU patch : for update single queue buffering percent*/ + GstSingleQueue *sq; +#endif }; static GstSingleQueue *gst_single_queue_new (GstMultiQueue * mqueue, guint id); @@ -205,6 +224,13 @@ static void gst_multi_queue_post_buffering (GstMultiQueue * mq); static void gst_single_queue_flush_queue (GstSingleQueue * sq, gboolean full); +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : work for get stream type to set single queue buffering params*/ +static void single_queue_set_stream_type (GstSingleQueue * squeue, + GstBuffer * buffer); +static void early_exit_buffering (GstMultiQueue * mq); +#endif + static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST, @@ -265,6 +291,20 @@ enum PROP_LOW_PERCENT, PROP_HIGH_PERCENT, PROP_SYNC_BY_RUNNING_TIME, +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : buffering params*/ + PROP_MAX_AUDIO_SIZE_BYTES, + PROP_MAX_AUDIO_SIZE_BUFFERS, + PROP_MAX_AUDIO_SIZE_TIME, + PROP_MAX_VIDEO_SIZE_BYTES, + PROP_MAX_VIDEO_SIZE_BUFFERS, + PROP_MAX_VIDEO_SIZE_TIME, + PROP_ENABLE_BUFFERING_OPT, +/*RVU patch : rvu reset, disable audio buffering and adaptive buffering property*/ + PROP_RESET_FLAG, + PROP_DISABLE_AUDIO_BUFFERING, + PROP_BUFFERING_ENHANCEMENT, +#endif PROP_LAST }; @@ -348,7 +388,6 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /* PROPERTIES */ - g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BYTES, g_param_spec_uint ("max-size-bytes", "Max. size (kB)", "Max. amount of data in the queue (bytes, 0=disable)", @@ -436,6 +475,59 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) "Synchronize deactivated or not-linked streams by running time", DEFAULT_SYNC_BY_RUNNING_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : buffering params property*/ + g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_BYTES, + g_param_spec_uint ("max-size-audio-bytes", "Max. size (kB)", + "Max. amount of data in the audio queue (bytes, 0=disable)", 0, + G_MAXUINT, DEFAULT_MAX_SIZE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_BUFFERS, + g_param_spec_uint ("max-size-audio-buffers", "Max. size (buffers)", + "Max. number of buffers in the audio queue (0=disable)", 0, G_MAXUINT, + DEFAULT_MAX_SIZE_BUFFERS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_TIME, + g_param_spec_uint64 ("max-size-audio-time", "Max. size (ns)", + "Max. amount of data in the audio queue (in ns, 0=disable)", 0, + G_MAXUINT64, DEFAULT_MAX_SIZE_TIME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_BYTES, + g_param_spec_uint ("max-size-video-bytes", "Max. size (kB)", + "Max. amount of data in the video queue (bytes, 0=disable)", + 0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_BUFFERS, + g_param_spec_uint ("max-size-video-buffers", "Max. size (buffers)", + "Max. number of buffers in the video queue (0=disable)", 0, G_MAXUINT, + DEFAULT_MAX_SIZE_BUFFERS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_TIME, + g_param_spec_uint64 ("max-size-video-time", "Max. size (ns)", + "Max. amount of data in the video queue (in ns, 0=disable)", 0, + G_MAXUINT64, DEFAULT_MAX_SIZE_TIME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ENABLE_BUFFERING_OPT, + g_param_spec_boolean ("enable-buffering-opt", + "make buffering optimize enable", + "enable to control the buffering queue size and time.", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + +/*RVU patch : rvu reset, disable audio buffering and adaptive buffering property*/ + g_object_class_install_property (gobject_class, PROP_RESET_FLAG, + g_param_spec_int ("buffering-reset-flag", "reset flag", + "reset buffering flag", 0, 1, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_DISABLE_AUDIO_BUFFERING, + g_param_spec_boolean ("disable-audio-buffering", + "disable audio stream buffering", "disable audio buffering solution", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_BUFFERING_ENHANCEMENT, + g_param_spec_boolean ("enhancement-buffering", "enhancement buffering solution", + "enhancement buffering solution", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif gobject_class->finalize = gst_multi_queue_finalize; @@ -478,6 +570,21 @@ gst_multi_queue_init (GstMultiQueue * mqueue) mqueue->counter = 1; mqueue->highid = -1; mqueue->high_time = GST_CLOCK_TIME_NONE; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : buffering params init*/ + mqueue->audio_max_size.bytes = DEFAULT_MAX_SIZE_BYTES; + mqueue->audio_max_size.visible = DEFAULT_MAX_SIZE_BUFFERS; + mqueue->audio_max_size.time = DEFAULT_MAX_SIZE_TIME; + mqueue->video_max_size.bytes = DEFAULT_MAX_SIZE_BYTES; + mqueue->video_max_size.visible = DEFAULT_MAX_SIZE_BUFFERS; + mqueue->video_max_size.time = DEFAULT_MAX_SIZE_TIME; + mqueue->buffering_start_time = 0; + mqueue->stream_duration = 0; +/*RVU patch : rvu reset flag, disable audio buffering flag and adaptive buffering flag*/ + mqueue->buffering_reset = FALSE; + mqueue->disable_audio_buffering = FALSE; + mqueue->enhancement_buffering = FALSE; +#endif g_mutex_init (&mqueue->qlock); g_mutex_init (&mqueue->buffering_post_lock); @@ -570,6 +677,45 @@ gst_multi_queue_set_property (GObject * object, guint prop_id, GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); gst_multi_queue_post_buffering (mq); break; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : buffering params property*/ + case PROP_MAX_AUDIO_SIZE_BYTES: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->audio_max_size.bytes = g_value_get_uint (value); + SET_CHILD_PROPERTY (mq, bytes); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; + case PROP_MAX_AUDIO_SIZE_BUFFERS: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->audio_max_size.visible = g_value_get_uint (value); + SET_CHILD_PROPERTY (mq, visible); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; + case PROP_MAX_AUDIO_SIZE_TIME: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->audio_max_size.time = g_value_get_uint64 (value); + SET_CHILD_PROPERTY (mq, time); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; + case PROP_MAX_VIDEO_SIZE_BYTES: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->video_max_size.bytes = g_value_get_uint (value); + SET_CHILD_PROPERTY (mq, bytes); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; + case PROP_MAX_VIDEO_SIZE_BUFFERS: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->video_max_size.visible = g_value_get_uint (value); + SET_CHILD_PROPERTY (mq, visible); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; + case PROP_MAX_VIDEO_SIZE_TIME: + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->video_max_size.time = g_value_get_uint64 (value); + SET_CHILD_PROPERTY (mq, time); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); + break; +#endif case PROP_EXTRA_SIZE_BYTES: mq->extra_size.bytes = g_value_get_uint (value); break; @@ -622,6 +768,29 @@ gst_multi_queue_set_property (GObject * object, guint prop_id, case PROP_SYNC_BY_RUNNING_TIME: mq->sync_by_running_time = g_value_get_boolean (value); break; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : rvu reset buffering, disable audio buffering and adaptive buffering property*/ + case PROP_RESET_FLAG: + mq->buffering = FALSE; + mq->percent = 0; + mq->buffering_reset = TRUE; + GST_DEBUG_OBJECT (mq, "MQ RESET FLAG!\n"); + break; + case PROP_DISABLE_AUDIO_BUFFERING: + { + mq->disable_audio_buffering = g_value_get_boolean (value); + GST_LOG_OBJECT (mq, "disable-audio-buffering %d\n", + mq->disable_audio_buffering); + } + break; + case PROP_BUFFERING_ENHANCEMENT: + { + mq->enhancement_buffering = g_value_get_boolean (value); + GST_LOG_OBJECT (mq, "mq->enhancement_buffering %d\n", + mq->enhancement_buffering); + } + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -701,6 +870,15 @@ gst_multi_queue_get_property (GObject * object, guint prop_id, case PROP_SYNC_BY_RUNNING_TIME: g_value_set_boolean (value, mq->sync_by_running_time); break; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : rvu disable audio buffering and adaptive buffering property*/ + case PROP_DISABLE_AUDIO_BUFFERING: + g_value_set_boolean (value, mq->disable_audio_buffering); + break; + case PROP_BUFFERING_ENHANCEMENT: + g_value_set_boolean (value, mq->enhancement_buffering); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -956,10 +1134,26 @@ get_percentage (GstSingleQueue * sq) tmp = (sq->cur_time * 100) / sq->max_size.time; percent = MAX (percent, tmp); } +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + /*RVU patch : rvu adaptive buffering */ + if (sq->mqueue->enhancement_buffering == TRUE) + GST_LOG_OBJECT (sq->mqueue, + "MULTIQUEUE ENHANCEMENT BUFFERING SOLUTION ENABLE!\n"); + + if (sq->mqueue->enhancement_buffering == FALSE) { + if (sq->max_size.bytes > 0) { + tmp = (size.bytes * 100) / sq->max_size.bytes; + percent = MAX (percent, tmp); + } + } else { + GST_LOG_OBJECT (sq->mqueue, "disable bytes buffering profile!\n"); + } +#else if (sq->max_size.bytes > 0) { tmp = (size.bytes * 100) / sq->max_size.bytes; percent = MAX (percent, tmp); } +#endif } return percent; @@ -970,21 +1164,97 @@ static void update_buffering (GstMultiQueue * mq, GstSingleQueue * sq) { gint percent; - +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + /*RVU patch : disable mq audio buffering solution */ + GstPad *audio_pad = NULL; + GstCaps *audio_caps = NULL; + GstStructure *audio_caps_str = NULL; + const char *audio_mime = NULL; + const char *audio_stream_type = NULL; +#endif /* nothing to dowhen we are not in buffering mode */ if (!mq->use_buffering) return; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + /*RVU patch : disable mq audio buffering solution */ + if ((sq != NULL) && (mq->disable_audio_buffering == TRUE)) { + GST_LOG_OBJECT (mq, "disable audio buffering solution start!\n"); + audio_pad = GST_PAD_PEER (sq->sinkpad); + audio_caps = gst_pad_get_current_caps (audio_pad); + if (NULL == audio_caps) { + GST_LOG_OBJECT (mq, "audio caps is null!\n"); + goto NEXT_STEP; + } + audio_caps_str = gst_caps_get_structure (audio_caps, 0); + if (NULL == audio_caps_str) { + GST_LOG_OBJECT (mq, "audio caps string is NULL!\n"); + goto NEXT_STEP; + } + + audio_mime = gst_structure_get_name (audio_caps_str); + if (NULL == audio_mime) { + GST_LOG_OBJECT (mq, "audio caps string mime is NULL!\n"); + goto NEXT_STEP; + } + + GST_LOG_OBJECT (mq, "audio_mime:[%s]\n", audio_mime); + if (g_strrstr (audio_mime, "audio")) { + GST_LOG_OBJECT (mq, + "non-drm audio single queue!, skip audio buffering\n"); + goto LAST_POS; + } else if (g_strrstr (audio_mime, "drm")) { + audio_stream_type = + gst_structure_get_string (audio_caps_str, "stream-type"); + if (NULL == audio_stream_type) { + GST_LOG_OBJECT (mq, "drm audio single queue can not get stream-type\n"); + goto NEXT_STEP; + } + if (g_strrstr (audio_stream_type, "audio")) { + GST_LOG_OBJECT (mq, "drm audio single queue!, skip audio buffering!\n"); + goto LAST_POS; + } + } + GST_LOG_OBJECT (mq, "disable audio buffering solution end!\n"); + } + +NEXT_STEP: + if (audio_caps != NULL) { + GST_LOG_OBJECT (mq, + "audio caps release for disable audio buffering solution!\n"); + gst_caps_unref (audio_caps); + audio_caps = NULL; + } +#endif percent = get_percentage (sq); if (mq->buffering) { if (percent >= mq->high_percent) { mq->buffering = FALSE; } +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : rvu reset buffering */ + if (mq->buffering_reset) { + if (percent < mq->low_percent) { + mq->buffering = TRUE; + mq->percent = percent; + mq->percent_changed = TRUE; + } + } +#endif /* make sure it increases */ percent = MAX (mq->percent, percent); SET_PERCENT (mq, percent); +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : adaptive buffering solution*/ + if (mq->enhancement_buffering == TRUE) { + if (percent >= mq->high_percent) { + mq->percent_changed = TRUE; + GST_LOG_OBJECT (mq, "MULTIQUEUE ENHANCEMENT BUFFERING!\n"); + } + } +#endif } else { GList *iter; gboolean is_buffering = TRUE; @@ -1004,6 +1274,109 @@ update_buffering (GstMultiQueue * mq, GstSingleQueue * sq) SET_PERCENT (mq, percent); } } +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*common update buffering */ +/*while starts buffering, need restore start time */ + if (mq->enable_buffering_opt) { + if (percent < mq->low_percent && mq->buffering == TRUE) { + struct timeval tv = { 0 }; + GList *iter = NULL; + gettimeofday (&tv, NULL); + + mq->buffering_start_time = + GST_SECOND * (guint64) tv.tv_sec + (guint64) tv.tv_usec * GST_USECOND; + /*update all single queue */ + for (iter = mq->queues; iter; iter = g_list_next (iter)) { + GstSingleQueue *oq = (GstSingleQueue *) iter->data; + oq->cur_time_of_begin_buffering = oq->cur_time; + } + GST_DEBUG_OBJECT (mq, + "update buffering start time, cur_time is : %" G_GUINT64_FORMAT, + sq->cur_time_of_begin_buffering); + } else if (mq->buffering == TRUE) { + struct timeval tv = { 0 }; + gettimeofday (&tv, NULL); + GstClockTime buffering_duration = sq->cur_time; + guint64 tmp_time = + GST_SECOND * (guint64) tv.tv_sec + (guint64) tv.tv_usec * GST_USECOND; + guint64 elapsed_time = 0; + + /*caculate elapsed time */ + tmp_time -= mq->buffering_start_time; + elapsed_time = tmp_time; + /*buffering percentage increase until its src pad is blocked, */ + if (sq->cur_time > sq->cur_time_of_begin_buffering) + buffering_duration = sq->cur_time - sq->cur_time_of_begin_buffering; + + GST_DEBUG_OBJECT (mq, + "%s, elapsed time is: %" G_GUINT64_FORMAT " cur_time is: %" + G_GUINT64_FORMAT, sq->sq_stream_type == SQ_VIDEO_STREAM ? "vq" : "aq", + elapsed_time, buffering_duration); + tmp_time /= GST_SECOND; + + /*demuxer speed is lower than decoder */ + if (tmp_time > 0 && (tmp_time % 3 == 0) + && buffering_duration < elapsed_time + && sq->sq_stream_type == SQ_VIDEO_STREAM) { + GstFormat format = GST_FORMAT_TIME; + guint64 cur_position = sq->srctime; + GstCaps *video_caps = NULL; + GstStructure *caps_structure = NULL; + gint rnum = 0, rdenom = 1; + gint r_framerate = 0, remaining_frame = 0, instant_throughput = + 0, estimated_video_frame_count = 0; + GstDataQueueSize size; + + if (cur_position <= 0 || mq->stream_duration <= 0) { + GST_DEBUG_OBJECT (mq, "no duration or position"); + return; + } + gst_data_queue_get_level (sq->queue, &size); + + video_caps = gst_pad_get_current_caps (sq->sinkpad); + GST_DEBUG_OBJECT (mq, "stream caps: %" GST_PTR_FORMAT, video_caps); + + if (video_caps != NULL) { + caps_structure = gst_caps_get_structure (video_caps, 0); + + if (caps_structure != NULL) + gst_structure_get_fraction (caps_structure, "r_framerate", &rnum, + &rdenom); + + gst_caps_unref (video_caps); + } + + else + return; + + if (rdenom != 0) + r_framerate = rnum / rdenom; + + GST_DEBUG_OBJECT (mq, "r_framerate is %d ", r_framerate); + + remaining_frame = (mq->stream_duration - cur_position) * r_framerate / GST_SECOND - size.visible; // packets num in video queue; + instant_throughput = size.visible * GST_SECOND / elapsed_time; // packets num / per seconds + GST_DEBUG_OBJECT (mq, "remaining_fram is %d, instant_throughput is %d", + remaining_frame, instant_throughput); + if (remaining_frame != 0) + estimated_video_frame_count = + (int) ((remaining_frame * r_framerate) / (r_framerate + + instant_throughput)); + } + } + } +#endif +#ifdef TIZEN_PROFILE_TV +/*RVU patch : rvu case disable audio buffering */ + return; +LAST_POS: + if (audio_caps != NULL) { + gst_caps_unref (audio_caps); + audio_caps = NULL; + } + GST_LOG_OBJECT (mq, "DISABLE AUDIO BUFFERING MESSAGE HANDLE!\n"); + return; +#endif } static void @@ -1439,7 +1812,18 @@ next: if (sq->flushing) goto out_flushing; - +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + if (mq->stream_duration == 0) { + GstPad *peer = NULL; + peer = gst_pad_get_peer (sq->sinkpad); + if (peer) { + if (!gst_pad_query_duration (peer, GST_FORMAT_TIME, + &(mq->stream_duration))) + GST_WARNING_OBJECT (mq, "Could not query upstream length!"); + gst_object_unref (peer); + } + } +#endif /* Get something from the queue, blocking until that happens, or we get * flushed */ if (!(gst_data_queue_pop (sq->queue, &sitem))) @@ -1692,6 +2076,70 @@ out_flushing: } } +#ifdef RVU_LIVESTREAMING_OPTIMIZATION +/*RVU patch : set buffering params*/ +static void +single_queue_set_stream_type (GstSingleQueue * squeue, GstBuffer * buffer) +{ + if (squeue->sq_stream_type == -1 && buffer) { + GstCaps *buffer_caps = NULL; + GstStructure *caps_str = NULL; + const gchar *mime_type = NULL; + const gchar *drm_stream_type = NULL; + struct timeval tv = { 0 }; + + do { + buffer_caps = gst_pad_get_current_caps (squeue->sinkpad); //GST_BUFFER_CAPS(buffer); + if (NULL == buffer_caps) { + GST_DEBUG_OBJECT (squeue->mqueue, "cannot get caps from single queue."); + break; + } + + GST_DEBUG_OBJECT (squeue->mqueue, "single queue caps %" GST_PTR_FORMAT, + buffer_caps); + + caps_str = gst_caps_get_structure (buffer_caps, 0); + if (NULL == caps_str) { + GST_DEBUG_OBJECT (squeue->mqueue, "cannot get structure from capse."); + break; + } + + mime_type = gst_structure_get_name (caps_str); + if (NULL == mime_type) { + GST_DEBUG_OBJECT (squeue->mqueue, + "cannot get mimetype from structure."); + break; + } + + drm_stream_type = gst_structure_get_string (caps_str, "stream-type"); + + if (g_strrstr (mime_type, "video/") || (drm_stream_type + && g_strrstr (drm_stream_type, "video/"))) { + squeue->sq_stream_type = SQ_VIDEO_STREAM; + /*subtitle stream */ + if (g_strrstr (mime_type, "video/x-dvb-subpicture")) + squeue->sq_stream_type = SQ_OTHER_STREAM; + + gettimeofday (&tv, NULL); + if (squeue->mqueue->buffering_start_time == 0) + squeue->mqueue->buffering_start_time = + GST_SECOND * (guint64) tv.tv_sec + + (guint64) tv.tv_usec * GST_USECOND; + } else if (g_strrstr (mime_type, "audio/") || (drm_stream_type + && g_strrstr (drm_stream_type, "audio/"))) { + squeue->sq_stream_type = SQ_AUDIO_STREAM; + gettimeofday (&tv, NULL); + if (squeue->mqueue->buffering_start_time == 0) + squeue->mqueue->buffering_start_time = + GST_SECOND * (guint64) tv.tv_sec + + (guint64) tv.tv_usec * GST_USECOND; + } else { + squeue->sq_stream_type = SQ_OTHER_STREAM; + } + } while (0); + } +} +#endif /** * gst_multi_queue_chain: * @@ -1711,6 +2159,11 @@ gst_multi_queue_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) sq = gst_pad_get_element_private (pad); mq = sq->mqueue; +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + if (mq->enable_buffering_opt) { + single_queue_set_stream_type (sq, buffer); + } +#endif /* if eos, we are always full, so avoid hanging incoming indefinitely */ if (sq->is_eos) goto was_eos; @@ -2463,6 +2916,9 @@ gst_single_queue_new (GstMultiQueue * mqueue, guint id) sq->sink_tainted = TRUE; sq->src_tainted = TRUE; +#ifdef TIZEN_FEATURE_TRUSTZONE + sq->sq_stream_type = -1; +#endif name = g_strdup_printf ("sink_%u", sq->id); sq->sinkpad = gst_pad_new_from_static_template (&sinktemplate, name); g_free (name); diff --git a/plugins/elements/gstmultiqueue.h b/plugins/elements/gstmultiqueue.h index d63eda5..28fd7e0 100644 --- a/plugins/elements/gstmultiqueue.h +++ b/plugins/elements/gstmultiqueue.h @@ -77,6 +77,16 @@ struct _GstMultiQueue { gboolean percent_changed; GMutex buffering_post_lock; /* assures only one posted at a time */ +#ifdef RVU_LIVESTREAMING_OPTIMIZATION + /*RVU patch - reset functionality & buffering optimization*/ + gboolean enable_buffering_opt; + guint64 buffering_start_time; + guint64 stream_duration; + GstDataQueueSize video_max_size, audio_max_size; + gboolean buffering_reset; + gboolean disable_audio_buffering; + gboolean enhancement_buffering; +#endif }; struct _GstMultiQueueClass {