[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