Opened 3 years ago

Closed 3 years ago

Last modified 2 years ago

#9563 closed defect (fixed)

Conversion between lossless formats not lossless

Reported by: Martijn van Beurden Owned by: anton@khirnov.net
Priority: important Component: ffmpeg
Version: git-master Keywords: wavpack regression
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
When converting a WAV file containing 32-bit integer PCM to wavpack, the resulting wavpack contains 24-bit integer samples.

How to reproduce:

% ffmpeg -i input.wav output.wv
ffmpeg version N-104950-gc47896536c Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10 (Debian 10.2.1-6)
  configuration: --enable-libx264 --enable-libfdk-aac --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libopus
  libavutil      57. 11.100 / 57. 11.100
  libavcodec     59. 14.100 / 59. 14.100
  libavformat    59. 10.100 / 59. 10.100
  libavdevice    59.  0.101 / 59.  0.101
  libavfilter     8. 20.100 /  8. 20.100
  libswscale      6.  1.101 /  6.  1.101
  libswresample   4.  0.100 /  4.  0.100
  libpostproc    56.  0.100 / 56.  0.100
Input #0, wav, from 'input.wav':
  Duration: 00:01:04.00, bitrate: 2822 kb/s
  Stream #0:0: Audio: pcm_s32le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s32, 2822 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s32le (native) -> wavpack (native))
Press [q] to stop, [?] for help
Output #0, wv, to 'output.wv':
  Metadata:
    encoder         : Lavf59.10.100
  Stream #0:0: Audio: wavpack, 44100 Hz, stereo, s32p, 128 kb/s
    Metadata:
      encoder         : Lavc59.14.100 wavpack
size=   10720kB time=00:01:04.00 bitrate=1372.2kbits/s speed=86.9x    
video:0kB audio:10720kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000847%

Resulting wavpack file:

% ffprobe output.wv
ffprobe version N-104950-gc47896536c Copyright (c) 2007-2021 the FFmpeg developers
  built with gcc 10 (Debian 10.2.1-6)
  configuration: --enable-libx264 --enable-libfdk-aac --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libopus
  libavutil      57. 11.100 / 57. 11.100
  libavcodec     59. 14.100 / 59. 14.100
  libavformat    59. 10.100 / 59. 10.100
  libavdevice    59.  0.101 / 59.  0.101
  libavfilter     8. 20.100 /  8. 20.100
  libswscale      6.  1.101 /  6.  1.101
  libswresample   4.  0.100 /  4.  0.100
  libpostproc    56.  0.100 / 56.  0.100
Input #0, wv, from 'output.wv':
  Metadata:
    encoder         : Lavf59.10.100
  Duration: 00:01:04.00, start: 0.000000, bitrate: 1372 kb/s
  Stream #0:0: Audio: wavpack, 44100 Hz, stereo, s32p (24 bit)

I have tried to trace the origin of the bug in the hope of submitting a patch, but I don't know enough about ffmpeg internals to fix this alone.

In fftools/ffmpeg.c, the following can be found

        if (ost->bits_per_raw_sample)
            enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
        else if (dec_ctx && ost->filter->graph->is_meta)
            enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample,
                                                 av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth);

If I remove ost->filter->graph->is_meta from the if, the conversion is lossless again. I think ost->filter->graph->is_meta is only initialized, not yet set at this point in the code. I'd like to fix this, but I'm not sure what to do. I think simply removing ost->filter->graph->is_meta as a condition is probably too simple.

Attachments (1)

signal_short.wav (562.6 KB ) - added by Martijn van Beurden 3 years ago.
WAV with 32 bit integer samples

Download all attachments as: .zip

Change History (6)

by Martijn van Beurden, 3 years ago

Attachment: signal_short.wav added

WAV with 32 bit integer samples

comment:1 by Martijn van Beurden, 3 years ago

Keywords: regression added

comment:2 by Balling, 3 years ago

Also affected. https://patchwork.ffmpeg.org/project/ffmpeg/patch/20220108142437.756529-1-mvanb1@gmail.com

When is the patch above going to be applied?

Workaround is -bits_per_raw_sample 32. Yes, it works on wv files too. Yes, it is x10 bigger.

Version 2, edited 3 years ago by Balling (previous) (next) (diff)

comment:3 by Balling, 3 years ago

Owner: set to anton@khirnov.net
Status: newopen

This was your patch that caused this. Please revert. https://patchwork.ffmpeg.org/project/ffmpeg/patch/20211123103001.12888-4-anton@khirnov.net/

It also failed to apply, BTW. And BTW, please consider going to 64 bit WAV if source is 64 bit, 32 bit if source is 32 and 24 if source is 24, because it causes quite a confusion, and for -f md5 it outright makes no sense, since 16 bit in 24 bit container and any data in that last 8 bits will cause it to be same md5.

Last edited 3 years ago by Balling (previous) (diff)

comment:4 by Balling, 3 years ago

Resolution: fixed
Status: openclosed

Finally fixed by e663030267851e0e0be54dc9d685fa9cd883cef6. Please resend the flac patches if you saying they are flowed.

P.S. Tested it, wv files are bitperfect, except for Lavf59.22.100 field.

BTW, please consider going to 64 bit WAV if source is 64 bit, etc

Not done, but that would be an API break.

Last edited 3 years ago by Balling (previous) (diff)

comment:5 by Carl Eugen Hoyos, 2 years ago

Keywords: bits_per_raw_sample lossless removed
Priority: normalimportant
Note: See TracTickets for help on using tickets.