FFmpeg介绍
官方网站:http://www.ffmpeg.org/
项目组成
- libavformat
封装模块,封装了Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透明的。FFmpeg能否支持一种封装格式的视频的封装与解封装,完全取决于这个库,例如mp4、flv、mkv等容器的封装与解封装;或者RTMP、RTSP、TCP、UDP等协议的封装与解封装;
- libavcodec
编解码模块,封装了Codec层,但是有一些codec是具备自己的License的,FFmpe不会默认添加像libx264、FDK-AAC、Lame等库,但是FFmpeg像一个平台,可以将其他的第三方codec以插件的方式添加进来,为开发者提供统一接口;
- libavutil
核心工具模块,最基础模块之一,其他模块都会依赖该库做一些基本的音视频处理操作;
- libavfilter
音视频滤镜模块,该模块包含了音频特效和视频特效的处理,在使用FFmpeg的API进行编解码的过程中,可以使用该模块高效的为音视频数据做特效处理;
- libavdevice
输入输出设备模块,例如需要编译出播放声音或者视频的工具ffplay,就需要确保该模块是打开的,同时也需要libsdl的预先编译,该设备模块播放声音和视频都是使用libsdl库;
- libswresample
该模块用于音频重采样,可以对数字音频进行声道数、数据格式、采样率等多种基本信息的转换;
- libswscale
该模块用于图像格式转换,可以将YUV的数据转换为RGB的数据;
- libpostproc
该模块用于进行后期处理,当我们使用filter的时候,则需要打开这个模块,filter会用到这个模块的一些基础函数;
常用名词释义
- 码流(码率)
码流(Data Rate)是指视频文件在单位时间内使用的数据流量,也叫码率,是视频编码中画面质量控制中最重要的部分。同样分辨率下,视频文件的码流越大,压缩比就越小,画面质量就越好。
- 采样率
采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样频率的倒数是采样周期或者叫作采样时间,它是采样之间的时间间隔。通俗的讲采样频率是指计算机每秒钟采集多少个信号样本。
- 比特率
比特率是指每秒传送的比特(bit)数。单位为bps(bit per second)也可表示为b/s,比特率越高,单位时间传送的数据量(位数)越大。
在视频领域,比特率常翻译为 “码率" 。 比特率表示经过编码(压缩)后的音、视频数据每秒钟需要用多少个比特来表示,而比特就是二进制里面最小的单位,要么是0,要么是1。比特率与音、视频压缩的关系,简单的说就是比特率越高,音、视频的质量就越好,但编码后的文件就越大;如果比特率越少则情况刚好相反。比特率是指将数字声音、视频由模拟格式转化成数字格式的采样率,采样率越高,还原后的音质、画质就越好。
- 帧速率
帧速率也称为 FPS(Frames PerSecond) 的缩写——帧/秒。FPS是指每秒钟刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。越高的帧速率可以得到更流畅、更逼真的动画。每秒钟帧数 (FPS) 越多,所显示的动作就会越流畅。
- I、P、B帧
I 帧(Intracoded frames):I 帧图像采用帧内编码方式,即只利用了单帧图像内的空间相关性,而没有利用时间相关性。I 帧使用帧内压缩,不使用运动补偿,由于 I 帧不依赖其它帧,所以是随机存取的入点,同时是解码的基准帧。I 帧主要用于接收机的初始化和信道的获取,以及节目的切换和插入,I 帧图像的压缩倍数相对较低。I 帧图像是周期性出现在图像序列中的,出现频率可由编码器选择。
P 帧(Predictedframes):P 帧和 B 帧图像采用帧间编码方式,即同时利用了空间和时间上的相关性。P 帧图像只采用前向时间预测,可以提高压缩效率和图像质量。P 帧图像中可以包含帧内编码的部分,即 P 帧中的每一个宏块可以是前向预测,也可以是帧内编码。
B 帧(Bi-directionalpredicted frames):B 帧图像采用双向时间预测,可以大大提高压缩倍数。值得注意的是,由于 B 帧图像采用了未来帧作为参考,因此 MPEG-2 编码码流中图像帧的传输顺序和显示顺序是不同的。
也就是说,一个 I 帧可以不依赖其他帧就解码出一幅完整的图像,而 P 帧、B 帧不行。P 帧需要依赖视频流中排在它前面的帧才能解码出图像。B 帧则需要依赖视频流中排在它前面或后面的帧才能解码出图像。
- GOP
GOP即Group of picture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧。所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。
需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。
- DTS、PTS
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
需要注意的是:虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。 当视频流中没有 B 帧时,通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,就回到了我们前面说的问题:解码顺序和播放顺序不一致了。
比如一个视频中,帧的显示顺序是:I B B P,现在我们需要在解码 B 帧时知道 P 帧中信息,因此这几帧在视频流中的顺序可能是:I P B B,这时候就体现出每帧都有 DTS 和 PTS 的作用了。DTS 告诉我们该按什么顺序解码这几帧图像,PTS 告诉我们该按什么顺序显示这几帧图像。
顺序大概如下:
PTS: 1 4 2 3
DTS: 1 2 3 4
Stream: I P B B
- 编码模式
VBR(Variable Bitrate)动态比特率 也就是没有固定的比特率,压缩软件在压缩时根据音频数据即时确定使用什么比特率,这是以质量为前提兼顾文件大小的方式,推荐编码模式;
ABR(Average Bitrate)平均比特率是VBR的一种插值参数。LAME针对CBR不佳的文件体积比和VBR生成文件大小不定的特点独创了这种编码模式。ABR在指定的文件大小内,以每50帧(30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量,可以做为VBR和CBR的一种折衷选择。
CBR(Constant Bitrate),常数比特率 指文件从头到尾都是一种位速率。相对于VBR和ABR来讲,它压缩出来的文件体积很大,而且音质相对于VBR和ABR不会有明显的提高。
- 音视频的同步
上面说了视频帧、DTS、PTS 相关的概念。我们都知道在一个媒体流中,除了视频以外,通常还包括音频。音频的播放,也有 DTS、PTS 的概念,但是音频没有类似视频中 B 帧,不需要双向预测,所以音频帧的 DTS、PTS 顺序是一致的。 音频视频混合在一起播放,就呈现了我们常常看到的广义的视频。在音视频一起播放的时候,我们通常需要面临一个问题:怎么去同步它们,以免出现画不对声的情况。 要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳。在播放时,读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放。这里的说的时间戳就是我们前面说的 PTS。实践中,我们可以选择:同步视频到音频、同步音频到视频、同步音频和视频到外部时钟。
目录:
1. FFmpeg简介 https://zhuanlan.zhihu.com/p/142593316
2.FFmpeg操作参数 https://zhuanlan.zhihu.com/p/145312133
3.FFmpeg常用操作 https://zhuanlan.zhihu.com/p/145592911
原创《You-Get从入门到实践》 https://zhuanlan.zhihu.com/p/325927078
Homebrew从入门到实践:视频教程 https://zhuanlan.zhihu.com/p/319809242
1. FFmpeg[1]
FFmpeg 强大专用于处理音视频的开源库,包含了先进的音视频编解码库,提供了录制、转换以及流传输音视频的完整跨平台解决方案。
既可以使用它的API对音视频进行处理,也可以使用它提供的工具,如 ffmpeg, ffplay, ffprobe,来编辑音视频文件。
开源代码
https://github.com/FFmpeg/FFmpeg
特点[2][3]
- 功能完整:FFmpeg是领先的多媒体框架,能够解码(decode)、编码(encode)、转码(transcode)、复用(mux)、解复用(demux)、流(stream)、过滤(filter)和播放(play)人类和机器创建的几乎所有内容。
- 几乎支持所有格式:FFmpeg支持最模糊的古代格式直至最前沿。无论是由某些标准委员会、社区还是公司设计的。
- 跨平台高度可移植性:FFmpeg可以在各种构建环境:机器体系结构和配置下,跨Linux、Mac OS X、Microsoft Windows、BSD、Solaris等编译,运行并通过测试基础架构 FATE。
- 每日更新的文档[4]:各种在线每晚更新一次,并且对应于最新的FFmpeg版本。
2. FFmpeg播放流程及相关术语
2.1 播放流程:
video.avi(Container) -> 打开得到 Video_Stream -> 读取Packet -> 解析到 Frame -> 显示Frame。[5]
2.2 相关术语:
2.2.1 「封装格式(Container Format)」
封装格式(Container Format),可看作是编码流(Stream)(音频、视频等)数据的一层外壳,将编码后的数据,存储于此封装格式的文件之内。[6]
封装又称容器(Container),容器的用词更为形象。容器就是存放内容的器具。
例如:饮料是内容,那么装饮料的瓶子就是容器。
对视频来说,封装格式是MP4、AVI、MKV、RMVB等格式。
2.2.2 「流(Stream)」
流(Stream)是一种音视频数据信息的传输方式。
有五种流:视频流(Video Stream)、音频流(Audio Stream)、字幕(Subtitle)、附件(t)、数据(d)。[7]
例如:曾经多年前使用VCD看港片,可以选择粤语或国语声音,是视频文件中存放了两路音频流,可供用户选择其中一路进行播放。
2.2.3 「帧(Frame)」
帧(Frame)本意代表一幅静止的图像。[8]
在流(Stream)中,帧代表最小数据单元,也是编解码器真正处理的最小处理单元。
数字视频处理的帧,通常不是说原始图像,而是被编码器编码后的一个图像。
对于视频来说,帧(Frame)是编码器编码后的一个图像;
对于音频来说,帧(Frame)是编码器编码后的一个声音。[9]
帧(Frame)分为:I帧:关键帧、P帧:预测帧、B帧:双向预测帧。
2.2.4 「编解码(Codec)」[10]
每路音视频流(Stream)都会以帧(Frame)为最小单位,被相应的编/解码器(Codec)进行编码或解码,以实现原始数据和压缩数据之间的相互转换。[11]
编码(Codec)是对原始数据的加工,是对输入源进行处理,然后输出的过程。简单说,就是对图像和声音的压缩方法。
视频编码主要有:H263、H264、H265、MPEG系列等。
编码(Codec)其实是编码(COde)和解码(DECode)的合称。
CODEC = COde(编码) + DECode(解码)
解码就是把编码后的东西还原为原来的状态。对于视频来说,就是把压缩的图像和声音还原为正常可以播放的图像和声音。
编码可以改变文件格式,或者文件格式不变,只更改其他数据。FFmpeg编解码是基于比特流进行的。
2.2.5 「数据包(Packet)」
数据包(Packet)是从流(Stream)中读取的原始Raw数据片段,这些数据片段中,包含的是解码后能被应用程序处理的原始帧(Raw Frame)数据。[12]
分开的数据流在送往编解码器(Codec)处理之前,要先放于缓存中,添加一些附属信息(例如:打上时间戳)以便后续处理,这个缓存空间就是数据包(Packet);
由于数据流是在时间轴上交错放置,所有的视频、音频、字幕都被分割成一段一段的数据,这些一段段的数据从数据流中解析出来之后,就是存放在各自的数据包(Packet)。
单纯的视频数据包来说,一个视频数据包可以存放一个视频帧;
单纯的音频帧来说,如果抽样率(sample-rate)是固定不变的,一个音频数据包可以存放几个音频帧;若是抽样率是可变的,则一个数据包就只能存放一个音频帧。[13]
3. FFmpeg转码流程及相关术语
3.1 文件转码流程:
解封装Demux ——> 解码Decode ——> 编码Encode ——> 封装Mux

3.2 相关术语
3.2.1 封装格式转换:解封装Demux与封装Mux(无编解码/转码)
封装(Container)见上文2.2.1称为容器。
3.2.1.1 封装,还称为多路复用(Mux)。
封装的目的:
1. 是为了在一个文件流(Stream)中能同时存储视频流(Video Stream)、音频流(Audio Stream)、字幕(Subtitle)、附件(t)、数据(d)等内容。这正是“复用”的含义所在(分时复用)。
2. 是在网络环境下确保数据的可靠快速传输。
3.2.1.2 封装格式转换:
包括封装与解封装,即「复用(Mux)」与「解复用(Demux)」。
封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间进行转换(对应.avi/.flv/.mkv/.mp4后缀文件)。
- 「复用(Mux)」又称为封装
将多路流(视频、音频、字幕等),按照某种容器规则,混入一路输出中(普通文件、流等)。是multiplex的缩写。
- 「解复用(Demux)」又称为解封装
复用(Mux) 的反操作。从一路输入中,解析分离出多路流(视频、音频、字幕等)。
- 「复用(Mux)」处理的是输入格式,「解复用(Demux)」处理的输出格式。
3.2.1.3 封装格式转换工作原理图[14]

封装格式转换并不进行视音频的编码和解码工作。而是直接将视音频压缩码流,从一种封装格式文件中获取出来,然后打包成另外一种封装格式的文件。
3.2.1.4 封装格式转换特点:
- 处理速度极快。视音频编解码算法十分复杂,占据了转码的绝大部分时间。因为不需要进行视音频的编码和解码,所以节约了大量的时间。
- 视音频质量无损。因为不需要进行视音频的编码和解码,所以不会有视音频的压缩损伤。
3.2.2 编解码转换(转码)
使用FFmpeg对输入源处理,然后输出的过程叫做转码。 转码可以改变文件格式,或者文件格式不变,只是更改其他数据。[15]
编码的目的
是为了压缩媒体数据。有别于通用文件数据的压缩,在图像或音频压缩的时候,可以借助图像特性(如前后关联、相邻图块关联)或声音特性(听觉模型)进行压缩,可以达到比通用压缩技术更高的压缩比。
传统的编码转换程序工作原理图[16]

3.3 转码步骤[17]
1. Demuxer 解复用器 进行Demuxing 解封装:
FFmpeg根据输入源的文件扩展名来选择最佳的解封装器:调用libavformat库(包含解复用器)读取 [输入文件(Input file)] ,解封装后生成 [包含编码数据的数据包(Encoded data packets)],即压缩状态的数据包。(文件file → 数据包data packets)
2. Decoder 解码器 进行Decoding解码 :
通过适当的解码器将步骤1里面的数据包解码为[未压缩的数据帧](原始视频/PCM音频/...),可以通过 ※过滤Optional filtering※ 进一步处理。(数据包data packages ——> 数据帧frames)
※ Optional filtering可选的滤镜:通过指定的滤镜修改解码后的数据帧。(修改数据帧)
如果使用-c copy或-codec copy,将不会有解码这个步骤,也就不会有下面的编码步骤。
3. Encoder 编码器 进行Encoding编码:
通过指定编码器,对其进行编码,将数据帧编码输出为[编码后的数据包(Encoded data packets)]。(数据帧frames ——> 数据包data packages)
4. Muxer 复用器 进行Muxing封装:
将[编码的数据包]封装为指定的媒体格式[输出文件(Output file)]。(数据包data packages ——> 文件file)
- FFmpeg播放流程及相关术语中易混淆的概念:
1.「文件格式(File Format)」与「封装格式(Container Format)」的区别[18]
「文件格式(File Format)」
由文件扩展名标识,主要起提示作用。通过扩展名提示文件类型(或封装格式)信息。
「封装格式/容器(Container Format)」
是存储媒体内容的实际容器格式。 不同的封装格式对应不同的文件扩展名,很多时候也用文件格式代指封装格式。
例如:常用ts格式(文件格式)代指mpegts格式(封装格式)。 修改后缀把test.ts改名为test.mkv。mkv扩展名提示了此文件封装格式为Matroska,但文件内容并无任何变化,使用ffprobe工具仍能正确探测出封装格式为mpegts。
2.「封装格式(Container Format)」与「编解码(Codec)」的区别:
封装的步骤:打开输入文件、打开输出文件、从输入文件读取编码帧、往输出文件写入编码帧。这些都不涉及编码解码层面。[19]
不同封装格式适用于不同的场合,支持的编码格式不一样。
主要封装格式一览表[20](可先不看)

「封装格式(Container Format)」与「编解码格式(Codec Format)」一览表[21]

如果只是容器改变,编码没改变。
可使用-c copy参数或-c:a copy参数或-c:v copy参数。
ffmpeg -i input.avi -q 1 -c copy output.mov

4. FFmpeg 工具[22]
- ffmpeg: 是可转换音频或视频格式的命令行工具。它还可以从各种硬件和软件源(例如电视捕获卡)实时捕获和编码。
- ffplay: 一个基于SDL和FFmpeg库的简单媒体播放器
- ffprobe: 一个简单的多媒体流分析仪。用于显示媒体信息(文本,CSV,XML,JSON)的命令行工具,另请参见Mediainfo。
- Demuxer 解复用器(file → packets): ffmpeg调用libavformat库(包含解复用器)读取[输入文件]并从中获取[包含编码数据的数据包]。
- Decoder 解码器(packets → frames): 产生[未压缩的帧](原始视频/PCM音频/...)。可以通过 过滤 进一步处理。
- Encoder 编码器(frames → packets): 对其进行编码并输出[编码后的数据包]。
- Muxer 复用器(packets → file): 将[编码的数据包]写入[输出文件]。
解复用器/分流器(demuxer)的工作流程
将处理的多媒体文件看成多媒体数据流, 先把多媒体数据流放入容器(AVFormatContext), 然后将数据流送入解复用器(demuxer),抽象为AVInputFormat。
demuxer又称分流器,把交错的各种基本数据流识别后,分开处理,再将分开的数据流,分别送到视频、音频、字幕编解码器处理。
4. FFmpeg基本组成模块(可先不看)
- libavformat - 用于各种音视频封装格式的生成和解析,包括获取解码所需信息、读取音视频数据等功能。
- libavcodec - 音视频各种格式的编解码。
- libavutil - 一些公共的工具函数的使用库,包括解码器,工具函数,算数运算,字符操作等。
- libswscale - 提供原始视频的比例缩放、色彩映射转换、缩放、图像颜色空间或格式转换的功能。
- libswresample - 提供音频混音和重采样,采样格式转换和混合等功能。
- libavfilter - 各种音视频滤波器。
- libpostproc - 用于后期效果处理,如图像的去块效应等。
- libavdevice - 用于硬件的音视频采集、加速和显示,访问捕获设备和回放设备的接口。
模块相关结构[23]
- libavformat有一个非常重要的结构: AVFormatContext;
它几乎是ffmpeg中的一颗树, 其成员AVStream可以包含0种或多种流,
在AVStream中又可以包含已经打开的编解码器codec, 另外还有AVIOContext成员,这个成员的作用就是io了,。
可以重写AVIOContext结构的成员函数read_packet或write_packet等,
来实现从不同介质读取音视频媒体数据(比如从网络、内存或磁盘等),
关于ffmpeg的io方面,还可以在libavformat中自己实现一个 PROTOCOL组件来实现同样的功能,
方法也很简单, 只要实现URLProtocol结构然后取个名字在allformats.c中使用REGISTER_PROTOCOL
添加一行注册自己的协议就行, 其它DEMUXER和MUXDEMUX方法也是相似的。
- libavformat也提供了AVOutputFormat、AVInputFormat、URLProtocol等。
- libavcodec也有一个非常重要的结构: AVCodecContext;
它包含了当前媒体信息的几乎所有参数(什么宽高, 运行估计, 码率控制...), 以及编解码指针(AVCodec),
甚至还可以设置硬件加速相关(如DXVA, linux下的 VAAPI).
其中最重要的属AVCodec, 它是直接指向编解码器实现,
如果你想自己实现一个编解码添加到libavcodec中, 那么也是非常方便的。
- libavcodec也提供了AVHWAccel、AVCodec、AVCodecParser、AVBitStreamFilter等。
4.1 封装格式
AVFormatContext - 描述了媒体文件的构成及基本信息,是统领全局的基本结构体,贯穿程序始终,很多函数都要用它作为参数,格式转换过程中实现输入和输出功能、保存相关数据的主要结构,描述了一个媒体文件或媒体流的构成和基本信息;
- nb_streams/streams :AVStream结构指针数组, 包含了所有内嵌媒体流的描述,其内部有 AVInputFormat + AVOutputFormat 结构体,来表示输入输出的文件格式
- avformat_open_input:创建并初始化部分值,但其他一些值(如 mux_rate、key 等)需要手工设置初始值,否则可能出现异常
- avformat_alloc_output_context2:根据文件的输出格式、扩展名或文件名等分配合适的 AVFormatContext 结构
AVInputFormat - 解复用器对象,每种作为输入的封装格式(例如FLV、MP4、TS等)对应一个该结构体,如libavformat/flvdec.c的ff_flv_demuxer;
AVOutputFormat - 复用器对象,每种作为输出的封装格式(例如FLV, MP4、TS等)对应一个该结构体,如libavformat/flvenc.c的ff_flv_muxer;
AVStream - 用于描述一个媒体流,其大部分信息可通过 avformat_open_input 根据文件头信息确定,其他信息可通过 avformat_find_stream_info 获取,典型的有 视频流、中英文音频流、中英文字幕流(Subtitle),可通过 av_new_stream、avformat_new_stream 等创建。
- index:在AVFormatContext中流的索引,其值自动生成(AVFormatContext::streams[index])
- nb_frames:流内的帧数目
- time_base:流的时间基准,是一个实数,该流中媒体数据的pts和dts都将以这个时间基准为粒度。通常,使用av_rescale/av_rescale_q可以实现不同时间基准的转换
- avformat_find_stream_info:获取必要的编解码器参数(如 AVMediaType、CodecID ),设置到 AVFormatContext::streams[i]::codec 中
- av_read_frame:从多媒体文件或多媒体流中读取媒体数据,获取的数据由 AVPacket 来存放
- av_seek_frame:改变媒体文件的读写指针来实现对媒体文件的随机访问,通常支持基于时间、文件偏移、帧号(AVSEEK_FLAG_FRAME)的随机访问方式
4.2 编解码
AVCodecContext - 描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,保存AVCodec指针和与codec相关的数据,包含了流中所使用的关于编解码器的所有信息;
- codec_name[32]、codec_type(AVMediaType)、codec_id(CodecID)、codec_tag:编解码器的名字、类型(音频/视频/字幕等)、ID(H264/MPEG4等)、FOURC等信息
- hight/width,coded_width/coded_height: Video的高宽
- sample_fmt:音频的原始采样格式, 是 SampleFormat 枚举
- time_base:采用分数(den/num)保存了帧率的信息
AVCodec - 编解码器对象,编解码器,采用链表维护,每一个都有其对应的名字、类型、CodecID和对数据进行处理的编解码函数指针,每种编解码格式(例如H.264、AAC等)对应一个该结构体。每个AVCodecContext中含有一个AVCodec;
AVCodecParameters - 编解码参数,每个AVStream中都含有一个AVCodecParameters,用来存放当前流的编解码参数。
- avcodec_find_decoder/avcodec_find_encoder :根据给定的codec id或解码器名称从系统中搜寻并返回一个AVCodec结构的指针
- avcodec_alloc_context3:根据 AVCodec 分配合适的 AVCodecContext
- avcodec_open/avcodec_open2/avcodec_close :根据给定的 AVCodec 打开对应的Codec,并初始化 AVCodecContext/ 关闭Codec
- avcodec_alloc_frame:分配编解码需要的 AVFrame 结构
- avcodec_decode_video/avcodec_decode_video2 :解码一个视频帧,输入数据在AVPacket结构中,输出数据在AVFrame结构中
- avcodec_decode_audio4:解码一个音频帧。输入数据在AVPacket结构中,输出数据在AVFrame结构中
- avcodec_encode_video/avcodec_encode_video2 :编码一个视频帧,输入数据在AVFrame结构中,输出数据在AVPacket结构中
4.3 网络协议
AVIOContext - 管理输入输出数据的结构体;
URLProtocol - 描述了音视频数据传输所使用的协议,每种传输协议(例如HTTP、RTMP)等,都会对应一个URLProtocol结构;
URLContext - 封装了协议对象及协议操作对象。
4.4 数据存放
AVPacket - 存放编码后、解码前的压缩数据,即ES数据, 暂存解码之前的媒体数据(一个音/视频帧、一个字幕包等)及附加信息(解码时间戳、显示时间戳、时长等),主要用于建立缓冲区并装载数据;
- data/size/pos: 数据缓冲区指针、长度和媒体流中的字节偏移量
- flags:标志域的组合,1(AV_PKT_FLAG_KEY)表示该数据是一个关键帧, 2(AV_PKT_FLAG_CORRUPT)表示该数据已经损坏
- destruct:释放数据缓冲区的函数指针,其值可为 [av_destruct_packet]/av_destruct_packet_nofree, 会被 av_free_packet 调用。
AVFrame - 存放编码前、解码后的原始数据,如YUV格式的视频数据或PCM格式的音频数据等;
- data/linesize:FFMpeg内部以平面的方式存储原始图像数据,即将图像像素分为多个平面(R/G/B或Y/U/V)数组
- data数组:其中的指针指向各个像素平面的起始位置,编码时需要用户设置数据
- linesize数组 :存放各个存贮各个平面的缓冲区的行宽,编码时需要用户设置数据
- key_frame:该图像是否是关键帧,由 libavcodec 设置
- pict_type:该图像的编码类型:Intra(1)/Predicted(2)/Bi-dir(3) 等,默认值是 NONE(0),其值由libavcodec设置
- pts:呈现时间,编码时由用户设置
- quality:从1(最好)到FF_LAMBDA_MAX(256*128-1,最差),编码时用户设置,默认值是0
- nterlaced_frame:表明是否是隔行扫描的,编码时用户指定,默认0
目录:
1. FFmpeg简介 https://zhuanlan.zhihu.com/p/142593316
2.FFmpeg操作参数 https://zhuanlan.zhihu.com/p/145312133
3.FFmpeg常用操作 https://zhuanlan.zhihu.com/p/145592911
YOU-GET基本用法 https://zhuanlan.zhihu.com/p/323984075
Homebrew从入门到实践:视频教程 https://zhuanlan.zhihu.com/p/319809242
参考
- ^FFmpeg介绍: https://www.cnblogs.com/renhui/p/6922971.html
- ^FFmpeg特点: About FFmpeg
- ^FFmpeg特点: https://www.cnblogs.com/sztom/p/11964797.html
- ^FFmpeg每日更新文档: Documentation
- ^FFmpeg播放视频基本流程: https://www.cnblogs.com/renhui/p/9508123.html
- ^封装格式(Container Format)的概念: https://www.cnblogs.com/leisure_chn/p/10506636.html
- ^流(Stream)的概念: https://www.cnblogs.com/sztom/p/11964797.html
- ^帧(Frame)的概念: https://www.cnblogs.com/sztom/p/11964797.html
- ^帧(Frame)的概念: 刻意练习FFmpeg - 知乎
- ^编解码(Codec)的概念: https://www.cnblogs.com/samirchen/archive/2017/06/24/7073102.html
- ^编解码(Codec)的概念: https://www.cnblogs.com/renhui/p/9293057.html
- ^数据包(Packet)的概念: https://www.cnblogs.com/samirchen/archive/2017/06/24/7073102.html
- ^数据包(Packet)的概念: FFMPEG中的一些基本概念-CSDN博客
- ^最简单的基于FFMPEG的封装格式转换器(无编解码)_mp4remuxer-CSDN博客
- ^转码的概念: https://www.cnblogs.com/yongfengnice/p/7133714.html
- ^最简单的基于FFMPEG的封装格式转换器(无编解码)_mp4remuxer-CSDN博客
- ^转码步骤 https://www.cnblogs.com/yongfengnice/p/7133714.html
- ^「文件格式(File Format)」与「封装格式(Container Format)」的区别: https://www.cnblogs.com/leisure_chn/p/10506636.html
- ^FFmpeg封装格式处理文件步骤: https://www.cnblogs.com/leisure_chn/p/10506636.html
- ^FFmpeg主要封装格式一览表: [总结]视音频编解码技术零基础学习方法-CSDN博客
- ^「封装格式(Container Format)」与「编解码格式(Codec Format)」一览表: https://www.cnblogs.com/yongfengnice/p/7133714.html
- ^FFmpeg 播放视频基本流程 https://www.cnblogs.com/renhui/p/9508123.html
- ^ffmpeg模块相关结构: https://www.cnblogs.com/brucehou/archive/2011/12/20/2295059.html
1. FFmpeg基本常识及编码流程 - 知乎目录: 1. FFmpeg简介 https://zhuanlan.zhihu.com/p/142593316 2.FFmpeg操作参数 https://zhuanlan.zhihu.com/p/145312133 3.FFmpeg常用操作 https://zhuanlan.zhihu.com/p/145592911 原创《You-Get从入门到实践…
https://zhuanlan.zhihu.com/p/142593316
相关文章:
FFmpeg介绍
官方网站:http://www.ffmpeg.org/ 项目组成 libavformat 封装模块,封装了Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透明的。FFmpeg能否支持一种封装格式的视频的封装与解封装,完全取决于这个库,…...
修改网卡PHY的灯-RK3568
文章目录 前言1.定制PHY的灯2.通过命令修改LED状态3.修改驱动效果前言 前面我们已经移植了网卡到开发板上面,也能够正常的进行通信,但是,我们会发现座子上面的灯并没有全部亮起来,而且这些灯的含义是什么,并没有讲解到,这里,就此问题,展开学习。 PHY 有一个重要的功能…...
11月29日作业
作业: 自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height), 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show(…...
【从删库到跑路 | MySQL总结篇】表的增删查改(进阶下)
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】🎈 本专栏旨在分享学习MySQL的一点学习心得,欢迎大家在评论区讨论💌 目录 一、联合…...
【机器学习 | 可视化系列】可视化系列 之 决策树可视化
🤵♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…...
配置阿里云的yum仓库
目录 配置阿里云的yum源 清理官方yum源 下载阿里云的yum源 centos7下载阿里云yum源: 清理yum缓存:yum cleam all 生成自己的yum缓存:yum makecache 使用centos自带的官方yum源下载很慢,那今天来跟大家说说配置阿里云的yum仓…...
Kubernetes之kubeadm日志展示篇—K8S私有云worker节点gluster安装部署
文章目录 一. 服务器信息1.1 环境准备1.2 配置hosts解析记录 二. 安装与部署2.1 配置仓库 (所有节点)2.2 安装服务 (所有节点)2.3 启动服务 (所有节点)2.4 配置资源池 (主节点)2.5 创…...
P3368 【模板】树状数组 2 (区间修改,单点查询)
本题链接:【模板】树状数组 2 - 洛谷 题目: 输入 5 5 1 5 4 2 3 1 2 4 2 2 3 1 1 5 -1 1 3 5 7 2 4 输出 6 10 思路: 根据题意,这里是需要区间添加值,单点查询值。如果区间添加值中暴力去一个个加值,肯定…...
智慧城市运营管理平台解决方案:PPT全文61页,附下载
关键词:智慧城市建设方案,智慧城市解决方案,智慧城市的发展前景和趋势,智慧城市建设内容,智慧城市运营管理平台 一、智慧城市运营平台建设背景 随着城市化进程的加速,城市面临着诸多挑战,如环…...
Vue性能优化方法
一、前言 1.1 为什么需要性能优化 用户体验:优化性能可以提升用户体验,降低加载时间和响应时间,让用户更快地看到页面内容。SEO优化:搜索引擎更喜欢快速响应的网站,优化性能可以提高网站的排名。节约成本࿱…...
关于网站的favicon.ico图标的设置需要注意的几点
01-必须在网页的head标签中放上对icon图标的说明语句: 比如下面这样的语句: <link rel"shortcut icon" href"/favicon.ico">否则,浏览器虽然能读到图标,但是不会把图标显示在标签上。 02-为了和本地开…...
PHP中关于func_get_args()方法
首先呢这个函数出现的是比较早的,大致应该是PHP4出现的, func_get_args — 返回一个包含函数参数列表的数组 说明 func_get_args(): array 获取函数参数列表的数组。 该函数可以配合 func_get_arg() 和 func_num_args() 一起使用,从而使得用户自定义函数可以接…...
EMA训练微调
就是取前几个epoch的weight的平均值,可以缓解微调时的灾难性遗忘(因为新数据引导,模型权重逐渐,偏离训练时学到的数据分布,忘记之前学好的先验知识) class EMA():def __init__(self, model, decay):self.…...
Kafka集群部署详细教程
版本说明 Ubuntu 18.04.6Zookeeper 3.5.9Kafka 2.7.0JDK8 集群配置 操作系统ip域名Zookeeper 端口Kafka 端口Ubuntu 18.04.6192.168.50.131kafka1.com21819092Ubuntu 18.04.6192.168.50.132kafka2.com21819092Ubuntu 18.04.6192.168.50.133kafka3.com21819092 安装 vim, cu…...
交叉编译
1. 交叉开发 交叉编译: 在电脑把程序编写 编译 调试好 再下载到嵌入式产品中运行 编译: gcc 之前编译环境和运行环境是一样的 交叉编译: 编译 把编译代码和运行分开 编译代码在虚拟机中 运行…...
数据结构与算法之递归: LeetCode 46. 全排列 (Typescript版)
全排列 https://leetcode.cn/problems/permutations/ 描述 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,…...
SQL中 JOIN 的两种连接类型:内连接(自然连接、自连接、交叉连接)、外连接(左外连接、右外连接、全外连接)
SQL中 JOIN 的两种连接类型:内连接(自然连接、自连接、交叉连接)、外连接(左外连接、右外连接、全外连接) 1. 自然连接(natural join)(内连接) 学生表 mysql> sele…...
微信小程序记住密码,让登录解放双手
密码是用户最重要的数据,也是系统最需要保护的数据,我们在登录的时候需要用账号密码请求登录接口,如果用户勾选记住密码,那么下一次登录时,我们需要将账号密码回填到输入框,用户可以直接登录系统。我们分别…...
国内划片机行业四大企业之博捷芯:技术驱动,领跑未来
在国内划片机行业中,公司以其卓越的技术实力和持续的创新精神,迅速崭露头角。作为国内划片机行业的四大企业之一,公司以其专业、高品质的划片机设备和解决方案,引领着行业的发展。 公司自创立以来,一直专注于划片机设备…...
后端整合Swagger+Knife4j接口文档
后端整合SwaggerKnife4j接口文档 接口文档介绍 什么是接口文档:写接口信息的文档,条接口包括: 请求参数响应参数 错误码 接口地址接口名称请求类型请求格式备注 为什么需要接口文档 who用?后端提供,前后端都需要使用…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
