rtph264depay->picture_start = FALSE;
rtph264depay->last_keyframe = FALSE;
rtph264depay->last_ts = 0;
+ rtph264depay->current_fu_type = 0;
}
static void
}
}
+static void
+gst_rtp_h264_push_fragmentation_unit (GstRtpH264Depay * rtph264depay)
+{
+ guint outsize;
+ guint8 *outdata;
+ GstBuffer *outbuf;
+
+ outsize = gst_adapter_available (rtph264depay->adapter);
+ outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
+ outdata = GST_BUFFER_DATA (outbuf);
+
+ GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
+
+ if (rtph264depay->byte_stream) {
+ memcpy (outdata, sync_bytes, sizeof (sync_bytes));
+ } else {
+ outsize -= 4;
+ outdata[0] = (outsize >> 24);
+ outdata[1] = (outsize >> 16);
+ outdata[2] = (outsize >> 8);
+ outdata[3] = (outsize);
+ }
+
+ gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf,
+ rtph264depay->fu_timestamp, rtph264depay->fu_marker);
+
+ rtph264depay->current_fu_type = 0;
+}
+
static GstBuffer *
gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
{
if (GST_BUFFER_IS_DISCONT (buf)) {
gst_adapter_clear (rtph264depay->adapter);
rtph264depay->wait_start = TRUE;
+ rtph264depay->current_fu_type = 0;
}
{
GST_DEBUG_OBJECT (rtph264depay, "NRI %d, Type %d", nal_ref_idc,
nal_unit_type);
+ /* If FU unit was being processed, but the current nal is of a different
+ * type. Assume that the remote payloader is buggy (didn't set the end bit
+ * when the FU ended) and send out what we gathered thusfar */
+ if (G_UNLIKELY (rtph264depay->current_fu_type != 0 &&
+ nal_unit_type != rtph264depay->current_fu_type))
+ gst_rtp_h264_push_fragmentation_unit (rtph264depay);
+
switch (nal_unit_type) {
case 0:
case 30:
/* NAL unit starts here */
guint8 nal_header;
+ /* If a new FU unit started, while still processing an older one.
+ * Assume that the remote payloader is buggy (doesn't set the end
+ * bit) and send out what we've gathered thusfar */
+ if (G_UNLIKELY (rtph264depay->current_fu_type != 0))
+ gst_rtp_h264_push_fragmentation_unit (rtph264depay);
+
+ rtph264depay->current_fu_type = nal_unit_type;
+ rtph264depay->fu_timestamp = timestamp;
+
rtph264depay->wait_start = FALSE;
/* reconstruct NAL header */
gst_adapter_push (rtph264depay->adapter, outbuf);
}
- /* if NAL unit ends, flush the adapter */
- if (E) {
- GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
-
- outsize = gst_adapter_available (rtph264depay->adapter);
- outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
- outdata = GST_BUFFER_DATA (outbuf);
+ rtph264depay->fu_marker = marker;
- if (rtph264depay->byte_stream) {
- memcpy (outdata, sync_bytes, sizeof (sync_bytes));
- } else {
- outsize -= 4;
- outdata[0] = (outsize >> 24);
- outdata[1] = (outsize >> 16);
- outdata[2] = (outsize >> 8);
- outdata[3] = (outsize);
- }
- gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
- marker);
- }
+ /* if NAL unit ends, flush the adapter */
+ if (E)
+ gst_rtp_h264_push_fragmentation_unit (rtph264depay);
break;
}
default: