From fae6fbaa6b8a32ef7cad3ad40c9d77bb2c3694cc Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Thu, 18 Jan 2024 16:54:22 +0100 Subject: [PATCH] flvdemux: don't re-use segment from one stream if the other has buffer earlier Fix first audio buffers being out of segment because the audio stream is starting earlier than the video one which was the first demuxed. Part-of: --- .../gst-plugins-good/gst/flv/gstflvdemux.c | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c b/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c index 52e3f26b8a..184d987e79 100644 --- a/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c +++ b/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c @@ -1125,9 +1125,32 @@ gst_flv_demux_sync_streams (GstFlvDemux * demux) } } -static void +/* ensure demux->new_seg_event is set, (re)creating it if required. + * + * Returns: TRUE if the previous segment has been replaced and should be sent on the + * other stream pad as well. +*/ +static gboolean ensure_new_segment (GstFlvDemux * demux, GstPad * pad) { + gboolean replaced_previous_segment = FALSE; + + if (demux->new_seg_event) { + const GstSegment *segment; + + gst_event_parse_segment (demux->new_seg_event, &segment); + if (demux->segment.position < segment->start) { + GST_DEBUG_OBJECT (pad, + "position is out of current segment boundaries, generate a new one"); + g_clear_pointer (&demux->new_seg_event, gst_event_unref); + /* re-sending the segment on the other stream will create a GAP but + * this will only happen at the very beginning of the stream so it's + * not that bad. + */ + replaced_previous_segment = TRUE; + } + } + if (!demux->new_seg_event) { GST_DEBUG_OBJECT (pad, "pushing newsegment from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT, @@ -1140,6 +1163,8 @@ ensure_new_segment (GstFlvDemux * demux, GstPad * pad) } else { GST_DEBUG_OBJECT (pad, "pushing pre-generated newsegment event"); } + + return replaced_previous_segment; } static GstFlowReturn @@ -1382,9 +1407,21 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer) /* Do we need a newsegment event ? */ if (G_UNLIKELY (demux->audio_need_segment)) { - ensure_new_segment (demux, demux->audio_pad); + gboolean replaced_video_segment; + + replaced_video_segment = ensure_new_segment (demux, demux->audio_pad); gst_pad_push_event (demux->audio_pad, gst_event_ref (demux->new_seg_event)); + if (replaced_video_segment) { + GST_DEBUG_OBJECT (demux->video_pad, "updating segment from %" + GST_TIME_FORMAT " to %" GST_TIME_FORMAT, + GST_TIME_ARGS (demux->segment.position), + GST_TIME_ARGS (demux->segment.stop)); + + gst_pad_push_event (demux->video_pad, + gst_event_ref (demux->new_seg_event)); + } + demux->audio_need_segment = FALSE; } @@ -1847,9 +1884,21 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer) /* Do we need a newsegment event ? */ if (G_UNLIKELY (demux->video_need_segment)) { - ensure_new_segment (demux, demux->video_pad); + gboolean replaced_audio_segment; + + replaced_audio_segment = ensure_new_segment (demux, demux->video_pad); gst_pad_push_event (demux->video_pad, gst_event_ref (demux->new_seg_event)); + if (replaced_audio_segment) { + GST_DEBUG_OBJECT (demux->audio_pad, "updating segment from %" + GST_TIME_FORMAT " to %" GST_TIME_FORMAT, + GST_TIME_ARGS (demux->segment.position), + GST_TIME_ARGS (demux->segment.stop)); + + gst_pad_push_event (demux->audio_pad, + gst_event_ref (demux->new_seg_event)); + } + demux->video_need_segment = FALSE; }