目录

一、RV1126 增加 USB 音视频设备

二、RkMedia 音频 API

2.1 PCM 音频输入

        系统初始化

        AI 通道配置

        AI 通道使能

        开启数据流

        获取数据

        保存数据

2.2 编码音频编码输入

2.3 PCM 音频输出


一、RV1126 增加 USB 音视频设备

配置过程

        第一步:来到 SDK 内核路径下

        source envsetup.sh --- 选择:rockchip_rv1126_rv1109_spi_nand 选项

        ./build.sh lunch --- 选择:BoardConfig-38x38-spi-nand.mk 选项

        cd kernel

        make ARCH=arm rv1126_defconfig

        make ARCH=arm menuconfig

USB 摄像头支持

Device Drivers --->

        <*> Multimedia support --->

                [*] Media USB Adapters --->

                        <*> USB Video Class (UVC)

                                [*] UVC input events device support

USB 音频

Device Drivers --->

        <*> Sound card support --->

                <*> Advanced Linux Sound Architecture --->

                        [*] USB sound devices --->

                                <*> USB Audio/MIDI driver

保存退出

        make ARCH=arm savedefconfig

        cp defconfig arch/arm/configs/rv1126_defconfig

        编译固件然后烧录

使用

查看声音输出设备

        aplay -l

        当前 USB 声卡为 card1

        所以执行的指令为:

        aplay -D plughw:1,0 /sdcard/1.wav

查看声音输入设备

arecord -l

查看视频输入设备

v4l2-ctl --list-devices

官方音频测试例程

        SDK/buildroot/output/rockchip_rv1126_rv1109/build/rkmedia/examples

                rkmedia_audio_test.c

像编译自己写的程序一样编译即可

编译内核红色的警告

这个是正常的,是 SDK 提醒不要随便改电源配置

二、RkMedia 音频 API

核心:音频

2.1 PCM 音频输入

        系统初始化

                RK_MPI_SYS_Init();

        AI 通道配置

                RK_MPI_AI_SetChnAttr(0, &ai_attr);

        AI 通道使能

                RK_MPI_AI_EnableChn(0);

        开启数据流

                RK_MPI_AI_StartStream(0);

        获取数据

        保存数据

arecord -L

        播放 PCM 的指令

        aplay -f S16_LE -r 48000 -c 2 9203.pcm

2.2 编码音频编码输入

        MP2

                用于和 H264 视频共同合成一个 mp4 文件

        G711A

                用于音频推流 --- rkmedia 不支持推太大的数据流

                编码后的文件是无法播放的

        后续 MP2 在合成的音视频中可以播放

        G711A 可以推流之后在 VLC 播放

        RV1126板子可以做的音频解码

                可以做 G711A 的解码

        编码和 PCM 多的内容在

                创建一个编码通道

                做一个绑定

2.3 PCM 音频输出

        主要使用的是 AO 通道

        AI --- 音频输入设置的参数

                为了保存数据

        AO --- 音频输出设置的参数

                为了准确无误的获取参数

        AO 的参数要和 AI 的参数保持一致

RK_MPI_SYS_Init();RK_MPI_AO_SetChnAttr(0, &ao_attr);RK_MPI_AO_EnableChn(0);//计算延时时间RK_U32 u32Timeval = u32FrameCnt * 1000000 / u32SampleRate; // usMB_AUDIO_INFO_S stSampleInfo = {ao_attr.u32Channels,ao_attr.u32SampleRate,ao_attr.u32NbSamples, ao_attr.enSampleFormat
};mb = RK_MPI_MB_CreateAudioBufferExt(&stSampleInfo, RK_FALSE, 0);fread(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);RK_MPI_SYS_SendMediaBuffer(RK_ID_AO, 0, mb);usleep(u32Timeval);RK_MPI_MB_ReleaseBuffer(mb);mb = NULL; 

         aplay -L

代码

mp2_aenc

#include "main.h"
#include <time.h>RK_U32 ai_chn = 2;      //于G711A编码格式给1
RK_U32 nbsmp = 1152;    //对于MP2编码格式给1152,对于G711A编码格式给1024
RK_U32 srate = 48000;   //PCM格式,不要太低,G711A编码格式给8000
int end_flag = 0;
FILE *file;// 输出回调函数
void myoutcbfunc(MEDIA_BUFFER mb) 
{if(end_flag){RK_MPI_MB_ReleaseBuffer(mb);return;}fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);RK_MPI_MB_ReleaseBuffer(mb);}int main(void)
{//PCM音频输入file = fopen("./9203.mp2", "w");//1.系统初始化RK_MPI_SYS_Init();//2.AI通道配置AI_CHN_ATTR_S ai_pstAttr = {0};ai_pstAttr.enAiLayout = AI_LAYOUT_NORMAL;ai_pstAttr.enSampleFormat = RK_SAMPLE_FMT_S16;ai_pstAttr.pcAudioNode = "default:CARD=Device";ai_pstAttr.u32Channels = ai_chn;                            //于G711A编码格式给1ai_pstAttr.u32NbSamples = nbsmp;     //对于MP2编码格式给1152,对于G711A编码格式给1024ai_pstAttr.u32SampleRate = srate;    //PCM格式,不要太低,G711A编码格式给8000RK_MPI_AI_SetChnAttr(0, &ai_pstAttr);//AI通道使能RK_MPI_AI_EnableChn(0);//开启数据流  RK_MPI_AI_StartStream(0);//获取数据MPP_CHN_S ai_pstChn = {0};ai_pstChn.enModId = RK_ID_AI;//视频输入通道ai_pstChn.s32ChnId = 0;//VI通道ai_pstChn.s32DevId = 0;RK_MPI_SYS_RegisterOutCb(&ai_pstChn, myoutcbfunc);int count = 10;while(1){sleep(1);if(!count){end_flag = 1;break;}printf("剩余 %d 秒结束\n", count);count--;}fclose(file);RK_MPI_AI_DisableChn(0);//保存数据return 0;
}

g711a_aenc

#include "main.h"
#include <time.h>RK_U32 ai_chn = 1;      //mp2给2, 于G711A编码格式给1
RK_U32 nbsmp = 1024;    //对于MP2编码格式给1152,对于G711A编码格式给1024
RK_U32 srate = 8000;   //PCM格式,不要太低,G711A编码格式给8000
int end_flag = 0;
FILE *file;// 输出回调函数
void myoutcbfunc(MEDIA_BUFFER mb) 
{if(end_flag){RK_MPI_MB_ReleaseBuffer(mb);return;}fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);RK_MPI_MB_ReleaseBuffer(mb);}int main(void)
{//PCM音频输入//file = fopen("./9203.mp2", "w");file = fopen("./9203.g711a", "w");//1.系统初始化RK_MPI_SYS_Init();//2.AI通道配置AI_CHN_ATTR_S ai_pstAttr = {0};ai_pstAttr.enAiLayout = AI_LAYOUT_NORMAL;ai_pstAttr.enSampleFormat = RK_SAMPLE_FMT_S16;ai_pstAttr.pcAudioNode = "default:CARD=Device";ai_pstAttr.u32Channels = ai_chn;                            //于G711A编码格式给1ai_pstAttr.u32NbSamples = nbsmp;     //对于MP2编码格式给1152,对于G711A编码格式给1024ai_pstAttr.u32SampleRate = srate;    //PCM格式,不要太低,G711A编码格式给8000RK_MPI_AI_SetChnAttr(0, &ai_pstAttr);//AI通道使能RK_MPI_AI_EnableChn(0);//开启数据流  RK_MPI_AI_StartStream(0);AENC_CHN_ATTR_S aenc_pstAttr = {0};// aenc_pstAttr.enCodecType = RK_CODEC_TYPE_MP2;// aenc_pstAttr.stAencMP2.u32Channels = ai_chn;// aenc_pstAttr.stAencMP2.u32SampleRate = srate;aenc_pstAttr.enCodecType = RK_CODEC_TYPE_G711A;aenc_pstAttr.stAencG711A.u32Channels = ai_chn;aenc_pstAttr.stAencG711A.u32NbSample = nbsmp;aenc_pstAttr.stAencG711A.u32SampleRate = srate;aenc_pstAttr.u32Bitrate = 64000; //严格来说,这个需要算aenc_pstAttr.u32Quality = 1;RK_MPI_AENC_CreateChn(0, &aenc_pstAttr);    //在此创建一个通道 --- 演示编码MP2编码(音视频合成)和G711A的编码(推流) --- AI0绑定AENC0,AI0绑定AENC1MPP_CHN_S a_pstSrcChn = {0};a_pstSrcChn.enModId = RK_ID_AI;a_pstSrcChn.s32ChnId = 0;a_pstSrcChn.s32DevId = 0;MPP_CHN_S a_pstDestChn = {0};a_pstDestChn.enModId = RK_ID_AENC;    //后续AENC的通道ID是需要改的a_pstDestChn.s32ChnId = 0;a_pstDestChn.s32DevId = 0;RK_MPI_SYS_Bind(&a_pstSrcChn, &a_pstDestChn);RK_MPI_SYS_RegisterOutCb(&a_pstDestChn, myoutcbfunc);int count = 10;while(1){sleep(1);if(!count){end_flag = 1;break;}printf("剩余 %d 秒结束\n", count);count--;}fclose(file);RK_MPI_SYS_UnBind(&a_pstSrcChn, &a_pstDestChn);RK_MPI_AENC_DestroyChn(0);RK_MPI_AI_DisableChn(0);//保存数据return 0;
}

ai_pcm

#include "main.h"
#include <time.h>RK_U32 ai_chn = 2;      //于G711A编码格式给1
RK_U32 nbsmp = 1152;    //对于MP2编码格式给1152,对于G711A编码格式给1024
RK_U32 srate = 48000;   //PCM格式,不要太低,G711A编码格式给8000
int end_flag = 0;
FILE *file;// 输出回调函数
void myoutcbfunc(MEDIA_BUFFER mb) 
{if(end_flag){RK_MPI_MB_ReleaseBuffer(mb);return;}fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);RK_MPI_MB_ReleaseBuffer(mb);}int main(void)
{//PCM音频输入file = fopen("./9203.pcm", "w");//1.系统初始化RK_MPI_SYS_Init();//2.AI通道配置AI_CHN_ATTR_S ai_pstAttr = {0};ai_pstAttr.enAiLayout = AI_LAYOUT_NORMAL;ai_pstAttr.enSampleFormat = RK_SAMPLE_FMT_S16;ai_pstAttr.pcAudioNode = "default:CARD=Device";ai_pstAttr.u32Channels = ai_chn;                            //于G711A编码格式给1ai_pstAttr.u32NbSamples = nbsmp;     //对于MP2编码格式给1152,对于G711A编码格式给1024ai_pstAttr.u32SampleRate = srate;    //PCM格式,不要太低,G711A编码格式给8000RK_MPI_AI_SetChnAttr(0, &ai_pstAttr);//AI通道使能RK_MPI_AI_EnableChn(0);//开启数据流  RK_MPI_AI_StartStream(0);//获取数据MPP_CHN_S ai_pstChn = {0};ai_pstChn.enModId = RK_ID_AI;//视频输入通道ai_pstChn.s32ChnId = 0;//VI通道ai_pstChn.s32DevId = 0;RK_MPI_SYS_RegisterOutCb(&ai_pstChn, myoutcbfunc);int count = 10;while(1){sleep(1);if(!count){end_flag = 1;break;}printf("剩余 %d 秒结束\n", count);count--;}fclose(file);RK_MPI_AI_DisableChn(0);//保存数据return 0;
}

ao_pcm

#include "main.h"
#include <time.h>RK_U32 ai_chn = 2;      //mp2给2, 于G711A编码格式给1
RK_U32 nbsmp = 1152;    //对于MP2编码格式给1152,对于G711A编码格式给1024
RK_U32 srate = 48000;   //PCM格式,不要太低,G711A编码格式给8000FILE *file;int main(void)
{file = fopen("./9203.pcm", "r");RK_MPI_SYS_Init();//1.设置AO通道属性AO_CHN_ATTR_S ao_pstAttr = {0};ao_pstAttr.enSampleFormat = RK_SAMPLE_FMT_S16;ao_pstAttr.pcAudioNode = "default:CARD=rockchipi2s0sou";ao_pstAttr.u32Channels = ai_chn;ao_pstAttr.u32NbSamples = nbsmp;ao_pstAttr.u32SampleRate = srate;RK_MPI_AO_SetChnAttr(0, &ao_pstAttr);//2.设置AO通道RK_MPI_AO_EnableChn(0);//3.计算延时时间RK_U32 u32Timeval = nbsmp * 1000000 / srate; // us//4.填充核心结构体MB_AUDIO_INFO_S stSampleInfo = {ao_pstAttr.u32Channels, ao_pstAttr.u32SampleRate,ao_pstAttr.u32NbSamples, ao_pstAttr.enSampleFormat};//5.创建Media BufferMEDIA_BUFFER mb = NULL;int ret = 0;    //结束标志while(1){mb = RK_MPI_MB_CreateAudioBufferExt(&stSampleInfo, RK_FALSE, 0);//6.读取一帧数据ret = fread(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);if(ret <= 0){break;}//7.发送给AO通道RK_MPI_SYS_SendMediaBuffer(RK_ID_AO, 0, mb);//8.延时usleep(u32Timeval);RK_MPI_MB_ReleaseBuffer(mb);mb = NULL;}RK_MPI_MB_ReleaseBuffer(mb);mb = NULL;fclose(file);RK_MPI_AENC_DestroyChn(0);//保存数据return 0;
}

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

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

相关文章

CETOL 6σ 帮助提升活检器械精度并降低制造成本

某全球医疗器械企业采用 Sigmetrix 的 CETOL 6σ 公差分析软件&#xff0c;针对一次性活检采集器械&#xff08;Biopsy Harvesting Instrument&#xff09;完成结构优化&#xff0c;成功解决颌骨动力学缺陷、4mm孔径精度控制及线缆传动敏感度等核心挑战&#xff0c;大大提高了活…

基于协同过滤算法的图书推荐系统设计与实现/基于python的图书推荐系统设计与实现/基于python的图书借阅系统设计与实现

基于协同过滤算法的图书推荐系统设计与实现采用django、vue技术用户&#xff1a;注册、登录、图书信息、公告信息、个人中心、借阅记录、归还记录、我的收藏。管理员&#xff1a;登录、用户、图书分类、图书信息、借阅记录、归还记录、系统管理、用户信息。

线程组和线程池的基本用法

1.线程组1.1创建线程组的方法public class xianchengzu {public static void main(String[] args) {ThreadGroup group new ThreadGroup("group");// 创建线程组时指定父线程组ThreadGroup parent new ThreadGroup("parent");ThreadGroup child new Thr…

百度华为硬件笔试机试题-卷4

百度华为硬件笔试机试题-卷4 收集整理了以下30道选择题和判断题,涵盖电源管理、功率放大、半导体器件、数字逻辑、信号处理和电磁理论等领域。题目涉及复杂计算和分析,给出了参考答案和详细的解析,非常适合硬件工程师笔试机试准备。 选择题 1. 电源纹波主要测量什么值? …

38-TS之类型保护

关注大师不迷路,大师带你上高度~ 文章目录 前言 一、类型保护是什么? 二、使用步骤 1. 使用 typeof 操作符 2. 使用 instanceof 操作符 3. 自定义类型保护函数 4. 使用 in 操作符 总结 前言 关注大师不迷路,大师带你上高度~ 在前端开发中,JavaScript 的动态类型特性提供了…

win下安装labelimg

1、anconda安装python、qt的版本 conda create -n labelme python3.10.18 PyQt5 5.15.11 <pip> PyQt5-Qt5 5.15.2 <pip> PyQt5_sip 12.17.0 <p…

【Qt开发】常用控件(二) -> enabled

目录 1 -> 什么是 enabled 属性 2 -> API 3 -> 代码示例 3.1 -> 创建禁用状态按钮 3.2 -> 通过按钮切换按钮的禁用状态 1 -> 什么是 enabled 属性 在 Qt 中&#xff0c;enabled 是 QWidget 类的一个基础属性&#xff0c;它控制控件是否对用户输入做出响…

MySQL 配置性能优化赛:核心策略与实战技巧

在数据库性能优化领域,MySQL 配置调优如同一场精密的竞技比赛 —— 既要深刻理解数据库内核机制,又要根据硬件环境和业务场景灵活调整参数,最终在性能指标上脱颖而出。本文将围绕 MySQL 配置性能优化的核心维度,解析关键参数调优策略与实战经验。 一、性能优化的底层逻辑:…

C++ WonderTrader源码分析之自旋锁实现

一、介绍 在WonderTrader的文件SpinMutex.hpp定义了跨平台的自旋锁的实现。 二、实现原理 1、类 SpinMutex&#xff1a;自旋锁实现SpinMutex 是一个轻量级的自旋锁&#xff08;Spinlock&#xff09;实现&#xff0c;用于多线程之间保护临界区资源。自旋锁通过不断尝试获取锁而不…

【AI大模型】Spring AI 基于Redis实现对话持久存储详解

目录 一、前言 二、Spring AI 会话记忆介绍 2.1 Spring AI 会话记忆概述 2.2 常用的会话记忆实现方式 2.2.1 集成数据库持久存储会话实现步骤 2.3 适用场景 三、Spring AI基于内存会话记忆存储 3.1 本地开发环境准备 3.2 工程搭建与集成 3.2.1 添加核心依赖 3.3.2 添…

Numpy科学计算与数据分析:Numpy数据分析与图像处理入门

Numpy实战&#xff1a;从数据分析到图像处理 学习目标 通过本课程&#xff0c;学员将学会运用Numpy库进行数据分析和图像处理。学习如何使用Numpy进行数据的高效处理&#xff0c;以及如何利用Numpy进行基本的图像操作。 相关知识点 Numpy的数据分析和图像处理 学习内容 1…

Vue框架总结案例

目录 一、验证用户名是否已经被注册过 二、过滤器 三、图书管理系统 四、axios网络请求 一、验证用户名是否已经被注册过 1.案例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script src"j…

hyper-v虚拟机启动失败:Virtual Pci Express Port无法打开电源,因为发生错误,找不到即插即用设备

启动错误 今天启动某个hyper-v虚拟机时&#xff0c;启动失败了&#xff0c;大概的错误信息为&#xff1a;尝试更改“ubuntu_desktop_2204”的状态时应用程序遇到错误。Virtual Pci Express Port (实例 ID 0445948B-C377-4912-AEEB-58A3D45C5694): 无法开机&#xff0c;因…

CSS包含块与百分比取值机制完全指南

引言&#xff1a;为什么需要理解包含块&#xff1f; 在CSS布局的世界中&#xff0c;包含块(Containing Block) 是一个基础但至关重要的概念。它就像是一个隐形的参考框架&#xff0c;决定了元素如何定位、尺寸如何计算以及百分比值如何解析。许多CSS开发者在使用百分比单位时遇…

Numpy科学计算与数据分析:Numpy数组操作入门:合并、分割与重塑

Numpy数组操作实战 学习目标 通过本课程的学习&#xff0c;学员将掌握Numpy中数组的基本操作&#xff0c;包括数组的合并、分割以及重塑等技巧&#xff0c;能够灵活运用这些操作处理数据&#xff0c;为后续的科学计算和数据分析打下坚实的基础。 相关知识点 Numpy数组操作 …

11_Mybatis 是如何进行DO类和数据库字段的映射的?

11_Mybatis 是如何进行DO类和数据库字段的映射的&#xff1f; 假设 VideoAbnormalContentMapper.xml 文件有如下方法&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN&quo…

2025年渗透测试面试题总结-06(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 逻辑漏洞 一、三大高危业务逻辑漏洞及修复方案 1. 订单金额篡改&#xff08;参数操纵&#xff09; 2. 重…

SpringBoot激活指定profile的方式

题目详细答案在 Spring Boot 中&#xff0c;可以通过多种方式激活指定的 Profile&#xff0c;以便在不同的环境中使用不同的配置。在application.properties文件中激活可以在默认的application.properties文件中通过spring.profiles.active属性激活某个 Profile。# application…

Pytest项目_day10(接口的参数传递)

接口的参数传递 如果我们需要在一个测试用例中使用另一个测试用例中获得的数据&#xff0c;应该怎么办&#xff1f; 解决方案一&#xff1a;使用函数返回值 - 我们可以在另一个测试用例中使用return来返回所需的数据&#xff0c;并在其他的测试用例中调用该测试用例&#xff08…

深信服GO面试题及参考答案(上)

Go 和 Java 的特点和区别是什么? Go 和 Java 都是静态类型、编译型语言,但在设计理念、语法特性、并发模型等方面存在显著差异,具体如下: 从语言设计目标来看,Go 由 Google 开发,旨在解决大型系统开发中的复杂性,强调“简单、高效、并发”,语法简洁,摒弃了许多传统面向…