rtph264depay: improve downstream flow return feedback to upstream

... although basertpdepay does not really make it easy/possible to do so
all the way.
This commit is contained in:
Mark Nauwelaerts 2011-09-20 13:38:53 +02:00
parent 82927d6bdd
commit fd757890eb

View file

@ -506,7 +506,7 @@ gst_rtp_h264_complete_au (GstRtpH264Depay * rtph264depay,
* so downstream waiting for keyframe can pick up at SPS/PPS/IDR */ * so downstream waiting for keyframe can pick up at SPS/PPS/IDR */
#define NAL_TYPE_IS_KEY(nt) (((nt) == 5) || ((nt) == 7) || ((nt) == 8)) #define NAL_TYPE_IS_KEY(nt) (((nt) == 5) || ((nt) == 7) || ((nt) == 8))
static gboolean static GstBuffer *
gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal, gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
GstClockTime in_timestamp, gboolean marker) GstClockTime in_timestamp, gboolean marker)
{ {
@ -592,23 +592,22 @@ gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
gst_base_rtp_depayload_push (depayload, outbuf);
} }
return TRUE; return outbuf;
/* ERRORS */ /* ERRORS */
short_nal: short_nal:
{ {
GST_WARNING_OBJECT (depayload, "dropping short NAL"); GST_WARNING_OBJECT (depayload, "dropping short NAL");
gst_buffer_unref (nal); gst_buffer_unref (nal);
return FALSE; return NULL;
} }
} }
static void static GstBuffer *
gst_rtp_h264_push_fragmentation_unit (GstRtpH264Depay * rtph264depay) gst_rtp_h264_push_fragmentation_unit (GstRtpH264Depay * rtph264depay,
gboolean send)
{ {
guint outsize; guint outsize;
guint8 *outdata; guint8 *outdata;
@ -630,17 +629,26 @@ gst_rtp_h264_push_fragmentation_unit (GstRtpH264Depay * rtph264depay)
outdata[3] = (outsize); outdata[3] = (outsize);
} }
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf,
rtph264depay->fu_timestamp, rtph264depay->fu_marker);
rtph264depay->current_fu_type = 0; rtph264depay->current_fu_type = 0;
if (send) {
outbuf = gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf,
rtph264depay->fu_timestamp, rtph264depay->fu_marker);
if (outbuf)
gst_base_rtp_depayload_push (GST_BASE_RTP_DEPAYLOAD (rtph264depay),
outbuf);
return NULL;
} else {
return gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf,
rtph264depay->fu_timestamp, rtph264depay->fu_marker);
}
} }
static GstBuffer * static GstBuffer *
gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
{ {
GstRtpH264Depay *rtph264depay; GstRtpH264Depay *rtph264depay;
GstBuffer *outbuf; GstBuffer *outbuf = NULL;
guint8 nal_unit_type; guint8 nal_unit_type;
rtph264depay = GST_RTP_H264_DEPAY (depayload); rtph264depay = GST_RTP_H264_DEPAY (depayload);
@ -695,7 +703,7 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
* when the FU ended) and send out what we gathered thusfar */ * when the FU ended) and send out what we gathered thusfar */
if (G_UNLIKELY (rtph264depay->current_fu_type != 0 && if (G_UNLIKELY (rtph264depay->current_fu_type != 0 &&
nal_unit_type != rtph264depay->current_fu_type)) nal_unit_type != rtph264depay->current_fu_type))
gst_rtp_h264_push_fragmentation_unit (rtph264depay); gst_rtp_h264_push_fragmentation_unit (rtph264depay, TRUE);
switch (nal_unit_type) { switch (nal_unit_type) {
case 0: case 0:
@ -757,7 +765,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outsize = gst_adapter_available (rtph264depay->adapter); outsize = gst_adapter_available (rtph264depay->adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize); outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp, marker); outbuf = gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
marker);
break; break;
} }
case 26: case 26:
@ -800,7 +809,7 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
* Assume that the remote payloader is buggy (doesn't set the end * Assume that the remote payloader is buggy (doesn't set the end
* bit) and send out what we've gathered thusfar */ * bit) and send out what we've gathered thusfar */
if (G_UNLIKELY (rtph264depay->current_fu_type != 0)) if (G_UNLIKELY (rtph264depay->current_fu_type != 0))
gst_rtp_h264_push_fragmentation_unit (rtph264depay); gst_rtp_h264_push_fragmentation_unit (rtph264depay, TRUE);
rtph264depay->current_fu_type = nal_unit_type; rtph264depay->current_fu_type = nal_unit_type;
rtph264depay->fu_timestamp = timestamp; rtph264depay->fu_timestamp = timestamp;
@ -843,11 +852,12 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
gst_adapter_push (rtph264depay->adapter, outbuf); gst_adapter_push (rtph264depay->adapter, outbuf);
} }
outbuf = NULL;
rtph264depay->fu_marker = marker; rtph264depay->fu_marker = marker;
/* if NAL unit ends, flush the adapter */ /* if NAL unit ends, flush the adapter */
if (E) if (E)
gst_rtp_h264_push_fragmentation_unit (rtph264depay); outbuf = gst_rtp_h264_push_fragmentation_unit (rtph264depay, FALSE);
break; break;
} }
default: default:
@ -870,13 +880,14 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outdata += sizeof (sync_bytes); outdata += sizeof (sync_bytes);
memcpy (outdata, payload, nalu_size); memcpy (outdata, payload, nalu_size);
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp, marker); outbuf = gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
marker);
break; break;
} }
} }
} }
return NULL; return outbuf;
/* ERRORS */ /* ERRORS */
undefined_type: undefined_type: