第一章

1.6 容器和协议

1. 媒体文件和编码的区别

文件是既包括视频又包括音频、甚至还带有脚本的一个集合,也可以叫做容器;

文件当中的视频和音频的压缩算法才是具体的编码。

2. 两大标准指定组织

两大组织分别是国际标准化组织(iso) 和国际电信联盟(itu)

在音视频压缩标准方面,mpeg系列的协议是iso 制定的标准,而h 系列的协议则是itu 制定的标准

3. h.264

h.264 单看名字,感觉是itu组织制定的,其实它还有一个名字叫mpeg-4 part 10, 这是因为h.264是iso 和itu组织共同制定的,版权共享。


1.7 常用概念介绍

1. 软解和硬解

软解就是通过软件让CPU进行视频解码处理;

硬解是指不依赖于CPU, 通过专门的设备(子卡)单独完成视频解码,目前常用的是GPU。


1.7.2 IBP帧

1. 帧

帧就是影像动画中最小单位的单幅影像画面,相当于电影胶片上的每一格镜头

I frame : 帧内编码帧 又称 intra picture, I 帧通常是每个GOP的第一帧, 经过适度地压缩,作为随机访问的参考点,可以当成图像。I帧可以看成是一个图像经过压缩后的产物。

P frame : 前向预测编码帧,又称predictive-frame, 通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧。

B frame : 双向预测内插编码帧, 又称bi-directional interpolated prediction frame, 既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧。

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

DTS : Decode Time Stamp. dts 主要是标识读入内存中的bit 流在什么时候开始送入解码器中进行解码。

ps, 在没有B帧存在的情况下,dts 的顺序和pts 的顺序应该是一样的。

2. I帧特点:


1. 它是一个全帧压缩编码帧,它将全帧图像信息进行JPEG压缩编码及传输

2. 解码时仅用I帧的数据就可以重构完整图像;

3. I帧描述了图像背景和运动主体的详情;

4. I帧不需要参考其他画面而生成;

5. I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);

6. I帧是帧组GOP的基础帧(第一帧), 在一组中只有一个I帧;

7. I帧不需要考虑运动矢量;

8. I帧所占数据的信息量比较大。


3. P帧: 前向预测编码帧

P帧的预测与重构:P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加得到P帧“某点”样值,从而得到完整的P帧。

P帧特点:


1. P帧是I帧后面相隔1~2帧的编码帧;

2. P帧采用运动补偿的方法传送它与前面的I帧或P帧的差值及运动矢量(预测误差);

3. 解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;

4. P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;

5. P帧可以是其后面P帧的参考帧,也可以是其前后B帧的参考帧;

6. 由于P帧也是参考帧,它可能造成解码错误的扩散;

7. 由于是差值传送,P帧的压缩比较高。


4. B帧: 双向预测内插编码帧

B帧以前面的I或P帧和户名的P帧为参考帧,找出B帧某点的预测值和两个运动矢量,并取预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中算出预测值并与差值求和,得到B帧某点样值,从而得到完整的B帧。

B帧特点:


1. B帧是从前面的I帧或P帧和后面的P帧来进行预测的;

2. B帧传送的是它与前面的I帧或P帧和后面的P帧之间的预测误差及运动矢量;

3. B帧是双向预测帧;

4. B帧压缩比最高,因为它只反映参考帧见运动主体的变化情况,预测比较准确;

5. B帧不是参考帧,不会造成解码错误的扩散。



注意:I、P、B帧是根据压缩算法需要,是认为定义的,它们是实实在在的物理帧,至于图像中的哪一帧是I帧,是随机的。


一般平均来说,I的压缩率是7, P是20, B可以达到50;

5. GOP

group of pictures 画面组

gop 策略影响编码质量,所谓gop, 意思是画面组,一个gop 就是一组连续的画面。

MPEG-2 压缩的帧结构有两个参数,一个是GOP图像组的长度,一般可按编码方式从1-15;另一个是I帧和P帧直接的B帧的数量,一般是1-2个。


1.7.5 码率

一般用kbps(千比特/秒)或者mbps(兆比特/秒)来表示


1.7.6 帧率

FPS (帧/秒),就是视频画面刷新的速度。作为参考,国内电视机一般是25FPS, 电影标准为24FPS。


1.7.7 RGB和YUV

RGB指的就是红绿蓝;而yuv主要指亮度和两个色差信号,被称为luminance 和chrominance。我们视频里面基本上都是用yuv格式。

视频压缩用到的是yuv420


1.7.8 实时和非实时

实时与非实时,主要用来形容编码器,它含有两个意思,一个是要保证帧率,也就是每秒25帧,另一个是live, 意味着直播。


第二章 FFmpeg框架

2.1 ffmpeg概述

open-source multimedia library, 遵从GPL/LGPL协议,ffmpeg只是一个商标,它的所有权属于ffmpeg org.

项目的名称来自MPEG视频编码标准,前面的FF代表Fast Forward

FFmpeg 是一套可以用来记录、转换数字音频、视频,并将其转化为流的开源计算机程序。


FFmpeg有非常强大的功能,包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。


2.1.3 模块组成


1. libavformat : 用于各种音视频封装格式的生成和解析,包括获取解码所需信息以及生成解码上下文结构和读取音视频帧等功能;音视频的格式解析协议,为livavcodec分析码流提供独立的音频或视频码流源。

2. libavcodec : 用于各种类型声音/图像编解码;该库是音视频编解码核心,实现了市面上大部分解码器的功能,libavcodec库被其他各大解码器ffdshow、Mplayer等所包含或应用;

3. libavdevice : 硬件采集、加速、显示。

4. libavfilter: filter(FileIO、FPS、DrawText)音视频滤波器的开发,如宽高比、裁剪、格式化、非格式化伸缩。

5. libavutil : 包含一些公共的工具函数的使用库,包括算数运算、字符运算

6. libavresample : 音视频封装编解码格式预设等

7. libswresample : 原始音频格式转换

8. libpostproc : (同步、时间计算的简单算法)用于后期效果处理;

9. ffmpeg: 该项目提供的一个工具,用于格式转换、解码或即时编码等

10. ffserver : 一个http 多媒体即时广播串流服务器

11. ffplay : 简单播放器


2.2 媒体播放器三大底层框架

大体来说业界主要有3大架构: MPC、Mplayer、VLC。


第三章 编译及简单应用

ffmpeg基础库编程开发 读书笔记_数据

1. 安装mingw

下载地址:​​https://sourceforge.net/projects/mingw/​

执行mingw-get-setup.exe, 一步一步安装

2. yasm : 汇编编译器

3. 这个文档是在windows下面编译安装ffmpeg的,所以后面的安装库就不记了。


3.2 流媒体数据流程讲解

ffmpeg基础库编程开发 读书笔记_参考帧_02


ffmpeg.c 文件中 main()---av_register_all()

 av_register_all(), 初始化libavcodec 库,并注册所有的编解码器和格式。

3.5 ffmpeg程序的使用


1. ffmpeg是用于转码的应用程序,详细说明文档:​​http://ffmpeg.org/ffmpeg.html​

2. ffplay 是用于播放的应用程序,详细说明文档:​​http://ffmpeg.org/ffplay.html​

3. ffprobe 是用于查看文件格式的应用程序,详细说明文档 :​​http://ffmpeg.org/ffprobe.html​



第五章 重要模块

5.1 libavutil 公共模块


1. common.h  : 基本上是一些宏定义和内联函数, common internal and external API header;

2. bswap.h : byte swapping routines, 字节顺序交换,和CPU大小端有关;

    常见的cpu 中,Intel X86 序列及其兼容序列只能是小端, ARM大端小端都支持,但默认小端。

3. rational.h : Utilties for rational number calculation, 有理数计算

4. mathematics.h : Mathematical utilities for working with timestamp and time base.

5. avutil.h : Convenience header that includes @ref lavu "libavutil"'s core.


总体来说,avutil 模块主要有如下功能:



  1. 数学函数
  2. 字符串操作
  3. 内存管理相关
  4. 数据结构相关
  5. 错误码及错误处理
  6. 日志输出
  7. 其他辅助信息,比如密钥、哈希值、宏、库版本、常量等


5.2 libavcodec 编解码模块


1. avcodec.h : Encoding/Decoding Library

   主要定义编解码库使用到的宏、数据结构和函数。通常这些宏、数据结构和函数在这个模块内相对全局有效。

   AV_CODEC_ID_H265 AV_CODEC_ID_HEVC 就是在这个头文件中定义的。

2. allcodec.c : Provide registration of all codecs, parsers and bitstream filters for libavcodec.

简单的注册、初始化函数,把编解码器用相应的链表串起来便于查找识别。

avcodec_register_all()函数中注册所有的编解码器。




5.3 libavformat 容器模块


1. avformat.h : Main libavformat public API header

定义识别文件格式和媒体类型库使用的宏、数据结构和函数。这些宏、数据结构和函数在这个模块内基本都是全局的。

2. allformat.c : 简单的注册、初始化函数,把编解码器用相应的链表串起来便于查找识别。

av_register_all()函数中注册所有的编解码器。

3. file.c : ffmpeg 把file当做类似于rtsp/rtp/tcp 等协议的一种协议,用file: 前缀标示file 协议

4. avio.h 文件: Buffered I/O operations

文件读写模块定义的数据结构和函数声明。


5.4 libswscale : 视频色彩空间转换

5.5 libswresample : 音频重采样

5.6 libavfilter : 音视频滤波器

5.7 libavdevice : 设备输入输出容器

5.8 libpostproc : 视频后期处理


第八章 关键函数介绍

8.1 avformat_open_input :

ffmpeg 打开媒体的过程开始于avformat_open_input, 该函数有两个功能:


1. 输入输出结构体AVIOContext的初始化;

2. 输入数据的协议(如RTMP,file)的识别,通过一套评分机制:1. 判断文件名的后缀;2. 读取文件头的数据进行比对


 每个具体的输入协议都有自己对应的URLProtocol,比如说rtmp 协议

URLProtocol ff_rtmp_protocol = {
.name = "rtmp",
.url_open = rtmp_open,
.url_read = rtmp_read,
.url_write = rtmp_write,
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
.url_get_file_handle = rtmp_get_file_handle,
.priv_data_size = sizeof(RTMP),
.flags = URL_PROTOCOL_FLAG_NETWORK,
};

8.2 avcodec_register_all

ffmpeg注册复用器、编码器等的函数av_register_all, 该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等。

8.3 av_read_frame

ffmpeg中的av_read_frame的作用是读取码流中的音频若干帧或者视频一帧;

解码视频的时候,每解码一个视频帧,需要先调用av_read_frame获得一帧视频的压缩数据,然后才能对该数据进行解码(例如H.264中一帧压缩数据通常对于一个NAL)


第九章 ffmpeg相关工程

9.1 ffdshow 

ffdshow是基于ffmpeg的解码器类库libavcodec的directshow filter.

ffdshow 是一个非常强大的DirectShow 解码器,封装了ffmpeg,libmpeg2 等解码库。它也提供了丰富的加工处理选

项,可以锐化画面,调节画面的亮度等等。不止是视频,FFDShow 现在同样可以解码音频,AC3、MP3 等音频格

式都可支持。并且可以外挂winamp 的DSP 插件,来改善听觉效果。一个词形容:强大。

9.2 LAV filters

LAV Filter 是基于ffmpeg 的解码器类库libavcodec,以及解封装器类库libavformat 的DirectShow Filter。广泛安装在

PC 上。

9.3 MPlayer

MPlayer 是一个LINUX 下的视频播放器,它支持相当多的媒体格式,无论在音频播放还是在视频播放方面,可以说

它支持的格式是相当全面的。

视频格式支持:MPEG、AVI、ASF 与WMV、QuickTime 与OGG/OGM、SDP、PVA、GIF。

音频格式支持:MP3、WAV、OGG/OGM 文件(Vorbis)、WMA 与ASF、MP4、CD 音频、XMMS。


第十一章 mp4 文件封装协议分析

11. 概述

MP4文件格式中,所有的内容存在一个称为movie的容器中, 一个movie可以由多个trak组成。 每个trak就是一个随时间变化的媒体序列。

注意:一帧音频可以分解成多个音频sample, 所有音频一般用sample作为单位,而不用帧。

MP4文件格式定义里面,用sample这个单词表示一个时间帧或者数据单元。

每个trak会有一个或者多个sample descriptions

MP4文件中所有的数据都封装在一些box中,以前叫atom


11.2  mp4 的物理结构

一个trak的连续几个sample组成的单元就被称为chunk


11.4 mp4 的时间结构

关键词:


1. trak 表示一些sample的集合,对于媒体数据来说,track表示一个视频或音频序列

2. sample video sample即为一帧视频,或一组连续视频帧,audio sample即为一段连续的压缩音频,它们统称
sample

3. chunk 一个trak的几个sample组成的单元;

4. box box 由header 和body 组成,其中header 统一指明box 的大小和类型,body 根据类型有不同的意义和格
式。标准的box 开头的4 个字节(32 位)为box size,该大小包括box header 和box body 整个box 的大小,这样我
们就可以在文件中定位各个box。size 后面紧跟的32 位为box type,一般是4 个字符,如“ftyp”、“moov”等,这
些box type 都是已经预定义好的,分别表示固定的意义


 MP4 文件的结构树:

ffmpeg基础库编程开发 读书笔记_音视频_03

 11.5 文件结构分析

1. File type box (ftyp)

该box 有且只有一个,并且只能被包含在文件层,而不能被其他box包含。该box应该被放在文件的最开始,指示该MP4文件应用的相关信息。

2. Movie Box (moov)

该box包含了文件媒体的metadata 信息, “moov”是一个container box, 具体内容信息由子box 诠释。同file type box 一样,该box 有且只有一个,且只被包含在文件层。一般情况下,moov会紧随ftyp 出现

一般情况下,moov中会包含一个mvhd和若干个trak, 其中mvhd 为header  box, 一般作为moov的第一个子box 出现。

3.  Movie Header Box (mvhd)

mvhd定义了整个movie的特性,例如time scale 和duration, 它的atom 类型是mvhd

4. Track box (trak)

主数据存储结构,一部movie可以包含一个或多个tracks, 它们之间相互独立,各自有各自的时间和空间信息,每个trak atom 都有与之关联的media atom

trak atoms 的atom 类型都是trak, trak atom 要求必须有一个trak header atom(tkhd) 和一个media atom(mdia).

5. Media box(mdia)

mdia 也是一个container box , 其子box 的结构和种类还是比较复杂的。树结构如下:

ffmpeg基础库编程开发 读书笔记_数据_04

总体来说,mdia 定义了trak媒体类型以及sample数据,描述sample信息。

一般mdia 包含一个mdhd, 一个hdlr,一个minf,其中mdhd 为media head box, hdlr 为handler reference box, minf 为media information box .

6. Sample Table Box (stbl)

stbl 包含了关于trak 中sample所有时间和位置的信息,以及sample的编解码等信息。利用这个表,可以解释sample的实现、类型、大小和在各自存储容器中的位置。stbl 是一个container box, 其子box 包括stsd, stts, stsz, stsc , stco, ctts, stss等


第十二章 flv 文件格式分析

12.1 概要

FLV视频格式是Adobe 公司设计开发的一种流媒体的封装格式,总体上看,FLV包括文件头(FLV Header)和文件体(FLV body)两部分,其中文件体由一系列的Tag 及Tag Size 对组成。

Tag 又可以分为三类:audio 、video、script

12.2 文件总体结构

ffmpeg基础库编程开发 读书笔记_音视频_05

 12.3 文件结构分析

1. flv 文件头的结构

在ffmpeg 进行格式识别的时候,是以头部的前3 个字节进行探测,识别到'F' 'L' 'V'即可认定该格式为flv 格式。

2. body 主体结构

Tag 包括Tag Header 和Tag Data 两部分。

3. 如果SoundFormat 是10 (AAC),TagDataHeader 后紧随着一个1 个字节的数据AACPacketType,这个字段来表

示AACAUDIODATA 的类型:0 = AAC sequence header,1 = AAC raw。在flv 中一般情况下,带有该AACPacketType

的Tag 只会在第一个audio Tag 中出现一次,因为aac 格式的音频需要在每帧AAC ES 流前边添加7 个字节ADST

头(相当于帧头),就是AAC 的纯ES 流要打包成ADST 格式的AAC 文件,解码器才能正常播放.特别对于RTSP,RTP

等实时传输流,ADST 必须存在,否则传输过来的流不知道该怎么播放。

4. SCRIPT Tag。该类型Tag 又通常被称为Metadata Tag

通常该类型Tag 会跟在File Header 后面作为第一个Tag 出现,而且只有一个

一般来说,该Tag Data 结构包含两个AMF 包。AMF(Action Message Format)是Adobe 设计的一种通用数据

封装格式,在Adobe 的很多产品中应用,简单来说,AMF 不区分根节点与子节点,将不同类型的数据用统一的格

式来描述。第一个AMF 包封装字符串类型数据,即:“02” type+string length+“onMetaData”。第二个AMF 包封装

一个数组类型,这个数组中包含了音视频信息项的名称和值。