Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions crates/enc-ffmpeg/src/video/h264_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,20 @@ impl H264PacketEncoder {
}

fn update_pts(&mut self, frame: &mut frame::Video, timestamp: Duration) {
// Use encoder_time_base (the value sent to the muxer subprocess via InitVideo),
// NOT self.encoder.time_base() which may be overridden by the codec after open.
// Mismatching these causes the muxer to rescale PTS using the wrong time base,
// producing wrong playback speed (observed as 4-8x too fast with h264_videotoolbox).
let tb = self.encoder_time_base;
if timestamp != Duration::MAX {
let tb = self.encoder.time_base();
let rate = tb.denominator() as f64 / tb.numerator() as f64;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tb is now coming from config (vs the post-open codec), so it might be worth guarding against an invalid/zero Rational here — otherwise rate can become inf/NaN and the float->int cast can silently produce huge PTS.

Suggested change
let rate = tb.denominator() as f64 / tb.numerator() as f64;
debug_assert!(
tb.numerator() > 0 && tb.denominator() > 0,
"invalid encoder_time_base"
);
let rate = tb.denominator() as f64 / tb.numerator() as f64;

let pts = (timestamp.as_secs_f64() * rate).round() as i64;
let first_pts = *self.first_pts.get_or_insert(pts);
let pts = normalize_input_pts(
pts - first_pts,
self.last_frame_pts,
tb,
self.encoder.frame_rate(),
self.frame_rate,
);
self.last_frame_pts = Some(pts);
frame.set_pts(Some(pts));
Expand All @@ -216,8 +220,8 @@ impl H264PacketEncoder {
let pts = normalize_input_pts(
pts - first_pts,
self.last_frame_pts,
self.encoder.time_base(),
self.encoder.frame_rate(),
tb,
self.frame_rate,
);
self.last_frame_pts = Some(pts);
frame.set_pts(Some(pts));
Expand Down
Loading