Opened 6 months ago
#11561 new defect
libavformat/demux.c avformat_find_stream_info returns incorrect sample format
| Reported by: | keks51 | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | avcodec |
| Version: | 7.1 | Keywords: | MP3 mp2 demuxer ffprobe codecpar format |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the bug:
libavformat/demux.c avformat_find_stream_info returns AVFormatContext with streams[i]->codecpar->format = fltp but decodes frames with s16p
How to reproduce:
% ffmpeg -f lavfi -i "aevalsrc='(sin(100*2*PI*t)):d=10'" res.mp2 % ffprobe -show_frames res.mp2 | grep sample_fmt ffprobe version 7.1.1 Copyright (c) 2007-2025 the FFmpeg developers built with Apple clang version 16.0.0 (clang-1600.0.26.6) configuration: ... libavutil 59. 39.100 / 59. 39.100 libavcodec 61. 19.101 / 61. 19.101 libavformat 61. 7.100 / 61. 7.100 libavdevice 61. 3.100 / 61. 3.100 libavfilter 10. 4.100 / 10. 4.100 libswscale 8. 3.100 / 8. 3.100 libswresample 5. 3.100 / 5. 3.100 libpostproc 58. 3.100 / 58. 3.100 [mp3 @ 0x155004fd0] Estimating duration from bitrate, this may be inaccurate Input #0, mp3, from 'res.mp2': Duration: 00:00:10.00, start: 0.000000, bitrate: 383 kb/s Stream #0:0: Audio: mp2 (mp3float), 44100 Hz, mono, fltp, 384 kb/s sample_fmt=s16p sample_fmt=s16p
The reason.
avformat_find_stream_info steps:
1.https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l2507
2.https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l2575
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l91
- codecs are chosen from libavcodec/codec_list.c. This file is generated based on https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavcodec/allcodecs.c#l503
- Since codec_id is AV_CODEC_ID_MP3 ff_mp3float_decoder is returned. Not ff_mp3_decoder despite they have the same codec_id AV_CODEC_ID_MP3. This is important for the following explanation
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l2693
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l1450
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavcodec/parser.c#l163
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavcodec/mpegaudio_parser.c#l73
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavcodec/mpegaudiodecheader.c#l134
- decoder was changed from MP3 to MP2. This is important.
- avformat_find_stream_info returns codec_id = MP2 sample_format=fltp
Decode frames steps:
- Find decoder for MP2
- https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavformat/demux.c#l91
- codecs are chosen from libavcodec/codec_list.c. This file is generated based on https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/refs/heads/master:/libavcodec/allcodecs.c#l500
- Since codec_id is AV_CODEC_ID_MP2 ff_mp2_decoder is returned. Not ff_mp2float_decoder despite they have the same codec_id AV_CODEC_ID_MP2.
- Decoding frames with sample_format=s16p
Is there any reason to keep different codecs order for mp3 and mp2?
Solution. Reorder mp3 decoder in the same order as mp2. For example
...
499 extern const FFCodec ff_mp2_encoder;
500 extern const FFCodec ff_mp2_decoder;
501 extern const FFCodec ff_mp2float_decoder;
502 extern const FFCodec ff_mp2fixed_encoder;
# was
503 extern const FFCodec ff_mp3float_decoder;
504 extern const FFCodec ff_mp3_decoder;
# reordered
504 extern const FFCodec ff_mp3_decoder;
503 extern const FFCodec ff_mp3float_decoder;
505 extern const FFCodec ff_mp3adufloat_decoder;
506 extern const FFCodec ff_mp3adu_decoder;
507 extern const FFCodec ff_mp3on4float_decoder;
508 extern const FFCodec ff_mp3on4_decoder;
509 extern const FFCodec ff_mpc7_decoder;
510 extern const FFCodec ff_mpc8_decoder;
...


