flvmux: use the correct timestamp to calculate wait times

Since c0bf793c05 ("flvmux: Set PTS based on
running time") the timestamp of the output buffer is already in running
time. So using that for 'srcpad->segment.position' does not work correctly
because gst_aggregator_simple_get_next_time() will convert it again with
gst_segment_to_running_time().
This means that the timestamp returned by
gst_aggregator_simple_get_next_time() may be incorrect. For example, if
flvmux is added to a already runinng pipeline then the timestamp is too
small and gst_aggregator_wait_and_check() returns immediately. As a result,
buffers may be muxed in the wrong order.

To fix this, use the PTS of the incoming buffer instead of the outgoing
buffer. Also add the duration as get_next_time() is supposed to return the
timestamp of the next buffer, not the current one.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4701>
This commit is contained in:
Michael Olbrich 2023-05-24 16:17:46 +02:00 committed by GStreamer Marge Bot
parent a15a16c99b
commit 2197cdc289

View file

@ -801,12 +801,6 @@ gst_flv_mux_release_pad (GstElement * element, GstPad * pad)
static GstFlowReturn static GstFlowReturn
gst_flv_mux_push (GstFlvMux * mux, GstBuffer * buffer) gst_flv_mux_push (GstFlvMux * mux, GstBuffer * buffer)
{ {
GstAggregator *agg = GST_AGGREGATOR (mux);
GstAggregatorPad *srcpad = GST_AGGREGATOR_PAD (agg->srcpad);
if (GST_BUFFER_PTS_IS_VALID (buffer))
srcpad->segment.position = GST_BUFFER_PTS (buffer);
/* pushing the buffer that rewrites the header will make it no longer be the /* pushing the buffer that rewrites the header will make it no longer be the
* total output size in bytes, but it doesn't matter at that point */ * total output size in bytes, but it doesn't matter at that point */
mux->byte_count += gst_buffer_get_size (buffer); mux->byte_count += gst_buffer_get_size (buffer);
@ -1660,6 +1654,8 @@ gst_flv_mux_write_buffer (GstFlvMux * mux, GstFlvMuxPad * pad,
{ {
GstBuffer *tag; GstBuffer *tag;
GstFlowReturn ret; GstFlowReturn ret;
GstClockTime pts = GST_BUFFER_PTS (buffer);
GstClockTime duration = GST_BUFFER_DURATION (buffer);
GstClockTime dts = GstClockTime dts =
gst_flv_mux_segment_to_running_time (&GST_AGGREGATOR_PAD (pad)->segment, gst_flv_mux_segment_to_running_time (&GST_AGGREGATOR_PAD (pad)->segment,
GST_BUFFER_DTS (buffer)); GST_BUFFER_DTS (buffer));
@ -1678,6 +1674,14 @@ gst_flv_mux_write_buffer (GstFlvMux * mux, GstFlvMuxPad * pad,
if (ret == GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (dts)) if (ret == GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (dts))
pad->last_timestamp = dts; pad->last_timestamp = dts;
if (ret == GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (pts)) {
GstAggregator *agg = GST_AGGREGATOR (mux);
GstAggregatorPad *srcpad = GST_AGGREGATOR_PAD (agg->srcpad);
srcpad->segment.position = pts;
if (GST_CLOCK_TIME_IS_VALID (duration))
srcpad->segment.position += duration;
}
return ret; return ret;
} }