From f00c2b71557a5115a60a642244717d2ef7a3fc8e Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Tue, 20 May 2014 12:39:31 +0200 Subject: [PATCH] rtph264pay: propagate the GST_BUFFER_FLAG_DISCONT flag Similarly to what we did with the DELTA_UNIT flag, this patch propagates the DISCONT flag to the first RTP packet being used to transfer a DISCONT buffer. https://bugzilla.gnome.org/show_bug.cgi?id=730563 --- gst/rtp/gstrtph264pay.c | 54 +++++++++++++++++++++++++++++++++++------ gst/rtp/gstrtph264pay.h | 2 ++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index c7089effb6..3d835aebcc 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -167,6 +167,7 @@ gst_rtp_h264_pay_init (GstRtpH264Pay * rtph264pay) rtph264pay->last_spspps = -1; rtph264pay->spspps_interval = DEFAULT_CONFIG_INTERVAL; rtph264pay->delta_unit = FALSE; + rtph264pay->discont = FALSE; rtph264pay->adapter = gst_adapter_new (); } @@ -706,7 +707,7 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader, static GstFlowReturn gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au, - gboolean delta_unit); + gboolean delta_unit, gboolean discont); static GstFlowReturn gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload, @@ -723,7 +724,7 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload, GST_DEBUG_OBJECT (rtph264pay, "inserting SPS in the stream"); /* resend SPS */ ret = gst_rtp_h264_pay_payload_nal (basepayload, gst_buffer_ref (sps_buf), - dts, pts, FALSE, FALSE); + dts, pts, FALSE, FALSE, FALSE); /* Not critical here; but throw a warning */ if (ret != GST_FLOW_OK) { sent_all_sps_pps = FALSE; @@ -737,7 +738,7 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload, GST_DEBUG_OBJECT (rtph264pay, "inserting PPS in the stream"); /* resend PPS */ ret = gst_rtp_h264_pay_payload_nal (basepayload, gst_buffer_ref (pps_buf), - dts, pts, FALSE, FALSE); + dts, pts, FALSE, FALSE, FALSE); /* Not critical here; but throw a warning */ if (ret != GST_FLOW_OK) { sent_all_sps_pps = FALSE; @@ -752,11 +753,14 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload, } /* @delta_unit: if %FALSE the first packet sent won't have the - * GST_BUFFER_FLAG_DELTA_UNIT flag. */ + * GST_BUFFER_FLAG_DELTA_UNIT flag. + * @discont: if %TRUE the first packet sent will have the + * GST_BUFFER_FLAG_DISCONT flag. + */ static GstFlowReturn gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au, - gboolean delta_unit) + gboolean delta_unit, gboolean discont) { GstRtpH264Pay *rtph264pay; GstFlowReturn ret; @@ -854,6 +858,12 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, else GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + if (discont) { + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); + /* Only the first packet sent should have the flag */ + discont = FALSE; + } + gst_rtp_buffer_unmap (&rtp); /* insert payload memory block */ @@ -926,6 +936,12 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, else GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + if (discont) { + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); + /* Only the first packet sent should have the flag */ + discont = FALSE; + } + /* add the buffer to the buffer list */ gst_buffer_list_add (list, outbuf); @@ -958,6 +974,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, GstBuffer *paybuf = NULL; gsize skip; gboolean delayed_not_delta_unit = FALSE; + gboolean delayed_discont = FALSE; rtph264pay = GST_RTP_H264_PAY (basepayload); @@ -976,6 +993,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, dts = GST_BUFFER_DTS (buffer); rtph264pay->delta_unit = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); + rtph264pay->discont = GST_BUFFER_IS_DISCONT (buffer); GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size); } else { dts = gst_adapter_prev_dts (rtph264pay->adapter, NULL); @@ -991,6 +1009,16 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, delayed_not_delta_unit = TRUE; } + if (GST_BUFFER_IS_DISCONT (buffer)) { + if (gst_adapter_available (rtph264pay->adapter) == 0) + rtph264pay->discont = TRUE; + else + /* This buffer has the DISCONT flag but the adapter isn't empty. So + * we'll purge it first by sending a first packet and then the second + * one will have the DISCONT flag set. */ + delayed_discont = TRUE; + } + if (!GST_CLOCK_TIME_IS_VALID (dts)) dts = GST_BUFFER_DTS (buffer); if (!GST_CLOCK_TIME_IS_VALID (pts)) @@ -1054,12 +1082,16 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, nal_len); ret = gst_rtp_h264_pay_payload_nal (basepayload, paybuf, dts, pts, - end_of_au, rtph264pay->delta_unit); + end_of_au, rtph264pay->delta_unit, rtph264pay->discont); if (!rtph264pay->delta_unit) /* Only the first outgoing packet doesn't have the DELTA_UNIT flag */ rtph264pay->delta_unit = TRUE; + if (rtph264pay->discont) + /* Only the first outgoing packet have the DISCONT flag */ + rtph264pay->discont = FALSE; + if (ret != GST_FLOW_OK) break; @@ -1190,7 +1222,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, /* put the data in one or more RTP packets */ ret = gst_rtp_h264_pay_payload_nal (basepayload, paybuf, dts, pts, - end_of_au, rtph264pay->delta_unit); + end_of_au, rtph264pay->delta_unit, rtph264pay->discont); if (delayed_not_delta_unit) { rtph264pay->delta_unit = FALSE; @@ -1200,6 +1232,14 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, rtph264pay->delta_unit = TRUE; } + if (delayed_discont) { + rtph264pay->discont = TRUE; + delayed_discont = FALSE; + } else { + /* Only the first outgoing packet have the DISCONT flag */ + rtph264pay->discont = FALSE; + } + if (ret != GST_FLOW_OK) { break; } diff --git a/gst/rtp/gstrtph264pay.h b/gst/rtp/gstrtph264pay.h index 5881a5a0b5..44f7af4409 100644 --- a/gst/rtp/gstrtph264pay.h +++ b/gst/rtp/gstrtph264pay.h @@ -77,6 +77,8 @@ struct _GstRtpH264Pay /* TRUE if the next NALU processed should have the DELTA_UNIT flag */ gboolean delta_unit; + /* TRUE if the next NALU processed should have the DISCONT flag */ + gboolean discont; }; struct _GstRtpH264PayClass