rtpmp4gdepay: detect broken senders who send AAC with ADTS frames

Strip ADTS headers if we detect any, apparently some Sony cameras
send AAC with ADTS headers. We could also change the stream-format
in the output caps, but that would be unexpected to pipeline builders
and would not exactly be backwards compatible.
This commit is contained in:
Tim-Philipp Müller 2018-09-21 19:47:44 +01:00
parent f255ea99f4
commit 506e080a15
2 changed files with 24 additions and 0 deletions

View file

@ -233,11 +233,14 @@ gst_rtp_mp4g_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
clock_rate = 90000; /* default */
depayload->clock_rate = clock_rate;
rtpmp4gdepay->check_adts = FALSE;
if ((str = gst_structure_get_string (structure, "media"))) {
if (strcmp (str, "audio") == 0) {
srccaps = gst_caps_new_simple ("audio/mpeg",
"mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "raw",
NULL);
rtpmp4gdepay->check_adts = TRUE;
} else if (strcmp (str, "video") == 0) {
srccaps = gst_caps_new_simple ("video/mpeg",
"mpegversion", G_TYPE_INT, 4,
@ -664,11 +667,30 @@ gst_rtp_mp4g_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
gst_adapter_push (rtpmp4gdepay->adapter, outbuf);
if (M) {
guint32 v = 0;
guint avail;
/* packet is complete, flush */
avail = gst_adapter_available (rtpmp4gdepay->adapter);
/* Some broken senders send ADTS headers (e.g. some Sony cameras).
* Try to detect those and skip them (still needs config set), but
* don't check every frame, only the first (unless we detect ADTS) */
if (rtpmp4gdepay->check_adts && avail >= 7) {
if (gst_adapter_masked_scan_uint32_peek (rtpmp4gdepay->adapter,
0xfffe0000, 0xfff00000, 0, 4, &v) == 0) {
guint adts_hdr_len = (((v >> 16) & 0x1) == 0) ? 9 : 7;
if (avail > adts_hdr_len) {
GST_WARNING_OBJECT (rtpmp4gdepay, "Detected ADTS header of "
"%u bytes, skipping", adts_hdr_len);
gst_adapter_flush (rtpmp4gdepay->adapter, adts_hdr_len);
avail -= adts_hdr_len;
}
} else {
rtpmp4gdepay->check_adts = FALSE;
}
}
outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail);
/* copy some of the fields we calculated above on the buffer. We also

View file

@ -67,6 +67,8 @@ struct _GstRtpMP4GDepay
guint32 prev_rtptime;
guint prev_AU_num;
gboolean check_adts; /* check for ADTS headers */
GQueue *packets;
GstAdapter *adapter;