zmwangx / rust-ffmpeg

Safe FFmpeg wrapper.
Do What The F*ck You Want To Public License
1.2k stars 195 forks source link

Unable to decode FLAC audio file on some platforms #142

Closed pyldin601 closed 1 year ago

pyldin601 commented 1 year ago

I am trying to decode a FLAC audio file, but it fails with the error code:

ffmpeg::Error(1094995529: Invalid data found when processing input)

Also, I see this in stderr:

[flac @ 0x55dfda1ffe80] invalid subframe padding 
[flac @ 0x55dfda1ffe80] decode_frame() failed

It works well if I'm doing things inside a docker container on Docker Desktop on macOS, but it fails in the same docker container on Linux and Windows WSL.

After inspecting the possible cause, I found that the packet I receive from the ictx.packets() iterator is sometimes corrupted. However, the file itself is OK.

I inspected the corrupted frame and discovered that sometimes the packet missed some bytes. That looks like bytes sequence 0x0D, 0x0A inside the packet is replaced with single byte 0x0A. This looks like a line ending conversion, but it doesn't make any sense, as FLAC demuxing should be done in binary mode, not text mode.

Here's the code to reproduce the issue:

use ffmpeg_next::codec::context::Context;
use ffmpeg_next::format::input;
use ffmpeg_next::frame::Audio;

fn main() {
    ffmpeg_next::init().unwrap();

    let path = String::from("test_file.flac");
    let mut ictx = input(&path).unwrap();
    let input = ictx
        .streams()
        .best(ffmpeg_next::media::Type::Audio)
        .unwrap();
    let input_index = input.index();
    let context = Context::from_parameters(input.parameters()).unwrap();
    let mut decoder = context.decoder().audio().unwrap();

    let mut frame = Audio::empty();

    for (stream, packet) in ictx.packets() {
        if stream.index() == input_index {
            decoder.send_packet(&packet).unwrap();

            while decoder.receive_frame(&mut frame).is_ok() {
                // NOP
            }
        }
    }

    decoder.send_eof().unwrap();
    while decoder.receive_frame(&mut frame).is_ok() {
        // NOP
    }
}

Here's the file I used to reproduce the issue: https://drive.google.com/file/d/11nOhNrx6QDhbUh4u6QItmyTxMT0TFz6l/view?usp=sharing

Polochon-street commented 1 year ago

hi,

seems like it is a problem with the file / ffmpeg itself, not rust-ffmpeg - trying to ffplay it yields

polochon@Coucou-PC /tmp $ ffplay test_file.flac                                                                                                           [0]
ffplay version n6.0 Copyright (c) 2003-2023 the FFmpeg developers
  built with gcc 12.2.1 (GCC) 20230201
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librav1e --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-version3 --enable-vulkan
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Input #0, flac, from 'test_file.flac': vq=    0KB sq=    0B f=0/0   
  Metadata:
    encoder         : Lavf59.27.100
  Duration: 00:00:02.83, start: 0.000000, bitrate: 1268 kb/s
  Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
[NULL @ 0x7f56b4001f00] sample/frame number mismatch in adjacent frames
[flac @ 0x7f56b4026f40] invalid subframe padding
[flac @ 0x7f56b4026f40] decode_frame() failed
[NULL @ 0x7f56b4001f00] sample/frame number mismatch in adjacent frames
    Last message repeated 1 times
[flac @ 0x7f56b4009480] invalid rice order: 12 blocksize 4608
[flac @ 0x7f56b4009480] decode_frame() failed
[flac @ 0x7f56b4026f40] invalid subframe padding
[flac @ 0x7f56b4026f40] decode_frame() failed
[flac @ 0x7f56b4099700] invalid subframe padding
[flac @ 0x7f56b4099700] decode_frame() failed
[flac @ 0x7f56b4009480] invalid subframe padding
[flac @ 0x7f56b4009480] decode_frame() failed
[flac @ 0x7f56b401c880] invalid subframe padding
[flac @ 0x7f56b401c880] decode_frame() failed
   2.45 M-A: -0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   

which looks like your error?

pyldin601 commented 1 year ago

Thanks for your help. I didn't try to play it inside a docker container. It seems like an issue with my git accidentally replacing line-endings for unknown audio files identifying them as text files.