Page 2 of 2

Re: opencv获取的图像mat 如何实现rstp进行推流

Posted: 2024-02-27 8:02
by Crocodile
Crocodile wrote: 2024-02-27 7:35
W凯先森~ wrote: 2024-02-26 4:31
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 方案,支持更多格式的输入。
如何创建一个 VIDEO_FRAME_INFO_S 结构体将 opencv-mobile 获取的图像数据拷贝进去再上传到 venc 编码?我这不行
您好,首先感谢您的尝试,瑞芯微的官方文档在构建 VIDEO_FRAME_INFO_S 结构体并没有提及太多的细节,经过我们的测试发现要使 VIDEO_FRAME_INFO_S 能够被 VENC 模块成功获取需要确保 内存缓冲块 能够成功申请,您需要执行的步骤如下:

1.构建一个内存缓冲池

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");	
2.从内存缓冲池中获取缓冲块

Code: Select all

MB_BLK src_Blk = RK_MPI_MB_GetMB(src_Pool, width*height*3, RK_TRUE);
3.将opencv获取到的图像转换为 RGB888 格式传入缓冲块的虚拟地址

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
	}
}
4.将创建的 VIDEO_FRAME_INFO_S 传入VENC中

Code: Select all

RK_MPI_VENC_SendFrame(0, &h264_frame,-1);
RTSP推流设置方面与例程一样,我们会测试这种图像捕获方式与 RKMPI 库之间的性能表现,决定是否对例程进行更新。
经过测试,这种方式捕获图像推流的性能较差,如果没有特殊需求还是推荐使用例程中提供的方式。

Re: opencv获取的图像mat 如何实现rstp进行推流

Posted: 2024-02-27 8:28
by Crocodile
Crocodile wrote: 2024-02-27 8:02
Crocodile wrote: 2024-02-27 7:35
W凯先森~ wrote: 2024-02-26 4:31
如何创建一个 VIDEO_FRAME_INFO_S 结构体将 opencv-mobile 获取的图像数据拷贝进去再上传到 venc 编码?我这不行
您好,首先感谢您的尝试,瑞芯微的官方文档在构建 VIDEO_FRAME_INFO_S 结构体并没有提及太多的细节,经过我们的测试发现要使 VIDEO_FRAME_INFO_S 能够被 VENC 模块成功获取需要确保 内存缓冲块 能够成功申请,您需要执行的步骤如下:

1.构建一个内存缓冲池

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");	
2.从内存缓冲池中获取缓冲块

Code: Select all

MB_BLK src_Blk = RK_MPI_MB_GetMB(src_Pool, width*height*3, RK_TRUE);
3.将opencv获取到的图像转换为 RGB888 格式传入缓冲块的虚拟地址

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
	}
}
4.将创建的 VIDEO_FRAME_INFO_S 传入VENC中

Code: Select all

RK_MPI_VENC_SendFrame(0, &h264_frame,-1);
RTSP推流设置方面与例程一样,我们会测试这种图像捕获方式与 RKMPI 库之间的性能表现,决定是否对例程进行更新。
经过测试,这种方式捕获图像推流的性能较差,如果没有特殊需求还是推荐使用例程中提供的方式。这里是测试例程,仅供 VIDEO_FRAME_INFO_S 创建参考学习,推荐使用 VI 捕获图像的例程来进行二次开发。
https://github.com/luckfox-eng29/luckfo ... cv_capture