[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