From 90807cb6bca3093512a3e9ad78ac3f94fbb5ebf7 Mon Sep 17 00:00:00 2001 From: wangchunlin Date: Wed, 6 Sep 2023 20:01:18 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E5=AD=98=E5=9C=A8=E6=AE=B5?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=8C=E4=BD=BF=E7=94=A8librt=E5=BA=93?= =?UTF-8?q?=E6=9D=A5=E6=93=8D=E4=BD=9C=E5=85=B1=E4=BA=AB=E5=86=85=E5=AD=98?= =?UTF-8?q?mmap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- receiver.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++ sender.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 receiver.cpp create mode 100644 sender.cpp diff --git a/receiver.cpp b/receiver.cpp new file mode 100644 index 0000000..c238500 --- /dev/null +++ b/receiver.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +int main() { + // 打开共享内存 + int shmFd = shm_open("/video_shm", O_RDWR, 0666); + if (shmFd == -1) { + std::cerr << "Failed to open shared memory" << std::endl; + return 1; + } + void* sharedMemory = mmap(NULL, sizeof(int) * 3 + sizeof(double), PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); + if (sharedMemory == MAP_FAILED) { + std::cerr << "Failed to map shared memory" << std::endl; + return 1; + } + + // 获取共享内存指针 + char* dataPtr = static_cast(sharedMemory); + + // 创建窗口用于显示视频 + cv::namedWindow("Received Video", cv::WINDOW_NORMAL); + + // 接收并实时播放视频帧 + while (true) { + // 读取图像尺寸 + int width = *reinterpret_cast(dataPtr); + dataPtr += sizeof(int); + int height = *reinterpret_cast(dataPtr); + dataPtr += sizeof(int); + int type = *reinterpret_cast(dataPtr); + dataPtr += sizeof(int); + + // 计算图像数据的大小 + size_t imageDataSize = width * height * CV_ELEM_SIZE(type); + + // 创建图像矩阵 + cv::Mat frame(height, width, type, reinterpret_cast(dataPtr)); + dataPtr += imageDataSize; + + // 读取帧率信息 + double fps = *reinterpret_cast(dataPtr); + dataPtr += sizeof(double); + + // 显示图像 + cv::imshow("Received Video", frame); + + // 打印帧率 + std::cout << "Received FPS: " << fps << std::endl; + + // 按下 ESC 键退出循环 + if (cv::waitKey(1) == 27) + break; + } + + // 关闭共享内存 + munmap(sharedMemory, sizeof(int) * 3 + sizeof(double)); + close(shmFd); + + return 0; +} diff --git a/sender.cpp b/sender.cpp new file mode 100644 index 0000000..00bcd7f --- /dev/null +++ b/sender.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +int main() { + // 打开视频文件 + cv::VideoCapture cap("1.mp4"); + if (!cap.isOpened()) { + std::cerr << "Failed to open video file" << std::endl; + return 1; + } + + // 获取视频帧率 + double fps = cap.get(cv::CAP_PROP_FPS); + std::cout << "Original FPS: " << fps << std::endl; + + // 获取图像尺寸 + int width = cap.get(cv::CAP_PROP_FRAME_WIDTH); + int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT); + int type = CV_8UC3; // 假设图像类型为 8 位 3 通道彩色图像 + + // 计算图像数据的大小 + size_t imageDataSize = width * height * CV_ELEM_SIZE(type); + + // 创建共享内存 + int shmFd = shm_open("/video_shm", O_CREAT | O_RDWR, 0666); + if (shmFd == -1) { + std::cerr << "Failed to create shared memory" << std::endl; + return 1; + } + size_t shmSize = sizeof(int) * 3 + imageDataSize + sizeof(double); // 计算共享内存大小 + ftruncate(shmFd, shmSize); + void* sharedMemory = mmap(NULL, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); + if (sharedMemory == MAP_FAILED) { + std::cerr << "Failed to map shared memory" << std::endl; + return 1; + } + + // 获取共享内存指针 + char* dataPtr = static_cast(sharedMemory); + + // 逐帧读取并发送 + cv::Mat frame; + while (cap.read(frame)) { + // 将图像尺寸复制到共享内存 + memcpy(dataPtr, &width, sizeof(int)); + dataPtr += sizeof(int); + memcpy(dataPtr, &height, sizeof(int)); + dataPtr += sizeof(int); + memcpy(dataPtr, &type, sizeof(int)); + dataPtr += sizeof(int); + + // 将图像数据复制到共享内存 + memcpy(dataPtr, frame.data, imageDataSize); + dataPtr += imageDataSize; + + // 将帧率信息复制到共享内存 + memcpy(dataPtr, &fps, sizeof(double)); + + // 等待接收方读取共享内存 + usleep(1000); + + // 打印帧率 + std::cout << "Sent FPS: " << fps << std::endl; + } + + // 关闭共享内存 + munmap(sharedMemory, shmSize); + close(shmFd); + shm_unlink("/video_shm"); + + return 0; +}