diff --git a/gstplugins_bad/ext/hls/gsthlsdemux.c b/gstplugins_bad/ext/hls/gsthlsdemux.c index 23958cef1d5902c06c9b0bcad284775db39c9ec8..121e1800cdb6e69adb54dabccb72a9f5d1ebfbac 100644 --- a/gstplugins_bad/ext/hls/gsthlsdemux.c +++ b/gstplugins_bad/ext/hls/gsthlsdemux.c @@ -131,6 +131,7 @@ static gboolean gst_hls_demux_get_bitrate_info(GstAdaptiveDemux * demux, #ifdef OHOS_EXT_FUNC // ohos.ext.func.0042 report selectBitrateDone static gint gst_hls_demux_get_current_bandwidth (GstAdaptiveDemuxStream * stream); +static guint64 gst_hls_demux_get_current_position (GstAdaptiveDemuxStream * stream); #endif #define gst_hls_demux_parent_class parent_class @@ -207,6 +208,7 @@ gst_hls_demux_class_init (GstHLSDemuxClass * klass) #ifdef OHOS_EXT_FUNC // ohos.ext.func.0042 report selectBitrateDone adaptivedemux_class->get_current_bandwidth = gst_hls_demux_get_current_bandwidth; + adaptivedemux_class->get_current_position = gst_hls_demux_get_current_position; #endif GST_DEBUG_CATEGORY_INIT (gst_hls_demux_debug, "hlsdemux", 0, @@ -1253,6 +1255,17 @@ gst_hls_demux_get_current_bandwidth (GstAdaptiveDemuxStream * stream) return hlsdemux->current_variant->bandwidth; } } + +static guint64 +gst_hls_demux_get_current_position (GstAdaptiveDemuxStream * stream) +{ + guint64 position = 0; + GstM3U8 *m3u8 = gst_hls_demux_stream_get_m3u8 (GST_HLS_DEMUX_STREAM_CAST (stream)); + if (m3u8 != NULL) { + position = m3u8->sequence_position; + } + return position; +} #endif static void diff --git a/gstplugins_bad/ext/hls/m3u8.c b/gstplugins_bad/ext/hls/m3u8.c index 4c1fcfb4bad1a9ddc4bdc40bd89767a60a263042..4e9d419eec419fd99cb1aaf996170fa9ba9cd703 100644 --- a/gstplugins_bad/ext/hls/m3u8.c +++ b/gstplugins_bad/ext/hls/m3u8.c @@ -1025,7 +1025,7 @@ void gst_m3u8_advance_fragment_by_position(GstM3U8 * m3u8, GstClockTime position GST_DEBUG ("Sequence position was %" GST_TIME_FORMAT, GST_TIME_ARGS (m3u8->sequence_position)); GST_DEBUG ("Sequence sequence was %" G_GINT64_FORMAT, m3u8->sequence); - GST_DEBUG ("Sequence position set to %" GST_TIME_FORMAT, GST_TIME_ARGS (position)); + GST_WARNING ("Sequence position set to %" GST_TIME_FORMAT, GST_TIME_ARGS (position)); gboolean flag = m3u8->sequence_position < position; while (m3u8->sequence_position != position) { if (flag) { @@ -1067,9 +1067,9 @@ void gst_m3u8_advance_fragment_by_position(GstM3U8 * m3u8, GstClockTime position if (!forward) { m3u8->sequence_position -= m3u8->current_file_duration; } - GST_DEBUG ("current Sequence position %" GST_TIME_FORMAT, GST_TIME_ARGS (m3u8->sequence_position)); - GST_DEBUG ("current Sequence %" G_GINT64_FORMAT, m3u8->sequence); - GST_DEBUG ("current_file_duration %" GST_TIME_FORMAT, GST_TIME_ARGS (m3u8->current_file_duration)); + GST_WARNING ("current Sequence position %" GST_TIME_FORMAT, GST_TIME_ARGS (m3u8->sequence_position)); + GST_WARNING ("current Sequence %" G_GINT64_FORMAT, m3u8->sequence); + GST_WARNING ("current_file_duration %" GST_TIME_FORMAT, GST_TIME_ARGS (m3u8->current_file_duration)); GST_M3U8_UNLOCK (m3u8); } #endif diff --git a/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.c index b64d48b67fea1423523e6ccb2e70d607b85fbb39..36b51235355d6dc334c7e3a5b1d630b5943502cb 100644 --- a/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.c +++ b/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.c @@ -470,7 +470,7 @@ gst_adaptive_demux_set_property (GObject * object, guint prop_id, // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate case PROP_SLICE_POSITION: demux->slice_position = g_value_get_uint64 (value); - GST_DEBUG_OBJECT (demux, "slice_position set to %" G_GUINT64_FORMAT, demux->slice_position); + GST_WARNING_OBJECT (demux, "slice_position set to %" G_GUINT64_FORMAT, demux->slice_position); break; #endif #ifdef OHOS_EXT_FUNC @@ -2911,8 +2911,12 @@ gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, if (klass->get_current_bandwidth) { bandwidth = klass->get_current_bandwidth(stream); } + guint64 position = 0; + if (klass->get_current_position) { + position = klass->get_current_position(stream); + } gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_NOMINAL_BITRATE, stream->fragment.bitrate, GST_TAG_BANDWIDTH, bandwidth, GST_TAG_SLICE_POSITION, stream->segment.position, NULL); + GST_TAG_NOMINAL_BITRATE, stream->fragment.bitrate, GST_TAG_BANDWIDTH, bandwidth, GST_TAG_SLICE_POSITION, position, NULL); #else gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, GST_TAG_NOMINAL_BITRATE, stream->fragment.bitrate, NULL); diff --git a/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.h index 4403861ad47f36e95f4a7001210dd2cdc86ede68..93d548c6a3b1d0ff90d671936bb2c4d6f72ce8c1 100644 --- a/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.h +++ b/gstplugins_bad/gst-libs/gst/adaptivedemux/gstadaptivedemux.h @@ -418,6 +418,7 @@ struct _GstAdaptiveDemuxClass #ifdef OHOS_EXT_FUNC // ohos.ext.func.0042 report selectBitrateDone gint (*get_current_bandwidth) (GstAdaptiveDemuxStream * stream); + guint64 (*get_current_position) (GstAdaptiveDemuxStream * stream); #endif /** diff --git a/gstplugins_bad/gst/mpegtsdemux/tsdemux.c b/gstplugins_bad/gst/mpegtsdemux/tsdemux.c index fc029ef4d61b823a8826add1f537e33b61f3bf15..e647f11fc15aae83cfe89b4f70173dab7ebc27d7 100644 --- a/gstplugins_bad/gst/mpegtsdemux/tsdemux.c +++ b/gstplugins_bad/gst/mpegtsdemux/tsdemux.c @@ -1142,6 +1142,31 @@ push_event (MpegTSBase * base, GstEvent * event) for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { TSDemuxStream *stream = (TSDemuxStream *) tmp->data; + +#ifdef OHOS_EXT_FUNC + // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate + gboolean pending_data = FALSE; + if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { + GstTagList *tagList; + guint64 position; + gst_event_parse_tag (event, &tagList); + if (gst_tag_list_get_uint64 (tagList, GST_TAG_SLICE_POSITION, &position)) { + pending_data = TRUE; + } + } + + if (stream->pad) { + /* If we are pushing out EOS, flush out pending data first */ + if ((GST_EVENT_TYPE (event) == GST_EVENT_EOS || pending_data) && gst_pad_is_active (stream->pad)) + gst_ts_demux_push_pending_data (demux, stream, NULL); + + gst_event_ref (event); + if (pending_data) { + GST_WARNING_OBJECT (stream->pad, "bitrate switch pushing tag"); + } + gst_pad_push_event (stream->pad, event); + } +#else if (stream->pad) { /* If we are pushing out EOS, flush out pending data first */ if (GST_EVENT_TYPE (event) == GST_EVENT_EOS && @@ -1151,6 +1176,7 @@ push_event (MpegTSBase * base, GstEvent * event) gst_event_ref (event); gst_pad_push_event (stream->pad, event); } +#endif } gst_event_unref (event); diff --git a/gstreamer/plugins/elements/gstmultiqueue.c b/gstreamer/plugins/elements/gstmultiqueue.c index ed2c1a31fa8e979977b0a569299f50096159b8c3..6d22fdfd45b4050c61ba75f578a93db7334b858e 100644 --- a/gstreamer/plugins/elements/gstmultiqueue.c +++ b/gstreamer/plugins/elements/gstmultiqueue.c @@ -936,6 +936,7 @@ gst_multi_queue_init (GstMultiQueue * mqueue) mqueue->allow_bitrate = -1; mqueue->prev_position = GST_CLOCK_TIME_NONE; mqueue->position = GST_CLOCK_TIME_NONE; + g_mutex_init (&mqueue->m3u8_lock); #endif g_mutex_init (&mqueue->qlock); @@ -954,6 +955,10 @@ gst_multi_queue_finalize (GObject * object) /* free/unref instance data */ g_mutex_clear (&mqueue->qlock); g_mutex_clear (&mqueue->buffering_post_lock); +#ifdef OHOS_EXT_FUNC + // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate + g_mutex_clear (&mqueue->m3u8_lock); +#endif G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -1062,7 +1067,7 @@ gst_multi_queue_set_property (GObject * object, guint prop_id, recheck_buffering_status (mq); break; #ifdef OHOS_EXT_FUNC -// ohos.ext.func.0013 + // ohos.ext.func.0013 case PROP_MQ_NUM_ID: mq->mq_num_id = g_value_get_uint (value); break; @@ -1201,9 +1206,11 @@ gst_multi_queue_get_property (GObject * object, guint prop_id, #ifdef OHOS_EXT_FUNC // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate case PROP_SLICE_POSITION: + g_mutex_lock (&mq->m3u8_lock); mq->prev_position = mq->position; g_value_set_uint64 (value, mq->position); - GST_INFO_OBJECT (mq, "position is %" G_GUINT64_FORMAT, mq->position); + GST_INFO_OBJECT (mq, "get next bitrate position is %" G_GUINT64_FORMAT, mq->position); + g_mutex_unlock (&mq->m3u8_lock); break; #endif case PROP_STATS: @@ -2112,9 +2119,11 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq, #ifdef OHOS_EXT_FUNC // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate if (sq->drop_mode) { - GST_DEBUG_OBJECT (mq, - "SingleQueue %d : Dropping data %p with ts %" GST_TIME_FORMAT, - sq->id, buffer, GST_TIME_ARGS (timestamp)); + if (mq->allow_bitrate != -1) { + GST_WARNING_OBJECT (mq, + "SingleQueue %d : Dropping data %p with ts %" GST_TIME_FORMAT, + sq->id, buffer, GST_TIME_ARGS (timestamp)); + } gst_buffer_unref (buffer); } else if (G_UNLIKELY (*allow_drop)) { GST_DEBUG_OBJECT (mq, @@ -2122,9 +2131,11 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq, sq->id, buffer, GST_TIME_ARGS (timestamp)); gst_buffer_unref (buffer); } else { - GST_DEBUG_OBJECT (mq, - "SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT, - sq->id, buffer, GST_TIME_ARGS (timestamp)); + if (mq->allow_bitrate != -1) { + GST_DEBUG_OBJECT (mq, + "SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT, + sq->id, buffer, GST_TIME_ARGS (timestamp)); + } result = gst_pad_push (srcpad, buffer); } #else @@ -2358,32 +2369,40 @@ next: #ifdef OHOS_EXT_FUNC // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate if (GST_IS_EVENT (object) && GST_EVENT_TYPE (GST_EVENT_CAST (object)) == GST_EVENT_TAG) { - GST_DEBUG_OBJECT (mq, "SingleQueue %d pop tag: %" GST_PTR_FORMAT, sq->id, GST_EVENT_CAST (object)); + GST_WARNING_OBJECT (mq, "SingleQueue %d pop tag: %" GST_PTR_FORMAT, sq->id, GST_EVENT_CAST (object)); GstTagList *tagList; guint bandwidth; guint64 position; + g_mutex_lock (&mq->m3u8_lock); gst_event_parse_tag(GST_EVENT_CAST (object), &tagList); - if (gst_tag_list_get_uint(tagList, GST_TAG_BANDWIDTH, &bandwidth) && - gst_tag_list_get_uint64(tagList, GST_TAG_SLICE_POSITION, &position)) { + if (gst_tag_list_get_uint (tagList, GST_TAG_BANDWIDTH, &bandwidth) && + gst_tag_list_get_uint64 (tagList, GST_TAG_SLICE_POSITION, &position)) { if (mq->allow_bitrate != -1) { - GST_DEBUG_OBJECT (mq, "bandwidth is %u", bandwidth); - GST_DEBUG_OBJECT (mq, "position is %" G_GUINT64_FORMAT, position); + GST_WARNING_OBJECT (mq, "bandwidth is %u", bandwidth); + GST_WARNING_OBJECT (mq, "position is %" G_GUINT64_FORMAT, position); if (bandwidth == mq->allow_bitrate || - (bandwidth == mq->prev_allow_bitrate && position == mq->prev_position)) { - GST_DEBUG_OBJECT (mq, "drop mode set to FALSE"); + (bandwidth == mq->prev_allow_bitrate && mq->prev_position != GST_CLOCK_TIME_NONE && + position <= mq->prev_position)) { + GST_WARNING_OBJECT (mq, "drop mode set to FALSE"); sq->drop_mode = FALSE; } else { - GST_DEBUG_OBJECT (mq, "drop mode set to TRUE"); + GST_WARNING_OBJECT (mq, "drop mode set to TRUE"); sq->drop_mode = TRUE; - gst_object_unref(object); + gst_event_unref (GST_EVENT_CAST (object)); + g_mutex_unlock (&mq->m3u8_lock); return; } } if (!sq->drop_mode) { - mq->position = position; - GST_DEBUG_OBJECT (mq, "slice-position is %" G_GUINT64_FORMAT, mq->position); + if (mq->position != GST_CLOCK_TIME_NONE) { + mq->position = position > mq->position ? position : mq->position; + } else { + mq->position = position; + } + GST_WARNING_OBJECT (mq, "slice-position is %" G_GUINT64_FORMAT, mq->position); } } + g_mutex_unlock (&mq->m3u8_lock); } #endif @@ -2874,6 +2893,14 @@ gst_multi_queue_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) res = gst_pad_push_event (srcpad, event); +#ifdef OHOS_EXT_FUNC + // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate + // flush position + g_mutex_lock (&mq->m3u8_lock); + mq->position = GST_CLOCK_TIME_NONE; + g_mutex_unlock (&mq->m3u8_lock); + GST_WARNING_OBJECT (mq, "Flush start, clean m3u8 position"); +#endif gst_single_queue_flush (mq, sq, TRUE, FALSE); gst_single_queue_pause (mq, sq); goto done; diff --git a/gstreamer/plugins/elements/gstmultiqueue.h b/gstreamer/plugins/elements/gstmultiqueue.h index a471ea82d0538cf2516c597b0c8f1585c2feef63..5c2b29eaff53c839b588e54d13fc12b2d24b5b30 100644 --- a/gstreamer/plugins/elements/gstmultiqueue.h +++ b/gstreamer/plugins/elements/gstmultiqueue.h @@ -100,6 +100,7 @@ struct _GstMultiQueue { // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate gint prev_allow_bitrate; gint allow_bitrate; + GMutex m3u8_lock; guint64 prev_position; guint64 position; #endif