文档章节

Android音频开发(5):音频数据的编解码

乐搏学院
 乐搏学院
发布于 2016/10/19 14:39
字数 1622
阅读 24
收藏 0

1. Android 官方的 MediaCodec API

 

首先,我们了解一下 Android 官方提供的音频编解码的 API,即 MediaCodec 类,该 API 是在 Andorid 4.1 (API 16) 版本引入的,因此只能工作于 Android 4.1 以上的手机上。(乐搏学院

 

1.1 MediaCodec 基本介绍

 

(1)提供了一套访问 Android 底层多媒体模块的接口,主要是音视频的编解码接口

 

(2)Android 底层多媒体模块采用的是 OpenMax 框架,任何 Android 底层编解码模块的实现,都必须遵循 OpenMax 标准。Google 官方默认提供了一系列的软件编解码器:包括:OMX.google.h264.encoder,OMX.google.h264.encoder, OMX.google.aac.encoder, OMX.google.aac.decoder 等等,而硬件编解码功能,则需要由芯片厂商依照 OpenMax 框架标准来完成,所以,一般采用不同芯片型号的手机,硬件编解码的实现和性能是不同的

 

(3)Android 应用层统一由 MediaCodec API 来提供各种音视频编解码功能,由参数配置来决定采用何种编解码算法、是否采用硬件编解码加速等等

 

1.2 MediaCodec 核心原理

 

我不准备详细介绍 MediaCodec API 的每个函数是怎么用,示例代码大家可以在后面给出的资源链接中查看和学习。

 

这里我准备重点介绍一下 MediaCodec 的核心工作原理,因为只有搞清楚了这一点,你才会明白为什么 MediaCodec API 提供的接口是这个样子的。

 

MediaCodec 使用的基本流程是:

 

1

2

3

4

5

6

7

8

9

10

11

- createEncoderByType/createDecoderByType

- configure

- start

while(1) {

    - dequeueInputBuffer

    - queueInputBuffer

    - dequeueOutputBuffer

    - releaseOutputBuffer

}

- stop

- release

 

由此可以看到,Buffer 队列的操作是其最核心的部分之一,关于 MediaCodec 的 Buffer 队列 ,示意图如下:

wKioL1cCSojSz4HdAAD0xxQxvwg230.png

 

 

MediaCodec 架构上采用了2个缓冲区队列,异步处理数据,下面描述的 Client 和 MediaCodec 模块是并行工作的(注:这里的 Client 就是指 “开发者,API 的使用者”):

 

(1)Client 从 input 缓冲区队列申请 empty buffer [dequeueInputBuffer]

(2)Client 把需要编解码的数据拷贝到 empty buffer,然后放入 input 缓冲区队列 [queueInputBuffer] 

(3)MediaCodec 模块从 input 缓冲区队列取一帧数据进行编解码处理

(4)编解码处理结束后,MediaCodec 将原始数据 buffer 置为 empty 后放回 input 缓冲区队列,将编解码后的数据放入到 output 缓冲区队列

(5)Client 从 output 缓冲区队列申请编解码后的 buffer [dequeueOutputBuffer]

(6)Client 对编解码后的 buffer 进行渲染/播放

(7)渲染/播放完成后,Client 再将该 buffer 放回 output 缓冲区队列 [releaseOutputBuffer]

 

MediaCodec 在架构上,其实是采用了一种基于“环形缓冲区”的“生产者-消费者”模式,它设计了 2 个基于 idx 序号的“环形缓冲区” ,注意,是 2 个,一个在 input 端, 一个在 output 端。

 

我曾经在 Github 上分享过一段 Linux C 代码,名叫:“rw_queue”,就是这种环形缓冲区的简化版,大家有兴趣可以看看,地址:https://github.com/Jhuster/clib/tree/master/rw_queue

 

基于 idx 的环形缓冲区的总体示意图如下,图中,wp 代表 “写指针”,指向的是 “empty buffer”, 而 rp 代表 “读指针”,指向的是 “filled buffer”:

 

wKioL1cCStbQJjLDAAB7AoEE3KU663.png

“生产者”和“消费者”其实是共用这一个缓冲区队列,“生产者”负责从队列中取出未使用的 Buffer,填入数据,然后放回队列,“消费者”则负责取出填入数据后的 Buffer,进行处理,处理结束后,再把 Buffer 标记为“空”,退回到队列中去以供“生产者”继续填充数据。

 

在 input 端,“Client”是这个环形缓冲区“生产者”,“MediaoCodec 模块”是“消费者”。

在 output 端,“MediaoCodec 模块”是这个环形缓冲区“生产者”,而“Client”则变成了“消费者”。

 

这就是其核心的工作原理,其实并不复杂,大家静下心来,很快就能理解其中的奥妙。

 

1.3  参考资源

 

关于 MediaCodec 的示例代码,网上其实也很多了,我就直接给出一些个人觉得不错的链接,有兴趣的小伙伴们可以去研究一下。

 

(1)Android 官方文档: 《MediaCodec》

(2)《Android MediaCodec stuff》

(3)《HWEncoderExperiments》

(4)一些开源的播放器 Android 源码,如 VLCijkplayer

 

2. 第三方音频编解码的库

 

官方的 MediaCodec API 虽然支持硬件编解码加速,但是问题和局限还是很多的,一方面是只能在 Android 4.1 以上机型上才能使用,另一方面,由于 Android 手机种类繁多,厂商对底层源码的修改各不相同,导致 MediaCodec API 在实际使用中,会遇到很多坑,有很多兼容性的问题,因此,我们也可以考虑采用第三方的编解码库。

 

这里,我简单推荐几款第三方音频编解码库(可以移植到 Android 平台的),大家可以直接去官网或者项目主页了解其详细信息。

 

(1) opus 编解码库

 

很喜欢 opus,低码率下 opus 完胜曾经优势明显的 HE AAC,我曾经用它实现了一款 Android 局域网的VoIP网络电话应用:“飞鸽电话”,效果很不错。

 

opus 官网地址:https://www.opus-codec.org

 

注:如今 Android 5.0 已经官方支持 opus 格式了,关于 Android 支持的多媒体格式列表可以查看 Android developer guide:《Supported Media Formats》

 

(2) Speex 编解码库

 

老牌的音频处理库,不仅是编解码,还提供了包括音频去噪、回声消除、静音检测等功能,官网地址:http://www.speex.org

 

(3) ffmpeg

 

大名鼎鼎的 ffmpeg 肯定不能错过,官网:https://www.ffmpeg.org

 

(4)Android AAC Encoder

 

一款轻量级的 Android aac 编码库:https://github.com/timsu/android-aac-enc

 

(5)opencore-amr-android

 

从 opencore 抽取出来的 amr 编解码库,地址:https://github.com/kevinho/opencore-amr-android

 

(6)iLBC-Android

 

iLBC 是著名的 WebRTC 项目的音频编解码模块,iLBC-Android 是从中抽取 iLBC 模块移植到 Android 平台的个人项目,地址:https://github.com/lukeweber/iLBC-Android

 

关于第三方编解码库就简单介绍到这里了,最后三个是个人项目,我没有使用过,真心感谢这些作者的无私奉献,另外,更多的第三方库欢迎大家留言或者来信补充。

结束语

免费学习更多精品课程,登录乐搏学院官网http://h.learnbo.cn/

本文出自 “Jhuster的专栏” 博客,请务必保留此出处http://ticktick.blog.51cto.com/823160/1760191

本文转载自:

乐搏学院
粉丝 9
博文 526
码字总数 707467
作品 0
丰台
程序员
私信 提问
Android音视频之使用MediaCodec编解码AAC

现在的短视频、音视频通话都离不开编码和解码,今天就来聊一下音频的编解码。 1. 音频的基本概念 在音频开发中,有些基本概念是需要了解的。 采样率(SampleRate):每秒采集声音的数量,它用...

落英坠露
05/03
0
0
音频编解码(软/硬编码),音频转码

> 音频编解码(软编码) FFMpeg视频软件编解码的。B站的ijkplayer等。 音频数据的编解码- http://blog.51cto.com/ticktick/1760191 1.Android AAC Encoder 一款轻量级的 Android aac 编码库:h...

desaco
01/06
0
0
直播,音视频编码器和解码器(EasyDarwin)-Android

使用摄像头采集视频数据,并通过MediaCodec进行H264编码,之后打包成RTSP格式并上传的。 TextuewView也提供了一个setTransform方法,该方法接收一个matrix参数,使用该参数对当前的渲染内容进...

shareus
2018/05/18
0
0
G711(PCM/PCMA/PCMU),G721,G723,G729音频编解码

G711,G721,G723音频编解码,G729音频库,Android G711(PCMA/PCMU)、G726、PCM音频转码到AAC,ffmpeg接收g723音频流,Android G726语音编解码库+除燥音算法,g729音频编解码静态库,G723 G729...

desaco
2018/12/18
0
0
android只用能AudioTrack播放实时音频

还有一篇:http://blog.51cto.com/13591594/2068009 (其项目地址: https://github.com/979451341/Audio-and-video-learning-materials ) 今天,简单讲讲AudioTrack的使用方法。 1、Android......

whoisliang
2018/11/12
44
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx常用命令

# cd /usr/local/nginx/sbin 查看版本 # ./nginx -v 查看进程 # ps -ef | grep nginx 查看nginx端口号 # ss -lnput | grep nginx 启动 # ./nginx 关闭 # ./nginx -s stop 重新加载配置文件 ......

行者终成事
10分钟前
3
0
002-docker的网络设置和数据管理

Docker 网络设置 docker会创建一个桥接网卡[docker 0],docker有两种映射方式,一种是随机映射,一种是指定映射 生产场景一般不用随机映射 随机映射的好处是端口由docker分配,不会冲突 安装n...

侠客行之石头
14分钟前
3
0
Rust学习笔记一 数据类型

写在前面 我也不是什么特别厉害的大牛,学历也很低,只是对一些新语言比较感兴趣,接触过的语言不算多也不算少,大部分也都浅尝辄止,所以理解上可能会有一些偏差。 自学了Java、Kotlin、Python、...

MusiCodeXY
16分钟前
3
0
Java 脚本引擎入门

Java Script Engine Java 脚本引擎可以将脚本嵌入Java代码中,可以自定义和扩展Java应用程序,自JDK1.6被引入,基于Rhino引擎,JDK1.8后使用Nashorn引擎,支持ECMAScript 5,但后期还可能会换...

阿提说说
今天
5
0
05.深入浅出索引(下)

在下面这个表T中,如果我们执行select * from T where k between 3 and 5,需要执行几次树的搜索操作,会扫描多少行? mysql> create table T ( id int primary key, k int not null default...

scgaopan
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部