From 6bf7f5cfd3d7bf5e9bd923bad948fa45ca795d72 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 15 Apr 2010 12:21:56 +0200 Subject: 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 Fixes #609658. --- gst/rtp/gstrtph264depay.c | 43 +++++++++++++++++++++++++++++++++++++++++++ gst/rtp/gstrtph264depay.h | 1 + 2 files changed, 44 insertions(+) diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c index 3223dcba3..a50141bed 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 e1fda3ffd..431d8d219 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 -- cgit v1.2.3