Opened 6 years ago

Closed 15 months ago

Last modified 13 months ago

#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)

truehd.wav (348.1 KB ) - added by James 6 years ago.

Download all attachments as: .zip

Change History (13)

by James, 6 years ago

Attachment: truehd.wav added

comment:1 by Carl Eugen Hoyos, 6 years ago

Keywords: thd added; truehd removed

comment:2 by Carl Eugen Hoyos, 3 years ago

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.

comment:3 by Balling, 15 months ago

Status: newopen

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).

Last edited 15 months ago by Balling (previous) (diff)

comment:4 by Balling, 15 months ago

Last edited 15 months ago by Balling (previous) (diff)

comment:5 by Balling, 15 months 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 Balling, 15 months 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 Balling, 15 months ago

Resolution: fixed
Status: openclosed

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!

Last edited 15 months ago by Balling (previous) (diff)

comment:8 by Balling, 14 months 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)

Last edited 14 months ago by Balling (previous) (diff)

comment:9 by Elon Musk, 14 months 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.

in reply to:  9 comment:10 by Balling, 14 months 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:11 by Elon Musk, 14 months ago

The thing is about stereo encoding, i yet have to fix mono.

comment:12 by Balling, 13 months ago

Your mono stereo commit in encoder caused this: https://github.com/mpv-player/mpv/issues/9380

Last edited 13 months ago by Balling (previous) (diff)
Note: See TracTickets for help on using tickets.