Android音视频开发,详说PCM音频重采样、PCM编码

Android音视频开发,详说PCM音频重采样、PCM编码_第1张图片

 Android音视频开发,详说PCM音频重采样、PCM编码_第2张图片

 直播伴音,两种数据能否合在一起?不能叠加在一起 会有噪音 合并以后 再去编码推流 直播的例子

客户端播放器,可以开启多个播放器

对于我们重采样 很多时候就是为了统一格式,就是为了要合并这个流,去推送,他最终要转成同样pcm格式,

合并码流可以通过ffmpeg amix 做混音,支持多音源合并 做混音,再做二次编码

Android音视频开发,详说PCM音频重采样、PCM编码_第3张图片

Android音视频开发,详说PCM音频重采样、PCM编码_第4张图片

振幅越大声音越大, 观察喇叭 开车音乐 比较大 手比较振 振幅

Android音视频开发,详说PCM音频重采样、PCM编码_第5张图片

Android音视频开发,详说PCM音频重采样、PCM编码_第6张图片

 波形 模拟时间  一秒钟我采集多少数据  可以1秒钟采集100万次,对于这个硬件成本能不能搞定

硬件采样速度越快  就需要他硬件资源就越多,那需要的成本就越多  采集这么频繁的频率有没有用?对于我们现实世界可以采集回来的一个频率 除以2 2倍去采集的话,

现实世界 500khz这个频率,我通过1000khz 我就可以采集回来 人的耳朵能否听到500khz的声音呢?高频率的 人的耳朵大概能听到20khz 超过就听不到了,

计算机采集大于40khz 就可以采集 就可以还原出现实世界的声音,这就是我们常见的采样率 44.1khz  48khz 怎么来的,就是根据人的耳朵的极限,有一点冗余 后面就开始定义44.1khz  48khz最经典的,看到无损这一些格式,96khz 192khz 这些采样率 这些是不是我的采样率越高 他越能还原出现实世界,就是有些人可以听的频率高一点,这个采样率越高 音质就会更好一些,

Android音视频开发,详说PCM音频重采样、PCM编码_第7张图片

 每个采样点 用多少个字节去表示?

2通道

4通道 

5.1通道 

某个通道 某个样本,并不是多个通道的占多少个字节 等等,

为什么16bit对这个现实世界还原度比较高呢?我们这个声音 刚才这个幅值 也是无线的,这个声音

大 到小,大有多大,这个有多小?这个模拟世界他就是一个无限,模拟无限

用2bit去表示样本点,

用2bit组合成  0  1  2  3  这4个值,我去描述一个声音,比如机顶盒声音调到最小,静音和最小的时候,他这个力度就非常的大,往下调就静音了,往上调 声音听起来有点大,就是因为他能表示的音的阶次不够多,如果你的声音只有 只有4个值,你肯定没办法表示这个音量,大小,经过使用得出来,大概是16bit能够对现实世界 这种声音能够做到比较好的采集还原, 表示某个声音 他当前幅值用16bit 他是比较好还原的,还有一些比较差的音质,比如8bit 对于这个8bit 他这个声音 音质是比较一般的,可能我们不一定能听得出来,我可以先去提取pcm数据

通过ffmpeg去提取的, 

48k产生处理 2通道,先用16bit这种格式,这边我们先提取出来,Android音视频开发,详说PCM音频重采样、PCM编码_第8张图片

 这边就提取出来huiguniang.MP3 pcm数据

Android音视频开发,详说PCM音频重采样、PCM编码_第9张图片

 

用8bit 提取出来pcm数据可能会小一点,

Android音视频开发,详说PCM音频重采样、PCM编码_第10张图片

 通过u8 u8提不出来了

这边我们播放16le

f32通过这个大家讲浮点数的

Android音视频开发,详说PCM音频重采样、PCM编码_第11张图片

f32和s16 同一个文件提取出来,这个浮点数 他是比我们s16大了一倍,

浮点数这个f32的一个样本,他是有4个字节,所以大家一定要注意一下,

这个是我们讲的采样率 为什么我们经常看到44.1khz 还有48khz 就是因为这个人的耳朵,大概是20khz左右吧,是一个上线 我们根据产生定理我们大于2倍的一个频率去做采集,才能去再次还原,所以我们20khz*2就是40khz 那这边我们就采用的是44.1khz 还有48khz这两种比较多

肯定很多朋友问为什么是44.1khz 还有48khz 而不是40 早期这个频率就已经定好的 就是为了冗余 就是给大家讲 就是一般人他是大于20khz但是有些人他会上一点点,

Android音视频开发,详说PCM音频重采样、PCM编码_第12张图片

 整数和浮点数他是不一样的,与我们格式搞混了,让你会播放,或者你再去做编码他是有噪音的,打比方我们去试一把,像刚才我们播放这个声音,是不是我刚才提取的f32 还有s16 那么这边我去播放 就是我们以s16这种格式,去播放f32的 就是播放浮点数的,那么我们可以看看,

 声音很辣耳朵,以后如果你编码的时候出现,那就是你这个格式,你输入的给你的编码要求不一样,

Android音视频开发,详说PCM音频重采样、PCM编码_第13张图片

 还有码率 还有比特率 不是特别关键的,

Android音视频开发,详说PCM音频重采样、PCM编码_第14张图片

这个pcm排列格式的问题

Android音视频开发,详说PCM音频重采样、PCM编码_第15张图片

 对于我们提取8bit这个采样点,也有,

Android音视频开发,详说PCM音频重采样、PCM编码_第16张图片

 8bit 已经称为s8了,并不是s8l1了,因为单个字节没有所谓的大小端,你只有这一个字节,

pcm数据排列格式的问题

音频的帧没有视频中那么清晰,视频他就是一张图像,但是对于我们这个音频来说这个概念,什么才是一帧数据呢?不同的编码格式他是有区别的, 比如说我们最常见的编码格式,acc

多少个样本数 作为 一帧数据做编码呢?  他通常是1024个样本,作为一帧数据,不同编码格式是不一样的,

比如对于mp3来讲, 他是1152个样本

不同的格式他是不同的

Android音视频开发,详说PCM音频重采样、PCM编码_第17张图片

Android音视频开发,详说PCM音频重采样、PCM编码_第18张图片

acc编码 支持 我是用  默认是 ffmpeg自带的acc编码

 给大家强调了这一块里面,这个acc编码168 跟libfdk_aac编码167他们有什么区别?

就是说ffmpeg自带aac 需要的格式 是采样格式  

设置要给参数,比如说我把这个pcm读进来,这个编码层通过aac.aac

aac这个后缀是什么意思? 我是使用了ffmpeg自带的aac编码器,

Android音视频开发,详说PCM音频重采样、PCM编码_第19张图片

我们可以debug一下,  

Android音视频开发,详说PCM音频重采样、PCM编码_第20张图片通过avcodec find encoder by_name方式去查找编码器,Android音视频开发,详说PCM音频重采样、PCM编码_第21张图片

 Android音视频开发,详说PCM音频重采样、PCM编码_第22张图片

这就是我们对应我们的编码 编成什么样的格式,这边都有一些讲解,

Android音视频开发,详说PCM音频重采样、PCM编码_第23张图片 找一下我们怎么去打开我们的编码器,

Android音视频开发,详说PCM音频重采样、PCM编码_第24张图片

 264 avcodecopen2 把我们编码器找出打开它,要编码成什么样的格式, 

我们通过AVCodec 发一个avcodec_find_encodel by name 212  我再强调一下 对于这个ffmpeg来讲,我还是回到刚才的问题,对于aac 编码器,那么我们到底有多少个aac编码器?能否有不同的aac编码器?他是可以有的,

Android音视频开发,详说PCM音频重采样、PCM编码_第25张图片

 把源码打开看看,多扩展一些知识,对ffmpeg有多深的理解,并不是说我单独的讲某个知识点,

查fdk aac

Android音视频开发,详说PCM音频重采样、PCM编码_第26张图片

对aac封装,为什么知道他是 aac编码器呢?他主要是这个id 比如说我们不同的aac编码器,他的id 是一样的,不一样 主要是他的名字不一样, 这个name他是唯一的,

ffmpeg自带的aac 

Android音视频开发,详说PCM音频重采样、PCM编码_第27张图片

这一块的id  ac 名字 aac 这里还有一个问题这边有一个sample fmts 我们对这个aac编码器他需要什么样的格式,那这个时候呢,那你需要跟我们fdk aac去对比一下,两者是有区别的,就是我们在使用的时候 我们用不同的格式,比如说你是用浮点数,

还是整数,这边支持他是不太一样的,蓝线部分

Android音视频开发,详说PCM音频重采样、PCM编码_第28张图片

就是 我们最终要用什么样的编码 用什么样的pcm格式,那你要根据不同的编码器去选择,

Android音视频开发,详说PCM音频重采样、PCM编码_第29张图片

 这个id的acc是一样的 这个name是不一样的,我们样本数用浮点数的方式还是整数的方式,整数方式和浮点数方式有什么区别呢?比如给大家讲这个s16 他是有负 有正,s16他这个范围有多少,这边我们给出来了

Android音视频开发,详说PCM音频重采样、PCM编码_第30张图片

 s16 -32768~32767

flt -1~1

这个浮点数并不是无限大,成一个-1~1这样的一个逻辑,这样我们可以引申一下,比如

Android音视频开发,详说PCM音频重采样、PCM编码_第31张图片

工具可以把我们pcm数据导进来, 看看这个格式,

Android音视频开发,详说PCM音频重采样、PCM编码_第32张图片

 把一个数值导进来看看,先导入s16的吧?我们在导数据到我们这个工具里,刚才我们选的是s16个格式,

Android音视频开发,详说PCM音频重采样、PCM编码_第33张图片

Android音视频开发,详说PCM音频重采样、PCM编码_第34张图片

这边就可以看到这个波形就可以  转成-1 到1.0实际上是一个整数来的,样本 对于我们在计算机表示的时候,

Android音视频开发,详说PCM音频重采样、PCM编码_第35张图片

我把间隔拉大后,我们每个样本之间他是有一个时间间隔的, 但是我们把他放小一点,我们这样子看的时候,看起来有一点像是连续的,但实际上它是离散的,这边我们可以把这边浮点数 把他导进来,

浮点数导进来的时候要选对了,这边选32位float 

Android音视频开发,详说PCM音频重采样、PCM编码_第36张图片

这边做规划统一,-1~1

我们s16跟浮点的规划统一后,这些值

这边是左通道的了,左通道要跟左通道做对比,右通道要跟右通道波形做对比,基本上是对起来的Android音视频开发,详说PCM音频重采样、PCM编码_第37张图片

 到时候你可以把他导进来去播一播 听听它的声音,都是可以看一下的,可以对比一下

 格式里面这个帧 样本数是多少的?就是作为一帧数据做编码,那你一定要看具体这个编码器

Android音视频开发,详说PCM音频重采样、PCM编码_第38张图片

 Android音视频开发,详说PCM音频重采样、PCM编码_第39张图片

 

 在调用if (avcodec_open2的时候,这里有codec_ctx上下文,那codec_ctx上下文里面有一个frame_size这样一个参数,这个参数是非常重要的,这里给出来到底有多少样本数,作为一帧数据做编码,现在他这个值是空值,刚才这个值是空值,现在这个值变成1024 这个时候我们每次要送多少数据  送多少个样本给编码器,那么我们就知道了,就是我们每个通道都是送1024个样本数给到对应的编码器作为一帧数据进行编码,
268逻辑稍微改一改,

Android音视频开发,详说PCM音频重采样、PCM编码_第40张图片

这是给到的48000hz frame_size:1024 

这边我再来看看 这边改成8k

再来看看Android音视频开发,详说PCM音频重采样、PCM编码_第41张图片

 对应的采样率,Android音视频开发,详说PCM音频重采样、PCM编码_第42张图片

目前也是1024  

你一定是要根据codec_ctx的frame_size为基准

Android音视频开发,详说PCM音频重采样、PCM编码_第43张图片

 这里还有个值 这个是采样格式 

(codec_ctx->sample tmt)

Android音视频开发,详说PCM音频重采样、PCM编码_第44张图片

 Android音视频开发,详说PCM音频重采样、PCM编码_第45张图片

刚才我是不是给大家讲过,我们 FMT_FLTP对应到刚才讲的avc里面,他需要的正常格式是不是

AV_SAMPLE_FMT_FLTP是什么意思呢?看一下源码,

Android音视频开发,详说PCM音频重采样、PCM编码_第46张图片

这个 AVSampleFormat他是有多种格式,AV SAMPLE FMT U8表示一个版本,

AV SAMPLE FMT S16就是16个bit表示样本,这里AV SAMPLE FMT S32就是我们32bit表示样本,他是整数的

AV SAMPLE FMT_FLT,32位浮点数,

AV SAMPLE_FMT_DBL 64位表示

这边上面和下面有什么区别呢?他的表现格式是不一样的,下面这种他是带了一个p 每一行都带了一个p 这边只的是planar 这个是什么意思呢?

两种格式 一种叫交错模式  一种叫非交错模式

非交错模式对应刚才我们这个图里面,这边我把他画出来,这是我们交错模式的

还有非交错模式

Android音视频开发,详说PCM音频重采样、PCM编码_第47张图片

这两个有什么区别,这边我是以一帧为例去讲解,打个比方,比如1024为一帧数据,如果是两通道对于s16 或者s32 我就不用去理他, 我们主要是讲planar是什么意思 

大家需要注意就是这边就是我们两个通道,就是对于我们一帧数据来讲 我们这个时候我们排列格式 你看到这个逻辑你理解了没有?我们1024和左右轴 1024个LR这样去排列的

接下来我们给大家讲非交错模式,

这个模式有什么区别呢?这边还是一帧数据  1024个包括这个左右通道是一帧数据 主要往下面看,对于我们来讲的非交错  我这边存数据  你要注意了  这边存的时候,我这边我就存1024个左, 再存 1024个右,这样一个模式

这两种模式如果你搞混了,那么你播放 或者你编码,打个比方就是如果你是本地是s16格式,但你丢给这个编码器需要planar这种格式,那肯定就会有问题,这一点就特别需要注意到

Android音视频开发,详说PCM音频重采样、PCM编码_第48张图片

 这个以f32le的方式我们去播另一个 48k通过s16这种格式

Android音视频开发,详说PCM音频重采样、PCM编码_第49张图片

为什么强调老是讲这个命令呢?我要给大家讲一下 因为我们这个通道  就有些朋友就是 举个例子,

他本身他解出来这个数据 比如ffmpeg 他自带的aac 他解码解出来的数据是什么格式?解码解出来他是浮点数的,

然后有个朋友他需要转成s16格式 在上面他解出的是fltp 浮点数planar  解出来的是整数 packed

我转出来我转成浮点数后他做了个重采样转成s16 他转成s16后 他把这个数据通过fwrite 写到我们本地 然后写到本地 他怎么测试的呢? 他现在已经 在s16 这个本地 这个重采样采集成s16后,然后他一直找张老师说,张老师我用这个重采样器为什么重采样这个数据有问题?我说怎么有问题?

然后他就给我截了一条命令 他去播这个数据

他采集的数据他应该使用这个f32le去播

明明重采样转成s16了 他干嘛不用s16去播呢?

我们转到f32的时候,我们不能用planar这种格式,我再强调一下,存到本地的数据不能用planar这种格式 那你要转成f32le这种格式,

就对应到就是我们这一个 刚才这个图里面 转到我们AV SAMPLE FMT FLT

有些朋友去验证这个ac解码的时候,直接把这个f32这个planar格式存到本地,直接去播,

这种工具导入数据 他也只能够导这种非交错模式 而且只能导交错模式,不能导planar模式,

Android音视频开发,详说PCM音频重采样、PCM编码_第50张图片

 涉及内容有点多,

Android音视频开发,详说PCM音频重采样、PCM编码_第51张图片

 decode编码 手动把他转成 左右左 这种格式,

Android音视频开发,详说PCM音频重采样、PCM编码_第52张图片

把对应的数据传进来,读一个mp3的文件,还是huiguniang.mp3文件, 

Android音视频开发,详说PCM音频重采样、PCM编码_第53张图片

这边我们就debug看一看, 

Android音视频开发,详说PCM音频重采样、PCM编码_第54张图片

 mp3 一般是1152 

Android音视频开发,详说PCM音频重采样、PCM编码_第55张图片

 Android音视频开发,详说PCM音频重采样、PCM编码_第56张图片

这边对应的是mp3的 是1152 

但具体的要根据编码器 解码器 解出来的为准,这边我们看有一个frame->nb_samples ;对应的参数,

Android音视频开发,详说PCM音频重采样、PCM编码_第57张图片

 format 是8的,我们去对一下 刚刚这个表,AVFrame这个参数 ,这个0  1 2  3  4  5  6 就是对应的 planar这种格式,所以大家理解就可以了,

Android音视频开发,详说PCM音频重采样、PCM编码_第58张图片

对于这个重采样器 官方有范例

ffmpeg源码 有个example 

Android音视频开发,详说PCM音频重采样、PCM编码_第59张图片

 去参考一下resampling audio.c 这个范例做重采样是可以的,只是对于我们课上 有些细节,会讲到 ,有一些参数 他的返回值 没有做判断,568

Android音视频开发,详说PCM音频重采样、PCM编码_第60张图片

他这些返回值本身要做一些判断才对的, 但是范例里面并没有做判断,这就是讲的重采样相关的原理,特别是planar这种格式对应的整数和浮点数,还有对应的采样率 为什么是44.1khz比较多,

Android音视频开发,详说PCM音频重采样、PCM编码_第61张图片

 流媒体服务器提升编程,对于

 掌握网络知识是非常有帮助的,有个学员面面腾讯 没有学到音视频网络相关的知识,我们音视频里面最专注的就是音视频的知识,当时就挂到网络原理这一块了,大公司大厂怎么不懂网络这块呢?

Android音视频开发,详说PCM音频重采样、PCM编码

你可能感兴趣的:(音视频,android,pcm)