Repository navigation
Re-encode plain WAV sources with an unspecified channel layout - #92
Merged
Merged
Conversation
A plain mono or stereo WAV leaves its channel order unspecified. swr_init normalises the resampler input to the default layout, so swr_convert_frame rejected every decoded frame with AVERROR_INPUT_CHANGED. Set the default layout before the decoder opens, as the ffmpeg CLI does, in extract_audio and transcode. The passthrough check no longer needs its unspecified-order branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before
A plain mono WAV from
ffmpeg -f lavfi -i sine=d=1:sample_rate=44100 a.wavhaschannel_layout=unknowninffprobe. Onmain, every call that resamples or re-encodes it fails:The new tests, run without the Rust fix:
Problem
ffmpegwrites mono and stereo WAV files without a channel mask. The decoder keeps the unspecified channel order.swr_initsets its input to the default layout for the channel count. Thenswr_convert_framesees the unspecified layout of each decoded frame as a changed input and rejects it. An AAC source works, because its layout is set.After
All calls above return
{:ok, _}.task test:integration: 107 passed (104 existing tests and 3 new ones). The WAV-to-WAV passthrough test still passes.task checkexits 0.mainDetails
Cause.
native/exmpeg_native/src/extract_audio.rs:extract_audioandnative/exmpeg_native/src/transcode.rs:build_audio_pipelineopen the decoder withAV_CHANNEL_ORDER_UNSPECfromcodecpar. The resampler normalises its input layout, so the frames no longer match it.Design. The new helper
audio::default_unspecified_layoutgives an unspecified decoder layout the default layout for its channel count (AVChannelLayout::from_nb_channels), beforedecoder.open. TheffmpegCLI does the same inguess_input_channel_layout(fftools/ffmpeg_demux.c). Both pipelines call the one helper. After it, the decoder layout is never unspecified, so I removed the unspecified branch of the passthrough check inextract_audio. A WAV with the default layout still matches the target and skips the resampler. Nounsafe.Tests. Three integration tests use the existing mono 44.1 kHz WAV fixture:
extract_audioto.mp3keeps 44 100 Hz and 1 channel.extract_audioto.opusresamples to 48 000 Hz.transcodeto.m4awithaudio_codec: "aac"re-encodes 1 stream.All three fail on
mainwith the error above and pass with the fix.