summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2014-05-06 17:42:14 +0200
committerWim Taymans <wtaymans@redhat.com>2014-06-19 12:22:38 +0200
commit4be99ec7d54a49a99b5cfd50c036b15c22dc54cd (patch)
tree59825a65c48c11fe7c96c4e1d79cf1b19f5dc813 /gst
parent42ff6423728b4453aa8761e0753471a255421c3b (diff)
downloadgstreamer-plugins-good-4be99ec7d54a49a99b5cfd50c036b15c22dc54cd.tar.gz
rtph264pay: propagate the GST_BUFFER_FLAG_DELTA_UNIT flag
Downstream elements may be interested knowing if a RTP packet is the start of a key frame (to implement a RTP extension as defined in the ONVIF Streaming Spec for example). We do this by checking the GST_BUFFER_FLAG_DELTA_UNIT flag we receive from upstream and propagate it to the *first* RTP packet outputted to transfer this buffer. https://bugzilla.gnome.org/show_bug.cgi?id=730563
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/gstrtph264pay.c56
-rw-r--r--gst/rtp/gstrtph264pay.h3
2 files changed, 53 insertions, 6 deletions
diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c
index 7c6c821a5..c7089effb 100644
--- a/gst/rtp/gstrtph264pay.c
+++ b/gst/rtp/gstrtph264pay.c
@@ -166,6 +166,7 @@ gst_rtp_h264_pay_init (GstRtpH264Pay * rtph264pay)
(GDestroyNotify) gst_buffer_unref);
rtph264pay->last_spspps = -1;
rtph264pay->spspps_interval = DEFAULT_CONFIG_INTERVAL;
+ rtph264pay->delta_unit = FALSE;
rtph264pay->adapter = gst_adapter_new ();
}
@@ -704,7 +705,8 @@ 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);
+ GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au,
+ gboolean delta_unit);
static GstFlowReturn
gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
@@ -721,7 +723,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);
+ dts, pts, FALSE, FALSE);
/* Not critical here; but throw a warning */
if (ret != GST_FLOW_OK) {
sent_all_sps_pps = FALSE;
@@ -735,7 +737,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);
+ dts, pts, FALSE, FALSE);
/* Not critical here; but throw a warning */
if (ret != GST_FLOW_OK) {
sent_all_sps_pps = FALSE;
@@ -749,9 +751,12 @@ gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
return ret;
}
+/* @delta_unit: if %FALSE the first packet sent won't have the
+ * GST_BUFFER_FLAG_DELTA_UNIT flag. */
static GstFlowReturn
gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
- GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au)
+ GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au,
+ gboolean delta_unit)
{
GstRtpH264Pay *rtph264pay;
GstFlowReturn ret;
@@ -843,6 +848,12 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
GST_BUFFER_PTS (outbuf) = pts;
GST_BUFFER_DTS (outbuf) = dts;
+ if (!delta_unit)
+ /* Only the first packet sent should not have the flag */
+ delta_unit = TRUE;
+ else
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+
gst_rtp_buffer_unmap (&rtp);
/* insert payload memory block */
@@ -909,6 +920,12 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
gst_buffer_copy_region (paybuf, GST_BUFFER_COPY_MEMORY, pos,
limitedSize));
+ if (!delta_unit)
+ /* Only the first packet sent should not have the flag */
+ delta_unit = TRUE;
+ else
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+
/* add the buffer to the buffer list */
gst_buffer_list_add (list, outbuf);
@@ -940,6 +957,7 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
gboolean avc;
GstBuffer *paybuf = NULL;
gsize skip;
+ gboolean delayed_not_delta_unit = FALSE;
rtph264pay = GST_RTP_H264_PAY (basepayload);
@@ -956,11 +974,23 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
size = map.size;
pts = GST_BUFFER_PTS (buffer);
dts = GST_BUFFER_DTS (buffer);
+ rtph264pay->delta_unit = GST_BUFFER_FLAG_IS_SET (buffer,
+ GST_BUFFER_FLAG_DELTA_UNIT);
GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size);
} else {
dts = gst_adapter_prev_dts (rtph264pay->adapter, NULL);
pts = gst_adapter_prev_pts (rtph264pay->adapter, NULL);
if (buffer) {
+ if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
+ if (gst_adapter_available (rtph264pay->adapter) == 0)
+ rtph264pay->delta_unit = FALSE;
+ else
+ /* This buffer contains a key frame but the adapter isn't empty. So
+ * we'll purge it first by sending a first packet and then the second
+ * one won't have the DELTA_UNIT flag. */
+ delayed_not_delta_unit = TRUE;
+ }
+
if (!GST_CLOCK_TIME_IS_VALID (dts))
dts = GST_BUFFER_DTS (buffer);
if (!GST_CLOCK_TIME_IS_VALID (pts))
@@ -1024,7 +1054,12 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
nal_len);
ret =
gst_rtp_h264_pay_payload_nal (basepayload, paybuf, dts, pts,
- end_of_au);
+ end_of_au, rtph264pay->delta_unit);
+
+ if (!rtph264pay->delta_unit)
+ /* Only the first outgoing packet doesn't have the DELTA_UNIT flag */
+ rtph264pay->delta_unit = TRUE;
+
if (ret != GST_FLOW_OK)
break;
@@ -1155,7 +1190,16 @@ 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);
+ end_of_au, rtph264pay->delta_unit);
+
+ if (delayed_not_delta_unit) {
+ rtph264pay->delta_unit = FALSE;
+ delayed_not_delta_unit = FALSE;
+ } else {
+ /* Only the first outgoing packet doesn't have the DELTA_UNIT flag */
+ rtph264pay->delta_unit = TRUE;
+ }
+
if (ret != GST_FLOW_OK) {
break;
}
diff --git a/gst/rtp/gstrtph264pay.h b/gst/rtp/gstrtph264pay.h
index e1f6c7f1a..5881a5a0b 100644
--- a/gst/rtp/gstrtph264pay.h
+++ b/gst/rtp/gstrtph264pay.h
@@ -74,6 +74,9 @@ struct _GstRtpH264Pay
guint spspps_interval;
gboolean send_spspps;
GstClockTime last_spspps;
+
+ /* TRUE if the next NALU processed should have the DELTA_UNIT flag */
+ gboolean delta_unit;
};
struct _GstRtpH264PayClass