RV1126+FFMPEG推流项目(3)VI模块视频编码流程

embedded/2025/1/15 23:26:06/

 视频编码的流程:   

        本章节讲的是RV1126视频编码的流程,在整个项目之中视频编码功能是核心之一。视频编码流程主要分三步:VI的初始化VENC的初始化(硬件编码)绑定VIVENC节点开启VENC线程进行视频编码的采集,注意一下这里的编码是硬件编码,不是使用ffmpeg软件编码

        rv1126有一份开发手册,很多东西都是在里面找到了。

        视频采集流程:

重要的结构体: 

        第一步要 rkmedia_function_init();该函数主要负责初始化rkmedia系统,确保系统准备就绪,可以执行后续的操作,它调用RK_MPI_SYS_Init()函数来进行实际的初始化工作

//初始化所有rkmedia的模块
int init_rkmedia_module_function()
{rkmedia_function_init(); //初始化rkmedia功能
}

        继续往下说之前,先来了认识几个重要的数据结构。RV1126_VI_CONFIG、RV1126_AI_CONFIG、RV1126_VENC_CONFIG、RV1126_AENC_CONFIG  这是个结构体都是自己封装的,对rv1126的一下api封装了一下都在rkmedia_config_public.h文件里面
        RV1126_VI_CONFIG:

/*** @brief RV1126_VI_CONFIG 结构体定义* * 该结构体用于配置RV1126视频输入(VI)的相关参数。* 包含视频通道的ID和属性配置。*/typedef struct
{unsigned int id;   ///< 视频通道ID,用于标识不同的视频输入通道VI_CHN_ATTR_S attr; ///< 视频通道属性,包含通道的具体配置信息
} RV1126_VI_CONFIG;

        VI_CHN_ATTR_S:在rk1126的开发文档里面


          RV1126_AI_CONFIG: 

/*** @brief RV1126_AI_CONFIG 结构体定义* * 该结构体用于配置RV1126音频输入(AI)的相关参数。* 包含音频通道的ID和属性配置。*/typedef struct
{unsigned int id;   ///< 音频通道ID,用于标识不同的音频输入通道AI_CHN_ATTR_S attr; ///< 音频通道属性,包含通道的具体配置信息
} RV1126_AI_CONFIG;

        AI_CHN_ATTR_S:在rk1126的开发文档里面


         RV1126_VENC_CONFIG:

/*** @brief RV1126_VENC_CONFIG 结构体定义* * 该结构体用于配置RV1126视频编码(VENC)的相关参数。* 包含视频编码通道的ID和属性配置。*/typedef struct
{unsigned int id;   ///< 视频编码通道ID,用于标识不同的视频编码通道VENC_CHN_ATTR_S attr; ///< 视频编码通道属性,包含通道的具体配置信息
} RV1126_VENC_CONFIG;

       VENC_CHN_ATTR_S: 在rk1126的开发文档里面 


        RV1126_AENC_CONFIG: 

/*** @brief RV1126_AENC_CONFIG 结构体定义* * 该结构体用于配置RV1126音频编码(AENC)的相关参数。* 包含音频编码通道的ID和属性配置。*/typedef struct
{unsigned int id;   ///< 音频编码通道ID,用于标识不同的音频编码通道AENC_CHN_ATTR_S attr; ///< 音频编码通道属性,包含通道的具体配置信息
} RV1126_AENC_CONFIG;

         AENC_CHN_ATTR_S:

开始编码: 

        在rkmedia_module_function.cpp(功能模块),还有一部分其他的源码,比如下面容器的一部分代码放在rkmedia_container.cpp (容器管理模块),主要功能是保存 VI 和 AI 初始化的设备节点,供多线程使用。这里就不上传了,不然就会很乱了,感兴趣的可以问我拿整个源码。

int init_rkmedia_module_function()
{int ret;rkmedia_function_init(); //初始化rkmedia功能RV1126_VI_CONFIG rv_vi;memset(&rv_vi, 0, sizeof(rv_vi));//初始化rv_virv_vi.id = 0; //视频通道IDrv_vi.attr.pcVideoNode = COMS_DEVICE_NAME; //video视频节点路径/*VI捕获视频缓冲区计数,默认是3比如说vi和摄像头直接基础没有缓存区,vi模块如果数度跟不上会造成数据的丢失所以加上缓存区的,就可以减轻vi模块的压力,也是类似与一个生产着和消费着模型,主要是摄像头每时每刻都在采集数据不会停的所以加上缓存去,就可以大大保存数据的完整性。至于为啥3,这是工程师的经验*/rv_vi.attr.u32BufCnt = 3; rv_vi.attr.u32Width = 1920;//视频输入的宽度,一般和CMOS摄像头或者外设的宽度一致rv_vi.attr.u32Width = 1080;视频输入的高度,一般和CMOS摄像头或者外设的高度一致rv_vi.attr.enPixFmt = IMAGE_TYPE_NV12; // 图形格式 和vi_chn_attr.enPixFmt保持一样/***  VI_CHN_BUF_TYPE_MMAP和VI_CHN_BUF_TYPE_DMA*  VI_CHN_BUF_TYPE_DMA:vi模块直接和内存打交道,优点:速度快,缺点:如果硬件差的,可能会造成发热,频繁操作加快硬件损坏* I_CHN_BUF_TYPE_MMAP:中间有一个虚拟内存,vi和内存不直接接触,优点:硬件使用时间会长,缺点:有一点点延迟,但是不影响*/rv_vi.attr.enBufType = VI_CHN_BUF_TYPE_MMAP; //视频输入的图像格式,默认是NV12(IMAGE_TYPE_NV12)rv_vi.attr.enWorkMode = VI_WORK_MODE_NORMAL; //VI的工作模式,默认是NORMAL(VI_WORK_MODE_NORMAL)ret = rkmedia_vi_init(&rv_vi);if(ret != 0){printf("vi初始化失败\n");}else{printf("vi 初始化成功\n");/*** 设置容器的目的是为了后面开发,可以轻易拿到 vi的id,直接从容器里面拿*/RV1126_VI_CONTAINER vi_container; //创建出容器vi_container.id = 0;vi_container.vi_id = rv_vi.id;set_vi_container(0, & vi_container); //把vi_id设置到容器里面}}


http://www.ppmy.cn/embedded/154233.html

相关文章

SQL中的行转列,列转行

SQL中的行列转换 1. 导入 有这样两张表&#xff0c;这两张表如何互相转换 student_table score_table 2. 行转列 使用 UNION ALL -- 行转列 SELECT name,语文 as subject,chinese_score as score FROM student_table UNION ALL SELECT name,数学 as subject,math_score…

微信小程序 实现拼图功能

微信小程序 实现拼图 效果示例功能描述代码示例 效果示例 微信小程序 碎片拼图 功能描述 在微信小程序中&#xff0c;实现一个简单的拼图小游戏。用户需要将四张碎片图片拖动到目标图片的正确位置&#xff0c;具体功能如下&#xff1a; 拖动功能&#xff1a; 用户可以通过手指…

react生命周期方法

一、挂载阶段 constructor&#xff1a;组件的构造函数&#xff0c;初始化state。statiic getDerivedStateFromProps:在组件实例被创建和更新之前调用&#xff0c;返回一个对象来更新state。render:渲染组件的UI。componentDidMount组件挂载完成后调用&#xff0c;通常用于发起…

华为2024嵌入式研发面试题

01 你认为最好的排序算法是什么&#xff1f; 在实际的编程中&#xff0c;最好的排序算法要根据实际需求和数据规模来选择&#xff0c;因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点&#xff1a; 冒泡排序 冒泡排序是一种简单直观的排序算法&#xff0…

c#-Halcon入门教程——标定

Halcon代码 read_image (NinePointCalibration, D:/Desktop/halcon/ca74d-main/九点标定/NinePointCalibration.gif)rgb1_to_gray (NinePointCalibration, GrayImage)get_image_size (GrayImage, Width, Height) dev_display (GrayImage)* 获取当前显示的窗口句柄 dev_get_win…

Linux IPC:管道与FIFO汇总整理

管道&#xff08;Pipes&#xff09;和先进先出&#xff08;FIFOs&#xff0c;也称为命名管道&#xff09;都是Linux中用于进程间通信&#xff08;IPC&#xff09;的机制。它们允许数据从一个进程流向另一个进程&#xff0c;类似于命令行中的管道操作符 |。下面详细介绍这两种机…

神经网络

“损失函数 王木头学科学-哔哩哔哩_bilibili 一、transformer和注意力机制的本质&#xff0c;以及编码和解码的结构及其与注意力机制的关系&#xff0c;帮助理解transformer的优势和应用场景。 00:01 - 介绍transformer是人工智能主流技术&#xff0c;大语言模型GBT是在其基础…

宁德时代C++后端开发面试题及参考答案

请阐述面向对象的三大特性。 面向对象编程有三大特性,分别是封装、继承和多态。 封装是指将数据和操作数据的方法绑定在一起,对数据的访问和操作进行限制。这样做的好处是可以隐藏对象的内部细节,只暴露必要的接口给外部。例如,我们可以把一个汽车类的内部引擎状态、速度等…