I'm currently working with OpenCV 4.10.0, built using the MSVC compiler. I need to load a saved .avi video file and play it back at either 30fps or 60fps, but it's not running at the exact frame rate. Upon investigation, I discovered that a significant delay is occurring in the waitKey function.
void Video::start()
{
cv::VideoCapture cam;
int delay = 1000.0 / 30.0;
cv::Mat frame;
int cnt = 0;
while(true)
{
auto loop_start_time = std::chrono::steady_clock::now();
auto frame_read_start_time = std::chrono::steady_clock::now();
cam >> frame;
auto frame_read_end_time = std::chrono::steady_clock::now();
auto frame_read_time = std::chrono::duration_cast<std::chrono::microseconds>(frame_read_end_time - frame_read_start_time).count();
std::cout << "frame read time\t: " << (double)frame_read_time / 1000.0 << std::endl;
if(frame.empty()) {std::cout << "empty" << std::endl; continue;}
cv::imshow("frame", frame);
auto draw_end_time = std::chrono::steady_clock::now();
auto frame_draw_time = std::chrono::duration_cast<std::chrono::microseconds>(draw_end_time - frame_read_end_time).count();
std::cout << "frame draw time\t: " << (double)frame_draw_time / 1000.0 << std::endl;
cv::waitKey(1); // not 1ms current 12ms~25ms
// std::clock_t start = std::clock();
// while(std::clock() - start < delay);
auto loop_end_time = std::chrono::steady_clock::now();
auto loop_time = std::chrono::duration_cast<std::chrono::microseconds>(loop_end_time - loop_start_time).count();
std::cout << "loop total time\t: " << (double)loop_time / 1000.0 << ",\tdelay\t: " << delay << std::endl;
}
}
The above code is intended to provide a 1ms delay while playing the image. However, instead of a 1ms delay, cv::waitKey(1) currently incurs a delay of 12 to 25ms.
As an alternative solution, I used the code below to create a delay within the loop, but if I don't call waitKey(1), the image does not display.
std::clock_t start = std::clock();
while(std::clock() - start < delay);
Could you advise if there is a solution to this issue?