ffmpeg编解码器相关函数
文章目录
- 🎯 你需要理解的核心结构体:
- 📦 常用函数及使用顺序(以解码为例)
- 1️⃣ `avcodec_find_decoder()` / `avcodec_find_encoder()`
- 2️⃣ `avcodec_alloc_context3()`
- 3️⃣ `avcodec_parameters_to_context()`
- 4️⃣ `avcodec_open2()`
- 5️⃣ `avcodec_send_packet()`(解码)
- 6️⃣ `avcodec_receive_frame()`(解码)
- 🔁 对于编码流程:
- 🧹 最后清理函数
- ✅ 编解码核心流程总结(解码):
- 1. **AVFormatContext**
- 2. **AVInputFormat**
- 3. **AVStream**
- 4. **AVCodecContext**
- 5. **AVCodec**
- 6. **AVPacket**
- 7. **AVFrame**
- 典型工作流程
🎯 你需要理解的核心结构体:
结构体名 | 作用 |
---|---|
AVCodec | 表示一个具体的编解码器(如 H264 解码器) |
AVCodecContext | 编解码器上下文,保存编解码过程中的状态和参数 |
AVCodecParameters | 存储编码参数,来自媒体容器(需要转换为 AVCodecContext) |
AVPacket | 表示压缩的数据包(来自媒体文件或编码后) |
AVFrame | 表示解码后的原始帧(音频/视频) |
📦 常用函数及使用顺序(以解码为例)
1️⃣ avcodec_find_decoder()
/ avcodec_find_encoder()
查找指定类型的编解码器(如 H264 解码器)
const AVCodec *codec = avcodec_find_decoder(codec_id);
codec_id
:如AV_CODEC_ID_H264
,AV_CODEC_ID_AAC
等- 返回
AVCodec*
,如果找不到返回NULL
2️⃣ avcodec_alloc_context3()
创建并初始化一个
AVCodecContext
,用于后续打开编解码器。
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
3️⃣ avcodec_parameters_to_context()
将
AVFormatContext
中的AVCodecParameters
拷贝到AVCodecContext
。
avcodec_parameters_to_context(codec_ctx, codecpar);
codecpar
来自AVFormatContext->streams[i]->codecpar
4️⃣ avcodec_open2()
打开编解码器,准备进行解码或编码。
avcodec_open2(codec_ctx, codec, NULL);
5️⃣ avcodec_send_packet()
(解码)
发送压缩包(如视频数据包)给解码器处理。
avcodec_send_packet(codec_ctx, &pkt);
- 解码器内部有缓存,你可能需要多次调用
receive_frame
6️⃣ avcodec_receive_frame()
(解码)
从解码器中取出解码好的帧。
ret = avcodec_receive_frame(codec_ctx, frame);
- 当返回
AVERROR(EAGAIN)
,表示还需要更多数据才能解出新帧 AVFrame
结构保存了解码后的一帧音视频数据(如 YUV 图像或 PCM 音频)
🔁 对于编码流程:
- 创建
AVFrame
(填充原始音视频数据) - 调用
avcodec_send_frame()
送帧进去 - 调用
avcodec_receive_packet()
取出压缩后的AVPacket
🧹 最后清理函数
avcodec_free_context(&codec_ctx);
av_frame_free(&frame);
av_packet_unref(&packet);
(或av_packet_free()
)
✅ 编解码核心流程总结(解码):
// 1. 找到解码器
const AVCodec *codec = avcodec_find_decoder(codec_id);// 2. 分配上下文
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);// 3. 从 AVCodecParameters 拷贝参数
avcodec_parameters_to_context(codec_ctx, codecpar);// 4. 打开解码器
avcodec_open2(codec_ctx, codec, NULL);// 5. 循环解码
while (av_read_frame(fmt_ctx, &pkt) >= 0) {if (pkt.stream_index == video_stream_index) {avcodec_send_packet(codec_ctx, &pkt);while (avcodec_receive_frame(codec_ctx, frame) == 0) {// 处理解码后的 frame,比如显示或保存}}av_packet_unref(&pkt);
}// 6. 清理资源
avcodec_free_context(&codec_ctx);
在 FFmpeg 中,处理音视频数据的各个组件是基于不同的结构体来管理的。这里我会简要讲解一下与音视频解复用、编码解码相关的结构体,重点关注 AVFormatContext
、AVInputFormat
、AVStream
、AVCodecContext
、AVCodec
、AVPacket
和 AVFrame
等。
1. AVFormatContext
AVFormatContext
是 FFmpeg 中的核心结构体之一,它表示多媒体文件的封装格式上下文。它用于管理和存储整个媒体文件的各种信息,如文件格式、流信息、解复用器等。它是解码过程中最为关键的结构体之一。
-
字段简介:
format_name
:媒体文件的格式名称(例如 MP4、AVI)。pb
:指向输入流的指针,用于读取数据。streams
:指向AVStream
结构体的数组,表示文件中的每一个流(视频流、音频流等)。flags
:文件格式的标志。nb_streams
:流的数量。
AVFormatContext
用于存储和管理与文件格式相关的上下文信息。每当你打开一个文件(通过avformat_open_input
函数),都会创建一个AVFormatContext
。
2. AVInputFormat
AVInputFormat
是一个输入格式的抽象层,它定义了如何解复用一个媒体文件的格式。每个格式(如 MP4、AVI、MKV)都对应一个 AVInputFormat
。
-
功能:
- 用于定义如何打开、读取和解码媒体文件(即数据流的读取和分割方式)。
- 它包含一组回调函数,如
read_header
(读取文件头)、read_packet
(读取数据包)、close
(关闭文件)。
AVInputFormat
是 FFmpeg 在解复用过程中使用的一个接口,用于解析不同的文件格式。
3. AVStream
AVStream
表示媒体流(如视频流或音频流),它通常是 AVFormatContext
结构体中的一个成员。每个 AVStream
描述了一个流的所有信息,例如编码参数、流类型等。
-
字段简介:
codecpar
:指向AVCodecParameters
的指针,包含了流的编解码参数。codec
:指向AVCodecContext
的指针,存储该流的解码上下文。time_base
:时间基准,用于表示时间戳(即时间单位)。
每个媒体文件可能包含多个流,如视频流、音频流、字幕流等,
AVStream
就是用来存储这些流的信息。
4. AVCodecContext
AVCodecContext
是解码和编码的上下文,它包含了与特定解码器或编码器相关的所有信息。每个流(如视频流、音频流)通常都会有一个对应的 AVCodecContext
。
-
字段简介:
codec
:指向AVCodec
的指针,表示该流的解码器或编码器。width
、height
:视频流的分辨率(仅对视频流有效)。sample_rate
:音频流的采样率。bit_rate
:音视频流的比特率。
AVCodecContext
是配置编解码器时的关键结构体,包含了用于解码或编码的参数和信息。
5. AVCodec
AVCodec
是一个解码器或编码器的实现结构体。FFmpeg 支持大量的视频和音频编码格式,每种编码格式都对应一个 AVCodec
实现。
-
字段简介:
name
:解码器或编码器的名称(例如 H.264、AAC)。id
:该解码器或编码器的唯一标识符。type
:解码器或编码器的类型(音频、视频、字幕等)。
AVCodec
是实现具体编解码操作的核心,它提供了操作数据流的接口,如decode
和encode
函数。
6. AVPacket
AVPacket
是一个数据包,它表示了经过解复用后的数据。解复用器将文件中的媒体流拆分成多个数据包,编码器或解码器将这些数据包传递给编解码器进行解码或编码。
-
字段简介:
data
:指向数据的指针,存储音视频数据。size
:数据的大小(字节数)。pts
、dts
:时间戳,表示数据的呈现时间和解码时间。
AVPacket
是传递音视频数据的核心结构,通常在解码或编码时作为数据传输的载体。
7. AVFrame
AVFrame
是解码后的帧数据结构,它存储了音视频解码后的数据(例如视频帧或音频样本)。
-
字段简介:
data
:指向音视频帧数据的指针。linesize
:每行数据的大小,用于视频数据。width
、height
:视频帧的分辨率。nb_samples
:音频帧的样本数量。
AVFrame
是音视频数据处理的主要结构体,解码后的视频帧或音频样本通常存储在此结构体中。
典型工作流程
- 打开文件:使用
avformat_open_input
打开媒体文件,获取AVFormatContext
。 - 读取头部信息:通过
avformat_find_stream_info
获取流的信息。 - 查找解码器:根据流类型(视频流或音频流),使用
avcodec_find_decoder
查找相应的解码器。 - 打开解码器:使用
avcodec_open2
打开解码器,获得AVCodecContext
。 - 解码数据:通过
av_read_frame
读取每个数据包(AVPacket
),然后通过avcodec_receive_frame
解码并存储到AVFrame
。 - 处理解码后的数据:解码后的数据可以用于播放或其他操作。
这些结构体和相关的 API 是 FFmpeg 进行音视频处理的核心部分。希望这些解释能帮助你更好地理解 FFmpeg 的基本流程和相关结构体。