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

参考

  1. ^FFmpeg介绍: https://www.cnblogs.com/renhui/p/6922971.html
  2. ^FFmpeg特点: About FFmpeg
  3. ^FFmpeg特点: https://www.cnblogs.com/sztom/p/11964797.html
  4. ^FFmpeg每日更新文档: Documentation
  5. ^FFmpeg播放视频基本流程: https://www.cnblogs.com/renhui/p/9508123.html
  6. ^封装格式(Container Format)的概念: https://www.cnblogs.com/leisure_chn/p/10506636.html
  7. ^流(Stream)的概念: https://www.cnblogs.com/sztom/p/11964797.html
  8. ^帧(Frame)的概念: https://www.cnblogs.com/sztom/p/11964797.html
  9. ^帧(Frame)的概念: 刻意练习FFmpeg - 知乎
  10. ^编解码(Codec)的概念: https://www.cnblogs.com/samirchen/archive/2017/06/24/7073102.html
  11. ^编解码(Codec)的概念: https://www.cnblogs.com/renhui/p/9293057.html
  12. ^数据包(Packet)的概念: https://www.cnblogs.com/samirchen/archive/2017/06/24/7073102.html
  13. ^数据包(Packet)的概念: FFMPEG中的一些基本概念-CSDN博客
  14. ^最简单的基于FFMPEG的封装格式转换器(无编解码)_mp4remuxer-CSDN博客
  15. ^转码的概念: https://www.cnblogs.com/yongfengnice/p/7133714.html
  16. ^最简单的基于FFMPEG的封装格式转换器(无编解码)_mp4remuxer-CSDN博客
  17. ^转码步骤 https://www.cnblogs.com/yongfengnice/p/7133714.html
  18. ^「文件格式(File Format)」与「封装格式(Container Format)」的区别: https://www.cnblogs.com/leisure_chn/p/10506636.html
  19. ^FFmpeg封装格式处理文件步骤: https://www.cnblogs.com/leisure_chn/p/10506636.html
  20. ^FFmpeg主要封装格式一览表: [总结]视音频编解码技术零基础学习方法-CSDN博客
  21. ^「封装格式(Container Format)」与「编解码格式(Codec Format)」一览表: https://www.cnblogs.com/yongfengnice/p/7133714.html
  22. ^FFmpeg 播放视频基本流程 https://www.cnblogs.com/renhui/p/9508123.html
  23. ^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从入门到实践…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/142593316

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT中的 容器(container)-大全

一、介绍 Qt库提供了一套通用的基于模板的容器类&#xff0c;可以用这些类存储指定类型的项。比如&#xff0c;你需要一个大小可变的QString的数组&#xff0c;则使用QVector<QString>。 这些容器类比STL&#xff08;C标准模板库&#xff09;容器设计得更轻量、更安全并…

光伏电站开发流程

随着人们对可再生能源的关注度不断提高&#xff0c;光伏电站的开发流程也变得越来越重要。光伏电站是一种利用太阳能发电的设施&#xff0c;它可以有效地减少化石能源的消耗&#xff0c;同时也可以为环保事业做出贡献。 首先&#xff0c;要进行光伏电站的开发&#xff0c;需要选…

PWM 正玄波形 通过C语言生成

#include <stdio.h> #include <math.h> #include <stdint.h>#define SAMPLE_POINT_NUM (200) /* 需要生成的点的个数 */ #define SINE_MAX (255) /* sin 函数幅值 */ #define PI (3.14…

pytorch训练模型内存溢出

1、训练模型命令命令 如下所示是训练命名实体识别的命令&#xff0c;在win10系统下执行 activate pytorch cd F:\Python\github\ultralytics-main\submain\pytorch_bert_bilstm_crf_ner-main f: python main.py --bert_dir"../model_hub/chinese-bert-wwm-ext/" --…

TIME_WAIT状态TCP连接导致套接字无法重用实验

理论相关知识可以看一下《TIME_WAIT相关知识》。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<errno.h> #include<syslog.h> #inc…

Echarts legend图例配置项 设置位置 显示隐藏

Echarts 官网完整配置项 https://echarts.apache.org/zh/option.html#legend 配置项 legend: { }设置图例为圆形 icon: circle,//设置图例为圆形设置图例位置 top: 20%//距离顶部百分之20//y:bottom 在底部显示设置图例 宽度 高度 itemWidth: 10,//设置图例宽度 itemHeight: …

每日一练【移动零】

一、题目描述 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 二、题目解析 可以…

Python中调用VisualStudio创建的DLL库

1、创建DLL 打开VisualStudio2022&#xff0c;创建新项目 动态链接库-下一步 设置项目名称、项目位置、创建 单击头文件、添加、新建项 选择.h、设置名称、添加 同样的在源文件新建项&#xff0c;创建 代码&#xff1a; test.h #pragma once#ifdef BUILD_TEST #define API_S…

unity3d NPC自动寻路不移动

烘焙的路面不能有间隔&#xff0c;调整地面重新烘焙

数据结构(超详细讲解!!)第二十五节 树与森林

1.树的存储结构 和线性表一样&#xff0c;树可以用顺序和链式两种存储结构。 树的顺序存储结构适合树中结点比较“满”的情况。根据树的非线性结构特点&#xff0c;常用链式存储方式来表示树。树常用的存储方法有&#xff1a;双亲表示法、孩子表示法和孩子兄弟表…

【Linux进阶之路】进程间通信

文章目录 一、原理二、方式1.管道1.1匿名管道1.1.1通信原理1.1.2接口使用 1.2命名管道 2.共享内存2.1原理2.2接口使用 3.消息队列原理 4.信号量引入原理 总结 一、原理 进程间的通信是什么&#xff1f;解释&#xff1a; 简单理解就是&#xff0c;不同进程之间进行数据的输入输出…

Typora+PicGo+Minio搭建博客图床

文章目录 TyporaPicGoMinio搭建博客图床前言什么是图床?为什么需要图床?准备工作一、Typora二、Picgo1. 下载Picgo2. 下载node.js3. 下载minio插件 三、服务器端配置1. 添加端口到安全组2. 使用Docker安装minio3. 配置minio image-20231127175530696四、minio插件配置五、Typ…

C++ day37 贪心算法 单调递增的数字 监控二叉树

题目1&#xff1a;738 单调递增的数字 题目链接&#xff1a;单调递增的数字 对题目的理解 返回小于或等于n的最大数字&#xff0c;且数字是单调递增&#xff08;单调递增数字的定义&#xff1a;每个相邻位上的数字满足x<y&#xff09; 贪心算法 注意本题的遍历顺序是从…

【带头学C++】----- 八、C++面向对象编程 ---- 8.1 面向对象编程概述

目录 8.1 面向对象编程概述 8.1.1 面向对象概念&#xff08;OOP&#xff09; 8.1.2 面向过程概念 8.2 :: 作用域运算符 8.3 命名空间namespace 8.3.1 C的命名空间 namespace 8.3.2 命名空间 namespace使用语法 1. 创建一个命名空间&#xff1a; 2. 命名空间只能在全局…

WIN10 x86环境部署ARM虚拟机(银河麒麟)

我们经常使用的是x86架构的cpu&#xff0c;而对于不同cpu架构的arm架构的操作系统&#xff0c;我们可以通过QEMU模拟器来进行模拟一个arm环境 1、部署前的准备 arm的镜像&#xff1a; 以此镜像为例&#xff1a;Kylin-Server-10-SP2-aarch64-Release-Build09-20210524.iso QE…

Co-DETR:DETRs与协同混合分配训练论文学习笔记

论文地址&#xff1a;https://arxiv.org/pdf/2211.12860.pdf 代码地址&#xff1a; GitHub - Sense-X/Co-DETR: [ICCV 2023] DETRs with Collaborative Hybrid Assignments Training 摘要 作者提出了一种新的协同混合任务训练方案&#xff0c;即Co-DETR&#xff0c;以从多种标…

人力资源管理后台 === 组织架构

目录 1.组织架构-树组件应用 2.组织架构-树组件自定义结构 3.组织架构-获取组织架构数据 4.组织架构-递归转化树形结构 5.组织架构-添加子部门-新建弹层组件 6.组织架构-添加子部门-表单结构 7.组织架构-添加子部门-表单基本校验 8.组织架构-添加子部门-表单业务校验 9…

什么是计算机病毒?

计算机病毒 1. 定义2. 计算机病毒的特点3. 计算机病毒的常见类型和攻击方式4. 如何防御计算机病毒 1. 定义 计算机病毒是计算机程序编制者在计算机程序中插入的破坏计算机功能或者破坏数据&#xff0c;影响计算机使用并且能够自我复制的一组计算机指令或程序代码。因其特点与生…

Redis面试题:分片集群相关问题

目录 面试官&#xff1a;redis的分片集群有什么作用 面试官&#xff1a;Redis分片集群中数据是怎么存储和读取的&#xff1f; 面试官&#xff1a;redis的分片集群有什么作用 候选人&#xff1a;分片集群主要解决的是&#xff0c;海量数据存储的问题&#xff0c;集群中有多个m…

0004Java程序设计-ssm基于微信小程序的校园第二课堂

文章目录 摘 要目录系统设计开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。…