commit 90807cb6bca3093512a3e9ad78ac3f94fbb5ebf7 Author: wangchunlin Date: Wed Sep 6 20:01:18 2023 +0800 现在存在段错误,使用librt库来操作共享内存mmap 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; +}