RKmedia进行vi-vo模块

一、简介

分析一下rkmedia的代码,给自己加深一下印象

二、代码

2.1 头文件以及定义

首先包含了必要的头文件,以及rkmedia底层的库

static bool quit 是定义了布尔类型的变量来表示这个程序的运行状态 false表示没停止 true表示停止

sigterm_handler(int sig)定义了一个信号处理函数,后面绑定信号,该函数内容是:

  • fprintf: 这一行将接收到的信号编号打印到标准错误流(stderr)。
  • quit = true: 这行代码将全局变量 quit 设置为 true。即表示停止程序。
// Copyright 2020 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>#include "common/sample_common.h"
#include "rkmedia_api.h"static bool quit = false;
static void sigterm_handler(int sig) {fprintf(stderr, "signal %d\n", sig);quit = true;
}

这里的optstr 和 long_options 分别是短选项字符串、长选项结构数组。(用于后面解析命令,在main函数的getopt_long用到)

这里短选项字符串定义了?、a、I、h、w、M几个参数,字符后有::表示可以要参数也可以不要,比如这里-a是用于指定iqfile路径的,它后面有两个:表示可以不指定所以我们实用的时候可以-a后面不接参数,字符后面有一个:的表示调用这个属性后面需要指定参数

这里的长选项结构数组也是类似的long_options中分别为:名称、需不需要参数、如果为 NULL,则返回第四个参数的值,反之返回自己、返回值

下面是一个介绍改函数用法的函数,这里简述一下:

-a 指定rkaiq文件路径 -I指定摄像头是哪个 -M指定是否使用多个摄像头 -w 宽度 -h高度也描述了他们的默认值

static RK_CHAR optstr[] = "?::a::I:h:w:M:";
static const struct option long_options[] = {{"aiq", optional_argument, NULL, 'a'},{"camid", required_argument, NULL, 'I'},{"multictx", required_argument, NULL, 'M'},{"help", optional_argument, NULL, '?'},{NULL, 0, NULL, 0},
};static void print_usage(const RK_CHAR *name) {printf("usage example:\n");
#ifdef RKAIQprintf("\t%s [-a [iqfiles_dir]]""[-I 0] ""[-M 0] ""\n",name);printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a ""/oem/etc/iqfiles/, ""set dirpath empty to using path by default, without this option aiq ""should run in other application\n");printf("\t-M | --multictx: switch of multictx in isp, set 0 to disable, set ""1 to enable. Default: 0\n");
#elseprintf("\t%s [-I 0]\n", name);
#endifprintf("\t-I | --camid: camera ctx id, Default 0\n");printf("\t-w: DisplayWidth, Default: 720\n");printf("\t-h: DisplayHeight, Default: 1280\n");
}

2.2main函数初始化参数

解释一下getopt_long函数:

传入参数 参数量、参数二级指针、短、长、NULL这是一个标准库函数

  • 如果解析到一个短选项或长选项,返回其对应的字符。例如,-a--aiq 返回 'a'
  • 如果遇到未知选项或选项参数缺失,返回 '?'
  • 如果没有更多的选项可以解析,返回 -1
int main(int argc, char *argv[]) {int ret = 0;
//图片分辨率int video_width = 1920;int video_height = 1080;
//显示分辨率即显示屏的分辨率,根据自己显示屏确定int disp_width = 720;int disp_height = 1280;
//摄像头默认ID  RK_S32 s32CamId = 0;
#ifdef RKAIQRK_BOOL bMultictx = RK_FALSE;
#endifint c;char *iq_file_dir = NULL;while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) {const char *tmp_optarg = optarg;switch (c) {case 'a':if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {tmp_optarg = argv[optind++];}if (tmp_optarg) {iq_file_dir = (char *)tmp_optarg;} else {//没-a指定时候默认iqfile位置iq_file_dir = "/oem/etc/iqfiles";}break;case 'I':s32CamId = atoi(optarg);break;case 'w':disp_width = atoi(optarg);break;case 'h':disp_height = atoi(optarg);break;
#ifdef RKAIQcase 'M':if (atoi(optarg)) {bMultictx = RK_TRUE;}break;
#endifcase '?':default:print_usage(argv[0]);return 0;}}printf("#CameraIdx: %d\n\n", s32CamId);if (iq_file_dir) {
#ifdef RKAIQprintf("#Rkaiq XML DirPath: %s\n", iq_file_dir);printf("#bMultictx: %d\n\n", bMultictx);rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;int fps = 30;SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);SAMPLE_COMM_ISP_Run(s32CamId);SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);
#endif

2.3输入模块vi初始化

首先初始化了  RK_MPI_SYS_Init();函数

然后就是对vi模块的配置

例如输入通道、通道数、输入宽高、输入像素颜色格式、工作模式,并对输入模块管道进行设置以及使能

注意这里设置的视频流 是0通道,RK_MPI_VI_SetChnAttr的第二个参数

 //初始化函数RK_MPI_SYS_Init();//定义 VI 通道属性结构体指针VI_CHN_ATTR_S vi_chn_attr;vi_chn_attr.pcVideoNode = "rkispp_scale0";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;//设置通道 摄像头号 通道号 刚才配置结构体指针ret = RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);//VI管道配置后需要使能ret |= RK_MPI_VI_EnableChn(s32CamId, 0);if (ret) {printf("Create vi[0] failed! ret=%d\n", ret);return -1;}

2.4RGA模块

首先初始化了一个覆盖信息与覆盖位置的结构体,

并设了覆盖颜色信息(argb8888与蓝色)

然后设置了覆盖位置是(0,0)到(100,100),但是初始化的时候吧通道设置为零1,因此我们在测试的时候看不到覆盖区域的蓝色方块,如果把这里的1改为0即保持与上述输入模块的视频流一个通道即可见

最后的一大段是配置了RGA的信息,大家可以主要看一下角度为旋转90°,最后设置了通道0

/* test rgn cover */COVER_INFO_S CoverInfo;OSD_REGION_INFO_S RngInfo;memset(&CoverInfo, 0, sizeof(CoverInfo));memset(&RngInfo, 0, sizeof(RngInfo));CoverInfo.enPixelFormat = PIXEL_FORMAT_ARGB_8888;CoverInfo.u32Color = 0xFFFF0000; // blue//CoverInfo.u32Color = 0xFFFF0000; // blueRngInfo.enRegionId = REGION_ID_0;RngInfo.u32PosX = 0;RngInfo.u32PosY = 0;RngInfo.u32Width = 100;RngInfo.u32Height = 100;RngInfo.u8Enable = 1;RK_MPI_VI_RGN_SetCover(s32CamId, 1, &RngInfo, &CoverInfo);// rga0 for primary planeRGA_ATTR_S stRgaAttr;memset(&stRgaAttr, 0, sizeof(stRgaAttr));stRgaAttr.bEnBufPool = RK_TRUE;stRgaAttr.u16BufPoolCnt = 3;//角度stRgaAttr.u16Rotaion = 90;stRgaAttr.stImgIn.u32X = 0;stRgaAttr.stImgIn.u32Y = 0;stRgaAttr.stImgIn.imgType = IMAGE_TYPE_NV12;stRgaAttr.stImgIn.u32Width = video_width;stRgaAttr.stImgIn.u32Height = video_height;stRgaAttr.stImgIn.u32HorStride = video_width;stRgaAttr.stImgIn.u32VirStride = video_height;stRgaAttr.stImgOut.u32X = 0;stRgaAttr.stImgOut.u32Y = 0;stRgaAttr.stImgOut.imgType = IMAGE_TYPE_RGB888;stRgaAttr.stImgOut.u32Width = disp_width;stRgaAttr.stImgOut.u32Height = disp_height;stRgaAttr.stImgOut.u32HorStride = disp_width;stRgaAttr.stImgOut.u32VirStride = disp_height;ret = RK_MPI_RGA_CreateChn(0, &stRgaAttr);if (ret) {printf("Create rga[0] falied! ret=%d\n", ret);return -1;}

2.5输出模块vo的初始化

 VO_CHN_ATTR_S stVoAttr = {0};// VO[0] for primary planestVoAttr.pcDevNode = "/dev/dri/card0";stVoAttr.emPlaneType = VO_PLANE_PRIMARY;stVoAttr.enImgType = IMAGE_TYPE_RGB888;stVoAttr.u16Zpos = 0;stVoAttr.stImgRect.s32X = 0;stVoAttr.stImgRect.s32Y = 0;stVoAttr.stImgRect.u32Width = disp_width;stVoAttr.stImgRect.u32Height = disp_height;stVoAttr.stDispRect.s32X = 0;stVoAttr.stDispRect.s32Y = 0;stVoAttr.stDispRect.u32Width = disp_width;stVoAttr.stDispRect.u32Height = disp_height;ret = RK_MPI_VO_CreateChn(0, &stVoAttr);if (ret) {printf("Create vo[0] failed! ret=%d\n", ret);return -1;}

2.6连接管道

经过上述对vi rga vo模块配置后,并没有把视频流连接起来因此下面我们需要绑定起来各个模块

下面,分别绑定了vi - rga rga-vo这样整体视频流向成功

MPP_CHN_S stSrcChn = {0};MPP_CHN_S stDestChn = {0};printf("#Bind VI[0] to RGA[0]....\n");stSrcChn.enModId = RK_ID_VI;stSrcChn.s32ChnId = 0;stDestChn.enModId = RK_ID_RGA;stDestChn.s32ChnId = 0;ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);if (ret) {printf("Bind vi[0] to rga[0] failed! ret=%d\n", ret);return -1;}printf("# Bind RGA[0] to VO[0]....\n");stSrcChn.enModId = RK_ID_RGA;stSrcChn.s32ChnId = 0;stDestChn.enModId = RK_ID_VO;stDestChn.s32ChnId = 0;ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);if (ret) {printf("Bind rga[0] to vo[0] failed! ret=%d\n", ret);return -1;}printf("%s initial finish\n", __func__);

2.7判断程序运行

这里类似于qt中的connect函数,signal是c库中函数,表示连接SIGINT与sigterm_handler函数,SIGINT是程序中断的函数,即你按下ctrl+c时候程序中断会触发该信号,sigterm_handler函数也是在2.1中就分析介绍了

signal(SIGINT, sigterm_handler);while (!quit) {usleep(500000);}

2.8退出函数

这里类似于linux总线驱动设备的驱动函数的出口函数一样,先断开了管道,后面销毁了各个模块的chn

printf("%s exit!\n", __func__);stSrcChn.enModId = RK_ID_VI;stSrcChn.s32ChnId = 0;stDestChn.enModId = RK_ID_RGA;stDestChn.s32ChnId = 0;ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);if (ret) {printf("UnBind vi[0] to rga[0] failed! ret=%d\n", ret);return -1;}stSrcChn.enModId = RK_ID_RGA;stSrcChn.s32ChnId = 0;stDestChn.enModId = RK_ID_VO;stDestChn.s32ChnId = 0;ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);if (ret) {printf("UnBind rga[0] to vo[0] failed! ret=%d\n", ret);return -1;}RK_MPI_VO_DestroyChn(0);RK_MPI_RGA_DestroyChn(0);RK_MPI_VI_DisableChn(s32CamId, 0);if (iq_file_dir) {
#ifdef RKAIQSAMPLE_COMM_ISP_Stop(s32CamId);
#endif}return 0;
}

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

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

相关文章

pdf压缩,pdf压缩在线,pdf文件太大怎么变小

在数字化时代&#xff0c;PDF文档因其跨平台、保持原样、易于阅读和打印等特点&#xff0c;成为了我们日常工作和生活中不可或缺的一部分。然而&#xff0c;随着PDF文件的不断累积&#xff0c;存储空间逐渐变得紧张&#xff0c;特别是在处理大量大型PDF文件时&#xff0c;如何有…

【Python】在 VS Code 里面绘制动图不显示动画的解决办法

在 VS Code 中&#xff0c;可以通过以下步骤来确保动画正确显示&#xff1a; 配置 VS Code 使用适当的绘图后端&#xff1a; VS Code 中使用 matplotlib 的动画功能&#xff0c;需要配置适当的绘图后端。推荐使用 TkAgg 或者 Qt5Agg 后端。你可以在代码中显式指定&#xff1a;…

若依前后端分离项目整合shardingjdbc分表(详细,分片字段订单id)

文章目录 1. 引入Maven依赖2.引入配置文件3.兼容之前的数据库源,使用现在的sharding数据库源&#xff08;shardingjdbc默认的数据源&#xff09;&#xff0c;但是配置好文件之后是没有生效的&#xff0c;需要加配置文件覆盖4. 检测是否成功5. 如何使用&#xff0c;在需要使用的…

qt开发-14_QListwidget 仿qq好友列表制作

QListWidget 继承 QListView。QListWidget 类提供了一个基于项的列表小部件。QListWidg et 是一个便捷的类&#xff0c;它提供了一个类似于 QListView&#xff08;下一小节将讲到&#xff09;提供的列表视图&#xff0c;但 是提供了一个用于添加和删除项目的基于项目的经典接口…

第10章 启动过程组 (启动过程组的重点工作)

第10章 启动过程组 10.3启动过程组的重点工作&#xff0c;在第三版教材第362~364页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;项目启动会议 1、作用 标志着对项目经理责权的定义结果的正式公布&#xff0c;通常由项目经理负责组织和召开。2、目的 使项目各…

数据库常用操作命令

数据库基本操作 #查看数据库 show databases#创建数据库 create database db DEFAULT CHARSET utf8 COLLATE utf8_general_ci;#使用数据库 use db;用户操作 #创建用户 create user 用户名IP地址 identified by 密码;#删除用户 drop user 用户名IP地址;#修改用户 rename user …

分享:Wordpress插件-AI Image Pro v2.6.0中文版语言包

AI Image Pro是一个wordpress插件,可将您的 WordPress 网站直接与最佳图像生成 A模型(DALL.E和稳定扩散)集成&#xff0c;并允许您利用 AI 生成图像、编辑(内画)图像和创建图像变体。最重要的是&#xff0c;它配备了许多一键式滤镜和许多微调选项,您可以使用它们来增强和创建令…

【算法介绍】开集识别算法 OpenMax

OpenMax算法简介 OpenMax是一种用于深度学习模型的开集识别算法&#xff0c;它能够在模型的输出中区分已知类别和未知类别。该算法的核心思想是利用深度神经网络的倒数第二层&#xff08;全连接层&#xff09;的激活向量&#xff0c;通过构建每个类别的平均激活向量&#xff0…

黑匣子问题:大语言模型的内部工作原理

像 GPT-3 这样的大型语言模型 (LLM) 已经展示了令人印象深刻的自然语言能力&#xff0c;但它们的内部工作原理仍然知之甚少。这种“黑匣子”性质使得ChatGPT在敏感的现实应用程序中部署时可能会出现问题。 什么是LLM黑匣子问题&#xff1f; 语言学习模型 (LLM) 是强大的工具&…

Postman 接口测试工具使用方法

Postman 是一个强大的 API 测试工具,广泛用于开发和测试 API。以下是对 Postman 的详细介绍,包括其主要功能、使用方法和一些高级功能。 一、Postman 简介 Postman 是一个用于 API 开发的协作平台,提供了丰富的功能来进行 API 请求、测试和文档编写。它可以用来测试 RESTfu…

要求全国70%中医院设置康复科!康复科门诊服务这样建设!

近日&#xff0c;国家中医药管理局印发《国家中医药管理局关于进一步加强中医医院康复科建设的通知》提出&#xff0c;中医医院应根据当地人口规模及中医药康复服务需求设置康复科并作为独立科室进行建设和管理。有条件的二级以上中医医院应当按照《中医医院康复科推荐配置标准…

软件质量保证与测试

目录 一、测试流程 二、测试用例 2.1概念 2.2用例编写格式 三、设计测试点 3.1等价类 3.1.1概念 3.1.2案例 3.1.3适用场景 3.1.4执行用例 3.2边界值 3.2.1概念 3.2.2案例 3.2.3使用场景 3.3判定表 3.3.1判定表使用原因 3.3.2概念 3.3.3案例 3.3.4使用场景 …

Day4: 两两交换链表中的节点 24 删除链表的倒数第N个节点 19 链表相交 02.07 环形链表II 142

题目24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* …

新鲜出炉的信息化一机两用方案

在信息化日益发展的今天&#xff0c;网络安全问题愈发凸显其重要性。尤其是在政府和企事业单位中&#xff0c;如何在保证业务流畅和工作效率的同时&#xff0c;确保信息高安全性&#xff0c;成为了一个亟待解决的问题。而“一机两用”政策&#xff0c;正是针对这一需求而提出的…

依法经营电信业务承诺书-ICP-模板范文

依法经营电信业务承诺书 xx省通信管理局 &#xff1a; 我公司在获得信息服务业务经营许可证以后&#xff0c;在从事电信业务经营活动中&#xff0c;将遵守如下承诺&#xff1a; 一、我们将严格遵守有关电信法律、法规和政策&#xff0c;严格按照已批准的业务服务范围&#…

QT布局管理(分割窗口QSplitter类、停靠窗口QDockWidget类、堆栈窗体QStackedWidget类、基本布局QLayout)

此片文章简单介绍布局管理的使用方法。通过实例先分别介绍分隔窗口QSplitter类、停靠窗口QDockWidget类及QStackedWidget类的使用&#xff0c;最后再通过一个实例介绍QLayout的使用。 分割窗口QSplitter类 分隔窗口可以灵活地布局窗口&#xff0c;可以用在文件资源管理器地窗…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 任务积分优化问题(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 任务积分优化问题(100分) 🌍 评测功能需要 订阅专栏 后私信…

python数据可视化:在带有子图的绘图中添加总标题 matplotlib.pyplot.suptitle()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python数据可视化&#xff1a; 在带有子图的绘 图中 添加总标题 matplotlib.pyplot.suptitle() 请问关于以下代码表述正确的选项是&#xff1f; import matplotlib.pyplot as plt fig, (ax…

查成绩啦!2024上半年软考成绩查询入口已开通!

2024上半年软考成绩查询入口已经开通啦&#xff01;下面&#xff0c;小编为你详细讲解软考成绩查询流程。 由于成绩查询入口开通时间全国是一样的&#xff0c;所以有可能同时查询的人数较多&#xff0c;从而导致查询系统出现问题无法进入的情况&#xff0c;如出现这种情况&…

LiveMedia视频汇聚平台的设备管理功能

LiveMedia视频汇聚平台的设备管理功能是实现视频资源有效管理和控制的关键组成部分。以下是设备管理功能的详细介绍&#xff1a; 设备接入与管理&#xff1a; 设备添加与编辑&#xff1a;平台支持添加、编辑与删除设备&#xff0c;可编辑的信息包括设备接入的协议类型、服务节…