P5 RV1126编码测试Demo

发布时间:2023年12月25日

目录

前言

01 测试Demo大致流程图

02 代码分析

2.1 VI设备初始化

2.2 使能通道 ——?RK_MPI_VI_EnableChn

?2.3 VI 和 VENC绑定

2.4 创建?编码线程


?

前言

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》????

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》???

🛸推荐专栏3:《嵌入式音视频_@ChenPi的博客-CSDN博客
🌺本篇简介 ?:使用RV1126进行编码测试??

首先我们使用的硬件为瑞芯微的RV1126

kmedia是RK官方封装一层简易的API,把RGA、MPP、RKNN等等这些接口封装成高级的接口

该平台支持以下功能:

  1. VI(输入视频捕获)
  2. VO(视频输出显示)
  3. AI(音频采集)、AO(音频输出)
  4. VENC(H.265/H.264/JPEG/MJPEG编码)
  5. VDEC(H.265/H.264/JPEG、MJPEG 解码)
  6. RGA视频处理(包括旋转、缩放、裁剪)
  7. AENC(音频编码)、ADEC(音频解码)、
  8. MD(移动侦测)
  9. OD(遮挡侦测)
  10. VMIX(视频合成)
  11. MUXER(视频封装)
  12. VP(视频一入四出)

01 测试Demo大致流程图

??

因为这个测试Demo主要是编码进行视频编码

所以只用到VI和VENC?

  1. VI(输入视频捕获)
  2. VENC(H.265/H.264/JPEG/MJPEG编码)

02 代码分析

2.1 VI设备初始化

VI设备初始化有两步

  1. 设置通道属性
  2. 使能通道

?设置通道属性 —— RK_MPI_VI_SetChnAttr

设置通道的属性关键在于VI_CHN_ATTR_S结构体

结构体原型:

typedef struct rkVI_CHN_ATTR_S {
  const RK_CHAR *pcVideoNode; //video节点路径
  RK_U32 u32Width;            //分辨率宽度
  RK_U32 u32Height;           //分辨率高度
  IMAGE_TYPE_E enPixFmt;      //(VI格式)  
  RK_U32 u32BufCnt;          // 映射类型默认是:MMAP
  VI_CHN_BUF_TYPE enBufType; // VI通道模式
  VI_CHN_WORK_MODE enWorkMode;   //VI工作模式
} VI_CHN_ATTR_S;

需要注意的点:

结构体中的enBufType //VI 捕 捉 视 频 的 类 型? :

  • DMA 模 式(VI_CHN_BUF_TYPE_DMA)?
  • MMAP 模式(VI_CHN_BUF_TYPE_MMAP)

DMA:指的是直接访问内存的方式,相当于音视频数据直接从硬件传输到内存里面。这种方式的优点就
是两边传输的速度非常之快,但缺点就是非常消耗硬件资源,对硬件外设资源要求较高。

MMAP:指的是内存映射,这种方式就是把硬件外设、磁盘的文件映射到虚拟内存上面。然后用户只需
要对虚拟内存进行读写操作就可以对硬件外设进行操作了。这种方法的优点是用户不需要直接操作硬件就能够修改硬件的内容,换言之就是对硬件的消耗没那么大。

但是缺点就是:

第一,它的读写速度相对 DMA来说没那么快;

第二,有时候硬件写到虚拟内存的数据可能会出现丢失情况,导致数据出现丢失的情况。

2.2 使能通道 ——?RK_MPI_VI_EnableChn

VENC的初始化:关键在于VENC_CHN_ATTR_S结构体,这个结构体是VENC设置的结构体

RV1126 编码器参数结构体包含在 VENC 通道属性结构体里面,我们可以看到 VENC 通道结
构 体 里 面 包 含 三 个 重 要 结 构 体 : 分 别 是

  • VENC_ATTR_S( 编 码 器 基 础 属 性 结 构 体 )?
  • VENC_RC_ATTR_S(编码码率控制属性结构体)
  • VENC_GOP_ATTR_S(编码器 GOP 属性结构体)

设置完上述成员变量后,则使用RK_MPI_VENC_CreateChn创建编码层。

?2.3 VI 和 VENC绑定

设置完VI模块和VENC模块后,需要进行绑定VI和VENC才能够正常采集到编码数据。

采集的时候用到的结构体·MPP_CHN_S

typedef struct rkMPP_CHN_S {
  MOD_ID_E enModId;
  RK_S32 s32DevId;
  RK_S32 s32ChnId;
} MPP_CHN_S;

其中MPP_CHN_S的enModId是模块的ID、 s32ChnId是通道id。

这里分别创建两个MPP_CHN_S结构体,

  • VI的MPP_CHN_S,它的enModId选择的是RK_ID_VI,s32Id应该和VI创建的ID进行适配;
  • VENC的MPP_CHN_S,它的enModId选择的是RK_ID_VENC,s32ChnId和VENC创建的Id对应。

创建完两个MPP_CHN_S结构体后,利用RK_MPI_SYS_BIND把VI和VENC进行绑定。

2.4 创建?编码线程

从collect_venc_thread线程主要作用是获取VENC编码的码流数据,并实时保存到H264文件。

在这个线程里面,有几个重要的API需要讲解:

RK_MPI_SYS_GetMediaBuffer的作用是获取对应通道的数据,

这个API第一个参数是模块ID,第二个参数是通道ID第三个参数阻塞时间这里默认是-1不阻塞。

获取VENC通道的数据后,这其中

  • RK_MPI_MB_GetPtr是获取VENC缓冲区数据,
  • RK_MPI_MB_GetSize是获取VENC的缓冲区长度,并把缓冲区数据fwrite写到H264文件。?
文章来源:https://blog.csdn.net/weixin_73901182/article/details/135186765
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。