3.0 数据结构
| 数据结构 | 用途 |
|---|---|
| AVIOContext | 自定义读取文件 |
| AVFormatContext | 封装格式上下文,记录打开一个封装音频的所有信息 |
| AVInputFormat | 解封装格式信息 |
| AVoutputFormat | 封装格式信息 |
| AVStream | 标识视频/音频流 |
| AVCodecContext | 编码器格式上下文 |
| AVCodec | 编码器信息 |
| AVSampleFormat | 枚举类型,包含编码器所支持的所有的音频采样格式 |
| AVPacket | 压缩数据包(AAC/AVC) |
| AVFrame | 原始数据包(PCM/YUV) |
| AVCodecParameters | |
| AVBSFContext | 比特率过滤器上下文 |
| AVBitStreamFilter | 比特流过滤器,用于从MP4中分离H264文件 |
| AVRational | 分数形式,常用 time_base、sample_rate等属性的表示 |
3.1 AVFormatContext
AVFormatContext 和 AVPacket 是 FFmpeg 中用于处理音视频数据的两个关键结构体。
-
AVFormatContext:
AVFormatContext主要用于存储整个音视频文件的格式相关信息,包括文件的封装格式、音视频流的详细信息、文件的全局元数据等。其主要字段包括:streams: 一个指针数组,包含了文件中每个音视频流的信息,每个元素是一个AVStream结构体。nb_streams: 表示流的个数。duration: 表示文件的总时长。metadata: 包含文件的全局元数据,如标题、作者等信息。
通过
AVFormatContext,你可以访问和操作文件级别的信息,例如确定文件中有多少个音视频流、获取文件的时长等。 -
AVPacket:
AVPacket用于存储编解码器产生的压缩后的音视频数据(帧)。 通过AVPacket,你可以访问和操作音视频数据的压缩包,其中包括数据本身以及与播放顺序和时间轴相关的时间戳信息。
总的来说,AVFormatContext 存储了整个文件的格式和元数据信息,而 AVPacket 存储了压缩后的音视频数据以及与时间相关的信息。这两个结构体在 FFmpeg 中一起协同工作,用于解析和处理音视频文件。
3.1.1 内置属性
保存一个完整封装的音频(MP4,FLV),将其压缩的音频流和视频流分开
| 属性 | 解释 |
|---|---|
nb_streans | 流个数 |
streams | 遍历循环AVStreams[]数组,得到准确的视频流/音频流的index |
duration | 微秒,除以100w变为秒,duration / AV_TIME_BASE |
url | 媒体路径 |
bit_rate | 码率 |
metadata | 包含文件的全局元数据,如标题、作者等信息 |
AVIOContext *pb | 用于存放通过IO打开文件的上下文信息 |
AVInputFormat *iformat | demuxing only |
AVOutputFormat *oformat | muxing only,包含封装时所需要的信息 |
typedef struct AVFormatContext {
const AVClass *av_class; // 类型信息
struct AVInputFormat *iformat; // 输入格式
struct AVOutputFormat *oformat; // 输出格式
void *priv_data; // 私有数据
AVIOContext *pb; // I/O 上下文
int ctx_flags; // 上下文标志
unsigned int nb_streams; // 流的数量
AVStream **streams; // 流数组
char filename[1024]; // 文件名或流的 URL
int64_t start_time; // 媒体流的起始时间
int64_t duration; // 媒体流的总时长
int bit_rate; // 比特率
unsigned int packet_size; // 数据包的大小
int max_delay; // 最大延迟
int flags; // 标志
int probesize; // 探测大小
int max_analyze_duration; // 最大分析时长
const uint8_t *key; // 解密密钥
int keylen; // 解密密钥长度
unsigned int nb_programs; // 节目数量
AVProgram **programs; // 节目数组
int video_codec_id; // 视频编解码器 ID
int audio_codec_id; // 音频编解码器 ID
int subtitle_codec_id; // 字幕编解码器 ID
int max_index_size; // 最大索引大小
int max_picture_buffer; // 最大图片缓冲
int nb_chapters; // 章节数量
AVChapter **chapters; // 章节数组
AVDictionary *metadata; // 元数据
int64_t start_time_realtime; // 实际起始时间
int fps_probe_size; // 探测帧率的大小
int error_recognition; // 错误识别
AVIOInterruptCB interrupt_callback; // 中断回调
int debug; // 调试信息
int64_t max_interleave_delta; // 最大交叉差值
int strict_std_compliance; // 严格标准兼容性
int event_flags; // 事件标志
int max_ts_probe; // 最大时间戳探测
int avoid_negative_ts; // 避免负时间戳
int ts_id; // 时间戳 ID
int audio_preload; // 音频预加载
int max_chunk_duration; // 最大块时长
int max_chunk_size; // 最大块大小
int use_wallclock_as_timestamps; // 使用壁钟作为时间戳
int avio_flags; // I/O 标志
int duration_estimation_method; // 时长估算方法
int skip_initial_bytes; // 跳过初始字节
int correct_ts_overflow; // 修正时间戳溢出
int seek2any; // 允许在任何地方定位
int flush_packets; // 刷新数据包
int probe_score; // 探测分数
int format_probesize; // 格式探测大小
AVCodecParameters *audio_codecpar; // 音频编解码器参数
AVCodecParameters *video_codecpar; // 视频编解码器参数
AVCodecParameters *subtitle_codecpar; // 字幕编解码器参数
AVFormatInternal *internal; // 内部数据结构
int io_repositioned; // I/O 重定位
AVCodec *video_codec; // 视频编解码器
AVCodec *audio_codec; // 音频编解码器
AVCodec *subtitle_codec; // 字幕编解码器
AVCodec *data_codec; // 数据编解码器
AVOpenCallback open_cb; // 打开回调
AVReadHeaderCallback read_header; // 读取头部回调
AVReadPacketCallback read_packet; // 读取数据包回调
AVReadCloseCallback read_close; // 读取关闭回调
AVReadPauseCallback read_pause; // 读取暂停回调
AVReadPlayCallback read_play; // 读取播放回调
AVSeekCallback seek2; // 定位回调
AVWriteHeaderCallback write_header; // 写入头部回调
AVWritePacketCallback write_packet; // 写入数据包回调
AVWriteTrailerCallback write_trailer; // 写入尾部回调
int64_t pb_pos; // I/O 位置
int64_t pb_duration; // I/O 时长
AVPacketList *packet_buffer; // 数据包缓冲
AVPacketList *packet_buffer_end; // 数据包缓冲尾部
int64_t data_offset; // 数据偏移
int raw_packet_buffer_size; // 原始数据包缓冲大小
AVPacketList *raw_packet_buffer; // 原始数据包缓冲
AVPacketList *raw_packet_buffer_end; // 原始数据包缓冲尾部
AVPacketList *parse_queue; // 解析队列
AVPacketList *parse_queue_end; // 解析队列尾部
int raw_packet_buffer_remaining_size; // 原始数据包缓冲剩余大小
AVIndexEntry *index_entries; // 索引条目
int nb_index_entries; // 索引条目数量
unsigned int index_entries_allocated_size; // 分配的索引条目大小
int init_range; // 初始化范围
int update_initial_durations_done; // 更新初始时长标志
int fps_probe_failed; // 帧率探测失败标志
int64_t fps_probe_size; // 帧率探测大小
int64_t fps_probe_count; // 帧率探测数量
int64_t last_duration; // 上一个时长
int64_t last_dts; // 上一个 DTS
int probe_packets; // 探测数据包
int codec_whitelist_depth; // 编解码器白名单深度
AVPacket *flush_packets; // 刷新数据包
AVPacket *flush_packets_end; // 刷新数据包尾部
int64_t first_dts; // 第一个 DTS
int probesize2; // 第二探测大小
int max_analyze_duration2; // 第二最大分析时长
const char *protocol_whitelist; // 协议白名单
int io_flags; // I/O 标志
int event_flags; // 事件标志
int max_ts_probe2; // 第二最大时间戳探测
int max_size; // 最大大小
int use_wallclock_as_timestamps; // 使用壁钟作为时间戳
int avio_flags; // I/O 标志
int duration_estimation_method; // 时长估算方法
int skip_initial_bytes; // 跳过初始字节
int correct_ts_overflow; // 修正时间戳溢出
int seek2any; // 允许在任何地方定位
int flush_packets; // 刷新数据包
int probe_score; // 探测分数
int format_probesize; // 格式探测大小
AVCodecParameters *audio_codecpar; // 音频编解码器参数
AVCodecParameters *video_codecpar; // 视频编解码器参数
AVCodecParameters *subtitle_codecpar; // 字幕编解码器参数
AVFormatInternal *internal; // 内部数据结构
int io_repositioned; // I/O 重定位
AVCodec *video_codec; // 视频编解码器
AVCodec *audio_codec; // 音频编解码器
AVCodec *subtitle_codec; // 字幕编解码器
AVCodec *data_codec; // 数据编解码器
AVOpenCallback open_cb; // 打开回调
AVReadHeaderCallback read_header; // 读取头部回调
AVReadPacketCallback read_packet; // 读取数据包回调
AVReadCloseCallback read_close; // 读取关闭回调
AVReadPauseCallback read_pause; // 读取暂停回调
AVReadPlayCallback read_play; // 读取播放回调
AVSeekCallback seek2; // 定位回调
AVWriteHeaderCallback write_header; // 写入头部回调
AVWritePacketCallback write_packet; // 写入数据包回调
AVWriteTrailerCallback write_trailer; // 写入尾部回调
int64_t pb_pos; // I/O 位置
int64_t pb_duration; // I/O 时长
AVPacketList *packet_buffer; // 数据包缓冲
AVPacketList *packet_buffer_end; // 数据包缓冲尾部
int64_t data_offset; // 数据偏移
int raw_packet_buffer_size; // 原始数据包缓冲大小
AVPacketList *raw_packet_buffer; // 原始数据包缓冲
AVPacketList *raw_packet_buffer_end; // 原始数据包缓冲尾部
AVPacketList *parse_queue; // 解析队列
AVPacketList *parse_queue_end; // 解析队列尾部
int raw_packet_buffer_remaining_size; // 原始数据包缓冲剩余大小
AVIndexEntry *index_entries; // 索引条目
int nb_index_entries; // 索引条目数量
unsigned int index_entries_allocated_size; // 分配的索引条目大小
int init_range; // 初始化范围
int update_initial_durations_done; // 更新初始时长标志
int fps_probe_failed; // 帧率探测失败标志
int64_t fps_probe_size; // 帧率探测大小
int64_t fps_probe_count; // 帧率探测数量
int64_t last_duration; // 上一个时长
int64_t last_dts; // 上一个 DTS
int probe_packets; // 探测数据包
int codec_whitelist_depth; // 编解码器白名单深度
AVPacket *flush_packets; // 刷新数据包
AVPacket *flush_packets_end; // 刷新数据包尾部
int64_t first_dts; // 第一个 DTS
int probesize2; // 第二探测大小
int max_analyze_duration2; // 第二最大分析时长
const char *protocol_whitelist; // 协议白名单
int io_flags; // I/O 标志
int event_flags; // 事件标志
int max_ts_probe2; // 第二最大时间戳探测
int max_size; // 最大大小
} AVFormatContext;
3.1.2 接口函数
// 打开本地/网络视频文件
int avformat_open_input(AVFormatContext **ps,
const char *url,
ff_const59 AVInputFormat *fmt,
AVDictionary **options);
// ps:格式上下文呢
// url:本地/网络 视频路径
// fmt:NULL
// options:NULL
int ret = avformat_open_input(&ifmt_ctx, in_filename, NULL, NULL);
// 读取音/视频流信息到packet
// 通过packet的stream_id 判断是音/视频
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
AVPacket *pkt = av_packet_alloc();
ret = av_read_frame(ifmt_ctx, pkt);
// 查找音视频流的id
audio_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
// 或者遍历streams[]查询