欢迎诸位来阅读在下的博文~
在这里,在下会不定期发表一些浅薄的知识和经验,望诸位能与在下多多交流,共同努力
文章目录
前期博客
FFmpeg的入门实践系列一(环境搭建)
FFmpeg的入门实践系列二(基础知识)
一、音视频常用术语
-
容器/文件(Container/File):
- 容器是一种文件格式,用于将多种媒体流(如视频、音频、字幕等)组合成一个单一的文件。
- 它定义了如何存储和访问这些媒体流,以及如何处理它们之间的同步和交互。
- 常见的容器格式包括MP4、FLV、MKV等,每种格式都有其特定的用途和优势。
-
媒体流(Stream):
- 媒体流是时间轴上的一段连续数据,可以是音频、视频或字幕等。
- 媒体流可以是压缩的,也可以是非压缩的。压缩的媒体流需要关联特定的编解码器才能进行解压缩和播放。
- 在容器文件中,不同的媒体流可以独立存储,但它们通常需要同步播放。
-
数据帧/数据包(Frame/Packet):
- 数据帧是媒体流的基本单元,对于压缩数据,帧通常对应编解码器的最小处理单元。
- 数据包是网络传输中的概念,它是在网络中传输的分组,可以包含一个或多个数据帧。
- 在容器文件中,不同媒体流的数据帧通常是交错存储的,以支持同步播放。
-
编解码器(Codec):
- 编解码器是一组算法,用于将原始数据(如视频或音频信号)编码成压缩格式,以及将压缩数据解码回原始格式。
- 编解码器通常以帧为单位工作,将每一帧数据转换成压缩格式,或者从压缩格式转换回原始格式。
- 编解码器的效率和质量直接影响到媒体内容的存储大小和播放质量。
-
复用器(Multiplexer)/ 解复用器(Demultiplexer)
在数字媒体处理中,复用器和解复用器是两个关键组件,它们分别负责将多个媒体流组合成一个容器文件,以及将容器文件中的媒体流分离出来。
- 编解码器
二、FFmpeg库的结构介绍
FFmpeg的8个常用库的简要说明:
库名称 | 功能描述 |
---|---|
AVUtil | 核心工具库,提供基本的数据结构和实用函数。其他模块依赖AVUtil进行基本的音视频处理操作。 |
AVFormat | 文件格式和协议库,处理多媒体文件的封装和解封装。封装了协议层、解复用器(Demuxer)和复用器(Muxer)层。 |
AVCodec | 编解码库,处理音视频的编码和解码。支持多种编解码器,包括第三方编解码器如libx264、FDK-AAC等。 |
AVFilter | 音视频滤镜库,提供音视频特效处理。可以直接在编解码过程中使用,方便高效。 |
AVDevice | 输入输出设备库,用于处理音视频的输入输出。比如ffplay播放器就需要这个模块来播放声音和视频。 |
SwrRessample | 音频重采样库,用于音频数据的转换,如声道数、数据格式、采样率等。 |
SWScale | 图像格式转换库,如YUV到RGB的转换,以及图像的缩放。 |
PostProc | 后期处理库,用于视频后期的处理,如去块效应、降噪等。在使用AVFilter时,可能需要打开PostProc模块。 |
三、FFmpeg的常用函数
初始化
- av_register_all() :
- 功能:这个函数用于注册所有的编解码器、复用器、解复用器和协议。在早期的FFmpeg版本中,这是必须调用的,以便使用FFmpeg的编解码功能。
- 弃用:从FFmpeg 4.0开始,这个函数已经被弃用,因为现在FFmpeg会自动注册所有的组件,所以不再需要显式调用这个函数。
- avdevice_register_all() :
- 功能:这个函数用于注册所有的输入和输出设备,比如V4L2(Video4Linux2),它是Linux系统下的一种视频捕获API。
- 使用场景:当你需要从或向硬件设备捕获/输出数据时,应该调用这个函数。
- avformat_network_init() :
- 功能:这个函数用于初始化网络库,包括网络协议和加密协议相关的库,比如OpenSSL。
- 使用场景:如果你打算使用FFmpeg进行网络流处理,比如从一个网络摄像头获取视频流,或者通过网络发送视频流,应该在程序开始时调用这个函数。
封装格式
- avformat_alloc_context() :
- 功能:分配并初始化一个
AVFormatContext
结构体,该结构体用于存储关于媒体文件格式或流的信息。这个函数会分配内存并设置一些默认值。
- 功能:分配并初始化一个
- avformat_free_context() :
- 功能:释放由
avformat_alloc_context()
分配的AVFormatContext
结构体及其包含的所有资源。这包括所有的流、编解码器上下文、缓冲区等。
- 功能:释放由
- avformat_close_input() :
- 功能:关闭解复用器,并释放与
AVFormatContext
相关的所有资源。这个函数应该在完成文件处理后调用,以避免内存泄漏。调用这个函数后,就不需要再调用avformat_free_context()
。
- 功能:关闭解复用器,并释放与
- avformat_open_input() :
- 功能:打开指定的媒体文件,并读取文件头,初始化
AVFormatContext
。这个函数会自动检测文件的格式,并分配必要的资源。
- 功能:打开指定的媒体文件,并读取文件头,初始化
- avformat_find_stream_info() :
- 功能:读取媒体文件或流的信息,并填充
AVFormatContext
中的流信息,如编解码器、时间基、帧率等。这个函数对于获取流信息非常重要。
- 功能:读取媒体文件或流的信息,并填充
- av_read_frame() :
- 功能:从媒体文件中读取一个音视频包(
AVPacket
)。这个函数通常在一个循环中被调用,以逐个读取媒体流中的所有包。
- 功能:从媒体文件中读取一个音视频包(
- avformat_seek_file() :
- 功能:在媒体文件中定位到一个特定的位置。这个函数可以用来进行精确的定位,比如跳转到特定的帧或时间点。
- av_seek_frame() :
- 功能:这个函数已经被
avformat_seek_file()
取代,不建议使用。avformat_seek_file()
提供了更灵活的定位功能。
在使用这些函数时,请注意以下事项:
- 功能:这个函数已经被
- 在打开文件后,确保在处理完成后关闭文件并释放资源。
- 在使用
avformat_find_stream_info()
之前,应该已经调用了avformat_open_input()
。 - 在读取数据之前,确保已经找到了流信息。
- 在定位媒体文件时,要注意时间基和帧率,以确保定位到正确的位置。
编解码器相关
- avcodec_alloc_context3() :
- 功能:分配并初始化一个
AVCodecContext
结构体,该结构体用于存储关于编解码器的信息。这个函数会分配内存并设置一些默认值。
- 功能:分配并初始化一个
- avcodec_find_decoder() :
- 功能:根据编解码器的ID查找解码器。这个ID通常是一个枚举值,如
AV_CODEC_ID_H264
。
- 功能:根据编解码器的ID查找解码器。这个ID通常是一个枚举值,如
- avcodec_find_decoder_by_name() :
- 功能:根据解码器的名称查找解码器。这个函数通常用于当编解码器的ID未知,但你知道其名称时。
- avcodec_open2() :
- 功能:打开一个编解码器。这个函数会初始化
AVCodecContext
,并准备进行编解码操作。
- 功能:打开一个编解码器。这个函数会初始化
- avcodec_decode_video2() :
- 功能:解码一帧视频数据。这个函数已经被新的API
avcodec_send_packet()
和avcodec_receive_frame()
取代,但在某些情况下仍然可以使用。
- 功能:解码一帧视频数据。这个函数已经被新的API
- avcodec_decode_audio4() :
- 功能:解码一帧音频数据。这个函数也是旧的API,新的API是
avcodec_send_packet()
和avcodec_receive_frame()
。
- 功能:解码一帧音频数据。这个函数也是旧的API,新的API是
- avcodec_send_packet() :
- 功能:发送一个编码数据包到解码器。这个函数是新的解码API的一部分,用于将压缩数据传递给解码器。
- avcodec_receive_frame() :
- 功能:接收解码后的数据。这个函数是新的解码API的一部分,用于从解码器获取解码后的帧。
- avcodec_free_context() :
- 功能:释放由
avcodec_alloc_context3()
分配的AVCodecContext
结构体及其包含的所有资源。这个函数会调用avcodec_close()
来关闭解码器。
- 功能:释放由
- avcodec_close() :
- 功能:关闭解码器。这个函数会释放与
AVCodecContext
相关的所有资源,但不包括AVCodecContext
结构体本身。通常,你应该使用avcodec_free_context()
来关闭和解码器上下文。
- 功能:关闭解码器。这个函数会释放与
在使用这些函数时,请注意以下事项:
- 在打开编解码器之前,确保已经分配了
AVCodecContext
。 - 在解码之前,确保已经找到了正确的解码器。
- 在解码过程中,使用
avcodec_send_packet()
和avcodec_receive_frame()
来发送和接收数据。 - 在完成解码后,确保释放
AVCodecContext
和关闭解码器。
四、FFmpeg常用的数据结构
- AVFormatContext :
- 描述:这是一个包含多媒体文件格式信息的上下文结构体。它是一个全局性的结构体,用于存储关于整个媒体文件的信息,包括封装格式、流信息、时间基等。
- 关键属性:
iformat
(输入格式)、oformat
(输出格式)、streams
(流数组)、duration
(时长)等。
- AVInputFormat :
- 描述:每种输入封装格式(如FLV、MKV、MP4、AVI)都有一个对应的
AVInputFormat
结构体。它包含了关于如何读取特定格式文件的信息。 - 关键属性:
name
(格式名称)、long_name
(格式长名称)、extensions
(文件扩展名数组)等。
- 描述:每种输入封装格式(如FLV、MKV、MP4、AVI)都有一个对应的
- AVOutputFormat :
- 描述:与
AVInputFormat
类似,但用于输出。它定义了如何写入特定格式的媒体文件。
- 描述:与
- AVStream :
- 描述:媒体文件中的每个视频或音频流都对应一个
AVStream
结构体。它包含了关于流的编解码器信息、时间基、帧率等。 - 关键属性:
codec
(编解码器上下文)、time_base
(时间基)、r_frame_rate
(帧率)等。
- 描述:媒体文件中的每个视频或音频流都对应一个
- AVCodecContext :
- 描述:这是一个包含编解码器信息的上下文结构体。它用于存储特定视频或音频流的编解码器设置和状态。
- 关键属性:
codec
(编解码器)、width
(视频宽度)、height
(视频高度)、sample_rate
(音频采样率)等。
- AVCodec :
- 描述:每种视频或音频编解码器(如H.264解码器)都有一个对应的
AVCodec
结构体。它包含了关于编解码器的静态信息,如编解码器的名称和ID。 - 关键属性:
name
(编解码器名称)、id
(编解码器ID)等。
- 描述:每种视频或音频编解码器(如H.264解码器)都有一个对应的
- AVPacket :
- 描述:用于存储一帧压缩编码数据。它通常在编解码器之间传递数据包。
- 关键属性:
data
(数据指针)、size
(数据大小)、pts
(显示时间戳)等。
- AVFrame :
- 描述:用于存储一帧解码后的像素(对于视频)或采样(对于音频)数据。它包含了关于帧的宽、高、格式等信息。
- 关键属性:
data
(数据指针数组)、linesize
(行大小数组)、width
(宽度)、height
(高度)等。
至此,结束~
望诸位不忘三连支持一下~