RKMEDIA--VP使用

本章描述rkmedia vp模块 即视频一入四处功能的介绍。

使用场景:主要用在DVR/DMS产品上,需要多路视频节点的输入和获取。

可以rv1126/rv1109可以外接模拟高清RX芯片(NVP6188,TP2815等),达到8路camera输入的能力。

在rga部分也有提及过,rv1126/rv1109只有一个硬件rga,所以工作能力有限,在dvr这种产品中需要多路视频的缩放,使用rga的话就无法达到需求。vp就可以解决视频分辨率缩放的功能,缓解rga的压力。

vp实际上就是使用RK平台上ispp模块,实现一个视频数据从rkispp_input_image节点对应的video节点输入,四个视频数据从rkispp_m_bypassrkispp_scale0rkispp_scale1rkispp_scale2节点对应video输出。。这样四个输出的节点中rkispp_scale0、rkispp_scale1、rkispp_scale2是具有缩放能力的。

使用方式:

因为我是使用的evb板,默认ispp0已经打开,也在使用。所以我用ispp1来做讲解。在实际使用时,你们的ispp可能都没有使用,所以可以从ispp0开始使用。

1、在dts文件中打开ispp1

 * 1. add code to kernel dts:
 &rkispp_vir1 {
     status = "okay";
 };

在dts里面打开ispp1后,重新编译kernel,烧录到开发板。启动后会在/dev/ 生成新的media节点

2、检查新的media节点所对应的video号,使用media-ctl -p -d 查看


[root@RV1126_RV1109:/userdata]# ls /dev/media
media0  media1  media2  media3
[root@RV1126_RV1109:/userdata]# media-ctl -p -d /dev/media3
Media controller API version 4.19.111

Media device information
------------------------
driver          rkispp
model           rkispp1
serial
bus info
hw revision     0x0
driver version  4.19.111

Device topology
- entity 1: rkispp_input_image (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video25
        pad0: Source
                -> "rkispp-subdev":0 [ENABLED]

- entity 5: rkispp_m_bypass (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video26
        pad0: Sink
                <- "rkispp-subdev":2 [ENABLED]

- entity 9: rkispp_scale0 (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video27
        pad0: Sink
                <- "rkispp-subdev":2 [ENABLED]

- entity 13: rkispp_scale1 (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video28
        pad0: Sink
                <- "rkispp-subdev":2 [ENABLED]

- entity 17: rkispp_scale2 (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video29
        pad0: Sink
                <- "rkispp-subdev":2 [ENABLED]

- entity 21: rkispp_iqtool (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video30
        pad0: Sink
                <- "rkispp-subdev":2 [ENABLED]

- entity 25: rkispp_input_params (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video31
        pad0: Source
                -> "rkispp-subdev":1 [ENABLED]

- entity 29: rkispp-stats (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video32
        pad0: Sink
                <- "rkispp-subdev":3 [ENABLED]

- entity 33: rkispp-subdev (4 pads, 8 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev1
        pad0: Sink
                [fmt:unknown/0x0
                 crop.bounds:(0,0)/0x0
                 crop:(0,0)/0x0
                 compose.bounds:(0,0)/0x0
                 compose:(0,0)/0x0]
                <- "rkispp_input_image":0 [ENABLED]
        pad1: Sink
                <- "rkispp_input_params":0 [ENABLED]
        pad2: Source
                [fmt:unknown/0x0]
                -> "rkispp_m_bypass":0 [ENABLED]
                -> "rkispp_scale0":0 [ENABLED]
                -> "rkispp_scale1":0 [ENABLED]
                -> "rkispp_scale2":0 [ENABLED]
                -> "rkispp_iqtool":0 [ENABLED]
        pad3: Source
                -> "rkispp-stats":0 [ENABLED]

[root@RV1126_RV1109:/userdata]#

如上所示,在打开ispp1的时候,会多出一个media3。使用命令查看media3的拓扑结构。

rkispp_input_imagevideo25
rkispp_m_bypassvideo26
rkispp_scale0video27
rkispp_scale1video28
rkispp_scale2video29

3、配置media节点

media-ctl -d /dev/media3 -l '"rkispp_input_image":0->"rkispp-subdev":0[1]'
media-ctl -d /dev/media3 --set-v4l2 '"rkispp-subdev":0[fmt:YUYV8_2X8/1920x1080]'
media-ctl -d /dev/media3 --set-v4l2 '"rkispp-subdev":2[fmt:YUYV8_2X8/1920x1080]'

以上是命令行执行的,在rkmedia_vi_vp_vo_test中是在代码中调用:

  char cmd[256];
  snprintf(
      cmd, sizeof(cmd),
      "media-ctl -d %s -l '\"rkispp_input_image\":0->\"rkispp-subdev\":0[1]'",
      media);
  system(cmd);
  snprintf(cmd, sizeof(cmd),
           "media-ctl -d %s --set-v4l2 "
           "'\"rkispp-subdev\":0[fmt:YUYV8_2X8/1920x1080]'",
           media);
  system(cmd);
  snprintf(cmd, sizeof(cmd),
           "media-ctl -d %s --set-v4l2 "
           "'\"rkispp-subdev\":2[fmt:YUYV8_2X8/1920x1080]'",
           media);
  system(cmd);

4、配置rkmedia vi 节点初始化。(输出的四个节点初始化要在vp之前)

int video_width = 1920;
int video_height = 1080;
int video1_width = 1920;
int video1_height = 1080;
int video2_width = 640;
int video2_height = 360;

// 先配置原始输入节点,就是用nvp6188在开发板上生成的节点
vi_chn_attr.pcVideoNode = "/dev/video0";
vi_chn_attr.u32BufCnt = 3;
vi_chn_attr.u32Width = video_width;
vi_chn_attr.u32Height = video_height;
vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;

//video0节点不支持dma申请内存,所以要配置成mmap
vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;   
ret = RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(s32CamId, 0);
if (ret) {
    printf("Create vi[0] failed! ret=%d\n", ret);
    return -1;
}

//配置media3 中的rkispp_m_bypass节点video26,rkispp_scale0 video27
//我这里就先用两个输出,如需多个,就再继续初始化即可
memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
vi_chn_attr.pcVideoNode = "/dev/video26";
vi_chn_attr.u32BufCnt = 3;
vi_chn_attr.u32Width = video1_width;
vi_chn_attr.u32Height = video1_height;
vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
ret = RK_MPI_VI_SetChnAttr(2, 2, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(2, 2);
if (ret) {
    printf("Create vi[2] failed! ret=%d\n", ret);
    return -1;
}


memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
vi_chn_attr.pcVideoNode = "/dev/video27";
vi_chn_attr.u32BufCnt = 3;
vi_chn_attr.u32Width = video2_width;
vi_chn_attr.u32Height = video2_height;
vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
ret = RK_MPI_VI_SetChnAttr(3, 3, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(3, 3);
if (ret) {
    printf("Create vi[3] failed! ret=%d\n", ret);
    return -1;
}


//接着初始化vp,实际上就是初始化media中rkispp_input_image 节点video25
VP_CHN_ATTR_S vp_chn_attr;
vp_chn_attr.pcVideoNode = "/dev/video25";
vp_chn_attr.u32BufCnt = 3;
vp_chn_attr.u32Width = video_width;
vp_chn_attr.u32Height = video_height;
vp_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
vp_chn_attr.enWorkMode = VP_WORK_MODE_NORMAL;
ret = RK_MPI_VP_SetChnAttr(0, 0, &vp_chn_attr);
ret |= RK_MPI_VP_EnableChn(0, 0);
if (ret) {
    printf("Create vp[0] failed! ret=%d\n", ret);
    return -1;
}

//最后就是将video0 绑定到video25, 这样video26、video27就可以像正常的video节点取流、绑定后级
MPP_CHN_S stSrcChn = {0};
MPP_CHN_S stDestChn = {0};

printf("#Bind VI[0] to VP[0]....\n");
stSrcChn.enModId = RK_ID_VI;
stSrcChn.s32ChnId = 0;
stDestChn.enModId = RK_ID_VP;
stDestChn.s32ChnId = 0;
ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (ret) {
    printf("Bind vi[0] to vp[0] failed! ret=%d\n", ret);
    return -1;
}

注意点:

1、video0不支持dma申请内存

2、rkispp_m_bypass节点不支持缩放。四个节点的缩放能力可以去看我前面介绍VI模块的章节。

        RKMEDIA--VI的使用_未_定的博客-CSDN博客

3、vp要放在最后初始化

以上就是一路vp的使用方式。在使用8路vp的时候基本上就是照葫芦画瓢,但是也需要改一些地方,需要修改的地方放在下面。

主要修改的是

1、dts加上其余的ispp和配置

2、设置ispp虚拟节点的数量

3、修改v4l2节点的数量

diff --git a/arch/arm/boot/dts/rv1109-evb-ddr3-v13-facial-gate.dts b/arch/arm/boot/dts/rv1109-evb-ddr3-v13-facial-gate.dts
index 982da51..97d91931 100644
--- a/arch/arm/boot/dts/rv1109-evb-ddr3-v13-facial-gate.dts
+++ b/arch/arm/boot/dts/rv1109-evb-ddr3-v13-facial-gate.dts
@@ -30,6 +30,26 @@
+&rkispp_vir2 {
+	status = "okay";
+};
 
+&rkispp_vir3 {
+	status = "okay";
+};
+
+&rkispp_vir4 {
+	status = "okay";
+};
+
+&rkispp_vir5 {
+	status = "okay";
+};
+
+&rkispp_vir6 {
+	status = "okay";
+};
+
+&rkispp_vir7 {
+	status = "okay";
+};
+
 &isp_reserved {
 	size = <0x8000000>;
 };
diff --git a/arch/arm/boot/dts/rv1126.dtsi b/arch/arm/boot/dts/rv1126.dtsi
index 194f2d1..c40fc92 100644
--- a/arch/arm/boot/dts/rv1126.dtsi
+++ b/arch/arm/boot/dts/rv1126.dtsi
@@ -2115,6 +2115,36 @@
+	rkispp_vir2: rkispp-vir2 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
 
+	rkispp_vir3: rkispp-vir3 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
+
+	rkispp_vir4: rkispp-vir4 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
+
+	rkispp_vir5: rkispp-vir5 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
+
+	rkispp_vir6: rkispp-vir6 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
+
+	rkispp_vir7: rkispp-vir7 {
+		compatible = "rockchip,rv1126-rkispp-vir";
+		rockchip,hw = <&rkispp>;
+		status = "disabled";
+	};
+
 	rkvdec: rkvdec@ffb80000 {
 		compatible = "rockchip,rkv-decoder-v1";
 		reg = <0xffb80000 0x400>;
diff --git a/drivers/media/platform/rockchip/isp/isp_ispp.h b/drivers/media/platform/rockchip/isp/isp_ispp.h
index 71878ca..beae6c6 100644
--- a/drivers/media/platform/rockchip/isp/isp_ispp.h
+++ b/drivers/media/platform/rockchip/isp/isp_ispp.h
@@ -34,6 +34,10 @@ enum rkisp_ispp_dev {
 	DEV_ID1,
 	DEV_ID2,
 	DEV_ID3,
+	DEV_ID4,
+	DEV_ID5,
+	DEV_ID6,
+	DEV_ID7,
 	DEV_MAX,
 };
 
 
 
 
 
 diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h
index cce6de4..83dc659 100644
--- a/lib/libv4l2/libv4l2-priv.h
+++ b/lib/libv4l2/libv4l2-priv.h
@@ -25,7 +25,7 @@
 
 #include "../libv4lconvert/libv4lsyscall-priv.h"
 
-#define V4L2_MAX_DEVICES 16
+#define V4L2_MAX_DEVICES 32
 /* Warning when making this larger the frame_queued and frame_mapped members of
    the v4l2_dev_info struct can no longer be a bitfield, so the code needs to
    be adjusted! */
diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
index f949b5d..ab0cffc 100644
--- a/lib/libv4l2/libv4l2.c
+++ b/lib/libv4l2/libv4l2.c
@@ -96,7 +96,11 @@ static struct v4l2_dev_info devices[V4L2_MAX_DEVICES] = {
 	{ .fd = -1 },
 	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
 	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
-	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }
+	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
+	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
+	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
+	{ .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 },
+	{ .fd = -1 }
 };
 static int devices_used;

以上就是vp的介绍,如有问题可在评论区探讨。

 文章汇总:RKMEDIA使用简介_未_定的博客-CSDN博客

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值