diff --git a/receiver.cpp b/receiver.cpp index 76d8bd6..e175d4f 100644 --- a/receiver.cpp +++ b/receiver.cpp @@ -3,6 +3,7 @@ #include #include #include +#include int main() { // 创建ZeroMQ上下文 @@ -21,6 +22,11 @@ int main() { double avgFps = 0.0; double avgInterval = 0.0; std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); + struct timeval tv1, tv2; + gettimeofday(&tv1, NULL); + int lastFrameCount = 0; + double lastTotalTime = 0.0; + float tspan = 0.0; // 接收并实时播放视频帧 while (true) { @@ -44,53 +50,69 @@ int main() { double fps; memcpy(&fps, static_cast(message.data()) + sizeof(int) * 3 + imageDataSize, sizeof(double)); - // 显示图像 - cv::imshow("Received Video", frame); + // 为了保证周期的准确,一下代码应该写到一起,关键点在于:算当前时间、等待剩余时间、重置时间三者的关系必须是依次紧挨这,中间不要加入额外操作,重置时间以后可以加入其他操作,不用着急imshow + { + // 获取当前时间点 + std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now(); - // 获取当前时间点 - std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now(); + // 计算已经过去的时间 + std::chrono::duration elapsedSeconds = currentTime - startTime; - // 计算已经过去的时间 - std::chrono::duration elapsedSeconds = currentTime - startTime; + // 计算应该等待的时间间隔 + double expectedInterval = 1000 / fps; - // 计算应该等待的时间间隔 - double expectedInterval = 1000 / fps; + // 计算实际需要等待的时间间隔 + double actualInterval = expectedInterval - elapsedSeconds.count() * 1000; - // 计算实际需要等待的时间间隔 - double actualInterval = expectedInterval - elapsedSeconds.count() * 1000; + // 等待剩余时间,以实现与原视频完全一致的帧率 + if (actualInterval > 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(static_cast(std::round(actualInterval)))); + } else { + printf("Error! Accept and process the image timeout, if it is the first frame please ignore!\n"); + } - // 更新统计变量 - frameCount++; - totalTime += elapsedSeconds.count(); + // 更新起始时间点和计时器 + startTime = std::chrono::steady_clock::now(); - // 每秒钟打印一次统计结果 - if (totalTime >= 1.0) { - avgFps = frameCount / totalTime; - avgInterval = 1000 / avgFps; - std::cout << "Average FPS (last 1 second): " << avgFps << std::endl; - std::cout << "Average Interval (last 1 second): " << avgInterval << " ms" << std::endl; - - // 重置统计变量 - frameCount = 0; - totalTime = 0.0; + // 打印帧率和时间间隔信息 + // std::cout << "Received FPS: " << fps << std::endl; + // std::cout << "Expected Interval: " << expectedInterval << " ms" << std::endl; + // std::cout << "Elapsed Seconds: " << elapsedSeconds.count() * 1000 << " ms" << std::endl; + // std::cout << "Actual Interval: " << actualInterval << " ms" << std::endl; + } + + // 调试,在imshow前引入time.h的时间来统计帧率,看是否已经实时播放 + { + gettimeofday(&tv2, NULL); + tspan = (tv2.tv_sec - tv1.tv_sec) * 1000.0 + (tv2.tv_usec - tv1.tv_usec) / 1000.0; + //printf("****************************the tspan=%f ms****************************\n", tspan); + gettimeofday(&tv1, NULL); } + // 显示图像 + cv::imshow("Received Video", frame); + // 按下 ESC 键退出循环 if (cv::waitKey(1) == 27) break; - // 打印帧率和时间间隔信息 - std::cout << "Received FPS: " << fps << std::endl; - std::cout << "Expected Interval: " << expectedInterval << " ms" << std::endl; - std::cout << "Elapsed Seconds: " << elapsedSeconds.count() << " s" << std::endl; - std::cout << "Actual Interval: " << actualInterval << " ms" << std::endl; + // 更新统计变量 + frameCount++; + totalTime += tspan/1000; - // 等待剩余时间,以实现与原视频完全一致的帧率 - if (actualInterval > 0) - std::this_thread::sleep_for(std::chrono::milliseconds(static_cast(std::round(actualInterval)))); + // 每秒钟打印一次统计结果 + if (totalTime - lastTotalTime >= 1.0) { + int currentFrameCount = frameCount - lastFrameCount; + double currentTotalTime = totalTime - lastTotalTime; + avgFps = currentFrameCount / currentTotalTime; + avgInterval = currentTotalTime * 1000 / currentFrameCount; + std::cout << "Average FPS (last 1 second): " << avgFps << std::endl; + std::cout << "Average Interval (last 1 second): " << avgInterval << " ms" << std::endl; - // 更新起始时间点 - startTime = currentTime; + // 更新上次统计的帧数和时间 + lastFrameCount = frameCount; + lastTotalTime = totalTime; + } } // 关闭套接字