codecs: import FLAC audio from MP4/MOV (pass STREAMINFO from dfLa)
The ISO-BMFF path created the FLAC decoder with no extra data, so every FLAC track in an MP4 or MOV failed with "flac: missing extra data". The decoder now gets the STREAMINFO body that `dfLa` carries after its 4-byte block header, as the Matroska path already did. Regression test `mp4_flac_audio` (an ffmpeg-made MP4 with FLAC audio) failed before this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2e21c44904
commit
f91b86dd48
|
|
@ -139,7 +139,8 @@ impl PacketDecoder {
|
|||
C::Mp3 => Self::new(CODEC_TYPE_MP3, rate, None),
|
||||
C::Ac3 { .. } => Self::ac3(),
|
||||
C::Alac { cookie } => Self::new(CODEC_TYPE_ALAC, rate, Some(cookie.clone())),
|
||||
C::Flac(_) => Self::new(CODEC_TYPE_FLAC, rate, None),
|
||||
// the decoder needs the STREAMINFO body: `dfLa` holds it after the 4-byte block header
|
||||
C::Flac(f) => Self::new(CODEC_TYPE_FLAC, rate, f.metadata_blocks.get(4..38).map(<[u8]>::to_vec)),
|
||||
C::Opus(o) => Self::opus(filmcraft_opus::OpusHead::from_dops(&o.to_bytes()).map_err(|e| CodecError::Unsupported(format!("Opus: {e}")))?),
|
||||
other => Err(CodecError::Unsupported(format!("{} audio", other.name()))),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,6 +224,18 @@ fn matroska_hevc_flac() {
|
|||
check_mkv("blue_hevc_flac.mkv", &["-c:v", "libx265", "-x265-params", "log-level=error", "-pix_fmt", "yuv420p"], &["-c:a", "flac"]);
|
||||
}
|
||||
|
||||
/// FLAC in MP4 (`fLaC` + `dfLa`): the decoder gets the STREAMINFO from `dfLa` (it was given
|
||||
/// nothing, and every FLAC track in an MP4 failed with "missing extra data").
|
||||
#[test]
|
||||
fn mp4_flac_audio() {
|
||||
let args = ["-f", "lavfi", "-i", "sine=frequency=1000:sample_rate=48000:d=2", "-c:a", "flac", "-strict", "-2"];
|
||||
let Some(b) = fixture("tone_flac.mp4", &args) else { return };
|
||||
let src = crate::open_bytes("tone_flac.mp4", b).expect("open");
|
||||
let a = src.audio(24_000, 4800, 48_000).expect("audio");
|
||||
let peak = a.channels[0].iter().fold(0f32, |m, s| m.max(s.abs()));
|
||||
assert!(peak > 0.05 && peak < 1.0, "audio peak {peak}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matroska_prores_pcm() {
|
||||
check_mkv("blue_prores_pcm.mkv", &["-c:v", "prores_ks", "-profile:v", "2"], &["-c:a", "pcm_s16le"]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue