Preserve fractional frame rates when encoding SDR video - #279
Open
Syed Osama Ali Shah (Osamaali313) wants to merge 1 commit into
Open
Preserve fractional frame rates when encoding SDR video#279Syed Osama Ali Shah (Osamaali313) wants to merge 1 commit into
Syed Osama Ali Shah (Osamaali313) wants to merge 1 commit into
Conversation
encode_video wrote the SDR H.264 stream with rate=int(fps), truncating fractional rates: 29.97 -> 29, 23.976 -> 23, 59.94 -> 59. The output is then tagged/timed at the wrong rate, so the video plays a bit too slow and muxed audio drifts out of sync over the clip. --frame-rate is a float CLI arg and every generation pipeline passes it straight through, so a standard broadcast rate reaches this path. Use Fraction(fps).limit_denominator(1000) for the stream rate, matching what encode_video's own HDR branch (float(fps)) and the sibling encoders already do (exr.py uses the same idiom with libx264, hlg.py with libx265, both to "match the input timing"). Integer rates are unchanged (Fraction(24.0).limit_denominator(1000) == 24). Also stop pre-truncating the source rate with int(src.fps) in the retake and dubit call sites so source-fps flows keep their true rate too.
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.
Summary
encode_videowrites the SDR H.264 stream with a truncated integer frame rate, so fractional rates are silently wrong.packages/ltx-pipelines/src/ltx_pipelines/utils/media_io/encode.py:int(fps)truncates29.97 → 29,23.976 → 23,59.94 → 59. The output file is then tagged/timed at the wrong rate, so it plays ~1.6–4.2% too slow and any muxed audio drifts progressively out of sync.This is reached on the normal path:
--frame-rateis afloatCLI argument (utils/args.py, "Frame rate of the generated video (fps)") and every generation pipeline (distilled,ti2vid_*,a2vid_two_stage,ic_lora,keyframe_interpolation, …) passesargs.frame_ratestraight toencode_video, so--frame-rate 29.97yields a 29 fps file.Fix
Use
Fraction(fps).limit_denominator(1000)for the stream rate (widening thefpsparameter tofloat). This matches what the codebase already does everywhere else:encode_video's own HDR branch forwardsfps=float(fps).media_io/exr.pyusesadd_stream("libx264", rate=Fraction(frame_rate).limit_denominator(1000))— the same codec — with the docstring "so playback matches the input timing."ltx_core/color/hlg.pyusesFraction(fps).limit_denominator(1000)for libx265.The SDR branch was the lone outlier. Integer rates are unchanged (
Fraction(24.0).limit_denominator(1000) == 24).I also removed the
int(src.fps)pre-truncation at theretakeanddubitcall sites (src.fpsis already a float fromfloat(video_stream.average_rate)), so source-fps flows keep their true rate too.Verification
Ran the real encoding path through PyAV (the same
add_stream+ frame-encode idiomencode_videouses):ruff checkandruff formatare clean on the changed files.