rkmedia_vi_get_frame_test.c 代码解析
使用示例:
录像:
rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12
然后用yuvplayer.exe可以播放。
录像10帧:
rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 -c 10
解析代码:
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>#include "common/sample_common.h"
#include "rkmedia_api.h"typedef struct { //用于传递输出参数char *file_path;int frame_cnt;
} OutputArgs;static bool quit = false;
static void sigterm_handler(int sig) { //用于控制程序退出fprintf(stderr, "signal %d\n", sig);quit = true;
}static void *GetMediaBuffer(void *arg) { //获取视频帧数据并保存到文件OutputArgs *outArgs = (OutputArgs *)arg; //使用`OutputArgs`结构体指针`outArgs`来获取输出参数,其中包括保存路径`save_path`和帧计数`save_cnt`。char *save_path = outArgs->file_path; //保存路径int save_cnt = outArgs->frame_cnt; //帧计数int frame_id = 0;FILE *save_file = NULL;if (save_path) {save_file = fopen(save_path, "w"); //打开保存路径指定的文件if (!save_file)printf("ERROR: Open %s failed!\n", save_path);}MEDIA_BUFFER mb = NULL;while (!quit) { //进入循环,当全局变量`quit`为假时持续循环。mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VI, 0, -1); //获取视频帧的媒体缓冲区`mb`,并检查是否获取成功if (!mb) {printf("RK_MPI_SYS_GetMediaBuffer get null buffer!\n");break;}//获取媒体缓冲区的图像信息`stImageInfo`,并打印相关信息,如帧指针、文件描述符、大小、时间戳等。MB_IMAGE_INFO_S stImageInfo = {0};int ret = RK_MPI_MB_GetImageInfo(mb, &stImageInfo);if (ret)printf("Warn: Get image info failed! ret = %d\n", ret);printf("Get Frame:ptr:%p, fd:%d, size:%zu, mode:%d, channel:%d, ""timestamp:%lld, ImgInfo:<wxh %dx%d, fmt 0x%x>\n",RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetChannelID(mb),RK_MPI_MB_GetTimestamp(mb), stImageInfo.u32Width,stImageInfo.u32Height, stImageInfo.enImgType);//如果已经打开了保存文件,则将媒体缓冲区中的帧数据写入到文件中,并打印保存信息。if (save_file) { fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), save_file);printf("#Save frame-%d to %s\n", frame_id++, save_path);}RK_MPI_MB_ReleaseBuffer(mb); //释放媒体缓冲区。if (save_cnt > 0) //如果设置了帧计数`save_cnt`且大于0,则递减计数。save_cnt--;// exit when completeif (!save_cnt) { //当完成保存指定数量的帧后,设置全局变量`quit`为真,退出循环。quit = true;break;}}if (save_file)fclose(save_file);return NULL;
}static RK_CHAR optstr[] = "?::a::w:h:c:o:d:I:M:";
static const struct option long_options[] = {{"aiq", optional_argument, NULL, 'a'},{"device_name", required_argument, NULL, 'd'},{"width", required_argument, NULL, 'w'},{"height", required_argument, NULL, 'h'},{"frame_cnt", required_argument, NULL, 'c'},{"output", required_argument, NULL, 'o'},{"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] ""[-w 1920] ""[-h 1080]""[-c 10] ""[-d rkispp_scale0] ""[-o out.nv12] \n",name);printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a ""/oem/etc/iqfiles/, ""set dirpath emtpty 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 [-w 1920] ""[-h 1080] ""[-c 10] ""[-d rkispp_scale0] ""[-I 0] ""[-o out.nv12] \n",name);
#endifprintf("\t-w | --width: VI width, Default:1920\n");printf("\t-h | --heght: VI height, Default:1080\n");printf("\t-d | --device_name: set device node(v4l2), Default:rkispp_scale0\n");printf("\t-I | --camid: camera ctx id, Default 0\n");printf("\t-c | --frame_cnt: record frame, Default:-1(unlimit)\n");printf("\t-o | --output: output path, Default:NULL\n");printf("Notice: fmt always NV12\n");
}int main(int argc, char *argv[]) {RK_U32 u32Width = 1920;RK_U32 u32Height = 1080;int frameCnt = -1;RK_CHAR *pDeviceName = "rkispp_scale0";RK_CHAR *pOutPath = NULL;RK_CHAR *pIqfilesPath = NULL;RK_S32 s32CamId = 0;
#ifdef RKAIQRK_BOOL bMultictx = RK_FALSE;
#endifint c;int ret = 0;//使用了 getopt_long 函数对命令行参数进行解析。然后根据解析得到的参数配置相应的采集参数,比如视频宽高、帧率等。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) {pIqfilesPath = (char *)tmp_optarg;} else {pIqfilesPath = "/oem/etc/iqfiles/";}break;case 'w':u32Width = atoi(optarg);break;case 'h':u32Height = atoi(optarg);break;case 'c':frameCnt = atoi(optarg);break;case 'o':pOutPath = optarg;break;case 'd':pDeviceName = optarg;break;case 'I':s32CamId = atoi(optarg);break;
#ifdef RKAIQcase 'M':if (atoi(optarg)) {bMultictx = RK_TRUE;}break;
#endifcase '?':default:print_usage(argv[0]);return 0;}}printf("#####Device: %s\n", pDeviceName);printf("#####Resolution: %dx%d\n", u32Width, u32Height);printf("#####Frame Count to save: %d\n", frameCnt);printf("#####Output Path: %s\n", pOutPath);printf("#CameraIdx: %d\n\n", s32CamId);signal(SIGINT, sigterm_handler);if (pIqfilesPath) {
#ifdef RKAIQprintf("#####Aiq xml dirpath: %s\n\n", pIqfilesPath);printf("#bMultictx: %d\n\n", bMultictx);// rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR2; //替换为HDR模式int fps = 30;SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, pIqfilesPath);SAMPLE_COMM_ISP_Run(s32CamId);SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);
#endif}//在相机初始化部分,通过 RK_MPI_VI_SetChnAttr 和 RK_MPI_VI_EnableChn 函数配置并启用了视频输入通道。RK_MPI_SYS_Init();VI_CHN_ATTR_S vi_chn_attr;vi_chn_attr.pcVideoNode = pDeviceName;vi_chn_attr.u32BufCnt = 3;vi_chn_attr.u32Width = u32Width;vi_chn_attr.u32Height = u32Height;vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;ret = RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);ret |= RK_MPI_VI_EnableChn(s32CamId, 0);if (ret) {printf("Create VI[0] failed! ret=%d\n", ret);return -1;}printf("%s initial finish\n", __func__);//在视频采集和处理部分,创建了一个线程用于获取媒体缓冲区,并通过 RK_MPI_VI_StartStream 开始采集。然后通过一个循环来等待退出信号,最后在退出时释放资源。pthread_t read_thread;OutputArgs outArgs = {pOutPath, frameCnt};pthread_create(&read_thread, NULL, GetMediaBuffer, &outArgs); //ret = RK_MPI_VI_StartStream(s32CamId, 0);if (ret) {printf("Start VI[0] failed! ret=%d\n", ret);return -1;}while (!quit) {usleep(500000);}RK_MPI_VI_DisableChn(s32CamId, 0);#ifdef RKAIQif (pIqfilesPath)SAMPLE_COMM_ISP_Stop(s32CamId);
#endifprintf("%s exit!\n", __func__);return 0;
}相关文章:
rkmedia_vi_get_frame_test.c 代码解析
使用示例: 录像: rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 然后用yuvplayer.exe可以播放。 录像10帧: rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 -c 10 解析代码: #include <as…...
探究Kafka原理-3.生产者消费者API原理解析
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理🔥如果感觉博主的文章还不错的话,请ὄ…...
Linux系统iptables扩展
目录 一. iptables规则保存 1. 导出规则保存 2. 自动重载规则 ①. 当前用户生效 ②. 全局生效 二. 自定义链 1. 新建自定义链 2. 重命名自定义链 3. 添加自定义链规则 4. 调用自定义链规则 5. 删除自定义链 三. NAT 1. SNAT 2. DNAT 3. 实验 ①. 实验要求 ②. …...
Openwrt 系统安装 插件名称与中文释义
系统镜像 当时是去官网找对应的,但是作为门外汉,想简单,可以试试这个网站 插件 OpenWrt/Lede全部插件列表功能注释...
[原创]Delphi的SizeOf(), Length(), 动态数组, 静态数组的关系.
[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…...
C++(20):bind_front
C(11):bind_c11 bind_风静如云的博客-CSDN博客 提供了方法来绑定函数参数的方法。 C20提供了bind_front用于简化这个绑定。 #include <iostream> #include <functional> using namespace std;void func1(int d1, int d2) {cout<<__func__<&l…...
【spring】bean的后处理器
目录 一、作用二、常见的bean后处理器2.1 AutowiredAnnotationBeanPostProcessor2.1.1 说明2.1.2 代码示例2.1.3 截图示例 2.2 CommonAnnotationBeanPostProcessor2.2.1 说明2.2.2 代码示例2.2.3 截图示例 2.3 ConfigurationPropertiesBindingPostProcessor2.3.1 说明2.3.2 代码…...
Centos7安装docker、java、python环境
文章目录 前言一、docker的安装二、docker-compose的安装三、安装python3和配置pip3配置python软链接(关键) 四、Centos 7.6操作系统安装JAVA环境 前言 每次vps安装docker都要看网上的文章,而且都非常坑,方法千奇百怪,…...
简单小结类与对象
/*** Description 简单小结类与对象*/ package com.oop;import com.oop.demo03.Pet;public class Application {public static void main(String[] args) {/*1.类与对象类是一个模版:抽象,对象是一个具体的实例2.方法定义、调用!3.对象的引用…...
ABAP 如何获取内表行的索引值(index) ?
获取索引值 在ABAP中,如果需要获取一个内表中某条记录的索引(index),可以使用 READ TABLE 语句。在 READ TABLE 语句后面的 WITH KEY 子句可以指定搜索条件,如果找到了匹配的记录,系统字段 SY-TABIX 将保存…...
ESP32-Web-Server编程- 使用表格(Table)实时显示设备信息
ESP32-Web-Server编程- 使用表格(Table)实时显示设备信息 概述 上节讲述了通过 Server-Sent Events(以下简称 SSE) 实现在网页实时更新 ESP32 Web 服务器的传感器数据。 本节书接上会,继续使用 SSE 机制在网页实时显…...
vue3 Hooks函数使用及常用utils封装
hooks 是什么 vue3使用了composition API,我们可自定义封装hooks,达到复用,在Vue2中采取的mixins,对mixins而言, hooks更清楚复用功能代码的来源, 更清晰易懂。 简单来说:hooks 就是函数的一种写法…...
matlab 无迹卡尔曼滤波
1、内容简介 略 26-可以交流、咨询、答疑 2、内容说明 无迹卡尔曼滤波 无迹卡尔曼滤波 无迹卡尔曼滤波 3、仿真分析 %该文件用于编写无迹卡尔曼滤波算法及其测试 %注解:主要子程序包括:轨迹发生器、系统方程 % 测量方程、UKF滤波器 %----…...
大脑--学习方法
1.大脑喜欢色彩。平时使用高质量的有色笔或使用有色纸,颜色能帮助记忆。 2.大脑集中精力最多只有25分钟。这是对成人而言,所以学习20到30分钟后就应该休息10分钟。你可以利用这段时间做点家务,10分钟后再回来继续学习,效果会更好…...
4.C转python
1.建立函数: def 函数名(形参): 函数体(记得写缩进) return 返回值(python中可以没有return) 2.调用函数: 函数名(实参) 实参和形参个数相等即可,类型不需要相同 其中接收返回值与C中的差不多 3.如果只是定义而不调用则函数不会执行 4.先定义函数,后调用 5.python中可以…...
YOLOv5项目实战(5)— 算法模型优化和服务器部署
前言:Hello大家好,我是小哥谈。近期,作者所负责项目中的算法模型检测存在很多误报情况,为了减少这种误报情况,作者一直在不断优化算法模型。鉴于此,本节课就给大家详细介绍一下实际工作场景中如何去优化算法模型和进行部署,另外为了方便大家进行模型训练,作者在文章中提…...
JavaScript类型判断:解密变量真实身份的神奇技巧
文章目录 1. typeof运算符2. instanceof运算符3. Object.prototype.toString4. Array.isArray5. 使用constructor属性6. 使用Symbol.toStringTag7. 使用is类型判断库8. 谨慎使用隐式类型转换结语 🎉JavaScript类型判断:解密变量真实身份的神奇技巧 ☆* o…...
MT6893_天玑 1200芯片规格参数介绍_datasheet规格书
天玑 1200(MT6893)是一款专为旗舰级全新5G芯片,它融合了先进的AI、相机和多媒体技术,为用户带来令人惊叹的体验。采用先进的6纳米制程设计,内置各种先进技术。该芯片采用旗舰级的八核CPU架构设计,支持16GB强大的四通道内存以及双通…...
【Android踩过的坑】13.Android Studio 运行成功,但APP没有安装上的问题
【Android踩过的坑】13.Android Studio 运行成功,但APP没有安装上的问题 解决办法: 在app的build.gradle文件下添加以下代码 android {...//android.useNewApkCreatorfalse 在高版本gradle下无效,添加以下代码解决冲突即可packagingOptions…...
redis安装配置
Windows 下 Redis 安装与配置 教程_redis windows-CSDN博客 启动Redis服务 打开cmd窗口,切换到Redis安装路径,输入 redis-server 启动 redis 服务...
油雾净化设备哪家技术更专业
在机械加工、五金锻造、热处理等工业生产场景中,机床切削、乳化液喷淋、高温加工会持续产生大量工业油雾。悬浮在车间内的油雾不仅会腐蚀生产设备、污染生产环境,还会刺激人体呼吸道,危害操作人员身体健康,同时超标排放还会违反环…...
别再乱用case了!Verilog里case、casez、casex到底啥区别?一个例子讲透
别再乱用case了!Verilog里case、casez、casex到底啥区别?一个例子讲透 第一次在Verilog代码里看到casez和casex时,我下意识以为它们只是case的某种变体语法。直到某次仿真结果出现诡异的不匹配,排查三小时后才发现是casex误用导致…...
Sixpack Redis数据存储策略:高效管理A/B测试数据的10个技巧
Sixpack Redis数据存储策略:高效管理A/B测试数据的10个技巧 【免费下载链接】sixpack Sixpack is a language-agnostic a/b-testing framework 项目地址: https://gitcode.com/gh_mirrors/si/sixpack Sixpack是一个语言无关的A/B测试框架,它通过R…...
【笔记】HarmonyOS核心设计理念
HarmonyOS初衷不是为了平替,是看到了万物智联时代,对智能终端操作系统有许多新的诉求; 本内容主要帮助理解HarmonyOS核心设计理念的关键背景与创新驱动力; 第一节:回顾操作系统的发展历史 第一台通用计算机诞生于1946年…...
模型加速全景图:从“瘦身”到“飞驰”的知识图谱
文章目录知识图谱:模型加速的三大维度维度一:模型自身优化(让模型更“瘦”)维度二:计算过程优化(让计算更“顺”)维度三:硬件与系统优化(让硬件更“忙”)如何…...
java springboot-vue社区资源共享系统 社区活动报名系统
目录同行可拿货,招校园代理 ,本人源头供货商项目概述技术栈核心功能模块系统架构设计部署方案扩展性设计项目技术支持源码获取详细视频演示 :同行可合作点击我获取源码->->进我个人主页-->获取博主联系方式同行可拿货,招校园代理 ,本人源头供货商 项目概述…...
C语言内联函数与宏的深度解析:性能、安全与工程实践
1. 项目概述:为什么我们需要关注内联与宏?在C语言的日常开发中,尤其是性能敏感或嵌入式领域的项目里,我们经常面临一个选择:为了实现一个简单的、频繁调用的功能,是写一个函数,还是用一个宏来搞…...
RAG架构全解析:从基础到高级,打造你的企业级知识库问答系统!
本文详细介绍了RAG(Retrieval-Augmented Generation)架构的多种变体,从基础的Naive RAG和Standard RAG开始,逐步深入到Advanced RAG、Hybrid Search RAG、Rerank型RAG、文档增强型RAG、Agentic RAG、Router RAG、GraphRAG、RAPTOR…...
【限时开放】ElevenLabs波斯文语音调试秘钥包(含Persian SSML扩展标签库、RTL音频波形对齐工具、实时音素诊断CLI):仅支持至2024年Q3 API v2退役前
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs波斯文语音支持的演进与技术边界 ElevenLabs自2022年推出多语言TTS服务以来,波斯文(Farsi)长期处于实验性支持阶段。早期版本仅能通过自定义音色音素级微调…...
OpenELB安全配置:RBAC、网络策略与证书管理最佳实践
OpenELB安全配置:RBAC、网络策略与证书管理最佳实践 【免费下载链接】openelb Load Balancer Implementation for Kubernetes in Bare-Metal, Edge, and Virtualization 项目地址: https://gitcode.com/gh_mirrors/op/openelb OpenELB是一款专为Kubernetes设…...
