rtph264depay: Complete merged AU on marker bit

The marker bit on a RTP packet means the AU has been completed, so push it out
immediately to reduce the latency.

https://bugzilla.gnome.org/show_bug.cgi?id=654850
This commit is contained in:
Olivier Crête 2011-07-18 16:46:27 -04:00 committed by Mark Nauwelaerts
parent 118a7cc36a
commit 2591a882ae

View file

@ -480,13 +480,34 @@ incomplete_caps:
} }
} }
static GstBuffer *
gst_rtp_h264_complete_au (GstRtpH264Depay * rtph264depay,
GstClockTime * out_timestamp, gboolean * out_keyframe)
{
guint outsize;
GstBuffer *outbuf;
/* we had a picture in the adapter and we completed it */
GST_DEBUG_OBJECT (rtph264depay, "taking completed AU");
outsize = gst_adapter_available (rtph264depay->picture_adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->picture_adapter, outsize);
*out_timestamp = rtph264depay->last_ts;
*out_keyframe = rtph264depay->last_keyframe;
rtph264depay->last_keyframe = FALSE;
rtph264depay->picture_start = FALSE;
return outbuf;
}
/* SPS/PPS/IDR considered key, all others DELTA; /* SPS/PPS/IDR considered key, all others DELTA;
* 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 gboolean
gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal, gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
GstClockTime in_timestamp) GstClockTime in_timestamp, gboolean marker)
{ {
GstBaseRTPDepayload *depayload = GST_BASE_RTP_DEPAYLOAD (rtph264depay); GstBaseRTPDepayload *depayload = GST_BASE_RTP_DEPAYLOAD (rtph264depay);
gint nal_type; gint nal_type;
@ -532,20 +553,9 @@ gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
} }
GST_DEBUG_OBJECT (depayload, "start %d, complete %d", start, complete); GST_DEBUG_OBJECT (depayload, "start %d, complete %d", start, complete);
if (complete && rtph264depay->picture_start) { if (complete && rtph264depay->picture_start)
guint outsize; outbuf = gst_rtp_h264_complete_au (rtph264depay, &out_timestamp,
&out_keyframe);
/* we had a picture in the adapter and we completed it */
GST_DEBUG_OBJECT (depayload, "taking completed AU");
outsize = gst_adapter_available (rtph264depay->picture_adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->picture_adapter, outsize);
out_timestamp = rtph264depay->last_ts;
out_keyframe = rtph264depay->last_keyframe;
rtph264depay->last_keyframe = FALSE;
rtph264depay->picture_start = FALSE;
}
/* add to adapter */ /* add to adapter */
GST_DEBUG_OBJECT (depayload, "adding NAL to picture adapter"); GST_DEBUG_OBJECT (depayload, "adding NAL to picture adapter");
@ -553,6 +563,10 @@ gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
rtph264depay->last_ts = in_timestamp; rtph264depay->last_ts = in_timestamp;
rtph264depay->last_keyframe |= keyframe; rtph264depay->last_keyframe |= keyframe;
rtph264depay->picture_start |= start; rtph264depay->picture_start |= start;
if (marker)
outbuf = gst_rtp_h264_complete_au (rtph264depay, &out_timestamp,
&out_keyframe);
} else { } else {
/* no merge, output is input nal */ /* no merge, output is input nal */
GST_DEBUG_OBJECT (depayload, "using NAL as output"); GST_DEBUG_OBJECT (depayload, "using NAL as output");
@ -615,11 +629,13 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
guint8 *outdata; guint8 *outdata;
guint outsize, nalu_size; guint outsize, nalu_size;
GstClockTime timestamp; GstClockTime timestamp;
gboolean marker;
timestamp = GST_BUFFER_TIMESTAMP (buf); timestamp = GST_BUFFER_TIMESTAMP (buf);
payload_len = gst_rtp_buffer_get_payload_len (buf); payload_len = gst_rtp_buffer_get_payload_len (buf);
payload = gst_rtp_buffer_get_payload (buf); payload = gst_rtp_buffer_get_payload (buf);
marker = gst_rtp_buffer_get_marker (buf);
GST_DEBUG_OBJECT (rtph264depay, "receiving %d bytes", payload_len); GST_DEBUG_OBJECT (rtph264depay, "receiving %d bytes", payload_len);
@ -703,7 +719,7 @@ 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); gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp, marker);
break; break;
} }
case 26: case 26:
@ -797,7 +813,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
outdata[2] = (outsize >> 8); outdata[2] = (outsize >> 8);
outdata[3] = (outsize); outdata[3] = (outsize);
} }
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp); gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
marker);
} }
break; break;
} }
@ -821,7 +838,7 @@ 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); gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp, marker);
break; break;
} }
} }