Reputation: 517
I need to capture 10 frames per second of a live camera for 15 min. I used dispatcherTimer class but seems it doesn't work accurately. How to make it accurate? I even don't save the image because it is time consuming and i just keep it in the memory but still it doesn't work correctly. should I use another library?
counter01 = new DispatcherTimer();
counter01.Tick += new EventHandler(counter01_Tick);
counter01.Interval = new TimeSpan(0, 0, 0,100); // every 100 milliseconds == 10 frames per seconds
Upvotes: 2
Views: 2584
Reputation: 3312
You actually can get the DispatcherTimer
to execute the DispatcherTimer.Tick
event every 100 milliseconds on a good PC, but you have to address 2 problems first (see below). However, as others wrote here correctly, the processing of a frame will take some time too and the fastest reliable tick frequency might only be 5 ticks per second, if the frame processing itself takes about 100 milliseconds.
1) Choose higher DispatcherTimer.Priority
The DispatcherTimer
runs on the WPF GUI thread. The advantage of this is that the code of DispatcherTimer.Tick
can access any WPF control. The WPF GUI thread is controlled by a Dispatcher
, which has a priority queue for activities the WPF GUI thread wants to execute. Rendering related activities have a higher priority than the DispatcherTimer
has per default. The default priority of the DispatcherTimer
is DispatcherPriority.Background
. With this priority, the Tick can execute on my PC not faster than every 100..300 milliseconds. However, create the timer like this: new DispatcherTimer (DispatcherPriority.Input)
and it will fire about 100..200 milliseconds. Rendering will still have a higher priority, so the user does not get a frozen GUI.
2) Improve Tick regularity
One problem with the DispatcherTimer
is that if the Tick event gets delayed by x milliseconds because the WPF GUI thread is busy with other activities, the next Tick will still wait for 100+ milliseconds. However, if you shorten DispatcherTimer.Interval
by x milliseconds, you will get a more regular firing of the tick event.
For more details see my article on CodeProject: Improving the WPF DispatcherTimer Precision
Final Consideration
Why do you want to process the frames on the WPF GUI thread ? Use a DispatcherTimer
only if the Tick event has little to do and needs access to the WPF controls. However, if you need to execute quite some code every 100 milliseconds, better use an additional thread. Your CPU has different cores and it is a good idea to distribute the workload over 2 cores.
Upvotes: 1
Reputation: 941715
It is as accurate as it can be. Which requires your UI thread to be responsive, quickly dispatching any messages it gets. Including the "time is up" notifications that DispatcherTimer generates, the ones that generate the Tick event.
The usual hangup with seeing DispatcherTimer triggering the Tick event handler late is that you have a firehose problem. In other words, the amount of time required by the event handler is longer than the timer's Interval property value. This takes care of itself in the manner you expect, whenever you try to do more than the machine can handle then whatever you are trying to do just runs later.
No lack of firehose problems with video, one frame can contain a lot of data. A typical hidef video stream runs at 25 frames per second with each frame containing 1920x1080 pixels. That's 25 x 1920 x 1080 x 3 = 148 megabytes/second. Short from decompressing overhead, you can't even write the data to a disk at that rate. Most consumer-level disk drives top out at 30 megabytes/second, give or take a factor of 2. Lowering the frame rate to 10/sec is not enough to solve it, that's still 60 MB/sec, you have to take more drastic measures like reducing the frame size. Or use a good video encoder that can compress video real-time.
This is a systemic problem, not a DispatcherTimer problem. Use a profiler to get more insight, it helps you identify the true bottle-neck.
Upvotes: 2
Reputation: 3625
MSDN states that:
Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs.
You can check StopWatch, it might help you.
Upvotes: 2