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; }