[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