rtpgstpay: Delay pushing of event packets until the next buffer

And also re-timestamp them with the current buffer's PTS.

Not doing so keeps the timestamps of event packets as
GST_CLOCK_TIME_NONE or the timestamp of the previous buffer, both of
which are bogus.

Making sure that (especially) the first packet has a valid timestamp
allows putting e.g. the NTP timestamp RTP header extension on it.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5173>
This commit is contained in:
Sebastian Dröge 2023-08-11 13:06:24 +03:00 committed by GStreamer Marge Bot
parent 37578454b9
commit b88d69b722
2 changed files with 21 additions and 17 deletions

View file

@ -182,7 +182,6 @@ gst_rtp_gst_pay_reset (GstRtpGSTPay * rtpgstpay, gboolean full)
rtpgstpay->current_CV = 0; rtpgstpay->current_CV = 0;
rtpgstpay->next_CV = 0; rtpgstpay->next_CV = 0;
} }
rtpgstpay->received_buffer = FALSE;
} }
static void static void
@ -366,6 +365,16 @@ gst_rtp_gst_pay_create_from_adapter (GstRtpGSTPay * rtpgstpay,
return TRUE; return TRUE;
} }
static gboolean
retimestamp_buffer (GstBuffer ** buffer, guint idx, gpointer user_data)
{
GstClockTime *timestamp = user_data;
GST_BUFFER_PTS (*buffer) = *timestamp;
return TRUE;
}
static GstFlowReturn static GstFlowReturn
gst_rtp_gst_pay_flush (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp) gst_rtp_gst_pay_flush (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp)
{ {
@ -373,13 +382,14 @@ gst_rtp_gst_pay_flush (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp)
gst_rtp_gst_pay_create_from_adapter (rtpgstpay, timestamp); gst_rtp_gst_pay_create_from_adapter (rtpgstpay, timestamp);
if (!rtpgstpay->received_buffer) {
GST_DEBUG_OBJECT (rtpgstpay,
"Can't flush without having received a buffer yet");
return GST_FLOW_OK;
}
if (rtpgstpay->pending_buffers) { if (rtpgstpay->pending_buffers) {
// make sure all buffers in the buffer list have the correct timestamp.
// If we created packets based on an event they would have
// GST_CLOCK_TIME_NONE as PTS.
gst_buffer_list_foreach (rtpgstpay->pending_buffers, retimestamp_buffer,
&timestamp);
/* push the whole buffer list at once */ /* push the whole buffer list at once */
ret = gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpgstpay), ret = gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpgstpay),
rtpgstpay->pending_buffers); rtpgstpay->pending_buffers);
@ -584,12 +594,10 @@ gst_rtp_gst_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
GST_DEBUG_OBJECT (rtpgstpay, "make event type %d for %s", GST_DEBUG_OBJECT (rtpgstpay, "make event type %d for %s",
etype, GST_EVENT_TYPE_NAME (event)); etype, GST_EVENT_TYPE_NAME (event));
gst_rtp_gst_pay_send_event (rtpgstpay, etype, event); gst_rtp_gst_pay_send_event (rtpgstpay, etype, event);
/* Do not send stream-start right away since caps/new-segment were not yet // do not flush events here yet as they would get no timestamp at all or
sent, so our data would be considered invalid */ // the timestamp of the previous buffer, both of which are bogus. We need
if (etype != 4) { // to wait until the next actual input frame to know the timestamp that
/* flush the adapter immediately */ // applies to the event.
gst_rtp_gst_pay_flush (rtpgstpay, GST_CLOCK_TIME_NONE);
}
} }
gst_event_unref (event); gst_event_unref (event);
@ -654,8 +662,6 @@ gst_rtp_gst_pay_handle_buffer (GstRTPBasePayload * basepayload,
rtpgstpay = GST_RTP_GST_PAY (basepayload); rtpgstpay = GST_RTP_GST_PAY (basepayload);
rtpgstpay->received_buffer = TRUE;
timestamp = GST_BUFFER_PTS (buffer); timestamp = GST_BUFFER_PTS (buffer);
running_time = running_time =
gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME, gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME,

View file

@ -57,8 +57,6 @@ struct _GstRtpGSTPay
guint config_interval; guint config_interval;
GstClockTime last_config; GstClockTime last_config;
gboolean force_config; gboolean force_config;
gboolean received_buffer;
}; };
struct _GstRtpGSTPayClass struct _GstRtpGSTPayClass