This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

[BUG] Incorrect handling of variable frame rate source file
#1
Bug 
I took this over to AI first (Abacus.ai ChatLLM in Agent mode set to Max - Fable 5.1 + GPT-6 Astra) for troubleshooting.

The problem is that I couldn't get smooth playback when re-encoding the source to CPS, and I also had mismatching frame totals, and mismatching frames from input file to output file when they did match.

Source:
General Count                                    : 365 Count of stream of this kind             : 1 Kind of stream                           : General Kind of stream                           : General Stream identifier                        : 0 Count of video streams                   : 1 Count of audio streams                   : 1 Video formats                            : HEVC Video formats (with hints)               : HEVC Codecs Video                             : HEVC Audio formats                            : AAC LC Audio formats (with hints)               : AAC LC Audio codecs                             : AAC LC Total audio channels                     : 2 Complete name                            : E:\test_vid\Test_vid_source.mov Folder name                              : E:\test_vid File name extension                      : Test_vid_source.mov File name                                : Test_vid_source File extension                           : mov Format                                   : MPEG-4 Format                                   : MPEG-4 Format/Extensions usually used           : braw mov mp4 m4v m4a m4b m4p m4r 3ga 3gpa 3gpp 3gp 3gpp2 3g2 k3g jpm jpx mqv ismv isma ismt f4a f4b f4v Commercial name                          : MPEG-4 Format profile                           : Base Media Internet media type                      : video/mp4 Codec ID                                 : isom Codec ID                                 : isom (isom/iso2/mp41) Codec ID/Url                             : http://www.apple.com/quicktime/download/standalone.html CodecID_Compatible                       : isom/iso2/mp41 File size                                : 525499133 File size                                : 501 MiB File size                                : 501 MiB File size                                : 501 MiB File size                                : 501 MiB File size                                : 501.2 MiB Duration                                 : 320189 Duration                                 : 5 min 20 s Duration                                 : 5 min 20 s 189 ms Duration                                 : 5 min 20 s Duration                                 : 00:05:20.189 Duration                                 : 00:05:18:32 Duration                                 : 00:05:20.189 (00:05:18:32) Overall bit rate                         : 13129724 Overall bit rate                         : 13.1 Mb/s Frame rate                               : 38.870 Frame rate                               : 38.870 FPS Frame count                              : 12434 Stream size                              : 427866 Stream size                              : 418 KiB (0%) Stream size                              : 418 KiB Stream size                              : 418 KiB Stream size                              : 418 KiB Stream size                              : 417.8 KiB Stream size                              : 418 KiB (0%) Proportion of this stream                : 0.00081 HeaderSize                               : 427858 DataSize                                 : 525071275 FooterSize                               : 0 Is streamable                            : Yes Encoded date                             : 2025-11-29 19:04:23 UTC Tagged date                              : 2025-11-29 19:05:42 UTC File creation date                       : 2026-10-30 06:11:12.699 UTC File creation date (local)               : 2026-10-30 02:11:12.699 File last modification date              : 2026-09-27 12:31:36.730 UTC File last modification date (local)      : 2026-09-27 08:31:36.730 major_brand                              : Apple QuickTime (.MOV/QT) minor_version                            : 0.0.0 compatible_brands                        : qt  creation_time                            : 2025-11-29T19:04:23.000000Z com.apple.quicktime.author               : ReplayKitRecording encoder                                  : Lavf62.6.101 Video Count                                    : 402 Count of stream of this kind             : 1 Kind of stream                           : Video Kind of stream                           : Video Stream identifier                        : 0 Stream order                             : 0 ID                                       : 1 ID                                       : 1 Format                                   : HEVC Format                                   : HEVC Format/Info                              : High Efficiency Video Coding Format/Url                               : http://www.itu.int Commercial name                          : HEVC Format profile                           : Main@L4.1@Main Internet media type                      : video/H265 Codec ID                                 : hvc1 Codec ID/Info                            : High Efficiency Video Coding Codec ID/Url                             : http://www.itu.int/ Duration                                 : 319874 Duration                                 : 5 min 19 s Duration                                 : 5 min 19 s 874 ms Duration                                 : 5 min 19 s Duration                                 : 00:05:19.874 Duration                                 : 00:05:18:32 Duration                                 : 00:05:19.874 (00:05:18:32) Source duration                          : 319890 Source duration                          : 5 min 19 s Source duration                          : 5 min 19 s 890 ms Source duration                          : 5 min 19 s Source duration                          : 00:05:19.890 Source duration                          : 00:05:18:32 Source duration                          : 00:05:19.890 (00:05:18:32) Bit rate                                 : 13005222 Bit rate                                 : 13.0 Mb/s Width                                    : 886 Width                                    : 886 pixels Height                                   : 1538 Height                                   : 1 538 pixels Stored_Width                             : 896 Stored height                            : 1552 Sampled width                            : 886 Sampled height                           : 1538 Pixel aspect ratio                       : 1.000 Display aspect ratio                     : 0.576 Display aspect ratio                     : 9:16 Rotation                                 : 0.000 Frame rate mode                          : VFR Frame rate mode                          : Variable Frame rate                               : 38.870 Frame rate                               : 38.870 FPS Minimum frame rate                       : 15.000 Minimum frame rate                       : 15.000 FPS Maximum frame rate                       : 60.000 Maximum frame rate                       : 60.000 FPS Frame count                              : 12434 Source frame count                       : 12434 Color space                              : YUV Chroma subsampling                       : 4:2:0 Chroma subsampling                       : 4:2:0 Bit depth                                : 8 Bit depth                                : 8 bits Bits/(Pixel*Frame)                       : 0.246 Stream size                              : 520030093 Stream size                              : 496 MiB (99%) Stream size                              : 496 MiB Stream size                              : 496 MiB Stream size                              : 496 MiB Stream size                              : 495.9 MiB Stream size                              : 496 MiB (99%) Proportion of this stream                : 0.98959 Source stream size                       : 520030093 Source stream size                       : 496 MiB (99%) Source stream size                       : 496 MiB Source stream size                       : 496 MiB Source stream size                       : 496 MiB Source stream size                       : 495.9 MiB Source stream size                       : 496 MiB (99%) Source_StreamSize_Proportion             : 0.98959 Title                                    : Core Media Video Writing library                          : HEVC Writing library                          : HEVC Encoded date                             : 2025-11-29 19:04:23 UTC Tagged date                              : 2025-11-29 19:05:42 UTC Color description present                : Yes Color description present (source)       : Container / Stream Color range                              : Full Color range (source)                     : Container / Stream Color primaries                          : BT.709 Color primaries (source)                 : Container / Stream Transfer characteristics                 : sRGB/sYCC Transfer characteristics (source)        : Container / Stream Matrix coefficients                      : BT.709 Matrix coefficients (source)             : Container / Stream Source_Delay                             : -100 Source_Delay_Source                      : Container mdhd_Duration                            : 319873 Codec configuration box                  : hvcC

It says, "Frame rate: 38.870 FPS". Hybrid is trying to use that, when it should instead be using 60 FPS (i.e., 60,1). It is also generating an incorrect Matroska timecode v2 file with 19,173 frames instead of the input file's actual frame count of 12,434.

According to the AI:

Quote:Your source isn't really "38.870 fps". It's an iPhone ReplayKit capture on a 60 Hz grid. Each frame stays on screen for 1, 2 or 3 display refreshes, so the video switches between 60, 30 and 20 fps depending on how much is moving. 38.87 is just the average (12,434 frames ÷ 319.8 s). No frame in the file actually lasts 1/38.87 s.

There are three separate problems. One is in how Hybrid calls ffmpeg, not in ffmpeg itself, and the other two are Hybrid logic choices:
  1. The 19,173-line timecode file. Hybrid runs ffmpeg without -fps_mode passthrough. The mkvtimestamp_v2 muxer is a raw-video output that doesn't declare variable-frame-rate support, so ffmpeg's default auto mode switches to CFR. It then fills a 59.94 fps grid by duplicating 6,739 frames (12,434 + 6,739 = 19,173 timestamps + header). ffmpeg logs this openly: dup=6739, "More than 1000 frames duplicated". That's documented, intended ffmpeg behaviour, not an ffmpeg bug.

  2. The VFR encode (8,065 frames, 3:27). Hybrid noticed the timecode count didn't match the frame count, then changed the frame count to fit the bad timecodes instead of rejecting them. On top of that, its frameserver pipe uses -fps_mode auto -r 3887/100, which drops frames. Only 8,065 frames got to x264, and they were timed with the first 8,065 entries of the bogus 59.94 grid.

  3. The CFR encode (choppy, frame numbers off). That one is working as designed, but 38.87 is the wrong target. L-SMASH (fpsnum=3887, fpsden=100) resamples 60/30/20 fps material onto a 38.87 grid. My simulation using your ffprobe timestamps: 2,133 frames dropped and 2,133 duplicated, unevenly spread. That's the judder on pans.
 

Here is the AI "bug report for the developer": Tongue

Quote:Hybrid 2026.10.10.1 (64-bit), Windows 10 22H2. VFR source (iPhone ReplayKit HEVC .mov, 12,434 frames, avg 38.87 fps, actual 60 Hz cadence with 1/2/3-refresh frame durations, tbn 19200, ffmpeg-reported tbr 59.94). ffmpeg N-126512-gf7fbb1260e.
  1. Timecode extraction produces CFR-padded timecodes.
    Call: ffmpeg.exe -y -i "X.mov" -map 0:0 -f mkvtimestamp_v2 "X.txt" (log line 1180).
    Because no -fps_mode is given, ffmpeg's auto mode chooses CFR for the mkvtimestamp_v2 (rawvideo-style) muxer and pads to the stream tbr (59.94): ffmpeg reports frame=19173 ... dup=6739 drop=0 and "More than 1000 frames duplicated" (lines 1248/1266). The resulting file is a pure 59.94 grid (16/17 ms deltas only) with 19,173 entries instead of 12,434.

    Fix: add -fps_mode passthrough (-vsync 0 / -vsync passthrough for older builds), and preferably -an -sn and -map 0:v:0. Alternatives: ffprobe -show_entries frame=pts_time (sorted) or mkvmerge + mkvextract timestamps_v2.

  2. Frame count is adjusted to a mismatching timecode count instead of rejecting the timecodes.
    Log lines 20451–20453: Adjusting frame count (12434) to time code entry count (19173). then Current frame rate: 59.946 differs from average time code frame rate: 38.87. This will be ignored since 'Check average fps of mkv/mp4 files' is disabled.
    A timecode count that differs from the decoder's frame count by 54 % should be treated as an error: warn, then fall back to a different extraction method or CFR. The job carries 19172/38.87 from then on (e.g. line 32289).

  3. VFR (non-CFR) jobs resample in the frameserver pipe.
    Decode call (line 147489): ffmpeg ... -i script.avs -an -sn -pix_fmt yuv420p -fps_mode auto -r 3887/100 -f rawvideo - | x264 ..., with a script using LWLibavVideoSource(...) without fpsnum (12,434 frames 1:1).
    -r + -fps_mode auto on rawvideo makes ffmpeg CFR-convert (nominal ~59.94 → 38.87), so only 8,065 of 12,434 frames reach x264. mp4fpsmod then applies the first 8,065 timecodes (video source duration 2:14.551 in MediaInfo; container 3:27.485).

    Fix: when timecodes will be applied, the pipe must use -fps_mode passthrough and no -r, so every frameserver frame reaches the encoder 1:1.

  4. Suggestion: CFR conversion target for VFR sources.
    With "CFR Output" checked, Hybrid uses fpsnum=3887,fpsden=100 (the average rate). For sources on a fixed refresh grid (screen recordings, phone captures: 60 Hz base, 19200 tbn), the average is the worst possible target: 2,133 drops + 2,133 dups here, visible judder, and frame indices drift (src 300 → dst ~380, src 3000 → dst ~2703). Using the base rate (60/1, derived from the timestamp GCD / timebase rather than the rounded 59.94 tbr), or at least offering it as an option, gives judder-free CFR output.
Debug logs (variable and constant runs), MediaInfo, ffprobe CSV and the bad/good timecode files are available.

Regarding the #4 "Suggestion" above, Hybrid output to the "Log" tab "Current frame rate: 59.946 differs from average time code frame rate: 38.87. This will be ignored since 'Check average fps of mkv/mp4 files' is disabled." As much as I tried, I could not find any Check average fps of mkv/mp4 files setting. I'm not sure if that would have any bearing on anything here. Confused
 

.zip   Hybrid_Variable_Framerate_Issue.zip (Size: 946,94 KB / Downloads: 4)

Contents of attachment:

  • MediaInfo_Source.txt - MediaInfo output (advanced) for source file.

  • MediaInfo_Destination_Variable.txt - MediaInfo output (advanced) for destination file encoded with Hybrid and variable bitrate using Test_vid_source.tc timecode v2 file with incorrect number of frames (19,173); number of frames (8,065) and duration (00:03:27.485) in output file are incorrect.

  • MediaInfo_Destination_Constant.txt - MediaInfo output (advanced) for destination file encoded with Hybrid and constant bitrate; number of frames (12,434) and duration (00:05:19.887) are correct in output file, audio is synced, but playback is choppy and video frame captures don't line up between source and destination matching frame numbers (checked using VirtualDub2).

  • Test_vid_source.tc - Output from ffmpeg.exe -y -i "Test_vid_source.mov" -map 0:0 -f mkvtimestamp_v2 "Test_vid_source.txt" (this is what Hybrid currently uses); incorrect number of frames (19,173).

  • Test_vid_source.csv - Output from ffprobe -v error -select_streams v:0 -show_entries frame=coded_picture_number,pts_time -of csv "Test_vid_source.mov" > "Test_vid_source.csv"; this takes longer to run than Hybrid's FFmpeg command above but is much more accurate, and in this case has the correct number of frames (12,434). You may want to consider using this instead of FFmpeg with -fps_mode passthrough.

  • HybridDebugOutput_variable.zip - Hybrid's highest level debug output file for re-encoding the source file with Hybrid and variable bitrate using Test_vid_source.tc timecode v2 file with incorrect number of frames (19,173); number of frames (8,065) and duration (00:03:27.485) in output file are incorrect.

  • HybridDebugOutput_constant.zip - Hybrid's highest level debug output file for re-encoding the source file with Hybrid and constant bitrate; number of frames (12,434) and duration (00:05:19.887) are correct in output file, audio is synced, but playback is choppy and video frame captures don't line up between source and destination matching frame numbers.

    AI Output Files

  • abacus_ai_chat_llm_agent_max.md - Full output from Abacus AI ChatLLM Agent/Max.

  • Test_vid_source_correct_v2.tc - "The corrected timecode v2 file built from your ffprobe CSV: 12,434 timestamps in ms, presentation order, starting at 0."

  • csv_to_tcv2.py - "Converts any ffprobe pts_time CSV into a v2 timecode file (run: python csv_to_tcv2.py in.csv out.tc)."
Reply
#2
If your got a 'buggy' source like this the
"Suggestion: CFR conversion target for VFR sources."
is reasonable and Hybrid already does support this.

You can tell Hybrid to work this way,
  • by enabling "Config->Input->Decoding->CFR output" you tell Hybrid to decode the source to CFR (with the detected average frame rate)
  • if the target frame rate is not detected correctly or should be something else "Filtering->Misc->Overwrite Input->Frame rate" allows to set the frame rate that should be assumed

If the time codes of your source are problematic you can also try enabling "Config->Internals->Handling->Ignore all input timecodes" and if needed overwrite the input frame rate as mentioned above.

If neither of those help, I would need a sample clip (~30 seconds) of such content to suggest another approach or modify on how to deal with such content.

Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)