#include #include #include #include #include int main() { // 创建ZeroMQ上下文 zmq::context_t context(1); // 创建套接字并绑定到接收方 zmq::socket_t socket(context, zmq::socket_type::pull); socket.bind("ipc:///tmp/video_socket"); // 创建窗口用于显示视频 cv::namedWindow("Received Video", cv::WINDOW_NORMAL); // 统计变量 int frameCount = 0; double totalTime = 0.0; double avgFps = 0.0; double avgInterval = 0.0; std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); // 接收并实时播放视频帧 while (true) { // 接收图像数据 zmq::message_t message; socket.recv(&message); // 解析接收到的图像数据 int width, height, type; memcpy(&width, message.data(), sizeof(int)); memcpy(&height, static_cast(message.data()) + sizeof(int), sizeof(int)); memcpy(&type, static_cast(message.data()) + sizeof(int) * 2, sizeof(int)); // 计算图像数据的大小 size_t imageDataSize = message.size() - sizeof(int) * 3 - sizeof(double); // 创建图像矩阵 cv::Mat frame(height, width, type, static_cast(message.data()) + sizeof(int) * 3); // 获取帧率信息 double fps; memcpy(&fps, static_cast(message.data()) + sizeof(int) * 3 + imageDataSize, sizeof(double)); // 显示图像 cv::imshow("Received Video", frame); // 获取当前时间点 std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now(); // 计算已经过去的时间 std::chrono::duration elapsedSeconds = currentTime - startTime; // 计算应该等待的时间间隔 double expectedInterval = 1000 / fps; // 计算实际需要等待的时间间隔 double actualInterval = expectedInterval - elapsedSeconds.count() * 1000; // 更新统计变量 frameCount++; totalTime += elapsedSeconds.count(); // 每秒钟打印一次统计结果 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; } // 按下 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; // 等待剩余时间,以实现与原视频完全一致的帧率 if (actualInterval > 0) std::this_thread::sleep_for(std::chrono::milliseconds(static_cast(std::round(actualInterval)))); // 更新起始时间点 startTime = currentTime; } // 关闭套接字 socket.close(); // 关闭 ZeroMQ 上下文 context.close(); return 0; }