Periodic 1-3 s "fps dips" (repeated frames) in recordings and preview, game frame pacing is even per CapFrameX

Hitman47

New Member
Title: Periodic 1-3 s "fps dips" (repeated frames) in recordings and preview, game frame pacing is even per CapFrameX

Setup
Ryzen 7 7700, RTX 4060 8 GB (driver 32.0.16.1714), 32 GB RAM, Windows 11 25H2, OBS 32.2.2.
OBS output 1920x1080 at 59.948 fps (also tested 60 and 120), NVENC H.264.
Main monitor 165 Hz with G-Sync, second monitor 60 Hz.
Game FPS capped to the same fractional value via NVIDIA panel or RTSS.
Games: DOOM The Dark Ages (Vulkan), Cyberpunk 2077, Stalker 2.

Problem
Roughly every 10 s (not exactly periodic) the picture looks like an fps drop for 1-3 seconds, not a freeze.
It is visible in the OBS preview without recording, in local recordings, in streams. The game itself looks smooth on the monitor.
It is often, but not always, in the same places of the DOOM benchmark.

Measurements
1) CapFrameX, same DOOM benchmark, capped at 59.948:
- Without OBS: MsBetweenPresents std 0.03 ms, no frame over 17.2 ms.
- With OBS open (preview on): presents stay even (std 0.39 ms), but MsBetweenDisplayChange std rises from 0.24 to 1.04 ms, intervals over 18 ms go from 36 to 330, under 14 ms from 2 to 58.
2) 54 s local recording (60 fps): container timestamps are even (16/17 ms), but frame content shows ~21 repeated frames within about 2 seconds (around 41-43 s), often followed by a larger motion step. A second cluster is at about 12-17 s. This matches where I saw the stutter.
3) OBS log: no skipped or lagged frames, profiler is clean (render 99.98% within 16.67 ms). Game capture "vulkan capture freed" restarts do not coincide with the stutters.
4) At 120 fps OBS output the result was mixed: one 2-minute gameplay recording looked almost clean, with one visible hitch that seems to match a game-side spike in CapFrameX (time alignment is approximate), while an earlier 120 fps test still showed the stutter.

Already tried, no improvement
Run as admin, process priority, Game Mode on/off, HAGS on/off (off is worse), G-Sync on/off, low latency mode (off is worse), Reflex off (worse), RTSS async / front edge sync, NVIDIA panel limiter, exact fractional fps caps in game / panel / RTSS / OBS, Display Capture and Window Capture (WGC and DXGI), game capture hook rate, new scene with only game capture, limit capture framerate, lowest NVENC settings, x264 (worse in Cyberpunk), second monitor disconnected, MPO off, power mode, Defender exclusions, lowering texture quality (VRAM), Frame Generation off, browser source hardware acceleration on/off. Network is not the cause (iperf3 at 12 Mbit/s and ping are clean, and the stutter is also in local recordings).

Question
Is this a known limitation of game capture on this kind of setup? Is there anything else I should check or measure? I can provide the full log, CapFrameX JSON files and a short clip.

https://obsproject.com/logs/GIwwfbBII7GqL3uW
 
Video stutter is very frustrating, I spent a long time doing the things you've tried until I found the video below on this forum. The video solved periodic stutter issues for me... or rather, a workaround I guess.

It was a while ago I looked at this, and some things may or may not be an issue now, or I was doing it wrong... below are some ramblings of my experience, but the video explains it all properly. I am using 60 Hz refresh on a single vsync monitor and OBS at 60 fps.

My main issues I think were:
  1. First, I needed to get the game itself running at stable 60 fps as much as possible, like 99% of the time, with slight drops in certain situations unavoidable. The video explains some set up stuff for that.
  2. In obs, I switched from manual to auto settings for recording and stream.
  3. There should be no dropped frames at all reported by obs during the recording, zero is what you want on that.
  4. Monitor refresh should be as close as possible to 60.000000 Hz (if recording at 60 fps). You can conveniently edit the refresh in a tool like CRU. See further down for drift line info, but the video explains it.
  5. Variable refresh is smooth in game, but wrecks the obs output for me. OBS wants perfect 60 fps. When playing WoW, it's as smooth as butter with zero hitching when I have the game optimized for 60 fps and vsync on the monitor. Any third party vsync tool was not needed for me, and standard Nvidia vsync is perfect.
  6. And I am not using no kind of fps limiter at all, using only vsync to keep fps as close as possible to monitor 60.000000 refresh. Seems like fps limiter creates a situation where the limiter and vsync are competing or something.
  7. The monitor drift line (see video) hitting top or bottom of screen causes a stutter in output but a possibly hard to notice hitch in game... the closer your refresh is to 60.000000 (or whatever monitor is at) the longer the stutter. For example if refresh is 60.1 the stutter could be a second or two every minute. If refresh is 60.000001 the line takes a very long time to reach top or bottom, and when it does the stutter is very long like an hour.
  8. If refresh is >= 60 the drift line moves down, below 60 it moves up. And the drift line could START near the top/bottom and reach there sooner. The video explains how to deal with that.
  9. Not using a single monitor, second monitor caused the drift line to move faster because it's refresh was less perfect than main monitor.
  10. For some reason, in the top quarter of my screen there is a zone where the drift line passing through it causes a hitch when line moves down, but not when moves up.
  11. And, I realized when I was skipping through the video to find hitches, that alone can cause what looks like a hitch or half fps. I have to pause the video once or twice after skipping through it to see it smooth, meaning the recording was not the issue in that instance.

 
Last edited:
Can you look at the OBS Full Screen Projector to find current frequency mismatch of the display device and let's say "capturing/rendering clocks"?
  1. Make a new Scene Collection and new Profile from main menu of OBS.
  2. Set OBS "Base (Canvas) Resolution" and "Output (Scaled) Resolution" to resolution of your monitor.
  3. Set farmerate of OBS to "Fractional FPS Value", Numerator=60000, Denominator=1000 (it is still = 60Hz; these values will be adjusted later, thus so strange numbers here).
  4. Add to the Sources list the test image that consist of vertical stripes of different width (the "tear_detector_texture_160x90.png" attached below).
  5. Apply Transform to the source to stretch the test image to fill whole canvas (right-click menu over the source Transform > Stretch to Screen or "Ctrl + S" shortcut).
  6. Add a new "Scroll" filter to the recently added source (from p.4).
  7. Set Horizontal speed for the filter, so the image moves from left to right with slow speed (about -40 pixels for the 1280 screen at 96dpi for 60 HZ device is OK).
  8. Right-click over the Preview window and run "Fullscreen Projector (Preview)" for the target display device.
  9. Look at the screen with scrolling image and try to notice the "tearing" effect. Is there any? Wait a bit, it maybe hard to see, if it is at the top or already at the bottom of the display.
Example. The picture emulates viewing experience of the "tearing" effect (horizontal "line"):
visual_perception_of_the_horizontal_tearing.png

Is there a tearing line that is slowly moving to the top (to the "59-" Hz line) or to the bottom (to the "60+" Hz line) in your setup?
If this line is moving from top to the bottom (to "60+") - set OBS framerate denominator (from p.3) to 999. If this line is moving from bottom to the top (to "59-") - set OBS framerate denominator (from p.3) to 1001. Then look at the Fullscreen Projector again and notice if the tearing line is moving slower or have changed its direction. The frequencies has tendency to float by itself, so it is almost never static line - it rather slowly moving. On the test image the "59-" sign at the top means that this display updates information from top to bottom and has frequency smaller than the OBS was configured to (60 Hz was set as the base value for the framerate in OBS).

Tearing effect best viewing conditions.
This is approximate formula for a small screens; 4K displays needs more dense texture (like x4 times tiled picture).
Set OBS "Scroll" filter parameter Horizontal speed = screen_width_px/23-displayDPI
Example: Horizontal speed = 1280/23-96=-40 (values for the "Philips 190C" display device from the log).

So, if you experience the mentioned effect, please read more info in these treads:
https://obsproject.com/forum/thread...-dropped-frames-in-the-recorded-video.186714/
https://obsproject.com/forum/thread...would-integrate-it-within-the-setting.160015/
I think, this is the most relevant information that you can find on this forum about the problem. Or maybe you have completely different problem.
 

Attachments

  • tear_detector_texture_160x90.png
    tear_detector_texture_160x90.png
    1.3 KB · Views: 35
Can you look at the OBS Full Screen Projector to find current frequency mismatch of the display device and let's say "capturing/rendering clocks"?
  1. Make a new Scene Collection and new Profile from main menu of OBS.
  2. Set OBS "Base (Canvas) Resolution" and "Output (Scaled) Resolution" to resolution of your monitor.
  3. Set farmerate of OBS to "Fractional FPS Value", Numerator=60000, Denominator=1000 (it is still = 60Hz; these values will be adjusted later, thus so strange numbers here).
  4. Add to the Sources list the test image that consist of vertical stripes of different width (the "tear_detector_texture_160x90.png" attached below).
  5. Apply Transform to the source to stretch the test image to fill whole canvas (right-click menu over the source Transform > Stretch to Screen or "Ctrl + S" shortcut).
  6. Add a new "Scroll" filter to the recently added source (from p.4).
  7. Set Horizontal speed for the filter, so the image moves from left to right with slow speed (about -40 pixels for the 1280 screen at 96dpi for 60 HZ device is OK).
  8. Right-click over the Preview window and run "Fullscreen Projector (Preview)" for the target display device.
  9. Look at the screen with scrolling image and try to notice the "tearing" effect. Is there any? Wait a bit, it maybe hard to see, if it is at the top or already at the bottom of the display.
Example. The picture emulates viewing experience of the "tearing" effect (horizontal "line"):

Is there a tearing line that is slowly moving to the top (to the "59-" Hz line) or to the bottom (to the "60+" Hz line) in your setup?
If this line is moving from top to the bottom (to "60+") - set OBS framerate denominator (from p.3) to 999. If this line is moving from bottom to the top (to "59-") - set OBS framerate denominator (from p.3) to 1001. Then look at the Fullscreen Projector again and notice if the tearing line is moving slower or have changed its direction. The frequencies has tendency to float by itself, so it is almost never static line - it rather slowly moving. On the test image the "59-" sign at the top means that this display updates information from top to bottom and has frequency smaller than the OBS was configured to (60 Hz was set as the base value for the framerate in OBS).

Tearing effect best viewing conditions.
This is approximate formula for a small screens; 4K displays needs more dense texture (like x4 times tiled picture).
Set OBS "Scroll" filter parameter Horizontal speed = screen_width_px/23-displayDPI
Example: Horizontal speed = 1280/23-96=-40 (values for the "Philips 190C" display device from the log).

So, if you experience the mentioned effect, please read more info in these treads:
https://obsproject.com/forum/thread...-dropped-frames-in-the-recorded-video.186714/
https://obsproject.com/forum/thread...would-integrate-it-within-the-setting.160015/
I think, this is the most relevant information that you can find on this forum about the problem. Or maybe you have completely different problem.
Thanks for the reply. I tried following your instructions step by step. I don't see any tearing lines at all, regardless of the framerate value I set in OBS. The image moves very smoothly most of the time, but there are periodic stutters (not screen tearing).
 
The tearing is just detector for the sync (timing). Try to read the info in the mentioned links, especially the: https://obsproject.com/forum/thread...would-integrate-it-within-the-setting.160015/

The tearing is just detector for the sync (timing). Try to read the info in the mentioned links, especially the: https://obsproject.com/forum/thread...would-integrate-it-within-the-setting.160015/
I tested different FPS values, using the exact fractional refresh rates of both my main monitor and my secondary monitor as reference points. However, the frame drops are still there.

The thing is, they occur even with G-Sync enabled, when the monitor's refresh rate is matched very closely to the game's FPS.

Without G-Sync, playing at 60 Hz is practically impossible because of severe synchronization issues, with constant screen tearing across the display.
 
Last edited:
165Hz / 60 fps = 2.75 - this is either 3 or 2 frames, thus some frames should be skipped or doubled.
120Hz / 60fps = 2 - this is always 2 frames.
60Hz / 60fps = 1 - this is always 1 frame.

OBS produces constant frame rate recordings.
G-sync adapts (on the fly) to already variable frame rate render.

Even variable frame rate recording wouldn't fix the problem. Because at some point you will try to edit such video in the video editor - and there all frames should be perfectly aligned in time. The frames rendered later should be displayed later. The moving object should be shifted in time and this "feel" that is not in the right place will break "smoothness" of the footage. Thus, the true feel of smooth movement cannot be reached. Better to have constant FPS. If you want to make some experiments, the NVIDIA app was mentioned in the https://obsproject.com/forum/threads/vrr-g-sync-freesync-support.196257/ thread as example of the tool that able to produce variable frame rate recordings (you may skip few words about the capture cards in that thread).

In short, what is good for a casual user is bad for the streamer.

Edit: typos.
 
Last edited:
165Hz / 60 fps = 2.75 - this is either 3 or 2 frames, thus some frames should be skipped or doubled.
120Hz / 60fps = 2 - this is always 2 frames.
60Hz / 60fps = 1 - this is always 1 frame.

OBS produces constant frame rate recordings.
G-sync adapts (on the fly) to already variable frame rate render.

Even variable frame rate recording wouldn't fix the problem. Because at some point you will try to edit such video in the video editor - and there all frames should be perfectly aligned in time. The frames rendered later should be displayed later. The moving object should be shifted in time and this "feel" that is not in the right place will break "smoothness" of the footage. Thus, the true feel of smooth movement cannot be reached. Better to have constant FPS. If you want to make some experiments, the NVIDIA app was mentioned in the https://obsproject.com/forum/threads/vrr-g-sync-freesync-support.196257/ thread as example of the tool that able to produce variable frame rate recordings (you may skip few words about the capture cards in that thread).

In short, what is good for a casual user is bad for the streamer.

Edit: typos.
I've been discussing my micro-stuttering issue with Claude Code for quite some time, and it eventually helped me create a patch for OBS Studio. It seems to work in my case, and the stuttering I've been experiencing appears to be completely gone.
This modification applies only to the "Legacy DXGI" screen capture method.
The following changes were made to the screen capture implementation in libobs-d3d11/d3d11-duplicator.cpp:
  • Moved frame acquisition to a separate thread using a dedicated D3D11 device.
  • Implemented a frame queue and a ring buffer of shared textures to transfer captured frames to the OBS rendering thread.
  • Added timestamp-based frame scheduling with a configurable buffer delay, along with frame dropping and frame repetition to handle differences between capture and rendering rates.
  • Added a fallback to the original capture implementation if the separate-device approach fails, as well as an option to force the legacy implementation for testing.
  • Added diagnostic logging and counters to help investigate capture errors, dropped frames, and repeated frames.
I'm still treating this as an experimental modification, and I can't say whether it would help in other systems or configurations.
If the community or OBS developers are interested, I can upload my modified OBS Studio build and the source changes to GitHub for analysis and testing.
Would this be useful for further investigation into DXGI capture stuttering?
dxgi.png
 
Last edited:
Similar solution was mentioned (and published on GitHub) in the: https://obsproject.com/forum/threads/fps-drop-preview-record-need-help.195614/
Feel free to compare to yours, and get the best parts from the both. Proposed code mentions almost the same "frame queue", "delayed input", "buffer" (or whatever you name it) programming technique.

As for the AI programming, there is what OBS project maintainers have in theirs minds (in short, if "AI" then "no go"): https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.md#aimachine-learning-policy
If to read the posts on the forum and the project's GitHub page - casual people use it; programmers also use it, but do not like to mention that AI was used until asked directly. It undermines people efforts that doing programming professionally. It seems, that this is main concern, behind all the words and messages. AI code listings usually complex, hard to understand and to read (if it can use lambdas - it will use it everywhere; it is not like this is bad or not efficient, but this approach is more "algorithmic" than what people usually think, do or say). Programmers has different skills, so this also affects acceptance of the AI solutions.
My own opinion - unlikely that the proposed changes will be accepted in a nearby 6 month.
 
I hope this gets added into OBS and solves the periodic stutter issue. The workaround I do by using vsync on the game and setting the single monitor's refresh as close as possible to 60.000000 Hz, and OBS at fixed 60 fps works... but it is kind of annoying to have to nudge the sync drift line into position before starting the stream/recording. And the workaround only delays the stutter, I have to stop the stream/recording before the line reaches the bottom of the screen (~3 hours).
 
Last edited:
Back
Top