P8 RV1126推流 —— 摄像头和咪头模块初始化

前言 

                             

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

🎬 个人主页:@ChenPi

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

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

🛸推荐专栏3:《嵌入式音视频_@ChenPi的博客-CSDN博客》
🌺本篇简介  :本章主要讲解VI VENC模块和AI AENC模块的初始化及具体函数详解

01 main函数

构造一个项目,我们需要先将大概的框架给理解清楚,这样对写代码提供很多帮助

首先,我们看一下主函数

我们的主函数我们就写成这样,把功能和任务都分模块写,这样看代码和移植到方便一些

我们可以看到主函数接收参数的

我们要接收三个参数

  • 参数1为可执行文件名
  • 参数2为复合流格式
  • 参数3为将要推流到的流媒体的地址

第三个红框就是初始化一些参数了

 我们重点最后一个红框

这里面的内容是项目跑起来的关键

02 模块参数初始化及模块配置

2.1 VI模块初始化

//1 VI设备参数初始化
int rkmedia_VI_Init()
{RV1126_VI_CONFIG vi_Config;    //VI模块配置信息结构体memset(&vi_Config, 0, sizeof(vi_Config));   vi_Config.id = 0;            vi_Config.attr.pcVideoNode = VI_4K_NodeName;       //设备节点vi_Config.attr.u32Height = 1080;                                         //视频输入的宽度,一般和CMOS摄像头或者外设的宽度一致vi_Config.attr.u32Width = 1920;                                         //视频输入的高度,一般和CMOS摄像头或者外设的高度一致vi_Config.attr.u32BufCnt = 3;                                               //缓冲区计数,一般默认为3vi_Config.attr.enWorkMode = VI_WORK_MODE_NORMAL;   //vi工作模式 VI_WORK_MODE_NORMAL正常模式 VI_WORK_MODE_LUMA_ONLY 亮度模式vi_Config.attr.enPixFmt = IMAGE_TYPE_NV12;                     //图像格式vi_Config.attr.enBufType = VI_CHN_BUF_TYPE_MMAP;  //vi关于视频的方式DMA和MMAP两种方式int ret = rkmedia_VI_Module_Init(&vi_Config);if(0 == ret){RV1126_VI_CONTAINTER venc_container;     //保存通道号的结构体venc_container.index = 0;                                      //第几组编号venc_container.Vi_Channel_ID = vi_Config.id;   //通道号IDset_vi_container(0,&venc_container);        //将通道号保存进去puts("container creat succeeded"); }else{puts("container creat failed");}return 0;
}

 

 首先我们来看一下VI模块的初始化

 RV1126_VI_CONFIG这个结构体实际上就是对VI_CHN_ATTR_S结构做了一个封装

多了一个变量ID,这个的作用是什么呢?这个是为了后期如果需要多路编码留下拓展空间

再看一下这行代码

int ret = rkmedia_VI_Module_Init(&vi_Config);

这个代码的实际是将VI和VENC模块的绑定操作进行了一个封装

 

2.2 VENC模块初始化

//初始化VENC模块
int rkmedia_VENC_Init()
{RV1126_VENC_CONFIG vencconfig;   //保存VENC模块配置信息结构体memset(&vencconfig, 0, sizeof(vencconfig));  vencconfig.id = 0;//1编码器基础属性结构体vencconfig.attr.stVencAttr.enType = RK_CODEC_TYPE_H264;   //编码器协议类型vencconfig.attr.stVencAttr.imageType = IMAGE_TYPE_NV12;     //输入图像类型vencconfig.attr.stVencAttr.u32PicWidth = 1920;                              //编码图像宽度    vencconfig.attr.stVencAttr.u32PicHeight = 1080;                             //编码图像高度vencconfig.attr.stVencAttr.u32VirWidth = 1920;                                //编码图像虚宽度,一般来说u32VirWidth和u32PicWidth是一致的vencconfig.attr.stVencAttr.u32VirHeight = 1080;                              //   vencconfig.attr.stVencAttr.u32Profile = 77;     //编码等级 有66 77 100 越高画质越好,但网络传输需要的带宽就越大//2编码码率控制属性结构体vencconfig.attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;  //编码器码率控制模式vencconfig.attr.stRcAttr.stH264Cbr.u32Gop = 30; // h264cbr 关键帧间隔vencconfig.attr.stRcAttr.stH264Cbr.u32BitRate = 1920*1080*3;      //编码码率/*原始帧和目标帧的分子分母*/vencconfig.attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum =25;    //目标帧vencconfig.attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;vencconfig.attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;    //原始帧vencconfig.attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;//3编码器GOP属性结构体int ret = rkmedia_VENC_Module_Init(&vencconfig);if(0 == ret){RV1126_VENC_CONTAINER venc_container;venc_container.index = 0;venc_container.VENC_Channel_ID = vencconfig.id;set_venc_container(0, &venc_container);}else{}return 0;
}

 这个的做法和VI模块配置是相似的

 需要注意的几个点

  • 需要理解VENC_CHN_ATTR_S这个结构体,这个结构体中还包括了三个结构体,每个结构体功能不一样
  • 需要按要求选择编码等级,不然选择了最高的编码等级但网络不好容易黑屏
  • 编码器的选择需要看仔细
  • 目标帧和原始帧最好选择和摄像头硬件匹配的,不然会有音频被加速的感觉。我的硬件25合适

 

2.3 AI模块初始化

int rkmedia_AI_Init()
{RV1126_AI_CONFIG ai_Config;memset(&ai_Config, 0, sizeof(ai_Config));ai_Config.id = 0;ai_Config.attr.pcAudioNode = "default";                                      //音频节点路径ai_Config.attr.enSampleFormat = RK_SAMPLE_FMT_S16;   //采样格式ai_Config.attr.u32SampleRate = 48000;                                         //采样率ai_Config.attr.u32Channels = 2;                                                         //通道数ai_Config.attr.u32NbSamples = 1024;                                              //每帧采样数ai_Config.attr.enAiLayout = AI_LAYOUT_NORMAL;                   //音频布局 int ret = rkmedia_AI_Module_Init(&ai_Config);if(0 == ret){RV1126_AI_CONTAINTER ai_container;ai_container.index = 0;ai_container.Ai_Channel_ID = ai_Config.id;set_ai_container(0,&ai_container);}else{puts("AI Init Failed");}return 0;
}

 

这个是音频的AI模块的初始化

注意点:

采样率:96000, 88200, 64000, 48000, 44100, 32000,采样率的选择很多,但一般48000就可以

通道数:单声道,双声道,四声道等等,一般2声道即可

采样个数:1024

2.4 AENC模块初始化

int rkmedia_AENC_Init()
{RV1126_AENC_CONFIG rkmedia_aenc_config; rkmedia_aenc_config.id = 0;rkmedia_aenc_config.attr.enCodecType = RK_CODEC_TYPE_AAC; //AENC的编码类型rkmedia_aenc_config.attr.u32Bitrate = 153600;                                       //AENC的音频码率rkmedia_aenc_config.attr.u32Quality = 1;                                                    //AENC编码质量rkmedia_aenc_config.attr.stAencAAC.u32Channels = 2;                         //AENC编码通道rkmedia_aenc_config.attr.stAencAAC.u32SampleRate = 48000;           //AENC编码采样率int ret = rkmedia_AENC_Module_Init(&rkmedia_aenc_config);if(0 == ret){RV1126_AENC_CONTAINER aenc_container;aenc_container.index = 0;aenc_container.AENC_Channel_ID = rkmedia_aenc_config.id;set_aenc_container(0, &aenc_container);puts("AENC Container Success!");}else{}return 0;
}

 注意:AENC的配置参数要和AI的参数对应上,声道数,采样率等等

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/318269.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

im6ull学习总结(三-2)文字显示中文字符

承接上篇文章 中文字符的点阵显示 使用点阵字库时,中文字符的显示原理跟 ASCII 字符是一样的。要注意的地方在于中文的编码:在 C 源文件中它的编码方式是 GB2312 还是 UTF-8?编译出的可执行程序,其中的汉字编码方式是 GB2312 还…

如何在Windows 10中扩展分区,这里提供步骤

一些PC制造商提供的电脑硬盘分为多个分区,一个用于Windows操作系统,另一个用于个人文件的空“数据”分区。如果你愿意,可以将这些分区合并为一个分区。 此技巧还可以用于删除恢复分区,从而释放通常用于恢复数据的空间。或者&…

MySQL——事物

目录 一.发现问题 二.什么时事物 三.事务提交方式 四.事物的常规操作方式 五. 事务隔离级别 1.如何理解隔离性 2.隔离级别 3.查看与设置隔离性 4.读未提交【Read Uncommitted】 5.读提交【Read Committed】 6.可重复读【Repeatable Read】 7.串行化【serializabl…

湖南大学-算法设计与分析-2023期末考试【原题】

前言 21:00刚刚结束的考试,凭着回忆把题目重现出来了,在复习的时候根本找不到往年的试卷,希望这张回忆的试卷能帮助到下一届的同学。知道题目基本上就能做出来了,但是不知道是真的做不出来,我就不给答案了…

数据结构第2章 栈和队列

名人说:莫听穿林打叶声,何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 本篇笔记整理:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 0、思维导图栈和队列1、栈1)特点2&#xff0…

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于回溯搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

C++多态性——(3)动态联编的实现——虚函数

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝 成功的秘诀就在于多努力一次&#xff…

《算法导论》复习——CHP1、CHP2 算法基础

基本定义: 算法是一组有穷的规则,规定了解决某一特定类型问题的一系列运算。 关心算法的正确性和效率。 算法的五个重要特性:确定性、能行性、输入、输出、有穷性。 基础方法: 伪代码(Pseudocode)&#xff…

主动IRS(Active IRS)模型总结

文章目录 A Framework for Transmission Design for Active RIS-Aided Communication with Partial CSIHybrid active and passive IRS从已有passive IRS算法拓展到active IRS算法 active IRS 与 passive IRS模型的区别 A Framework for Transmission Design for Active RIS-Ai…

工作中redis相关知识总结

这里写目录标题 一、Redis数据持久化概念二、redis数据类型三、redis缓存的应用流程四、什么样的数据适合存放到redis中?1、什么情况下,redis中会没有数据?2、redis缓存项目在测试中的注意事项a、更新缓存b、淘汰缓存 五、什么是缓存击穿1、缓…

ChatGPT学习笔记——大模型基础理论体系

1、ChatGPT的背景与意义 近期,ChatGPT表现出了非常惊艳的语言理解、生成、知识推理能力, 它可以极好的理解用户意图,真正做到多轮沟通,并且回答内容完整、重点清晰、有概括、有条理。 ChatGPT 是继数据库和搜索引擎之后的全新一代的 “知识表示和调用方式”如下表所示。 …

三种方式在ASP.NET Core中实现代理功能请求获取数据的接口(以请求百度统计数据接口为例)

一、定义请求数据属性 TargetUrl参数是目标接口的URL,RequestDataArray参数是要发送的请求数据列表 //定义属性:TargetUrl参数是目标接口的URL,RequestDataArray参数是要发送的请求数据列表public class ToResponseBody{[JsonPropertyName("Target…