C++ | 内存共享
2021/8/1 7:07:34
本文主要是介绍C++ | 内存共享,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、背景
最近在做美颜软件虚拟摄像头的功能,类似YY开播(我们获取笔记本的摄像头列表时,列表中除了自带的摄像头,以及usb的摄像头,还有YY开播),查了一下网络上实现的虚拟摄像头展示的都是本地的视频,但是我这边的美颜软件需要读取自带摄像头拍摄的画面,美颜后将视频帧数据传输到虚拟摄像头中,当我们调用虚拟摄像头的时候就能看到美颜后的画面,这个功能的实现就用到了美颜软件和虚拟摄像头的内存共享。
二、代码实现
1.美颜软件写数据
(1)注册共享句柄
QMap<const char*, void*> mRegisterData; void* RegisterSendData(const char *name, const int buf_size) { if (mRegisterData.count(name) > 0) { return mRegisterData[name]; } HANDLE hMapFile2 = CreateFileMapping( INVALID_HANDLE_VALUE, // 物理文件句柄 NULL, // 默认安全级别 PAGE_READWRITE, // 可读可写 0, // 高位文件大小 buf_size, // 低位文件大小 name // 共享内存名称 ); // 映射缓存区视图 , 得到指向共享内存的指针 if (hMapFile2 != nullptr) { void* lpBase2 = MapViewOfFile( hMapFile2, // 共享内存的句柄 FILE_MAP_ALL_ACCESS, // 可读写许可 0, 0, buf_size ); mRegisterData.insert (name, lpBase2); return mRegisterData[name]; } else { return nullptr; } }
(2)写共享数据
void set_buffer_data(LPVOID lpBase,unsigned char* buffer_data, int buffer_size) { if(lpBase) { memcpy((unsigned char*)lpBase, buffer_data, buffer_size); } }
(3)调用
LPVOID lpBase= register_data("FrameBuffer",800* 600 * 3); if(lpBase) { QImage map_img = effectImage.scaled(800,600);//effectImage即美颜后的图片 set_buffer_data(lpBase,map_img.bits(),BUF_SIZE); }
2.虚拟摄像头读数据
(1)注册共享句柄并获取共享内容
bool GetFrameBuffer(const char* name, unsigned char* buffer_data, const int buf_size) { if (buffer_data == nullptr) { return false; } 打开共享的文件对象 HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, name); if (hMapFile) { LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); // 将共享内存数据拷贝出来 if (lpBase != nullptr) { memcpy(buffer_data, lpBase, buf_size); // 解除文件映射 UnmapViewOfFile(lpBase); } // 关闭内存映射文件对象句柄 CloseHandle(hMapFile); return true; } else { // 打开共享内存句柄失败 std::cout << "打开共享失败!" << std::endl; return false; } }
(2)调用
unsigned char* szBuffer = nullptr; szBuffer = (unsigned char*)malloc(800*600*3*sizeof(char)); GetFrameBuffer("FrameBuffer", szBuffer, 800*600*3);
这篇关于C++ | 内存共享的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享