HydrogenAudio

Hydrogenaudio Forum => General Audio => Topic started by: Kraeved on 2024-04-07 19:42:20

Title: flac and wavpack bitdepth in ffmpeg
Post by: Kraeved on 2024-04-07 19:42:20
One of the major changes in this release is the inclusion of multithreading in the command line tool.

While I was comparing the speed of operations between the last year's and the current version of FFMPEG, I noticed an oddball behavior of the following command: ffmpeg -i in.wav out.wv. If WAV is 16-bit, then WV is 16-bit, but if WAV is 24-bit, then WV is 32-bit. Dear @Porcus, you test lossless a lot, maybe you know what's going on?


Title changed, was: [Split TOS#5 (https://hydrogenaud.io/index.php/topic,3974.0.html) - not ffmpeg 7.0 exclusive issue] FFmpeg 7.0 "Dijkstra" released 2024-04-05 (https://hydrogenaud.io/index.php/topic,125757.0.html)
Title: Re: flac and wavpack bitdepth in ffmpeg
Post by: ktf on 2024-04-07 20:33:41
If WAV is 16-bit, then WV is 16-bit, but if WAV is 24-bit, then WV is 32-bit.
ffmpeg internally knows 16-bit and 32-bit, but it doesn't have an internal representation for 24-bit. So, on decoding, it decodes to 32-bit and then 'forgets' the actual number of bits the data uses, and thus encodes to 32-bit.
Title: Re: flac and wavpack bitdepth in ffmpeg
Post by: danadam on 2024-04-07 21:02:57
If you know that the input is 24-bit then the option:
Code: [Select]
-bits_per_raw_sample 24
creates 24-bit WV.
Title: Re: flac and wavpack bitdepth in ffmpeg
Post by: Porcus on 2024-04-07 21:10:30
Ah, I thought the multithreading was for encoding audio and video separately etc., but yes decoding and encoding is a point indeed.
 

As for 24 vs 32:
* ffmpeg does that for WavPack, but not for FLAC. Precisely why I don't know, but there was no 32-bit way to do it when there was no 32-bit FLAC support. Anyway the size penalty isn't that big, since WavPack compresses away wasted bits - until you convert to something that doesn't (like, WAVE which doesn't compress neither wasted bits nor anything else)
* For 8 bits, the situation is the other way around: ffmpeg creates 8-bit WavPack, as should - but 16 bit FLAC. That is,
ffmpeg -i 8bitfile.wav outfile.flac makes a 16 bit flac file, but ffmpeg -i 8bitfile.wav outfile.wv makes an 8-bit WavPack file. (Whether source is WAVE or AIFF doesn't matter.)

If you know that the input is 24-bit then the option:
Code: [Select]
-bits_per_raw_sample 24
creates 24-bit WV.
But, -bits_per_raw_sample 8 does not create 8-bit FLAC.

Anyway, bloody annoying there is no way to force ffmpeg into "read input bit depth and use that for output".
Title: Re: flac and wavpack bitdepth in ffmpeg
Post by: danadam on 2024-04-08 00:29:08
Quote from: Porcus
* ffmpeg does that for WavPack, but not for FLAC. Precisely why I don't know, but there was no 32-bit way to do it when there was no 32-bit FLAC support.
When ffmpeg uses 32-bit for internal processing then flac codec by itself overwrites "bits_per_raw_sample" to 24. You have to use:
Code: [Select]
-strict experimental
to stop it from doing that. With that you can produce 32-bit flacs. You can then also use:
Code: [Select]
-bits_per_raw_sample 24
yourself to overwrite it back to 24 :)

(see libavcodec/flacenc.c (https://github.com/FFmpeg/FFmpeg/blob/2d33d6bfcc2ab4031862aeb35bc0cb536019ac09/libavcodec/flacenc.c#L280))

Quote from: Porcus
* For 8 bits, the situation is the other way around: ffmpeg creates 8-bit WavPack, as should - but 16 bit FLAC.
That's because wavpack codec has support for all ffmpeg internal datatypes while flac only has support for 16 and 32-bit ones.

In libavcodec/wavpackenc.c (https://github.com/FFmpeg/FFmpeg/blob/2d33d6bfcc2ab4031862aeb35bc0cb536019ac09/libavcodec/wavpackenc.c#L2971):
Code: [Select]
const FFCodec ff_wavpack_encoder = {
    ...
    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_S16P,
                                                     AV_SAMPLE_FMT_S32P,
                                                     AV_SAMPLE_FMT_FLTP,
                                                     AV_SAMPLE_FMT_NONE },

In libavcodec/flacenc.c (https://github.com/FFmpeg/FFmpeg/blob/2d33d6bfcc2ab4031862aeb35bc0cb536019ac09/libavcodec/flacenc.c#L1752):
Code: [Select]
const FFCodec ff_flac_encoder = {
    ...
    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                     AV_SAMPLE_FMT_S32,
                                                     AV_SAMPLE_FMT_NONE },


Merged topics, removed unnecessary reference to other topic.
Title: Re: flac and wavpack bitdepth in ffmpeg
Post by: Porcus on 2024-04-08 22:03:29
Yeah well, but that just pushes the question one step: why haven't they? 8-bit audio isn't exactly the latest news.