[FFmpeg-trac] #9764(avcodec:new): MP3 decoding errors on ARMv4 hardware

FFmpeg trac at avcodec.org
Tue May 3 01:10:56 EEST 2022


#9764: MP3 decoding errors on ARMv4 hardware
-------------------------------------+-------------------------------------
             Reporter:  David        |                     Type:  defect
  Fletcher                           |
               Status:  new          |                 Priority:  normal
            Component:  avcodec      |                  Version:  git-
                                     |  master
             Keywords:               |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 Summary of the bug: There is distortion, especially for low bitrate
 stations, using the FFmpeg fixed point mp3 decoder on older (ARMv4)
 processors. This does not occur using the same configuration in x86 or
 more modern/capable ARM processors.

 The problem can be worked around using the libmad MP3 decoder which works
 perfectly on the ARMv4 processor (see patch [http://ffmpeg.org/pipermail
 /ffmpeg-devel/2022-May/295941.html]. But this just works around the issue
 rather than fixing it. I spent a lot of time looking at the fixed point
 math routines, especially libavcodec/arm/mpegaudiodsp_fixed_armv6.S. This
 is the main place there's ARM6 specific code - I wrote a new version of
 this for AMRv4 but it didn't fix the issue.

 == How to reproduce: ==

 I've made a demonstration of transcoding an MP3 radio stream and saving it
 to file. It is saved in the AU format (this is useful in my application,
 changing the output format does not solve the issue). Relevant files are
 in "mp3_decode_ARMv4_errors.tar.gz" uploaded to upload.ffmpeg.org.

 transcode_v4_ffmpeg.c - program to do the transcoding (Instructions to
 compile are at the top of this file. It makes use of static libraries for
 form a static binary. In the case of the ARMv4 hardware this is required
 as part of reducing binary size to get it onto the filesystem of the
 embedded board which has only 32MB storage, and 32MB RAM. I followed the
 same static route for the ARMv7 case - use of static libraries is not the
 issue).

 output_armv4t.au - output from the ARMv4 system - listenable, but poor
 quality
 output_arm7.au - output from the ARMv7 system - very good quality sound

 Below is debug output generated from both systems, and also the
 configuration used to compile the libraries. This differs between the
 systems as for ARM4 it's a cross-compilation on another machine, whereas
 for ARM7 the compiler exists on the same machine that the binary will run
 on.

 == Arm 7 implimentation: ==

 ./transcode_v4_ffmpeg
 [NULL @ 0xdcd260] Opening
 'http://stream.live.vc.bbcmedia.co.uk/bbc_world_service' for reading
 [http @ 0xdcd5c0] Setting default whitelist
 'http,https,tls,rtp,tcp,udp,crypto,httpproxy,data'
 [tcp @ 0xdd0130] Original list of addresses:
 [tcp @ 0xdd0130] Address 132.185.209.55 port 80
 [tcp @ 0xdd0130] Address 132.185.210.58 port 80
 [tcp @ 0xdd0130] Address 132.185.209.58 port 80
 [tcp @ 0xdd0130] Address 132.185.210.72 port 80
 [tcp @ 0xdd0130] Interleaved list of addresses:
 [tcp @ 0xdd0130] Address 132.185.209.55 port 80
 [tcp @ 0xdd0130] Address 132.185.210.58 port 80
 [tcp @ 0xdd0130] Address 132.185.209.58 port 80
 [tcp @ 0xdd0130] Address 132.185.210.72 port 80
 [tcp @ 0xdd0130] Starting connection attempt to 132.185.209.55 port 80
 [tcp @ 0xdd0130] Successfully connected to 132.185.209.55 port 80
 [http @ 0xdcd5c0] request: GET /bbc_world_service HTTP/1.1
 User-Agent: Lavf/LIBAVFORMAT_VERSION
 Accept: */*
 Range: bytes=0-
 Connection: close
 Host: stream.live.vc.bbcmedia.co.uk
 Icy-MetaData: 1


 [http @ 0xdcd5c0] Metadata update for StreamTitle: BBC World Service
 Online
 [mp3 @ 0xdcd260] Format mp3 probed with size=65536 and score=50
 [mp3 @ 0xdcd260] Skipping 28 bytes of junk at 0.
 [mp3 @ 0xdcd260] Before avformat_find_stream_info() pos: 28 bytes
 read:65679 seeks:0 nb_streams:1
 [mp3 @ 0xdcd260] All info found
 [mp3 @ 0xdcd260] After avformat_find_stream_info() pos: 9244 bytes
 read:65679 seeks:0 frames:50
 Input #0, mp3, from
 'http://stream.live.vc.bbcmedia.co.uk/bbc_world_service':
   Metadata:
     icy-br          : 56
     icy-pub         : 0
     icy-name        : BBC Radio
     icy-description : BBC Radio
     StreamTitle     : BBC World Service Online
   Duration: N/A, start: 0.000000, bitrate: 56 kb/s
   Stream #0:0, 50, 1/14112000: Audio: mp3, 24000 Hz, stereo, s16p, 56 kb/s
 Frame rate 1: 24000
 [file @ 0xde1000] Setting default whitelist 'file,crypto,data'
 [SWR @ 0xdfe350] Using s16p internally between filters
 Incoming bit rate: 14492400Frame rate: 24000

 (I noted that the incoming bit rate is shown incorrectly, while shown ok
 on the ARMv4 version. Probably something about 32bit of 64bit and the
 printf formatting)

 == Arm 4 implementation: ==


 ./transcode_v4_ffmpeg
 [NULL @ 0x187120] Opening
 'http://stream.live.vc.bbcmedia.co.uk/bbc_world_service' for reading
 [http @ 0x187470] Setting default whitelist
 'http,https,tls,rtp,tcp,udp,crypto,httpproxy,data'
 [tcp @ 0x189f50] Original list of addresses:
 [tcp @ 0x189f50] Address 132.185.209.59 port 80
 [tcp @ 0x189f50] Address 132.185.210.58 port 80
 [tcp @ 0x189f50] Address 132.185.209.71 port 80
 [tcp @ 0x189f50] Address 132.185.210.69 port 80
 [tcp @ 0x189f50] Interleaved list of addresses:
 [tcp @ 0x189f50] Address 132.185.209.59 port 80
 [tcp @ 0x189f50] Address 132.185.210.58 port 80
 [tcp @ 0x189f50] Address 132.185.209.71 port 80
 [tcp @ 0x189f50] Address 132.185.210.69 port 80
 [tcp @ 0x189f50] Starting connection attempt to 132.185.209.59 port 80
 [tcp @ 0x189f50] Successfully connected to 132.185.209.59 port 80
 [http @ 0x187470] request: GET /bbc_world_service HTTP/1.1
 User-Agent: Lavf/LIBAVFORMAT_VERSION
 Accept: */*
 Range: bytes=0-
 Connection: close
 Host: stream.live.vc.bbcmedia.co.uk
 Icy-MetaData: 1


 [http @ 0x187470] Metadata update for StreamTitle: BBC World Service
 Online
 [mp3 @ 0x187120] Format mp3 probed with size=65536 and score=50
 [mp3 @ 0x187120] Skipping 85 bytes of junk at 0.
 [mp3 @ 0x187120] Before avformat_find_stream_info() pos: 85 bytes
 read:65679 seeks:0 nb_streams:1
 [mp3 @ 0x187120] All info found
 [mp3 @ 0x187120] After avformat_find_stream_info() pos: 9301 bytes
 read:65679 seeks:0 frames:50
 Input #0, mp3, from
 'http://stream.live.vc.bbcmedia.co.uk/bbc_world_service':
   Metadata:
     icy-br          : 56
     icy-pub         : 0
     icy-name        : BBC Radio
     icy-description : BBC Radio
     StreamTitle     : BBC World Service Online
   Duration: N/A, start: 0.000000, bitrate: 56 kb/s
   Stream #0:0, 50, 1/14112000: Audio: mp3, 24000 Hz, stereo, s16p, 56 kb/s
 Frame rate 1: 24000
 [file @ 0x194020] Setting default whitelist 'file,crypto,data'
 [SWR @ 0x1ac220] Using s16p internally between filters
 Incoming bit rate: 56000Frame rate: 24000


 == Configuration of FFmpeg libraries ==

 FFmpeg version: ffmpeg-master-b67572c (current on 2nd May 2022)

 '''ARMv7 (native compilation on Raspberry Pi)'''

 ./configure --disable-everything --disable-avdevice --disable-swscale
 --disable-postproc --disable-avfilter --disable-encoders --enable-
 encoder='pcm_s16be,pcm_mulaw' --disable-filters --enable-shared --disable-
 muxers --enable-muxer=au --disable-bsfs --enable-bsf=remove_extradata
 --disable-decoders --enable-decoder=mp3 --disable-doc --disable-protocols
 --enable-protocol='http,file' --disable-demuxers --enable-
 demuxer='mp3,mpegts' --disable-parsers --disable-libxcb --disable-bzlib
 --disable-iconv --disable-lzma --disable-xlib --disable-zlib --disable-
 cuda --disable-cuvid --disable-nvenc --disable-vaapi --disable-vdpau
 --disable-libv4l2 --extra-cflags='-ffast-math' --disable-iconv --disable-
 linux-perf --disable-debug --enable-small --disable-vfp --disable-neon
 --enable-asm --enable-gpl --enable-nonfree

 ''Environment:''
 gcc version 10.2.1 20210110 (Raspbian 10.2.1-6+rpi1)
 Linux version 5.15.32-v7+
 Processor: RP3A0 - ARMv7 Processor rev 4 (v7l)


 '''ARMv4T (cross-compilation on Slackware linux)'''

 ./configure --disable-everything --disable-avdevice --disable-swscale
 --disable-postproc --disable-avfilter --disable-encoders --enable-
 encoder='pcm_s16be,pcm_mulaw' --disable-filters --enable-shared --disable-
 muxers --enable-muxer=au --disable-bsfs --enable-bsf=remove_extradata
 --disable-decoders --enable-decoder=mp3 --disable-doc --disable-protocols
 --enable-protocol='http,file' --disable-demuxers --enable-
 demuxer='mp3,mpegts' --disable-parsers --disable-libxcb --disable-bzlib
 --disable-iconv --disable-lzma --disable-xlib --disable-zlib --disable-
 cuda --disable-cuvid --disable-nvenc --disable-vaapi --disable-vdpau
 --disable-libv4l2 --extra-cflags='-ffast-math
 -I/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu/arm-9tdmi-
 linux-gnu/include/ -I/tmp/reciva/root/include/
 -I/tmp/reciva/root/usr/include/' --enable-cross-compile --cross-
 prefix=/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu/bin/arm-
 9tdmi-linux-gnu- --arch=armv4t --target-os=linux --prefix=/tmp/reciva/root
 --disable-iconv --tempprefix=/home/dif/tmp/ --pkg-config=/usr/bin/pkg-
 config --disable-linux-perf --disable-debug --enable-small --disable-vfp
 --disable-neon --enable-asm --enable-gpl --enable-nonfree

 ''Environment''
 gcc version 4.1.0
 Compilation machine: Linux version 2.4.22
 Target machine running code: Linux version 2.4.26-vrs1-bast2
 Processor: Arm920Tid(wb) rev 0 (v4l)

 ----

 Quite likely the ARMv4 version is using some code in FFmpeg that is very
 little used. ARMv4 has no floating point CPU, whereas ARM7 does - not both
 were configured to use the fixed point mp3 decoder (from reading the code
 this is a default unless you specifically ask for the floating point
 version).

 The cross-compilation environment is ancient (a consequence of the target
 system, the Reciva Radio platform being ~16-17 years old). But compilation
 runs without errors other than lines 123 of libavutil/error.c which throw
 an error about "wrong type of argument to unary minus" - this can be
 resolved by commenting out the offending line and making the function
 return -1. This has no effect on the primary mp3 decoding issue. Multiple
 other libraries compiled using the same cross-compilation system and also
 making machine code optimisations are working fine (wolfSSL, libmad, fdk-
 aac-free(libfdk-aac).

 There could be a compiler issue, but I think it's more likely something
 about the fixed point math routines used in FFmpeg. Working with version
 5.0.1 I got this issue, but all tests were repeated using git-master.
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9764>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list