OpenGL video playback frame rate

Started by
4 comments, last by irreversible 14 years, 7 months ago
I want to playback a video which has 24 frames per second. How would I render that in OpenGL. Do I lock OpenGL to only render 24 times a second? How would I do that? Thanks.
Advertisement
just load the video into an opengl texture, then draw the texture.
This would result in rendering the video as fast as possible. I guess I implement a timer and check in the OpenGL render function if 1/24th of a second has passed and then render the texture...
QueryPerformanceCounter()
QueryPerformanceFrequency()
See also VB example on usage.

and Sleep(0)

AFAIK these are the closest friends you have. It's devilishly difficult to achieve precise timing in windows as the only tools at your disposal are Sleep() or running your own poll thread (which uses QPC() (see above)).

Sleep(), even when set to 1 ms precision has huge actual granularity (even more so at default setting, which AFAIR is around 10-50 ms!). Granularity is the "error" in the sleep period (eg if you call QPC(), Sleep(20) and then QPC() again, you might notice 47 ms have elapsed instead of 20 - that's granularity).

If you need as accurate timing as possible, the best I can come up with is either creating a separate thread with below normal priority and running a tight loop in it that polls RDTSC (time stamp counter - returns essentially the same value as QPC()). Note that this will cause your application to eat up all available CPU time on the core the thread is running on (see also thread affinity). Also note that if there's a resource whore of a process running, it may cause your low priority thread to lose sync.

The most realistic solution, however, would be to use a separate thread running at high priority, polling Sleep(0) and RDTSC/QPC(). Note that calling Sleep() with the argument 0, according to specs, causes the thread to relinquish control for that cycle without causing it to miss any subsequent cycles. However, for very precise timings this may not be enough as thread CPU allocation windows (cycles) are not standardized (they depend on currently active thread/process priorities which, incidentally, you cannot foresee).

edit: to set/unset Sleep() granularity check out timeBeginPeriod() and timeEndPeriod.
You don't need highly accurate timing for rendering video. Your idea about checking whether 1/24 of a second has passed is heading in the right direction.

All you need to do is render a texture onto a quad. In your rendering loop, check whether it has been 1/24s since the last update, if not, continue, if it has been then you need to get the next frame from memory and update the OpenGL texture (using glTexSubImage2D() or something similar).

This is will allow you to update a texture at an arbitrary frame rate. Please note that issues will arise (obviously) if your rendering loop goes below 24 fps.
Very much true - 24 fps can handle up to ~41 ms granularity (and most people won't even notice you're not running at full 24 fps if you happen to fall behind a little; especially if the video is without sound). However, a non-constant framerate or (alas!) a lack of audio sync is not that hard to notice - especially since 24 fps is on the very marginal end of human perception. Fall behind sound by two frames and even though most people won't be able to pinpoint quite what the problem is, watching the video becomes uncanny. That's why clapper boards are used - getting audio and video well in sync is a real pain. Sync is also the reason why a number of timecode schemes have been devised: it needs to be accurate.

This topic is closed to new replies.

Advertisement