Repository navigation
Trim MP3 encoder delay as FFmpeg does - #22
Merged
Merged
Conversation
MP3 encoders prime their output: LAME's delay plus the decoder's adds 1105 samples at the start, recorded in the LAME header. FFmpeg trims them; Align's in-process decoder did not, so MP3 audio sat 23 to 25 ms early and synchronized that far off. The delay Symphonia reports now becomes the stream's lead, which every decode path already skips for MP4 edit lists. Only the start is trimmed. Symphonia's gapless mode would also cut the end at a frame count that files without a Xing header merely estimate, which dropped audio after a quiet stretch, and it underflows on an inconsistent Xing frame count. The encoder priming test now covers MP3, and a new test keeps headerless VBR files and contradictory frame counts decoding in full.
Merged
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.
Stacked on the #16 branch (
fix/damaged-audio-packets), which introduced theextension-named container readers this change configures.
MP3 encoders prime their output: LAME adds 1105 samples of delay at the start
and padding at the end, and records both in its LAME/Info header. FFmpeg
trims them. Align's in-process decoder (Symphonia, on Windows and Linux) did
not, so MP3 audio sat 23 to 25 ms early and synchronized that far off — more
than half a frame at 25 fps.
The delay Symphonia reads from the LAME header (encoder delay plus the
decoder's 529 samples, 1105 for LAME) now becomes the stream's
lead, whichwhole-file decoding, seeks, refinement windows and native decoding already
skip for MP4 edit lists. Files without a LAME header are unchanged (nothing
records their delay; FFmpeg cannot trim them either).
Only the start is trimmed, deliberately. Symphonia's own gapless mode, tried
first, also trims the end at a frame count that files without a Xing header
merely estimate from their first frames, which dropped the audio after a quiet
stretch, and it underflows when the Xing frame count contradicts the LAME
delay. End padding (under one frame) does not affect synchronization.
Evidence, on the 59-file decoder differential: the three MP3 files (CBR, VBR
with ID3, 44.1 kHz mono) moved from 1.977, 1.977 and 1.975 s to exactly
2.000 s; nothing else changed.
Tests:
aac_priming_matches_ffmpeg_timingbecomesencoder_priming_matches_ffmpeg_timingand also covers MP3 (skippedwithout libmp3lame). Without the trim it fails with the click at sample
73105 instead of 72000, the 1105-sample LAME delay.
mp3_frame_counts_never_cut_audio: a headerless VBR file (loud, silent,loud) decodes as long as FFmpeg's output, and a Xing frame count of 1
neither panics nor shortens decoding. With Symphonia's gapless mode it
decodes 94464 of 200448 frames.
The fingerprint cache namespace moved to
portable4in the #16 branch. Ifthis change ships in a later release than that one, bump it again so cached
MP3 fingerprints are recomputed.
Validation:
cargo fmt --all -- --checkcargo clippy --locked --workspace --all-targets -- -D warningscargo test --locked --workspace: 382 passed, 1 ignored