mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
rtph264depay: Cope with FU-A E bit not being set
Some h264 payloaders are unfortunately buggy and don't correctly set the E bit in FU-A NAL when they have ended. Work around this by assuming such a fragmentation unit has ended when there was no packet loss and a new NAL is started
This commit is contained in:
parent
89564fcb69
commit
4c73439ee3
2 changed files with 56 additions and 19 deletions
|
@ -168,6 +168,7 @@ gst_rtp_h264_depay_reset (GstRtpH264Depay * rtph264depay)
|
||||||
rtph264depay->picture_start = FALSE;
|
rtph264depay->picture_start = FALSE;
|
||||||
rtph264depay->last_keyframe = FALSE;
|
rtph264depay->last_keyframe = FALSE;
|
||||||
rtph264depay->last_ts = 0;
|
rtph264depay->last_ts = 0;
|
||||||
|
rtph264depay->current_fu_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -606,6 +607,35 @@ short_nal:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 *
|
static GstBuffer *
|
||||||
gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -619,6 +649,7 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
if (GST_BUFFER_IS_DISCONT (buf)) {
|
if (GST_BUFFER_IS_DISCONT (buf)) {
|
||||||
gst_adapter_clear (rtph264depay->adapter);
|
gst_adapter_clear (rtph264depay->adapter);
|
||||||
rtph264depay->wait_start = TRUE;
|
rtph264depay->wait_start = TRUE;
|
||||||
|
rtph264depay->current_fu_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -659,6 +690,13 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
GST_DEBUG_OBJECT (rtph264depay, "NRI %d, Type %d", nal_ref_idc,
|
GST_DEBUG_OBJECT (rtph264depay, "NRI %d, Type %d", nal_ref_idc,
|
||||||
nal_unit_type);
|
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) {
|
switch (nal_unit_type) {
|
||||||
case 0:
|
case 0:
|
||||||
case 30:
|
case 30:
|
||||||
|
@ -758,6 +796,15 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
/* NAL unit starts here */
|
/* NAL unit starts here */
|
||||||
guint8 nal_header;
|
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;
|
rtph264depay->wait_start = FALSE;
|
||||||
|
|
||||||
/* reconstruct NAL header */
|
/* reconstruct NAL header */
|
||||||
|
@ -796,26 +843,11 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
gst_adapter_push (rtph264depay->adapter, outbuf);
|
gst_adapter_push (rtph264depay->adapter, outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtph264depay->fu_marker = marker;
|
||||||
|
|
||||||
/* if NAL unit ends, flush the adapter */
|
/* if NAL unit ends, flush the adapter */
|
||||||
if (E) {
|
if (E)
|
||||||
GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
|
gst_rtp_h264_push_fragmentation_unit (rtph264depay);
|
||||||
|
|
||||||
outsize = gst_adapter_available (rtph264depay->adapter);
|
|
||||||
outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
|
|
||||||
outdata = GST_BUFFER_DATA (outbuf);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -56,6 +56,11 @@ struct _GstRtpH264Depay
|
||||||
gboolean picture_start;
|
gboolean picture_start;
|
||||||
GstClockTime last_ts;
|
GstClockTime last_ts;
|
||||||
gboolean last_keyframe;
|
gboolean last_keyframe;
|
||||||
|
|
||||||
|
/* Work around broken payloaders wrt. FU-A & FU-B */
|
||||||
|
guint8 current_fu_type;
|
||||||
|
GstClockTime fu_timestamp;
|
||||||
|
gboolean fu_marker;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRtpH264DepayClass
|
struct _GstRtpH264DepayClass
|
||||||
|
|
Loading…
Reference in a new issue