一、rv1126开发之视频输入和视频编码

RV1126 H264/HEVC编码流程

一、RV1126编码的流程图:

在这里插入图片描述

二、每个代码模块详细讲解

2.1. VI模块的创建

在这里插入图片描述VI模块的初始化:关键在于VI_CHN_ATTR_S结构体,这个结构体是VI设置的结构体。这个结构体的成员变量包括:pcVideoNode(video节点路径)、u32BufCnt(VI捕获视频缓冲区计数)、u32Width(分辨率宽度)、u32Height(分辨率高度)、 enPixFmt(VI格式)、enBufType(映射类型默认是:MMAP)、enWorkMode(VI通道模式)等成员变量。设置完成之后,则使用RK_MPI_VI_SetChnAttr进行设置VI操作,设置完成之后使用RK_MPI_VI_EnableChn使能VI层。

2.2. VENC模块的初始化

在这里插入图片描述VENC的初始化:关键在于VENC_CHN_ATTR_S结构体,这个结构体是VENC设置的结构体。这个结构体包含以下成员变量:enType(编码类型)、enRcMode()、u32Gop(关键帧间隔)、u32Bitrate(编码码率)、u32SrcFrameRateDen(原始帧率分母)、u32SrcFrameRateNum(目标帧率分子)、 fr32DstFrameRateNum(目标帧率分母)、 fr32DstFrameRateDen(目标帧率分子)、 imageType(流格式)、u32PicWidth(分辨率长度)、u32PicHeight(分辨率高度)、u32VirWidth(分辨率虚长度)、u32VirHeight(分辨率虚高度)、u32Profile(编码等级)。
设置完上述成员变量后,则使用RK_MPI_VENC_CreateChn创建编码层。

2.3. 绑定VI和VENC模块

在这里插入图片描述设置完VI模块和VENC模块后,需要进行绑定VI和VENC才能够正常采集到编码数据。采集的时候用到的结构体·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. 创建线程采集VENC数据

在这里插入图片描述在这里插入图片描述从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文件。

#include <stdio.h>
#include "rkmedia_config.h"void * collect_venc_thread(void * args)
{pthread_detach(pthread_self());  //线程取消和主线程的绑定,当结束时自动销毁MEDIA_BUFFER mb;FILE * h264_file = fopen("./test_output.h264", "w+");while (1){mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 0 , -1);   //从编码器中获取一帧数据放到缓冲区  参数(模块(venc),通道号,-1(非阻塞,>=0:阻塞等待的时间)),if(!mb){printf("Get Venc Buffer Break....\n");break;}printf("mmmmmm\n");//这里的mb只是一个地址,也就是指针//从缓冲区读取数据RK_MPI_MB_GetPtr(mb),大小RK_MPI_MB_GetSize(mb)也就是一帧编码的大小fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file); }return NULL;
}int main()
{RK_U32 u32Width = 1920;RK_U32 u32Height = 1080;RK_CHAR *pDeviceName = "rkispp_scale0";  //最大宽度3264,可进行缩放1-8倍,这部分去看rv1126的手册中的VI视频节点部分RK_CHAR *pOutPath = NULL;RK_CHAR *pIqfilesPath = NULL;CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264;  //编码类型RK_CHAR *pCodecName = "H264";RK_S32 s32CamId = 0;  //vi管道号,一般为0RK_U32 u32BufCnt = 3;#if 0rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;SAMPLE_COMM_ISP_Init(hdr_mode, RK_FALSE);SAMPLE_COMM_ISP_Run();SAMPLE_COMM_ISP_SetFrameRate(30);
#endifint ret;RK_MPI_SYS_Init();VI_CHN_ATTR_S vi_chn_attr;vi_chn_attr.pcVideoNode = pDeviceName;  //设置 VI的视频节点,比如“/dev/video0”,这部分去看rv1126的手册中的VI视频节点部分vi_chn_attr.u32BufCnt = u32BufCnt;  //vi捕获视频缓冲区计数vi_chn_attr.u32Width = u32Width;    //分辨率设置vi_chn_attr.u32Height = u32Height;vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;     //视频的格式vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;     //映射的方式vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;//通道号这里应该设置为0ret = RK_MPI_VI_SetChnAttr(s32CamId, 1, &vi_chn_attr);  //设置vi设备属性,参数(vi管道号,vi通道号,vi通道属性结构体指针),管道号对应了sensor的个数ret |= RK_MPI_VI_EnableChn(s32CamId, 1);if (ret){printf("ERROR: create VI[0] error! ret=%d\n", ret);return 0;}VENC_CHN_ATTR_S venc_chn_attr;memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));/*编码属性结构体之编码器属性*/venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264; //设置编码器属性的编码类型为H264venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;  //输入图形类型//下面这部分是分辨率,设置为想要的分辨率即可 venc_chn_attr.stVencAttr.u32PicWidth = u32Width; venc_chn_attr.stVencAttr.u32PicHeight = u32Height;venc_chn_attr.stVencAttr.u32VirWidth = u32Width;venc_chn_attr.stVencAttr.u32VirHeight = u32Height;venc_chn_attr.stVencAttr.u32Profile = 77; //编码等级,这块查看文档/*编码属性结构体之码率控制属性*/venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;  //编码协议类型,H264//H264编码通道Cbr模式属性,此外还有H265,Mjpeg的模式属性venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30;   //GOP,I帧间隔        venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = u32Width * u32Height;   //平均比特率,取值[2000-98000000],比特率设置,单位bps// frame rate: in 30/1, out 30/1.  这样的设置实际输入帧率是30,输出帧率为30venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;   //目标帧率分母venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;  //目标帧率分子venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;    //数据源帧率分母venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;   //数据源帧率分子ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);   //参数(通道号,视频编码属性结构体)if (ret){printf("ERROR: create VENC[0] error! ret=%d\n", ret);return 0;}/* vi视频输入通道和venc视频编码通道绑定 */MPP_CHN_S stSrcChn;stSrcChn.enModId = RK_ID_VI;  //属性设置为vistSrcChn.s32DevId = 0;  //vi设备号,其实就是上面的管道号stSrcChn.s32ChnId = 1;  //vi设备的通道号,与上面设置的属性对应MPP_CHN_S stDestChn;stDestChn.enModId = RK_ID_VENC;  //属性设置为vencstDestChn.s32DevId = 0;   // 视频编码设备号默认0stDestChn.s32ChnId = 0;     //视频编码通道ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);if (ret){printf("ERROR: Bind VI[0] and VENC[0] error! ret=%d\n", ret);return 0;}pthread_t pid;ret = pthread_create(&pid, NULL, collect_venc_thread, NULL);if(ret != 0){printf("Create Venc Thread Failed....\n");}while (1){sleep(20);}return 0;
}

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

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

相关文章

[力扣 129]求根节点到叶节点之和

题目描述&#xff1a; 思路&#xff1a; 可以采用递归回溯。递归访问左->右->根节点并记录路径。到叶节点后&#xff0c;计算数字并相加。 代码&#xff1a; class Solution:def sumNumbers(self, root: TreeNode) -> int:res 0path []def backtrace(root):nonl…

Autosar Crypto Driver学习笔记(二)

文章目录 Crypto DriverFunction definitionsGeneral APICrypto_InitCrypto_GetVersionInfo Job Processing InterfaceCrypto_ProcessJob Job Cancellation InterfaceKey Management InterfaceKey Setting Interface密钥设置接口Crypto_KeyElementSetCrypto_KeySetValid Key Ex…

RabbitMQ集群部署

集群部署 我们看看如何安装RabbitMQ的集群。 1.集群分类 在RabbitMQ的官方文档中&#xff0c;讲述了两种集群的配置方式&#xff1a; 普通模式&#xff1a;普通模式集群不进行数据同步&#xff0c;每个MQ都有自己的队列、数据信息&#xff08;其它元数据信息如交换机等会同…

2024年高压电工证模拟考试题库及高压电工理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年高压电工证模拟考试题库及高压电工理论考试试题是由安全生产模拟考试一点通提供&#xff0c;高压电工证模拟考试题库是根据高压电工最新版教材&#xff0c;高压电工大纲整理而成&#xff08;含2024年高压电工证…

【Leetcode每日一题】 递归 - Pow(x, n)(难度⭐⭐)(40)

1. 题目解析 题目链接&#xff1a;50. Pow(x, n) 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 在这个算法中&#xff0c;递归函数的任务是求出 x 的 n 次方。那么&#xff0c;这个函数是怎么工作的呢&#xff1f;它…

es 集群核心概念以及实践

节点概念&#xff1a; 节点是一个Elasticsearch的实例 本质上就是一个JAVA进程一台机器上可以运行多个Elasticsearch进程&#xff0c;但是生产环境一般建议一台机器上只运行一个Elasticsearch实例 每一个节点都有名字&#xff0c;通过配置文件配置&#xff0c;或者启动时候 -…

软件工程-第5章 结构化设计

5.1 总体设计的目标及其表示方法 5.2 总体设计 变换设计基本步骤&#xff1a; 第1步&#xff1a;设计准备--复审并精华系统模型&#xff1b; 第2步&#xff1a;确定输入、变换、输出这三部分之间的边界&#xff1b; 第3步&#xff1a;第一级分解--系统模块结构图顶层和第一层…

产品软文怎么写?媒介盒子分享公式

软文写出来的目的除了提高品牌知名度外&#xff0c;还需要推广产品&#xff0c;当企业新品上市、推广产品以及营销产品的时候&#xff0c;就需要产品类软文出手。然而产品软文想要写好还需要一定的技巧&#xff0c;今天媒介盒子就来和大家分享&#xff1a;产品软文写作公式。 一…

把txt、pdf等文件转为一行一行的doccano数据集输入格式

文章目录 doccano 数据集导入简介代码实现代码运行结果代码公开 doccano 数据集导入 在Doccano 导入数据集时&#xff0c;使用TextLine的文件格式&#xff0c;导入的文件需要为一行一行文本的数据格式&#xff0c;每一行文本在导入Doccano后就是一条数据。 简介 主要工作说明…

[linux]--关于进程概念(下)

目录 孤儿进程 环境变量 将程序放到PATH路径下 设置PATH环境变量 设置别名 环境变量相关的命令 环境变量的组织方式​编辑 通过系统调用获取环境变量 环境变量通常是具有全局属性的 进程优先级 查看系统进程 用top命令更改已存在进程的nice&#xff1a; 程序地址空…

(附源码)基于SSM的校园兼职系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31…

uniapp ios证书失效

前面是按照网上查找的方法 作者大大的地址 1、一个ios账户&#xff08;688付费版&#xff09; 2、登录 Apple Developer 3、创建Identifiers ps&#xff1a;创建时需继承苹果的sdk&#xff0c;只需要一个就行 点击continue再点击Register即可 4、创建.cer证书 &…

tcp seq ack

seq&#xff08;Sequence Number&#xff09;&#xff1a;32bits&#xff0c;表示这个tcp包的序列号。tcp协议拼凑接收到的数据包时&#xff0c;根据seq来确定顺序&#xff0c;并且能够确定是否有数据包丢失。 ack&#xff08;Acknowledgment Number&#xff09;&#xff1a;3…

安卓开发日记:实现APP重启逻辑,适用于热更后重启游戏进行加载

可根据合适的弹窗搭配使用重启逻辑&#xff0c;建议使用在热更包加载后使用&#xff0c;帮助部分热更后未及时生效的逻辑范围首先&#xff0c;在逻辑调用Activity类中创建一个成员变量&#xff0c;给后续逻辑接口直接使用 如下 public class MainActivity extends Activity {…

想当初级爬虫工程师,需要把爬虫学到什么程度?

这篇文章会说说我自己的心得体验&#xff0c;关于爬虫、关于工作&#xff0c;仅供参考。 学到哪种程度 暂且把目标定位初级爬虫工程师&#xff0c;简单列一下吧&#xff1a; &#xff08;必要部分&#xff09; 语言选择&#xff1a;一般是了解Python、Java、Golang之一 熟悉…

SCI一区 | Matlab实现SSA-TCN-BiGRU-Attention麻雀算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现SSA-TCN-BiGRU-Attention麻雀算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现SSA-TCN-BiGRU-Attention麻雀算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程序…

Vue2在一个页面内动态切换菜单显示对应的路由组件

项目的需求是在一个页面内动态获取导航菜单&#xff0c;导航菜单切换的时候显示对应的路由页面&#xff0c;类似于tab切换的形式&#xff0c;切换的导航菜单和页面左侧导航菜单是同一个路由组件&#xff0c;只是放到了一个页面上&#xff0c;显示的个数不同&#xff0c;所有是动…

基于Python的Django开发接口框架搭建

1、安装Django&#xff0c;如图1 命令行执行&#xff1a;pip install django 2、创建Django项目&#xff0c;如图2 django-admin startproject imooc 3、创建Django的应用项目&#xff0c;如图3 必须进入项目文件下执行命令&#xff1a; python3 manage.py startapp app 4、…

Python基础学习笔记(一)

Python简介 Python 语言是一种跨平台、开源、免费、解释型、面向对象、动态数据类型的高级程序设计语言。早期版本的 Python 被称作是 Python1&#xff1b;Python2 最后一个版本是 2.7&#xff1b;Python3 是目前最活跃的版 本&#xff0c;基本上新开发的 Python 代码都会支持…

线程池实现“线程复用”的原理

线程池实现“线程复用”的原理 学习线程复用的原理&#xff0c;以及对线程池的 execute 这个非常重要的方法进行源码解析。 线程复用原理 我们知道线程池会使用固定数量或可变数量的线程来执行任务&#xff0c;但无论是固定数量或可变数量的线程&#xff0c;其线程数量都远远…