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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5940>
This commit is contained in:
Guillaume Desmottes 2024-01-18 16:54:22 +01:00
parent 632ee523fb
commit fae6fbaa6b

View file

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