Search code examples
c#multithreadingvideoopencvemgucv

How to use c# to write a simple video player which plays the video with accurate fps?


I'm write a simple video play with Emgu, which is a c# wrapper of opencv.

Now I can play a video, but I found the fps is not accurate, a little faster than normal.

In my code, I use Thread.sleep() to wait a while between 2 frames. The code is:

int fps = getFromFile(file); // which is 30
while (true) {
    var frame = CvInvoke.cvQueryFrame(capture);
    if (frame.ToInt32() == 0) break;

    Image<Bgr, byte> dest = new Image<Bgr, byte>(Convert.ToInt32(width), Convert.ToInt32(height));
    CvInvoke.cvCopy(frame, dest, IntPtr.Zero);
    box.Image = dest;

    Thread.Sleep(1000 / Convert.ToInt32(fps));
}

Where is wrong, and how to fix it?


update

The box in the code is Emgu.UI.ImageBox, which is thread-safety, and I can access it from other thread directly: box.Image = dest


Solution

  • You need to keep a queue of frame objects 'topped up' and render them using a timer of some sort. Usually, I would use a pool of frame objects that are continually recycled.

    There is no simple video - vlc.exe: 13 threads, realplay.exe: 19 threads, divX player: 23 threads.