Android音视频的基础

视频是什么?

视频就是由一系列图片构成的。

视频帧

帧,是视频的一个基本概念,表示一张画面,如上面的翻页动画书中的一页,就是一帧。一个视频就是由许许多多帧组成的。

帧率

帧率,即单位时间内帧的数量,单位为:帧/秒 或fps(frames per second)。

帧率的一般以下几个典型值:

24/25 fps:1秒 24/25 帧,一般的电影帧率。

30/60 fps:1秒 30/60 帧,游戏的帧率,30帧可以接受,60帧会感觉更加流畅逼真。

85 fps以上人眼基本无法察觉出来了,所以更高的帧率在视频里没有太大意义。

色彩空间

这里我们只讲常用到的两种色彩空间。

RGB

RGB的颜色模式应该是我们最熟悉的一种,在现在的电子设备中应用广泛。通过R G B三种基础色,可以混合出所有的颜色。

YUV

这里着重讲一下YUV,这种色彩空间并不是我们熟悉的。这是一种亮度与色度分离的色彩格式。

早期的电视都是黑白的,即只有亮度值,即Y。有了彩色电视以后,加入了UV两种色度,形成现在的YUV,也叫YCbCr。

Y:亮度,就是灰度值。除了表示亮度信号外,还含有较多的绿色通道量。

U:蓝色通道与亮度的差值。

V:红色通道与亮度的差值。

YUV和RGB的换算

c 复制代码
Y = 0.299R + 0.587G + 0.114B 
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
------------------------------------------------------
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U

音频是什么?

音频数据的承载方式最常用的是脉冲编码调制,即PCM

PCM采集

在自然界中,声音是连续不断的,是一种模拟信号,那怎样才能把声音保存下来呢?那就是把声音数字化,即转换为数字信号。

采集步骤:模拟信号->采样->量化->编码->数字信号

采样频率

采样频率:⼀秒钟内采样的次数。采样频率越⾼,越接近原始信号。

根据Nyquist采样定理,要想重建原始信号,采样频率必须⼤于信号中最⾼频率的两倍 。⼈能感受到的频率范围为20HZ--20kHZ, ⼀般⾳乐的采样频率为44.1kHZ, 更⾼的可以是48kHZ和96kHZ。

采样位数

数字信号是⽤0和1来表示的。采样位数就是采样值⽤多少位0和1来表示,也叫采样精度
位数越多,记录的值越准确,还原度越高。

声道

声道:处理的声⾳是单声道还是⽴体声。Android⽀持双声道⽴体声和单声道。
CHANNEL_IN_MONO单声道,CHANNEL_IN_STEREO⽴体声。

码率(比特率)

⽐特率:每秒传送的⽐特(bit)数。(单位时间播放连续的媒体(如压缩后的音频或视频)的比特数量。)比特率越高,带宽消耗得越多。

码率 = 采样率 * 采样位数 * 声道数 (单位:bps)

音频采集和播放:

⼀般⽤专⻔的芯⽚(通常叫codec芯⽚)采集⾳频,做AD转换,然后把数字信号通过I2S总线(主流⽤I2S总线,也可以⽤其他总线,⽐如PCM总线)送给CPU处理(也有的会把codec芯⽚与CPU芯⽚集成在⼀块芯⽚中)。当要播放时CPU会把⾳频数字信号通过I2S总线送给codec芯⽚,然后做DA转换得到模拟信号再播放出来。

为什么要编码,如何编码(编码原理) ?

编码的目的

为了压缩。各种视频编码方式,都是为了让视频变得体积更小,有利于存储和传输。

1、视频编码

视频编码格式

名称 推出机构 推出机构 目前使用领域
HEVC(H.265) MPEG/ITU-T 2013 研发中
H.264 MPEG/ITU-T 2003 各个领域
MPEG4 MPEG 2001 不温不火
MPEG2 MPEG 1994 数字电视
VP9 Google 2013 研发中
VP8 Google 2008 不普及
VC-1 Microsoft Inc. 2006 微软
...... ...... ...... ......

2、音频编码

音频编码格式

名称 推出机构 推出机构 目前使用领域
AAC MPEG 1997 各个领域(新)
AC-3 Dolby Inc. 1992 电影
MP3 MPEG 1993 各个领域(旧)
WMA Microsoft Inc. 1999 微软平台
...... ...... ...... ......

H264介绍

一、H264简介

H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)

H264是目前最主流的视频编码标准,所以接下来我们主要介绍一下H264

二、H264相关概念

1、H.264 的基本单位

H.264定义的结构中,一个视频图像编码后的数据叫做一帧。 一帧是由一个或多个片(slice)组成的,一个片是由一个或多个宏块(MB)组成的(宏块是H264编码的基本单位),一个宏块是由16x16的yuv数据组成的。

2、帧类型

H.264的协议中,定义了三类帧,分别是:I帧、B帧和P帧。

  • I帧:帧内编码帧。就是一个完整帧(key frame)

    • I帧可以看作一个图像经过压缩之后的产物,是一种自带全部信息的独立帧,无需参考其他图像便可独立进行解码,可以简单理解为一张静态图像; (压缩率最低
  • P帧:前向预测编码帧。是一个非完整帧,通过参考前面的I帧或P帧生成。

    • 记录了本帧跟之前的一个关键帧(或P帧)的差别。编码时编码当前P帧与参考帧的差异数据,解码时需要用之前缓存的画 面叠加上本帧定义的差别,生成最终画面。 (压缩率比I帧高,比B帧低
  • B帧:双向预测内插编码帧。参考前后图像帧编码生成。B帧依赖其前最近的一个I帧或P帧及其后最近的一个P帧。(双向预测 / 参考)

    • 编码时,只编码当前B帧与前后参考帧的差异数据。解码时,需要先解码出前后的参考帧,再结合差异数据解码出当前B帧完整的图像。(压缩率是最高,但是耗时
  • DTS:Decode Time Stamp(解码时间戳)。DTS主要是标识读入内存中的帧数据在什么时候开始送入解码器中进行解码。

  • PTS:Presentation Time Stamp(显示时间戳)。PTS主要用于度量解码后的视频帧什么时候被显示出来

在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。

因为B帧打乱了解码和显示的顺序(要解码B帧需要先解码后面的P帧),所以一旦存在B帧,PTS和DTS就会不同。

DTS主要用于视频的解码,在解码阶段使用。PTS主要用于视频的同步和输出.在显示的时候使用。

3、GOP画面组

一组变化不大的视频帧。

GOP结构一般有两个数字,其中一个是GOP的长度(即两个I帧之间的B帧和P帧数),另一个数字为I帧和P帧之间的间隔距离(即B帧数)。

M=3,N=12,M指两个I帧和P帧之间的距离,N指定两个I帧之间的距离。

例如M=3,N=12的GOP结构为:IBBPBBPBBPBBI

GOP的第一帧成为关键帧:IDR
IDR帧一定是I帧,但是I帧不一定是IDR帧。

4、色彩空间

H264采用的是YUV。

YUV存储方式分为两大类:planar 和 packed。

planar :先存储所有Y,紧接着存储所有U,最后是V。

packed:每个像素点的 Y、U、V 连续交叉存储。

由于人眼对色度敏感度低,所以可以通过省略一些色度信息,即亮度共用一些色度信息,进而节省存储空间。

因此,planar又区分了以下几种格式: YUV444、 YUV422、YUV420

三、H264压缩方式

1、H264压缩算法

H264采用的核心算法是帧内压缩帧间压缩 ,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。

帧内(Intraframe)压缩的原理是:当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩率一般不高。

帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。

2、H264压缩方式

H.264压缩视频数据时的具体方式步骤如下:

  1. 分组,也就是将一系列变换不大的图像归为一个组,即一个GOP
  2. 定义帧,将每组的图像帧归分为I帧、P帧和B帧三种类型
  3. 预测帧, 以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧
  4. 数据传输, 最后将I帧数据与预测的差值信息进行存储和传输

四、H264分层结构

H264的主要目标是为了有高的视频压缩比和良好的网络亲和性,为了达成这两个目标,H264的解决方案是将系统框架分为两个层面,分别是视频编码层面(VCL)和网络抽象层面(NAL)

  1. VLC层(Video Coding Layer)

VLC层是对核心算法引擎、块、宏块及片的语法级别的定义,负责有效表示视频数据的内容,最终输出编码完的数据SODB
通俗的讲:负责高效的视频内容表示, VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。

  1. NAL层(Network Abstraction Layer)

NAL层:负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。
通俗的讲 :负责以网络所要求的恰当的方式对数据进行打包和传送,是传输层 。不管在本地播放还是网络播放,都要通过这一层来传输。
NAL层将SODB打包成RBSP然后加上NAL头组成一个NALU单元

  1. NALU (NAL Unit)

H.264原始码流(裸流)是由一个接一个NALU组成,结构如下图:

NALU = 一组对应于视频编码的
NALU头部信息
+ 一个原始字节序列负荷RBSP (Raw Byte Sequence Payload)

然后一个NALU又被分为: [StartCode] [NALU Header] [NALU Payload] 三部分

  1. StartCode
    Start Code 用于标示这是一个NALU 单元的开始,必须是"00 00 00 01" 或"00 00 01"
  2. NALU Header
    NAL Header由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。
  3. SODB、 RBSP

SODB (String Of Data Bit): 数据比特串,是编码后的原始数据;
RBSP (Raw Byte Sequence Payload): 原始字节序列载荷,是在原始编码数据后面添加了结尾比特,一个bit 1和若干个bit 0,用于字节对齐。

五、H264码流结构

H264码流是由一个个的NAL单元组成,其中SPS、PPS、IDR和SLICE是NAL单元某一类型的数据。

SPS是序列参数集、PPS是图像参数集

一帧图片经过 H.264 编码器之后,NAL单元就是装载着这些片(被编码为一个或多个片 slice), 每片包含整数个宏块(至少一个宏块,最多包含整个图像宏块)

六、H264封装格式

H264码流分两种组织⽅式,⼀种是AnnexB格式,⼀种是AVCC格式。

  1. AnnexB格式
    [start code]NALU | [start code] NALU |...这种格式比较常见,也就是我们熟悉的每个帧前⾯都有0x00 00 00 01或者0x00 00 01作为起始码。
    H264文件就是采⽤的这种格式,每个帧前⾯都要有个起始码。SPS PPS等也作为⼀类NALU存储在这个码流中,⼀般在码流最前面。也就是说这种格式包含VCL 和非VCL 类型的NALU。
    一般H.264编码器的默认输出为:起始码+NALU(Nal单元)

为什么需要起始码:0x00000001或者0x000001?

答:因为每一个NALU都需要分隔,要分隔帧操作,就相对于写文章断句一样

从上面我们指定每个NAL header = forbidden_bit(1bit) + nal_reference_bit(2bits) + nal_unit_type(5bits)

这个头部信息是可以区分类型的,例如:I帧、P帧、B帧。通过下面的表可以查询到具体的类型。

相关推荐
拭心3 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
darkdragonking4 小时前
FLV视频封装格式详解
音视频
带电的小王5 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡5 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道6 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库7 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道7 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe7 小时前
Android Hook - 动态加载so库
android
居居飒8 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He11 小时前
桌面列表小部件不能点击的问题分析
android