#6216 closed defect (fixed)
TrueHD encoder creates non bitexact files
Reported by: | James | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | avcodec |
Version: | git-master | Keywords: | thd |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Summary of the bug:
How to reproduce:
./ffmpeg -i truehd.wav -f md5 - ffmpeg version N-83737-g68ee800a9d Copyright (c) 2000-2017 the FFmpeg developers built with gcc 6.3.0 (Rev2, Built by MSYS2 project) configuration: --enable-gpl --enable-nonfree --enable-libx264 --enable-libx265 --enable-libfdk_aac --enable-libvpx --enable-libmp3lame --enable-libvorbis --enable-libopus --target-os=mingw32 --arch=x86_64 --cpu=haswell --extra-cflags='-D_WIN32_WINNT=0x0602' --cc='ccache gcc' --samples=../samples --prefix=/mingw64 libavutil 55. 47.101 / 55. 47.101 libavcodec 57. 82.100 / 57. 82.100 libavformat 57. 66.103 / 57. 66.103 libavdevice 57. 3.100 / 57. 3.100 libavfilter 6. 74.100 / 6. 74.100 libswscale 4. 3.101 / 4. 3.101 libswresample 2. 4.100 / 2. 4.100 libpostproc 54. 2.100 / 54. 2.100 Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, wav, from 'truehd.wav': Metadata: encoder : Lavf57.66.103 Duration: 00:00:02.02, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help Output #0, md5, to 'pipe:': Metadata: encoder : Lavf57.66.103 Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s Metadata: encoder : Lavc57.82.100 pcm_s16le MD5=d886c9feaf7dddcdff3a5adcfa4c57bc size= 0kB time=00:00:02.02 bitrate= 0.1kbits/s speed= 952x video:0kB audio:348kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
% ./ffmpeg -i truehd.wav -c:a truehd -strict -2 truehd.thd ffmpeg version N-83737-g68ee800a9d Copyright (c) 2000-2017 the FFmpeg developers built with gcc 6.3.0 (Rev2, Built by MSYS2 project) configuration: --enable-gpl --enable-nonfree --enable-libx264 --enable-libx265 --enable-libfdk_aac --enable-libvpx --enable-libmp3lame --enable-libvorbis --enable-libopus --target-os=mingw32 --arch=x86_64 --cpu=haswell --extra-cflags='-D_WIN32_WINNT=0x0602' --cc='ccache gcc' --samples=../samples --prefix=/mingw64 libavutil 55. 47.101 / 55. 47.101 libavcodec 57. 82.100 / 57. 82.100 libavformat 57. 66.103 / 57. 66.103 libavdevice 57. 3.100 / 57. 3.100 libavfilter 6. 74.100 / 6. 74.100 libswscale 4. 3.101 / 4. 3.101 libswresample 2. 4.100 / 2. 4.100 libpostproc 54. 2.100 / 54. 2.100 Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, wav, from 'truehd.wav': Metadata: encoder : Lavf57.66.103 Duration: 00:00:02.02, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> truehd (native)) Press [q] to stop, [?] for help Output #0, truehd, to 'truehd.thd': Metadata: encoder : Lavf57.66.103 Stream #0:0: Audio: truehd, 44100 Hz, stereo, s16, 128 kb/s Metadata: encoder : Lavc57.82.100 truehd size= 57kB time=00:00:02.02 bitrate= 231.8kbits/s speed= 103x video:0kB audio:57kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
./ffmpeg -i truehd.thd -f md5 - ffmpeg version N-83737-g68ee800a9d Copyright (c) 2000-2017 the FFmpeg developers built with gcc 6.3.0 (Rev2, Built by MSYS2 project) configuration: --enable-gpl --enable-nonfree --enable-libx264 --enable-libx265 --enable-libfdk_aac --enable-libvpx --enable-libmp3lame --enable-libvorbis --enable-libopus --target-os=mingw32 --arch=x86_64 --cpu=haswell --extra-cflags='-D_WIN32_WINNT=0x0602' --cc='ccache gcc' --samples=../samples --prefix=/mingw64 libavutil 55. 47.101 / 55. 47.101 libavcodec 57. 82.100 / 57. 82.100 libavformat 57. 66.103 / 57. 66.103 libavdevice 57. 3.100 / 57. 3.100 libavfilter 6. 74.100 / 6. 74.100 libswscale 4. 3.101 / 4. 3.101 libswresample 2. 4.100 / 2. 4.100 libpostproc 54. 2.100 / 54. 2.100 Input #0, truehd, from 'truehd.thd': Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Audio: truehd, 44100 Hz, stereo, s32 (24 bit) Stream mapping: Stream #0:0 -> #0:0 (truehd (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help Output #0, md5, to 'pipe:': Metadata: encoder : Lavf57.66.103 Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s Metadata: encoder : Lavc57.82.100 pcm_s16le [truehd @ 0000000002544f40] Lossless check failed - expected 07, calculated 04. [truehd @ 0000000002544f40] Lossless check failed - expected 06, calculated 04. [truehd @ 0000000002544f40] Lossless check failed - expected 00, calculated 02. [truehd @ 0000000002544f40] Lossless check failed - expected 01, calculated 03. MD5=cba280ea373fa6287016c9bca7900bac size= 0kB time=00:00:01.99 bitrate= 0.1kbits/s speed= 104x video:0kB audio:346kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
The resulting stream is also for some reason reported as 24bit (s32) instead of 16bit.
Attachments (1)
Change History (13)
by , 8 years ago
Attachment: | truehd.wav added |
---|
comment:1 by , 8 years ago
Keywords: | thd added; truehd removed |
---|
comment:2 by , 5 years ago
comment:3 by , 3 years ago
Status: | new → open |
---|
I suppose this patch. https://patchwork.ffmpeg.org/project/ffmpeg/patch/20171128195544.5283-1-onemda@gmail.com/ by Paul will fix "a little shorter" part. I can confirm that last 16 frames are indeed not reencoded (otherwise the sample is bitperfect, LOL!) on my 1 102.5 fps (yeah, not 1200 fps, WHAT?) sample too. To be precise every time ~1818 (or ~1 696 bytes) bytes are being lost with ffmpeg -i sampleN.thd -strict -2 sampleNplus1.thd.
As for bitness, that is strange bug, as bitness makes little sense for now for TrueHD, since 24 bit encoder from 32 bit encoder is not even activated yet! It was supposed to be activated here https://ffmpeg.org/pipermail/ffmpeg-devel/2019-July/246357.html (patch not on patchwork, of course, no surprises here) but was NAK'ed by Lynne here: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20190710035638.30961-1-me@jailuthra.in/#41950
Second patch in series https://patchwork.ffmpeg.org/project/ffmpeg/patch/20171128195544.5283-2-onemda@gmail.com/ evolved into c1c3916cec9ca627b9bff4a34683f66664ff787d because of logic by author here: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20190709201901.26693-1-me@jailuthra.in/#41930
32 bit activation happens by just adding AV_SAMPLE_FMT_S32 in two places, not cool it is not on.
What is most funny is that lossless check problem happens with ffplay/mpv when you seeked, which means it has nothing to do with the file (FIXED in 5673a4842556b79a92a1ede6e9696506fd4161ad).
comment:4 by , 3 years ago
As for bitness, I suppose problem is here: https://github.com/FFmpeg/FFmpeg/blame/870bfe16a12bf09dca3a4ae27ef6f81a2de80c40/libavcodec/mlp_parse.c#L126
It was there since the very beginning though. 6b493b2f2fd241f6b893f6aa549f10aee1b9ad0c
comment:5 by , 3 years ago
So, seeking is fixed with adding flush, but still every reencode loses 16 frames, I just checked for a very large 8 channel sample with 408525 frames of 1200 fps. Next reencode loses 16 frames to 408509. Next one too: 408493. So... This should be applied https://patchwork.ffmpeg.org/project/ffmpeg/patch/20171128195544.5283-1-onemda@gmail.com/
Next: the problem there about "Trying to remove > 40 samples, but the queue is empty" is interesting, but... remember that it is the case with all thd as mediainfo shows:
Samples per frame: 40
Afaik it should be 40*16==640 actual samples.
comment:6 by , 3 years ago
Apparently madshi says that all TrueHD is always 24 bit. Dah.
https://forum.doom9.org/showpost.php?p=1078061&postcount=2102
comment:7 by , 3 years ago
Resolution: | → fixed |
---|---|
Status: | open → closed |
This is now fixed in 9f420163c6207b9c54badd30056974a6b3450bfd. MLP bitstream reencode will not be bitperfect (amount of frames is now the same), since shorten_by will be present now in bitstream (cannot be seen in mediainfo, alas) after the commit, but old 16 bit in 24 package THD will be reencoded losslessly (after decoding to wav both before and new reencoded from that old mlp file after that commit will produce the same bit-per-bit perfect wav). I did not test -c:a pcm_s24le in full, but at least on my sample it also produces bit perfect result.
There is no 24/16 bit metadata in 0xba type (only in 0xbb), so as mentioned by madshi above and now by mediainfo main dev: https://github.com/MediaArea/MediaInfoLib/issues/1102#issuecomment-908614414 this cannot be and should not be fixed, because it is very much possible to have 16 bit sound in 24 bit and yet some sequences of frames will have out of 16-bit content. Of course, 20 bit in 24 bit encoding should be done, but that will require implementing AV_SAMPLE_FMT_S20 (flac also wants to use it and alac and what not).
This sample is now bitperfect and this means it cannot be considered -strict -2 anymore and 30 bit full support should be activated, even if it may be not perfect yet:
PS C:\Users\xxxx> L:\5777\ffmpeg\bin\ffmpeg -i C:\Users\xxxx\csdncvsdenvsw.thd -f md5 - ffmpeg version N-103469-g034133a0df-20210901 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10-win32 (GCC) 20210408 configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-shared --disable-static --disable-w32threads --enable-pthreads --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-libvorbis --enable-opencl --enable-libvmaf --enable-vulkan --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-avisynth --enable-libdav1d --enable-libdavs2 --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libglslang --enable-libgme --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpx --enable-libwebp --enable-lv2 --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --disable-vaapi --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-ldexeflags= --extra-libs=-lgomp --extra-version=20210901 libavutil 57. 4.101 / 57. 4.101 libavcodec 59. 6.100 / 59. 6.100 libavformat 59. 4.102 / 59. 4.102 libavdevice 59. 0.101 / 59. 0.101 libavfilter 8. 7.100 / 8. 7.100 libswscale 6. 0.100 / 6. 0.100 libswresample 4. 0.100 / 4. 0.100 libpostproc 56. 0.100 / 56. 0.100 Input #0, truehd, from 'C:\Users\xxxx\csdncvsdenvsw.thd': Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Audio: truehd, 44100 Hz, stereo, s32 (24 bit) Stream mapping: Stream #0:0 -> #0:0 (truehd (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help Output #0, md5, to 'pipe:': Metadata: encoder : Lavf59.4.102 Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s Metadata: encoder : Lavc59.6.100 pcm_s16le MD5=d886c9feaf7dddcdff3a5adcfa4c57bcrate= 0.0kbits/s speed=N/A size= 0kB time=00:00:02.00 bitrate= 0.1kbits/s speed= 91x video:0kB audio:348kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Moreover since -f md5 defaults to -c:a pcm_s16le, I also tested
ffmpeg -i truehd.wav -c:a pcm_s24le -f md5 -
ffmpeg -i truehd.thd -c:a pcm_s24le -f md5 -
Which both gave 4ded2127735c325bc2364a1c2e311f1d.
Congrats to Elon Mask for implementing this!
comment:8 by , 3 years ago
Your latest patch is IMHO wrong, mediainfo prints channel0 instead of C, that it prints on Mono.mlp file, while before your fix it was printing Channel layout: L R. Also it breaks older version of decoder due to:
[truehd @ 000002693a4c9180] Assignment of matrix channel 0 to invalid output channel -22 is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
Newest version
Audio Format : MLP FBA Format/Info : Meridian Lossless Packing FBA Commercial name : Dolby TrueHD Bit rate mode : Variable Maximum bit rate : 9 597 kb/s Channel(s) : channel0
original mono.mlp file:
Audio Format : MLP FBA Format/Info : Meridian Lossless Packing FBA Commercial name : Dolby TrueHD Bit rate mode : Variable Maximum bit rate : 513 kb/s Channel(s) : 1 channel Channel layout : C Sampling rate : 48.0 kHz Frame rate : 1 200.000 FPS (40 SPF) Compression mode : Lossless
In practice this is:
000009 2ch_presentation_channel_modifier: 3 (0x3) - (2 bits) 000009 6ch_presentation_channel_modifier: 0 (0x0) - (2 bits) 000009 6ch_presentation_channel_assignment: 2 (0x02) - (5 bits) - 1 (0x1) - Front: L, R 00000A 8ch_presentation_channel_modifier: 0 (0x0) - (2 bits) 00000A 8ch_presentation_channel_assignment: 2 (0x0002) - (13 bits) - 1 (0x1) - Front: L, R *** 8-ch presentation: 3 (0x3) - (3 bits) 000015 6-ch presentation: 3 (0x3) - (2 bits) 000015 reserved: 0 (0x0) - (2 bits) 000016 channel_meaning (8 bytes) 000016 Unknown: 0 (0x00) 000017 Unknown: 0 (0x00) 000018 Unknown: 63 (0x3F) 000019 Unknown: 31 (0x1F) 00001A Unknown: 227 (0xE3) 00001B Unknown: 7 (0x07) 00001C Unknown: 227 (0xE3) 00001D Unknown: 0 (0x0) - (7 bits)
In practice it is 2ch_presentation_channel_modifier: 3 (0x3) - (2 bits) that means it is mono: https://developer.dolby.com/globalassets/technology/dolby-truehd/dolby-truehd-mlp-bitstreams-within-the-iso-base-media-file-format.pdf (page 14)
follow-up: 10 comment:9 by , 3 years ago
No, it is not wrong. Mediainfo is very buggy piece of software, you should not relied on it, especially for truehd. This was tested with official dolby decoder and it works fine, except for last frame, which get error out for some yet unknown reason.
comment:10 by , 3 years ago
Replying to Elon Musk:
No, it is not wrong.
Can you at least fix regression of reporting stereo instead of mono in ffprobe on original file, I gave regression commits? Also, why not drop second channel from decoded multichannel wav? Also, AGAIN. Dolby decoder (what do you use?) is not the reference! HW decoders are with Atmos, original Mono.mlp is decoded perfectly on my LG C9 as mono. And the spec says that you should also set all bits in 2ch_presentation_channel_modifier for mono. BTW, a question. What is inside a fake second substream and why it was a good idea from the point of view of Dolby?
BTW, I just got that LAvfilters are not yet updated with your timebase 44100 patch, so maybe that will fix MAT 2.0 bitstream timestamps and desync on 44100 samples?
BTW, about last frame, are you sure your shorten_by is in the right substream for mono?
comment:12 by , 3 years ago
Your mono stereo commit in encoder caused this: https://github.com/mpv-player/mpv/issues/9380
Most issues were fixed by Jai Luthra in c1c3916cec9ca627b9bff4a34683f66664ff787d, the output file is still a little shorter than the input file, bitdepth is also still wrong.