FFmpeg 基本数据结构 AVStream分析

1、AVStream 定义

AVStream 是 FFmpeg 中表示单个媒体流(视频、音频、字幕等)的核心数据结构,负责存储流的元数据、时间信息和编解码参数。AVStream 是 FFmpeg 中用于表示媒体文件(容器)中一个独立媒体流的抽象。 一个媒体文件(如 MP4、MKV)通常包含多个流:

  • 一个视频流(Video Stream)
  • 一个或多个音频流(Audio Stream,如不同语言)
  • 可能还有字幕流(Subtitle Stream)、数据流等
    AVStream 就是描述这其中每一个流的信息的载体。它不包含具体的压缩数据(那是 AVPacket 的职责),而是包含流的元数据(Metadata)和配置信息。
    在这里插入图片描述

2、AVStream 具体成员分析

AVStream核心作用:

  1. 流标识:通过 index 和 id 唯一标识媒体流
  2. 参数存储:通过 codecpar 保存编解码参数
  3. 时间管理:通过 time_base 和 duration 维护时间体系
  4. 元数据承载:存储语言、标题等描述信息
  5. 帧率控制:提供真实帧率和平均帧率数据
  6. 事件响应(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数组中。
[图片]

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函数对队列中的数据进行排序,并调整字幕持续时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给大佬递杯卡布奇诺

你们的鼓励就是我传作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值