Sign in to follow this  

Sync Video Frame Rate

This topic is 2830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Guys. I am using SDL to development my experiment program. My experiment requires a very accurate time control. My question is if I can fresh my program exactly at the same time when the video freshes itself? So, say if my monitor freshes 60frames per second. Then I need my program to fresh synchronizely with the monitor every frame. Therefore, if I run something like below
int result;
timer.start();
for(int i = 0; i < 60; i ++)
    SDL_Flip(screen); // or any other blit function here
result = timer.get_ticks();
I would expect that the result was 1000, ie. one second.. Any help will be highly appreciated. Please see the diagrams in 4th post, which might explain clearer what I want [Edited by - mylifemysoul on March 15, 2010 2:52:17 PM]

Share this post


Link to post
Share on other sites
In most applications it'll do that automatically. It's called vsync and is enabled by default in any OpenGL/DirectX application.

However, that doesn't guarantee you will run at 60fps. It just means you won't run faster than 60fps. You can run much slower, depending on how fast your code is (use a profiler if you're running less than 60fps to find out why). Also, the monitor isn't that accurately timed so it's not useful to use that as a timer.

You're better off using something like QueryPerformanceTimer (if you're on windows) to calculate the time since last frame and passing that delta time through your update methods.

-me

Share this post


Link to post
Share on other sites
I understand what you're saying.

diagram 1

A B C D
|_____________|____________|_____________|
| | |
(1) (2) (3)


In the above diagram, "A,B,C,D" means where the monitor actually refreshes itself.
So, if my monitor's fresh rate is 100Hz. Then, the time between every two letters should be 10ms.

If I can ensure my program's logic update fast enough before the monitor fresh itself, e.g. at (1), (2), (3). When I do a SDL_Flip(screenSurface) (or other functions in OpenGL or Direct3d) at these places, do they wait until they get to B, C, D to blit the 'screenSurface' on the screen?

If so, when I do the code in my first post, the timer should get a value of one second, shouldn't it?

My purpose is prevent the sitation showed in the following diagram from happening.
diagram 2

A B C D E
|_____________|____________|_____________|_____________|
| | |
(1) (2) (3)

As you can see, if something happens in (2). It ends up with (1) and (3) updates in one frame time, but (2) will use 2 frames time, i.e. B and C will display a same image one the screen.

If I knew the above thing could happen, then I would rather both (1) and (3) also take 2 frames time. So there would be no jitters at all. Look at the following diagram.
diagram 3

A B C D ...
|_______|_______|_______|_______|_______|_______|_______|_____
| | | |
(1) (2) (3) ...


[Edited by - mylifemysoul on March 15, 2010 3:49:26 PM]

Share this post


Link to post
Share on other sites
Yes it should, but it depends on how you set SDL up and possibly other things, like settings in your graphics card control panel. See documentation for SDL_Flip for example. Look up documentation on the functions you use to set up, such as SDL_SetVideoMode, to see what they say about vsync.

Share this post


Link to post
Share on other sites
Quote:
Original post by Erik Rufelt
Yes it should, but it depends on how you set SDL up and possibly other things, like settings in your graphics card control panel. See documentation for SDL_Flip for example. Look up documentation on the functions you use to set up, such as SDL_SetVideoMode, to see what they say about vsync.


I did. But there isn't any information from SDL about VSYNC.
Any suggestion?

Share this post


Link to post
Share on other sites
Reading that page on SDL_Flip I linked to and the one on SDL_SetVideoMode, it seems to me you need to use SDL_DOUBLEBUF and SDL_HWSURFACE when setting the video mode. Does it not work?

For the situation you want to avoid, where (2) lags behind a frame, you can't prevent that with vsync. It would be a result of that your program logic can't keep up with the refresh rate, and if your program can't run at 60 Hz then there's nothing to do. What you might mean, is if you run at 80 Hz or something, so that (2) would never have the chance to be displayed before (3) is done, or similar. This can be fixed with vsync, as Flip will always wait until monitor refresh (ignoring potential frame-buffering for the first few frames).

What exactly is it you want to achieve with this?
It might be better to write your program logic separate from the screen refresh, depending on what your desired end result is.

Share this post


Link to post
Share on other sites
Quote:
Original post by Erik Rufelt
Reading that page on SDL_Flip I linked to and the one on SDL_SetVideoMode, it seems to me you need to use SDL_DOUBLEBUF and SDL_HWSURFACE when setting the video mode. Does it not work?

For the situation you want to avoid, where (2) lags behind a frame, you can't prevent that with vsync. It would be a result of that your program logic can't keep up with the refresh rate, and if your program can't run at 60 Hz then there's nothing to do. What you might mean, is if you run at 80 Hz or something, so that (2) would never have the chance to be displayed before (3) is done, or similar. This can be fixed with vsync, as Flip will always wait until monitor refresh (ignoring potential frame-buffering for the first few frames).

What exactly is it you want to achieve with this?
It might be better to write your program logic separate from the screen refresh, depending on what your desired end result is.


My purpose is to avoid jitters as much as possible. So if (2) takes 2 frames, as I show in diagram 3, I will want both (1) and (3) to use 2 frames as well.

Share this post


Link to post
Share on other sites
Use D3D or OpenGL, and specify a swap-interval. In OpenGL on Windows you use wglSwapIntervalEXT, which can be told to update at either 0, which means as fast as possible, or every N screen refreshes. The same functionality exists in D3D, when creating your device or swap-chain, and sometimes as part of the actual Flip function. If you create your OpenGL context through SDL this should still work.

There's no built-in functionality to slow all frames down to 2 refreshes just because one frame takes too long, but you could implement it yourself by checking if the time from last frame is too large. If it is, increase the number to wglSwapIntervalEXT. Again, this can almost always be overridden from the graphics card control panel, which means your wglSwapIntervalEXT calls will silently fail and won't have any effect. The user can always override this behavior, but often (most of the time?) the application is allowed to decide.

Share this post


Link to post
Share on other sites
Quote:
Original post by Erik Rufelt
Use D3D or OpenGL, and specify a swap-interval. In OpenGL on Windows you use wglSwapIntervalEXT, which can be told to update at either 0, which means as fast as possible, or every N screen refreshes. The same functionality exists in D3D, when creating your device or swap-chain, and sometimes as part of the actual Flip function. If you create your OpenGL context through SDL this should still work.

There's no built-in functionality to slow all frames down to 2 refreshes just because one frame takes too long, but you could implement it yourself by checking if the time from last frame is too large. If it is, increase the number to wglSwapIntervalEXT. Again, this can almost always be overridden from the graphics card control panel, which means your wglSwapIntervalEXT calls will silently fail and won't have any effect. The user can always override this behavior, but often (most of the time?) the application is allowed to decide.


Thanks for the suggestion of using SDL_OpenGL.

I've just searched the form and get a previous post regards this:
http://www.gamedev.net/community/forums/topic.asp?topic_id=381574

The author mentioned in FULLSCREEN mode, the SDL_Flip() will wait for Vsync, which I am really not sure. If it is true, then the code in my first post will result 1000ms

Share this post


Link to post
Share on other sites

This topic is 2830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this