[FFmpeg-devel] [PATCH] libavformat/rtpdec_mpeg: handle bare ADTS packets with explicit decoder config

Jeff Mahoney jeffm at jeffm.io
Tue Oct 19 17:10:48 EEST 2021


On 10/17/21 21:28, lance.lmwang at gmail.com wrote:
> 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.


Thanks, Lance.  This wasn't in the master branch when I posted this.
It's much cleaner and I'm happy to adapt to it.

-Jeff

>> +
>> +            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".
> 


-- 
Jeff Mahoney


More information about the ffmpeg-devel mailing list