经过测试,这种方式捕获图像推流的性能较差,如果没有特殊需求还是推荐使用例程中提供的方式。Crocodile wrote: ↑2024-02-27 7:35您好,首先感谢您的尝试,瑞芯微的官方文档在构建 VIDEO_FRAME_INFO_S 结构体并没有提及太多的细节,经过我们的测试发现要使 VIDEO_FRAME_INFO_S 能够被 VENC 模块成功获取需要确保 内存缓冲块 能够成功申请,您需要执行的步骤如下:W凯先森~ wrote: ↑2024-02-26 4:31如何创建一个 VIDEO_FRAME_INFO_S 结构体将 opencv-mobile 获取的图像数据拷贝进去再上传到 venc 编码?我这不行Crocodile wrote: ↑2024-02-22 2:10 您好,这是一个 luckfox-pico 使用 rtsp 推流人脸检测结果图像的例程,您可以参考一下
https://github.com/luckfox-eng29/luckfo ... etinaface/
目前使用的方案是 vi 与 vpss 连接,从 vpss 中获取一帧图像使用 opencv-mobile 处理后使用 RK_MPI_VENC_SendFrame 将帧数据上传到 venc 编码为 H264 再进行 rtsp 推流。
您可以参考这个例程直接创建一个 VIDEO_FRAME_INFO_S 结构体将 opencv-mobile 获取的图像数据拷贝进去再上传到 venc 编码;
本例程使用的 rtsp 推流方案使用的是瑞芯微官方提供的接口,对输入格式有需求也没有开放源码,您也可以采取使用其他 rtspsetver 方案,支持更多格式的输入。
1.构建一个内存缓冲池2.从内存缓冲池中获取缓冲块Code: Select all
VIDEO_FRAME_INFO_S h264_frame; MB_POOL_CONFIG_S PoolCfg; memset(&PoolCfg, 0, sizeof(MB_POOL_CONFIG_S)); PoolCfg.u64MBSize = width*height*3 ; PoolCfg.u32MBCnt = 1; PoolCfg.enAllocType = MB_ALLOC_TYPE_DMA; //PoolCfg.bPreAlloc = RK_FALSE; MB_POOL src_Pool = RK_MPI_MB_CreatePool(&PoolCfg); printf("Create Pool success !\n");
3.将opencv获取到的图像转换为 RGB888 格式传入缓冲块的虚拟地址Code: Select all
MB_BLK src_Blk = RK_MPI_MB_GetMB(src_Pool, width*height*3, RK_TRUE);
4.将创建的 VIDEO_FRAME_INFO_S 传入VENC中Code: Select all
h264_frame.stVFrame.u32Width = 480; h264_frame.stVFrame.u32Height = 480; h264_frame.stVFrame.u32VirWidth = 480; h264_frame.stVFrame.u32VirHeight = 480; h264_frame.stVFrame.enPixelFormat = RK_FMT_RGB888; h264_frame.stVFrame.u32TimeRef = H264_TimeRef++; //标识为第几帧 h264_frame.stVFrame.u64PTS = TEST_COMM_GetNowUs(); //获取当前时间戳 h264_frame.stVFrame.u32FrameFlag = 160; h264_frame.stVFrame.pMbBlk = src_Blk; unsigned char *data = (unsigned char *)RK_MPI_MB_Handle2VirAddr(src_Blk); cap >> bgr; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { cv::Vec3b pixel = bgr.at<cv::Vec3b>(y, x); data[(y * width + x) * 3 + 0] = pixel[2]; // Red data[(y * width + x) * 3 + 1] = pixel[1]; // Green data[(y * width + x) * 3 + 2] = pixel[0]; // Blue } }
RTSP推流设置方面与例程一样,我们会测试这种图像捕获方式与 RKMPI 库之间的性能表现,决定是否对例程进行更新。Code: Select all
RK_MPI_VENC_SendFrame(0, &h264_frame,-1);
opencv获取的图像mat 如何实现rstp进行推流
Crocodile wrote: ↑2024-02-27 8:02经过测试,这种方式捕获图像推流的性能较差,如果没有特殊需求还是推荐使用例程中提供的方式。这里是测试例程,仅供 VIDEO_FRAME_INFO_S 创建参考学习,推荐使用 VI 捕获图像的例程来进行二次开发。Crocodile wrote: ↑2024-02-27 7:35您好,首先感谢您的尝试,瑞芯微的官方文档在构建 VIDEO_FRAME_INFO_S 结构体并没有提及太多的细节,经过我们的测试发现要使 VIDEO_FRAME_INFO_S 能够被 VENC 模块成功获取需要确保 内存缓冲块 能够成功申请,您需要执行的步骤如下:
1.构建一个内存缓冲池2.从内存缓冲池中获取缓冲块Code: Select all
VIDEO_FRAME_INFO_S h264_frame; MB_POOL_CONFIG_S PoolCfg; memset(&PoolCfg, 0, sizeof(MB_POOL_CONFIG_S)); PoolCfg.u64MBSize = width*height*3 ; PoolCfg.u32MBCnt = 1; PoolCfg.enAllocType = MB_ALLOC_TYPE_DMA; //PoolCfg.bPreAlloc = RK_FALSE; MB_POOL src_Pool = RK_MPI_MB_CreatePool(&PoolCfg); printf("Create Pool success !\n");
3.将opencv获取到的图像转换为 RGB888 格式传入缓冲块的虚拟地址Code: Select all
MB_BLK src_Blk = RK_MPI_MB_GetMB(src_Pool, width*height*3, RK_TRUE);
4.将创建的 VIDEO_FRAME_INFO_S 传入VENC中Code: Select all
h264_frame.stVFrame.u32Width = 480; h264_frame.stVFrame.u32Height = 480; h264_frame.stVFrame.u32VirWidth = 480; h264_frame.stVFrame.u32VirHeight = 480; h264_frame.stVFrame.enPixelFormat = RK_FMT_RGB888; h264_frame.stVFrame.u32TimeRef = H264_TimeRef++; //标识为第几帧 h264_frame.stVFrame.u64PTS = TEST_COMM_GetNowUs(); //获取当前时间戳 h264_frame.stVFrame.u32FrameFlag = 160; h264_frame.stVFrame.pMbBlk = src_Blk; unsigned char *data = (unsigned char *)RK_MPI_MB_Handle2VirAddr(src_Blk); cap >> bgr; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { cv::Vec3b pixel = bgr.at<cv::Vec3b>(y, x); data[(y * width + x) * 3 + 0] = pixel[2]; // Red data[(y * width + x) * 3 + 1] = pixel[1]; // Green data[(y * width + x) * 3 + 2] = pixel[0]; // Blue } }
RTSP推流设置方面与例程一样,我们会测试这种图像捕获方式与 RKMPI 库之间的性能表现,决定是否对例程进行更新。Code: Select all
RK_MPI_VENC_SendFrame(0, &h264_frame,-1);
https://github.com/luckfox-eng29/luckfo ... cv_capture