[FFmpeg-devel] [PATCH] libavformat/rtpdec_mpeg: handle bare ADTS packets with explicit decoder config
lance.lmwang at gmail.com
lance.lmwang at gmail.com
Mon Oct 18 04:28:50 EEST 2021
On Fri, Oct 01, 2021 at 06:53:23PM -0400, Jeff Mahoney wrote:
> When SDP specifies a decoder config, there may not be any AU headers
> provided by the sender. This can result in rtp_parse_mp4_au failing
> and aac_parse_packet reporting "Error parsing AU headers." and no audio
> is recovered from the stream.
>
> This commit modifies aac_parse_header to check for an explicit decoder config
> set by the sdp parser (e.g. a:fmtp # config=hexvalue). If it has and there
> is an ADTS header present, it skips the header and copies the RTP
> payload directly as an AAC packet.
>
> This resolves an issue observed with some inexpensive IP cameras.
>
> Signed-off-by: Jeff Mahoney <jeffm at jeffm.io>
> ---
> libavformat/rtpdec_mpeg4.c | 34 +++++++++++++++++++++++++++++++++-
> 1 file changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
> index 34c7950bcc..dd0ced790e 100644
> --- a/libavformat/rtpdec_mpeg4.c
> +++ b/libavformat/rtpdec_mpeg4.c
> @@ -176,7 +176,7 @@ static int aac_parse_packet(AVFormatContext *ctx, PayloadContext *data,
> int flags)
> {
> int ret;
> -
> + AVCodecParameters *par = st->codecpar;
>
> if (!buf) {
> if (data->cur_au_index > data->nb_au_headers) {
> @@ -204,6 +204,38 @@ static int aac_parse_packet(AVFormatContext *ctx, PayloadContext *data,
> return 1;
> }
>
> + /* Check for an explicit decoder config (e.g. SDP a:fmtp... config=) */
> + if (par->extradata && len > 7) {
> + /*
> + * Start of ADTS header - syncword
> + * If present skip the header and copy the entire payload as AAC data
> + */
> + if (buf[0] == 0xff && (buf[1] & 0xf0) == 0xf0) {
> + /*
> + * The ADTS header is 7 or 9 bytes depending on whether
> + * the protection absent bit is set. If it is unset, a 16-bit CRC
> + * is appended to the header.
> + */
> + size_t header_size = 7 + ((buf[1] & 0x01) ? 0 : 2);
> + if (len < header_size) {
> + ac_log(ctx, AV_LOG_ERROR, "Error parsing ADTS header\n");
> + return -1;
> + }
I prefer to use avpriv_adts_header_parse() for ADTS header parse.
> +
> + buf += header_size;
> + len -= header_size;
> +
> + if ((ret = av_new_packet(pkt, len)) < 0) {
> + av_log(ctx, AV_LOG_ERROR, "Out of memory\n");
> + return ret;
> + }
> + memcpy(pkt->data, buf, len);
> + pkt->stream_index = st->index;
> +
> + return 0;
> + }
> + }
> +
> if (rtp_parse_mp4_au(data, buf, len)) {
> av_log(ctx, AV_LOG_ERROR, "Error parsing AU headers\n");
> return -1;
> --
> 2.33.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
--
Thanks,
Limin Wang
More information about the ffmpeg-devel
mailing list