Sign in to follow this  
Lukas Kadej

Videos micro stuttering with VSYNC enabled.

Recommended Posts

Lukas Kadej    176
Hey!
 
I have been struggling with this problem for quite a long time now and still cannot deal with it once and for all. There is weird micro stuttering going on during rendering of a video.
 
Let me introduce game loop sketch:
 
EngineTime lastRenderTick = EngineTime::GetNow();

EngineTime endTime;
Bool running = true;

while ( running )
{
   Bool canTick = false;
   Bool isPlayingVideo = GetVideoPlayer()->IsPlayingVideo();
   const Float minTimeDelta = 1.0f / 30.0f;
   const EngineTime currentTime = EngineTime::GetNow();
   Float timeDelta = static_cast< Float >( currentTime - lastRenderTick );
   const EngineTime timeLimit( 1.0f / 35.0f );
   if ( unclampedTimeDelta >= minTimeDelta )
   {
      canTick = true;
      lastRenderTick = currentTime;
      endTime = currentTime + timeLimit;

      // video tick (skip up to 2 frames if timeDelta > video frame length)
      m_videoPlayer->Advance( timeDelta, 2 );
   }

   while ( !m_renderCommands.Empty() && (EngineTime::GetNow() < endTime ))
   {
      //Process render commands out of which one of them is RenderFrame which renders video frame:
      if(canTick)
      {
         //Render 2D texture containing a video frame
         Render2D();
      }
   }
}
 
The issue with all this is that video suffers from micro stuttering when VSYNC is enabled. I've checked the video with external playing devices and it seems to work fine. The video framerate is 30 fps and the timeDelta that I obtain each frame varies like this (data per frame, 0.001s = 1ms):
...
0.01653
0.01647
0.01673
0.0169
0.0167
0.01649
0.01692
0.01646
0.01691
0.01649
0.01684
0.01646
0.01671
0.01701
0.01657
0.01644
0.01675
0.01692
0.01661
0.01648
0.0169
0.0165
0.01687
0.01649
0.01687
0.01649
0.01689
0.0165
0.0169
...
I also have done some GPU/CPU traces which confirm that VSYNC behaves properly, however there's this delta time varying slightly each frame so I guess maybe accumulation of the delta errors causes some frames to be skipped.
 
In order to test it decently I've prepared a test video containing 30 frames, each has an order number on it. Even frames are all white, odd ones are black. I've captured this with a 240fps GoPro camera and the maths says it should be 8 frames per single video frame. However the value differes each 5-6 frames. It takes twice as much (16 frames -> 2 VBLANKS I guess) for a frame to switch. 
 
Anyone has ever fought with such problem? Will appreciate any kind of help.

Share this post


Link to post
Share on other sites
NumberXaero    2624

Im just curious, why this, const EngineTime timeLimit( 1.0f / 35.0f ); ?

Also the branch in the while loop is dependant on if(canTick), if(canTick) outside the while loop might make more sense.

Share this post


Link to post
Share on other sites

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