graphics/ffmpeg: avformat/aacdec: fix demuxing of small frames

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

graphics/ffmpeg: avformat/aacdec: fix demuxing of small frames

Jeremie Courreges-Anglas-2

I couldn't get mpv to read the .m4a files produced by my Android phone.

--8<--
ritchie ~$ file zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
zic/phone/France-Sunn-O)))-Stereolux.m4a: MPEG ADTS, AAC, v2 LC, 48 kHz, stereo
# Before:
ritchie ~/zic/phone$ mpv 'France-Sunn-O)))-Stereolux.m4a'
Playing: France-Sunn-O)))-Stereolux.m4a
[ffmpeg/demuxer] aac: Could not find codec parameters for stream 0 (Audio: aac, 0 channels, fltp): unspecified sample rate
[ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' and 'probesize' options
 (+) Audio --aid=1 (aac)
[lavf] error reading packet.
[lavf] error reading packet.
ritchie ~/zic/phone$
--8<--

sthen and I found those reports upstream:

  https://trac.ffmpeg.org/ticket/7869
  https://trac.ffmpeg.org/ticket/7271

Applying https://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
lets mpv play these files again.

-->8--
# After:
ritchie ~$ mpv zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
Playing: zic/phone/France-Sunn-O)))-Stereolux.m4a
[ffmpeg/audio] aac: Input buffer exhausted before END element found
[ffmpeg/demuxer] aac: Estimating duration from bitrate, this may be inaccurate
 (+) Audio --aid=1 (aac 2ch 48000Hz)
[ffmpeg/audio] aac: Input buffer exhausted before END element found
Error decoding audio.
AO: [sdl] 48000Hz stereo 2ch s32
A: 00:00:14 / 03:06:47 (0%)
-->8--


ok?


Index: Makefile
===================================================================
RCS file: /cvs/ports/graphics/ffmpeg/Makefile,v
retrieving revision 1.187
diff -u -p -r1.187 Makefile
--- Makefile 13 Jun 2019 21:03:55 -0000 1.187
+++ Makefile 27 Jun 2019 11:24:22 -0000
@@ -4,7 +4,7 @@ COMMENT= audio/video converter and strea
 
 V= 4.1.3
 DISTNAME= ffmpeg-${V}
-REVISION= 4
+REVISION= 5
 EPOCH= 0
 CATEGORIES= graphics multimedia
 MASTER_SITES= https://ffmpeg.org/releases/
Index: patches/patch-libavformat_aacdec_c
===================================================================
RCS file: patches/patch-libavformat_aacdec_c
diff -N patches/patch-libavformat_aacdec_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-libavformat_aacdec_c 27 Jun 2019 11:24:22 -0000
@@ -0,0 +1,76 @@
+$OpenBSD$
+
+From: James Almer <[hidden email]>
+Date: Thu, 25 Apr 2019 22:04:01 +0000 (-0300)
+Subject: avformat/aacdec: fix demuxing of small frames
+X-Git-Url: http://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
+
+avformat/aacdec: fix demuxing of small frames
+
+10 bytes (id3v2 header amount of bytes) were being read before any checks
+were made on the bitstream. The result was that we were overreading into
+the next frame if the current one was 8 or 9 bytes long.
+
+Fixes tickets #7271 and #7869.
+
+Signed-off-by: James Almer <[hidden email]>
+
+
+Index: libavformat/aacdec.c
+--- libavformat/aacdec.c.orig
++++ libavformat/aacdec.c
+@@ -20,6 +20,7 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+
++#include "libavutil/avassert.h"
+ #include "libavutil/intreadwrite.h"
+ #include "avformat.h"
+ #include "avio_internal.h"
+@@ -154,17 +155,8 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
+ {
+     int ret, fsize;
+
+-    // Parse all the ID3 headers between frames
+-    while (1) {
+-        ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE));
+-        if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
+-            if ((ret = handle_id3(s, pkt)) >= 0) {
+-                continue;
+-            }
+-        }
+-        break;
+-    }
+-
++retry:
++    ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);
+     if (ret < 0)
+         return ret;
+
+@@ -174,8 +166,24 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
+     }
+
+     if ((AV_RB16(pkt->data) >> 4) != 0xfff) {
+-        av_packet_unref(pkt);
+-        return AVERROR_INVALIDDATA;
++        // Parse all the ID3 headers between frames
++        int append = ID3v2_HEADER_SIZE - ADTS_HEADER_SIZE;
++
++        av_assert2(append > 0);
++        ret = av_append_packet(s->pb, pkt, append);
++        if (ret != append) {
++            av_packet_unref(pkt);
++            return AVERROR(EIO);
++        }
++        if (!ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
++            av_packet_unref(pkt);
++            return AVERROR_INVALIDDATA;
++        }
++        ret = handle_id3(s, pkt);
++        if (ret < 0)
++            return ret;
++
++        goto retry;
+     }
+
+     fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;


--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: graphics/ffmpeg: avformat/aacdec: fix demuxing of small frames

Stuart Henderson-6
OK sthen@.

On 2019/06/27 15:10, Jeremie Courreges-Anglas wrote:

>
> I couldn't get mpv to read the .m4a files produced by my Android phone.
>
> --8<--
> ritchie ~$ file zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
> zic/phone/France-Sunn-O)))-Stereolux.m4a: MPEG ADTS, AAC, v2 LC, 48 kHz, stereo
> # Before:
> ritchie ~/zic/phone$ mpv 'France-Sunn-O)))-Stereolux.m4a'
> Playing: France-Sunn-O)))-Stereolux.m4a
> [ffmpeg/demuxer] aac: Could not find codec parameters for stream 0 (Audio: aac, 0 channels, fltp): unspecified sample rate
> [ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' and 'probesize' options
>  (+) Audio --aid=1 (aac)
> [lavf] error reading packet.
> [lavf] error reading packet.
> ritchie ~/zic/phone$
> --8<--
>
> sthen and I found those reports upstream:
>
>   https://trac.ffmpeg.org/ticket/7869
>   https://trac.ffmpeg.org/ticket/7271
>
> Applying https://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
> lets mpv play these files again.
>
> -->8--
> # After:
> ritchie ~$ mpv zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
> Playing: zic/phone/France-Sunn-O)))-Stereolux.m4a
> [ffmpeg/audio] aac: Input buffer exhausted before END element found
> [ffmpeg/demuxer] aac: Estimating duration from bitrate, this may be inaccurate
>  (+) Audio --aid=1 (aac 2ch 48000Hz)
> [ffmpeg/audio] aac: Input buffer exhausted before END element found
> Error decoding audio.
> AO: [sdl] 48000Hz stereo 2ch s32
> A: 00:00:14 / 03:06:47 (0%)
> -->8--
>
>
> ok?
>
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/graphics/ffmpeg/Makefile,v
> retrieving revision 1.187
> diff -u -p -r1.187 Makefile
> --- Makefile 13 Jun 2019 21:03:55 -0000 1.187
> +++ Makefile 27 Jun 2019 11:24:22 -0000
> @@ -4,7 +4,7 @@ COMMENT= audio/video converter and strea
>  
>  V= 4.1.3
>  DISTNAME= ffmpeg-${V}
> -REVISION= 4
> +REVISION= 5
>  EPOCH= 0
>  CATEGORIES= graphics multimedia
>  MASTER_SITES= https://ffmpeg.org/releases/
> Index: patches/patch-libavformat_aacdec_c
> ===================================================================
> RCS file: patches/patch-libavformat_aacdec_c
> diff -N patches/patch-libavformat_aacdec_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libavformat_aacdec_c 27 Jun 2019 11:24:22 -0000
> @@ -0,0 +1,76 @@
> +$OpenBSD$
> +
> +From: James Almer <[hidden email]>
> +Date: Thu, 25 Apr 2019 22:04:01 +0000 (-0300)
> +Subject: avformat/aacdec: fix demuxing of small frames
> +X-Git-Url: http://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
> +
> +avformat/aacdec: fix demuxing of small frames
> +
> +10 bytes (id3v2 header amount of bytes) were being read before any checks
> +were made on the bitstream. The result was that we were overreading into
> +the next frame if the current one was 8 or 9 bytes long.
> +
> +Fixes tickets #7271 and #7869.
> +
> +Signed-off-by: James Almer <[hidden email]>
> +
> +
> +Index: libavformat/aacdec.c
> +--- libavformat/aacdec.c.orig
> ++++ libavformat/aacdec.c
> +@@ -20,6 +20,7 @@
> +  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> +  */
> +
> ++#include "libavutil/avassert.h"
> + #include "libavutil/intreadwrite.h"
> + #include "avformat.h"
> + #include "avio_internal.h"
> +@@ -154,17 +155,8 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
> + {
> +     int ret, fsize;
> +
> +-    // Parse all the ID3 headers between frames
> +-    while (1) {
> +-        ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE));
> +-        if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
> +-            if ((ret = handle_id3(s, pkt)) >= 0) {
> +-                continue;
> +-            }
> +-        }
> +-        break;
> +-    }
> +-
> ++retry:
> ++    ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);
> +     if (ret < 0)
> +         return ret;
> +
> +@@ -174,8 +166,24 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
> +     }
> +
> +     if ((AV_RB16(pkt->data) >> 4) != 0xfff) {
> +-        av_packet_unref(pkt);
> +-        return AVERROR_INVALIDDATA;
> ++        // Parse all the ID3 headers between frames
> ++        int append = ID3v2_HEADER_SIZE - ADTS_HEADER_SIZE;
> ++
> ++        av_assert2(append > 0);
> ++        ret = av_append_packet(s->pb, pkt, append);
> ++        if (ret != append) {
> ++            av_packet_unref(pkt);
> ++            return AVERROR(EIO);
> ++        }
> ++        if (!ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
> ++            av_packet_unref(pkt);
> ++            return AVERROR_INVALIDDATA;
> ++        }
> ++        ret = handle_id3(s, pkt);
> ++        if (ret < 0)
> ++            return ret;
> ++
> ++        goto retry;
> +     }
> +
> +     fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;
>
>
> --
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: graphics/ffmpeg: avformat/aacdec: fix demuxing of small frames

Brad Smith-14
In reply to this post by Jeremie Courreges-Anglas-2
OK.

On 6/27/2019 9:10 AM, Jeremie Courreges-Anglas wrote:

> I couldn't get mpv to read the .m4a files produced by my Android phone.
>
> --8<--
> ritchie ~$ file zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
> zic/phone/France-Sunn-O)))-Stereolux.m4a: MPEG ADTS, AAC, v2 LC, 48 kHz, stereo
> # Before:
> ritchie ~/zic/phone$ mpv 'France-Sunn-O)))-Stereolux.m4a'
> Playing: France-Sunn-O)))-Stereolux.m4a
> [ffmpeg/demuxer] aac: Could not find codec parameters for stream 0 (Audio: aac, 0 channels, fltp): unspecified sample rate
> [ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' and 'probesize' options
>   (+) Audio --aid=1 (aac)
> [lavf] error reading packet.
> [lavf] error reading packet.
> ritchie ~/zic/phone$
> --8<--
>
> sthen and I found those reports upstream:
>
>    https://trac.ffmpeg.org/ticket/7869
>    https://trac.ffmpeg.org/ticket/7271
>
> Applying https://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
> lets mpv play these files again.
>
> -->8--
> # After:
> ritchie ~$ mpv zic/phone/France-Sunn-O\)\)\)-Stereolux.m4a
> Playing: zic/phone/France-Sunn-O)))-Stereolux.m4a
> [ffmpeg/audio] aac: Input buffer exhausted before END element found
> [ffmpeg/demuxer] aac: Estimating duration from bitrate, this may be inaccurate
>   (+) Audio --aid=1 (aac 2ch 48000Hz)
> [ffmpeg/audio] aac: Input buffer exhausted before END element found
> Error decoding audio.
> AO: [sdl] 48000Hz stereo 2ch s32
> A: 00:00:14 / 03:06:47 (0%)
> -->8--
>
>
> ok?
>
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/graphics/ffmpeg/Makefile,v
> retrieving revision 1.187
> diff -u -p -r1.187 Makefile
> --- Makefile 13 Jun 2019 21:03:55 -0000 1.187
> +++ Makefile 27 Jun 2019 11:24:22 -0000
> @@ -4,7 +4,7 @@ COMMENT= audio/video converter and strea
>  
>   V= 4.1.3
>   DISTNAME= ffmpeg-${V}
> -REVISION= 4
> +REVISION= 5
>   EPOCH= 0
>   CATEGORIES= graphics multimedia
>   MASTER_SITES= https://ffmpeg.org/releases/
> Index: patches/patch-libavformat_aacdec_c
> ===================================================================
> RCS file: patches/patch-libavformat_aacdec_c
> diff -N patches/patch-libavformat_aacdec_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libavformat_aacdec_c 27 Jun 2019 11:24:22 -0000
> @@ -0,0 +1,76 @@
> +$OpenBSD$
> +
> +From: James Almer <[hidden email]>
> +Date: Thu, 25 Apr 2019 22:04:01 +0000 (-0300)
> +Subject: avformat/aacdec: fix demuxing of small frames
> +X-Git-Url: http://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=d88193c2196cf5342424aaa7a44b046c71c2527a
> +
> +avformat/aacdec: fix demuxing of small frames
> +
> +10 bytes (id3v2 header amount of bytes) were being read before any checks
> +were made on the bitstream. The result was that we were overreading into
> +the next frame if the current one was 8 or 9 bytes long.
> +
> +Fixes tickets #7271 and #7869.
> +
> +Signed-off-by: James Almer <[hidden email]>
> +
> +
> +Index: libavformat/aacdec.c
> +--- libavformat/aacdec.c.orig
> ++++ libavformat/aacdec.c
> +@@ -20,6 +20,7 @@
> +  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> +  */
> +
> ++#include "libavutil/avassert.h"
> + #include "libavutil/intreadwrite.h"
> + #include "avformat.h"
> + #include "avio_internal.h"
> +@@ -154,17 +155,8 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
> + {
> +     int ret, fsize;
> +
> +-    // Parse all the ID3 headers between frames
> +-    while (1) {
> +-        ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE));
> +-        if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
> +-            if ((ret = handle_id3(s, pkt)) >= 0) {
> +-                continue;
> +-            }
> +-        }
> +-        break;
> +-    }
> +-
> ++retry:
> ++    ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);
> +     if (ret < 0)
> +         return ret;
> +
> +@@ -174,8 +166,24 @@ static int adts_aac_read_packet(AVFormatContext *s, AV
> +     }
> +
> +     if ((AV_RB16(pkt->data) >> 4) != 0xfff) {
> +-        av_packet_unref(pkt);
> +-        return AVERROR_INVALIDDATA;
> ++        // Parse all the ID3 headers between frames
> ++        int append = ID3v2_HEADER_SIZE - ADTS_HEADER_SIZE;
> ++
> ++        av_assert2(append > 0);
> ++        ret = av_append_packet(s->pb, pkt, append);
> ++        if (ret != append) {
> ++            av_packet_unref(pkt);
> ++            return AVERROR(EIO);
> ++        }
> ++        if (!ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
> ++            av_packet_unref(pkt);
> ++            return AVERROR_INVALIDDATA;
> ++        }
> ++        ret = handle_id3(s, pkt);
> ++        if (ret < 0)
> ++            return ret;
> ++
> ++        goto retry;
> +     }
> +
> +     fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;
>
>