FFmpeg介绍

news2024/11/24 16:05:18

官方网站: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.coloradmin.cn/o/1265558.html

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

相关文章

《微信小程序开发从入门到实战》学习三十五

4.2 云开发JSON数据库 4.2.3 权限控制 在云开发控制台可以对数据库中的数据进行操作, 在小程序端和云函数可以分别使用小程序API和服务端API对数据中的数据进行操作。 以上操作受到权限控制。 对数据库进行查询属于读操作,增删改操作属于写操作。 …

Python自动化办公:PDF文件的加密与解密

在本篇文章中,我们将介绍如何使用PyPDF2库对PDF文件进行加密和解密操作。 包括如何给PDF文件添加密码,以及如何从受密码保护的PDF文件中删除密码。 注:删除密码的操作,前提是需要知道密码哦 1. 安装PyPDF2库 首先,…

【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核任务中断)、与硬件的关系实现

文章目录 一、为什么要学习μC/OS-III二、嵌入式操作系统的发展历史三、实时操作系统的特点四、基本概念1. 前后台系统2. 操作系统3. 实时操作系统(RTOS)4. 内核5. 任务6. 任务优先级7. 任务切换8. 调度9. 非抢占式(合作式)内核10…

el-table,列表合并,根据名称列名称相同的品名将其它列值相同的进行合并

el-table,列表合并,根据名称列名称相同的品名讲其它列值相同的进行合并,并且不能垮品名合并 如图 用到el-table合并行的方法合并 tableSpanMethod({ row, column, rowIndex, columnIndex }) {if (column.property "materielName") {//合并商品名const _row this…

CI/CD 构建中能保护好 SSHKEY吗?

目录 背景 方案 编码存储 逐行存储 合并存储 打马赛克 结论 背景 使用极狐GitLab CI/CD,在部署方面,主要有两种方式: 部署到K8S集群 Push模式:流水线通过kubectl执行命令部署,这需要把K8S的权限给流水线&#xf…

【python程序】把小于10的数值都变成1

【python程序】把小于10的数值都变成1 import numpy as np import xarray as xra xr.DataArray(np.arange(25).reshape(5, 5)) a[np.where(a < 10)] 1 print(a)

微信小程序+中草药分类+爬虫+torch

1 介绍 本项目提供中草药数据集&#xff0c;使用gpu、cpu版本的torch版本进行训练&#xff0c;将模型部署到后端flask&#xff0c;最后使用微信小程序进行展示出来。 数据爬虫可以参考&#xff1a;http://t.csdnimg.cn/7Olus 项目中的爬虫代码&#xff0c;并且本项目提供相同的…

拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!

拆解 外观和配色个人感觉还行,比较青春 拉开拉链&#xff0c;拆开外面的布面&#xff0c;里面还有一层纱面 按键部分使用魔术贴固定 拆开纱面后&#xff0c;看到里面的结构&#xff0c;整体是一个海绵 可以看到如下&#xff0c;电池&#xff0c;按键板&#xff0c;充电线的三条…

匿名内部类(内部类) - Java

匿名内部类 1、理解2、语法3、使用&#xff08;1&#xff09;基于接口的内部类&#xff08;2&#xff09;基于类的内部类&#xff08;3&#xff09;基于抽象类的匿名内部类 4、细节&注意事项5、最佳应用场景&#xff08;1&#xff09;当作实参直接传递&#xff0c;简洁高效…

Alibaba Java诊断工具Arthas查看Dubbo动态代理类

原创/朱季谦 阅读Dubbo源码过程中&#xff0c;会发现&#xff0c;Dubbo消费端在做远程调用时&#xff0c;默认通过 Javassist 框架为服务接口生成动态代理类&#xff0c;调用javassist框架下的JavassistProxyFactory类的getProxy(Invoker invoker, Class<?>[] interfac…

GO 集成Prometheus

一、Prometheus介绍 Prometheus&#xff08;普罗米修斯&#xff09;是一套开源的监控&报警&时间序列数据库的组合&#xff0c;起始是由SoundCloud公司开发的。随着发展&#xff0c;越来越多公司和组织接受采用Prometheus&#xff0c;社会也十分活跃&#xff0c;他们便…

GAN:GAN论文学习

论文&#xff1a;https://arxiv.org/pdf/1406.2661.pdf 发表&#xff1a;2014 一、GAN简介&#xff1a;Generative Adversarial Network GAN是由Ian Goodfellow于2014年提出&#xff0c;GAN&#xff1a;全名叫做生成对抗网络。GAN的目的就是无中生有&#xff0c;以假乱真。 …

day64 django中间件的复习使用

django中间件 django中间件是django的门户 1.请求来的时候需要先经过中间件才能达到真正的django后端 2.响应走的时候也需要经过中间件 ​ djangp自带七个中间件MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddle…

java开发需要掌握的maven相关知识和Junit单元测试

maven简介 什么是maven&#xff1a; maven是一款管理和构建java项目的工具&#xff0c;是apache旗下的一个开源项目。 maven的作用&#xff1a; 依赖管理&#xff1a; 方便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;。 项目构建&#xff1a; 标准化的跨平台&#…

MacBook如何远程控制华为手机?

将手机屏幕投影到电脑上可以提供更大的屏幕空间&#xff0c;方便观看电影、浏览照片、阅读文档等。然而&#xff0c;除了想将手机投屏到电脑&#xff0c;还想要在电脑上直接操作手机&#xff0c;有方法可以实现吗&#xff1f; 现在使用AirDroid Cast的远程控制手机功能就可以实…

【数据结构】树与二叉树(廿五):树搜索给定结点的父亲(算法FindFather)

文章目录 5.3.1 树的存储结构5. 左儿子右兄弟链接结构 5.3.2 获取结点的算法1. 获取大儿子、大兄弟结点2. 搜索给定结点的父亲a. 算法FindFatherb. 算法解析c. 代码实现 3. 代码整合 5.3.1 树的存储结构 5. 左儿子右兄弟链接结构 【数据结构】树与二叉树&#xff08;十九&…

Linux dig指令的十三种用法

文章目录 dig指令有哪些作用dig 具体用法推荐阅读 dig指令有哪些作用 DIG命令(Domain Information Groper命令)是一个网络工具&#xff0c;具有基本的命令行接口&#xff0c;用于进行不同的DNS(域名系统)查询。您可以使用DIG命令: 诊断您的域名服务器。检查所有这些服务器或每…

《数据结构与测绘程序设计》试题详细解析(仅供参考)

一. 选择题&#xff08;每空2分&#xff0c;本题共30分&#xff09; &#xff08;1&#xff09;在一个单链表中&#xff0c;已知q所指结点是p所指结点的前驱结点&#xff0c;若在q和p之间插入结点s&#xff0c;则执行( B )。 A. s->nextp->next; p->nexts; …

Qt路径和Anaconda中QT路径冲突(ubuntu系统)

最近做一个项目需要配置QT库&#xff0c;本项目配置环境如下&#xff1a; Qt version 5 Operating system, version and so on ubuntu 20.04 Description 之前使用过anaconda环境安装过QT5&#xff0c;所以在项目中CMakeLists文件中使用find_package时候&#xff0c;默认使用An…

C#,数值计算——插值和外推,径向基函数插值(RBF_inversemultiquadric)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class RBF_inversemultiquadric : RBF_fn { private double r02 { get; set; } public RBF_inversemultiquadric(double scale 1.0) { this.r02 Globals.SQR(scale); …