1、AVStream 定义
AVStream 是 FFmpeg 中表示单个媒体流(视频、音频、字幕等)的核心数据结构,负责存储流的元数据、时间信息和编解码参数。AVStream 是 FFmpeg 中用于表示媒体文件(容器)中一个独立媒体流的抽象。 一个媒体文件(如 MP4、MKV)通常包含多个流:
- 一个视频流(Video Stream)
- 一个或多个音频流(Audio Stream,如不同语言)
- 可能还有字幕流(Subtitle Stream)、数据流等
AVStream 就是描述这其中每一个流的信息的载体。它不包含具体的压缩数据(那是 AVPacket 的职责),而是包含流的元数据(Metadata)和配置信息。

2、AVStream 具体成员分析
AVStream核心作用:
- 流标识:通过 index 和 id 唯一标识媒体流
- 参数存储:通过 codecpar 保存编解码参数
- 时间管理:通过 time_base 和 duration 维护时间体系
- 元数据承载:存储语言、标题等描述信息
- 帧率控制:提供真实帧率和平均帧率数据
- 事件响应(FFmpeg 7+):支持动态参数变更通知
具体定义如下:
typedef struct AVStream {
const AVClass *av_class; // 指向一个表示AVStream结构的AVClass结构的指针
int index; // 流索引
int id; // 流ID
AVCodecParameters *codecpar; // 指向一个AVCodecParameters结构的指针,用于存储编解码器参数
void *priv_data; // 指向私有数据的指针
AVRational time_base; // 时间基准
int64_t start_time; // 开始时间
int64_t duration; // 持续时间
int64_t nb_frames; // 帧数
int disposition; // disposition
enum AVDiscard discard; // 丢弃策略
AVRational sample_aspect_ratio; // 采样比例
AVDictionary *metadata; // 元数据
AVRational avg_frame_rate; // 平均帧率
AVPacket attached_pic; // 附加图片
attribute_deprecated
AVPacketSideData *side_data; // 指向AVPacketSideData结构的指针,用于存储侧数据
attribute_deprecated
int nb_side_data; // 侧数据数量
int event_flags; // 事件标志
AVRational r_frame_rate; // 原始帧率
int pts_wrap_bits; // PTS包装位
} AVStream;
各个成员的含义如下:
- av_class: 一个指向AVClass结构的指针,用于表示AVStream的属性。
- index: 一个整数,用于表示流索引。
- id: 一个整数,用于表示流ID。
- codecpar: 一个指向AVCodecParameters结构的指针,用于存储编解码器参数。
- priv_data: 一个指向私有数据的指针。
- time_base: 一个AVRational结构体,用于表示时间基准。
- start_time: 一个int64_t类型的整数,用于表示开始时间。
- duration: 一个int64_t类型的整数,用于表示持续时间。
- nb_frames: 一个int64_t类型的整数,用于表示帧数。
- disposition: 一个整数,用于表示 disposition。
- discard: 一个枚举类型,用于表示丢弃策略。
- sample_aspect_ratio: 一个AVRational结构体,用于表示采样比例。
- metadata: 一个指向AVDictionary结构的指针,用于表示元数据。
- avg_frame_rate: 一个AVRational结构体,用于表示平均帧率。
- attached_pic: 一个AVPacket结构体,用于表示附加图片。
- side_data: 一个指向AVPacketSideData结构的指针,用于存储侧数据(已弃用)。
- nb_side_data: 一个整数,用于表示侧数据数量(已弃用)。
- event_flags: 一个整数,用于表示事件标志。
- r_frame_rate: 一个AVRational结构体,用于表示原始帧率。
- pts_wrap_bits: 一个整数,用于表示PTS包装位。
解复用的目的就是从容器中分离出来不同的流,ffmpeg中AVStream,它是由解复用器的read_header函数创建的,并保存在AVFormatContext的nb_streams(容器中的流条数)以及stream数组中。
![[图片]](https://i-blog.csdnimg.cn/direct/a82a70c953714871a3516b68c6958473.png)
3、AVStream 创建分析
以ff_srt_demuxer为例,它的read_header指向srt_read_heade函数,该函数主要完成以下功能。
- (1) 调用avformat_new_stream函数创建一条流。
- 调整AVFormatContext->streams的大小。
- 申请流空间并清零。
- 申请AVStream->info空间并清零。
- 申请AVStream->codec(AVCodecContext对象)空间并设置默认值(avcodec_get_context_default3函数设置)。
- 设置流的其余参数默认值。
- 将流的指针放入AVFormatContext->streams数组的末尾。
- (2)设置AVStream->codec->codec_type及AVStream->codec->codec_id分别为AVMEDIA_TYPE_SYBTITLE、AV_CODEC_ID_SUBRIP。
- (3)循环读入每条字幕(ff_subtitles_read_chunk函数),并从中解析出字幕细腻些(PTS、duration以及字幕内容),然后调用ff_subtitiles_queue_insert函数将字幕内容插入队列并返回AVPacket指针(以便插入从字幕中解析出私有数据)。
- (4)读入完成后,调用ff_subtitiles_queue_finalize函数对队列中的数据进行排序,并调整字幕持续时间。
401

被折叠的 条评论
为什么被折叠?



