summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-04-15 10:21:56 (GMT)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-04-30 11:50:03 (GMT)
commit6bf7f5cfd3d7bf5e9bd923bad948fa45ca795d72 (patch)
tree2140c8b99418b0447744797d06f18b52cd6858e2
parent0206b67b1dad066472e6557f6ada167a91c8ea6f (diff)
rtph264depay: DELTA_UNIT marking of output buffers
... which evidently makes (most) sense if output buffers are actually frames. Partially based on a patch by Miguel Angel Cabrera <mad_aluche at hotmail.com> Fixes #609658.
-rw-r--r--gst/rtp/gstrtph264depay.c43
-rw-r--r--gst/rtp/gstrtph264depay.h1
2 files changed, 44 insertions, 0 deletions
diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c
index 3223dcb..a50141b 100644
--- a/gst/rtp/gstrtph264depay.c
+++ b/gst/rtp/gstrtph264depay.c
@@ -399,6 +399,31 @@ incomplete_caps:
}
}
+/* nal must have writable meta-data,
+ * returns TRUE if delta unit */
+static gboolean
+gst_rtp_h264_depay_mark_delta (GstRtpH264Depay * rtph264depay, GstBuffer * nal)
+{
+ gint nal_unit_type;
+ gboolean res = FALSE;
+
+ if (G_UNLIKELY (GST_BUFFER_SIZE (nal) < 5))
+ return FALSE;
+
+ nal_unit_type = (GST_BUFFER_DATA (nal))[4] & 0x1f;
+ GST_DEBUG_OBJECT (rtph264depay, "type %d", nal_unit_type);
+ /* non-IDR VCL layer NAL considered DELTA */
+ if (nal_unit_type >= 1 && nal_unit_type <= 4) {
+ GST_BUFFER_FLAG_SET (nal, GST_BUFFER_FLAG_DELTA_UNIT);
+ res = TRUE;
+ } else {
+ GST_BUFFER_FLAG_UNSET (nal, GST_BUFFER_FLAG_DELTA_UNIT);
+ }
+
+ return res;
+}
+
+/* nal must have writable meta-data */
static GstBuffer *
gst_rtp_h264_depay_push_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
GstClockTime timestamp)
@@ -441,6 +466,7 @@ gst_rtp_h264_depay_push_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
if (rtph264depay->picture_complete) {
outsize = gst_adapter_available (rtph264depay->picture_adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->picture_adapter, outsize);
+ outbuf = gst_buffer_make_metadata_writable (outbuf);
rtph264depay->picture_complete = FALSE;
rtph264depay->picture_start = start;
@@ -453,9 +479,17 @@ gst_rtp_h264_depay_push_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
if (GST_CLOCK_TIME_IS_VALID (timestamp) &&
GST_CLOCK_TIME_IS_VALID (rtph264depay->last_ts))
GST_BUFFER_DURATION (outbuf) = timestamp - rtph264depay->last_ts;
+
+ if (rtph264depay->last_delta)
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+ else
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+ rtph264depay->last_delta = FALSE;
}
rtph264depay->last_ts = timestamp;
+ rtph264depay->last_delta = rtph264depay->last_delta ||
+ gst_rtp_h264_depay_mark_delta (rtph264depay, nal);
gst_adapter_push (rtph264depay->picture_adapter, nal);
return outbuf;
@@ -585,6 +619,9 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (!rtph264depay->merge) {
outsize = gst_adapter_available (rtph264depay->adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
+ outbuf = gst_buffer_make_metadata_writable (outbuf);
+
+ gst_rtp_h264_depay_mark_delta (rtph264depay, outbuf);
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
return outbuf;
}
@@ -670,6 +707,7 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outsize = gst_adapter_available (rtph264depay->adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
+ outbuf = gst_buffer_make_metadata_writable (outbuf);
outdata = GST_BUFFER_DATA (outbuf);
if (rtph264depay->byte_stream) {
@@ -694,6 +732,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outbuf = gst_rtp_h264_depay_push_nal (rtph264depay, outbuf, ts);
if (!outbuf)
break;
+ } else {
+ gst_rtp_h264_depay_mark_delta (rtph264depay, outbuf);
}
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
@@ -733,6 +773,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outbuf = gst_rtp_h264_depay_push_nal (rtph264depay, outbuf, ts);
if (!outbuf)
break;
+ } else {
+ gst_rtp_h264_depay_mark_delta (rtph264depay, outbuf);
}
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
@@ -781,6 +823,7 @@ gst_rtp_h264_depay_change_state (GstElement * element,
gst_adapter_clear (rtph264depay->picture_adapter);
rtph264depay->picture_start = FALSE;
rtph264depay->picture_complete = FALSE;
+ rtph264depay->last_delta = FALSE;
break;
default:
break;
diff --git a/gst/rtp/gstrtph264depay.h b/gst/rtp/gstrtph264depay.h
index e1fda3f..431d8d2 100644
--- a/gst/rtp/gstrtph264depay.h
+++ b/gst/rtp/gstrtph264depay.h
@@ -56,6 +56,7 @@ struct _GstRtpH264Depay
gboolean picture_start;
gboolean picture_complete;
GstClockTime last_ts;
+ gboolean last_delta;
};
struct _GstRtpH264DepayClass