|
|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
#include <zmq.hpp>
|
|
|
|
|
#include <chrono>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
|
|
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<char*>(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<double> elapsedSeconds = currentTime - startTime;
|
|
|
|
|
|
|
|
|
|
// 计算已经过去的时间
|
|
|
|
|
std::chrono::duration<double> 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<int>(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<int>(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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关闭套接字
|
|
|
|
|
|