TB-RK3399ProD实现USBcamera通过V4L2图像采集+RKMPP编码成H264+OpenCV显示采集的图像
前期准备
需要以下设备:
1、Toybrick TB-RK3399ProD开发板
2、USB摄像头(Logitech Webcam C270)
3、HDMI显示器、USB鼠标/键盘、以太网线缆
一、操作系统
我用的TB-RK3399ProD开发板跑的操作系统是烧写的Toybrick官方提供的Debian10固件(Toybrick社区重点维护),下载地址:(http://t.rock-chips.com/wiki.php?mod=view&id=11)
二、开发环境搭建
1、软件升级
sudo apt update
sudo apt upgrade
2、drm、rga、mpp安装
参考:http://t.rock-chips.com/wiki.php?mod=view&id=115
sudo apt install rockchip-drm-dev libdrm-dev
sudo apt install rockchip-rga-dev
sudo apt install rockchip-mpp-dev
3、ISP安装
sudo apt install rockchip-isp
4、OpenCV安装:
sudo apt-get update
sudo apt install libopencv-dev
注:安装后的头文件目录:/usr/include/rockchip、库目录:/usr/lib/aarch64-linux-gnu、example目录:/usr/share/rockchip-xxx
三、功能实现
本功能的是基于上面几个库的example例程参考实现的
1、USB camera的V4L2图像采集参考:/usr/share/rockchip-isp/example/example.cpp
2、V4L2采集的图像调用RKMPP编码参考:/usr/share/rockchip-mpp/example/mpp_encode.cpp
3、OpenCV要播放V4L2获取的图像,需要先用RKRGA图像加速库把视频格式转换成V4L2_PIX_FMT_RGB24,参考:/usr/share/rockchip-rga/example/rga_convert.cpp
四、主体源码
源码编译:源码是放到板子进行编译的
源码增加了三个宏开关,如下:
#define RK_MPP_ENC 1 //使用RKMPP编码并存储到H264文件宏开关
#define RK_SAVE_YUYV 1 //V4L2采集到的原始图像存成YUYV文件宏开关
#define RK_OPENCV_SHOW 1 //使用RKRGA进行原始图像格式转换并送给OpenCV显示宏开关
功能源码主要部分如下:
int camera(char *dev, __u32 w, __u32 h, RgaRotate r, int V, int H, __u32 cx, __u32 cy, __u32 cw, __u32 ch, CameraType type, __u32 f)
{
int ret = 0;
int frames = PLAY_FRAMES;
v4l2_camera camera;
rockchip_rga rga;
Mat mat;
FILE *fp = NULL;
FILE *fp_h264 = NULL;
#if RK_SAVE_YUYV
/* Save to file */
if(f == V4L2_PIX_FMT_YUYV)
fp = fopen("test.yuyv", "w+");
else if(f == V4L2_PIX_FMT_YUV420)
fp = fopen("test.yuv420", "w+");
else
fp = fopen("test.unknown", "w+");
if (fp == NULL)
return -EIO;
#endif
#if RK_OPENCV_SHOW
cv::namedWindow(winname);
cv::moveWindow(winname, w, h);
mat.create(cv::Size(RGA_ALIGN(w, 16), RGA_ALIGN(h, 16)), CV_8UC3);
ret = rga.init();
if(ret < 0)
goto exit;
#endif
/* TODO: Init camera deivce */
ret = camera.init(dev, type);
if(ret < 0)
goto exit;
/* TODO: Set picture format */
ret = camera.setfmt(w, h, f);
if(ret < 0)
goto exit;
/* TODO: Request and mmap buffers */
ret = camera.reqbufs_mmap(4);
if(ret < 0)
goto exit;
/* TODO: Start stream capture */
ret = camera.start();
if(ret < 0)
goto exit;
#if RK_MPP_ENC
fp_h264 = fopen("test.h264", "w+");
ret = mpp_enc_init(fp_h264, f, w, h);
if(ret < 0)
goto exit;
#endif
while(frames--) {
int index;
size_t len = 0;
void *buf = NULL;
unsigned long long t1, t2, t3, t4;
#if RK_OPENCV_SHOW
struct rga_format src_fmt, dst_fmt;
struct rga_crop crop;
src_fmt.width = w;
src_fmt.height = h;
src_fmt.format = f;
dst_fmt.width = w;
dst_fmt.height = h;
dst_fmt.format = V4L2_PIX_FMT_RGB24;
crop.x = cx;
crop.y = cy;
crop.h = ch;
crop.w = cw;
#endif
t1 = nanoTime();
/* TODO: Dequeue buffer */
buf = camera.dequeue(&index, &len);
#if RK_MPP_ENC
mpp_enc(fp_h264, buf, len);
#endif
#if RK_SAVE_YUYV
fwrite(buf, len, 1, fp);
#endif
t2 = nanoTime();
#if RK_OPENCV_SHOW
ret = rga.convert(buf, mat.data, src_fmt, dst_fmt, crop, r);
if(ret < 0)
goto exit;
#endif
/* TODO: Enqueue buffer */
camera.enqueue(index);
t3 = nanoTime();
#if RK_OPENCV_SHOW
imshow(winname, mat);
cv::waitKey(1);
#endif
t4 = nanoTime();
printf("Picture size %llu, dequeue time %llums, enqueue time: %llums, display time: %llums\n",
len, (t2 - t1) / 1000000, (t3 - t2) / 1000000, (t4 - t3) / 1000000);
}
exit:
#if RK_MPP_ENC
mpp_enc_unit();
if(fp_h264 != NULL)
fclose(fp_h264);
#endif
#if RK_SAVE_YUYV
if(fp != NULL)
fclose(fp);
#endif
return ret;
}
五、OpenCV视频画面
download
https://download.youkuaiyun.com/download/qq_22633333/12854201