FFmpeg源码分析: AVStream码流

本文详细介绍了FFmpeg中的AVStream结构体,它包含了视频、音频和字幕流的所有信息,如时间基、时长、编解码器参数等。通过AVStream的索引数组,可以进行高效的时间戳定位。文章还展示了ffprobe输出的码流信息,包括不同类型的码流编码器、参数和语言详情,并探讨了AVCodecContext的编解码器参数。此外,重点讨论了time_base时间基的计算和其在转换真实时间中的作用。
摘要由CSDN通过智能技术生成

在AVCodecContext结构体存储有AVStream数组,包含所有视频流、音频流、字幕流的信息。每个码流包含有时间基、时长、索引数组、编解码器参数、dts、元数据。其中,索引数组用于保存每帧数据包offset、size、timestamp、flag,用于seek定位某个时间戳对应的帧。

AVStream结构体如下:

typedef struct AVStream {
	// 数组索引
    int index;
    // stream id
    int id;
    // 私有数据
    void *priv_data;
    // 时间基
    AVRational time_base;
    // 开始时间
    int64_t start_time;
    // 码流时长
    int64_t duration;
    // 帧数
    int64_t nb_frames;
    int disposition; /**< AV_DISPOSITION_* bit field */
    // 选择丢弃哪些packets
    enum AVDiscard discard;
    // 宽高比
    AVRational sample_aspect_ratio;
    // 码流的元数据信息
    AVDictionary *metadata;
    // 平均帧率
    AVRational avg_frame_rate;
    // 封面信息
    AVPacket attached_pic;
    // 附加数据
    AVPacketSideData *side_data;
    int            nb_side_data;

    int event_flags;

    AVRational r_frame_rate;
    // 编解码器参数
    AVCodecParameters *codecpar;

    int pts_wrap_bits;

    int64_t first_dts;
    int64_t cur_dts;
    int64_t last_IP_pts;
    int last_IP_duration;

    int probe_packets;

    int codec_info_nb_frames;

    /* av_read_frame() support */
    enum AVStreamParseType need_parsing;
    struct AVCodecParserContext *parser;
    // 索引数组
    AVIndexEntry *index_entries;
	// 索引数组长度
    int nb_index_entries;
    unsigned int index_entries_allocated_size;

    int stream_identifier;

    AVStreamInternal *internal;
} AVStream;

我们来看下ffprobe打印的码流信息,该mp4文件有5个码流,属于双音轨双字幕。第一个是video,编码器为h264,帧率为23.98fps,分辨率为720x306,像素格式为yuv420p;第二个是audio,编码器为aac,采样率为44100,立体声,语言为印地语;第三个也是audio,参数与第二个相同,除了语言是英语;第四个是subtitle,语言为英语,编码器为mov_text;第五个也是subtitle,参数与第四个相同。具体的码流信息如下:

 

 接下来是调试的实时数据,stream数组信息:

 然后是AVCodecContext的编解码器参数,包括codec_type(媒体类型)、codec_id、bit_rate、profile、level、width、height、sample_rate、channels等。具体参数如下:

 另外,AVStream内部有nb_index_entries(索引数组长度)、index_entries(索引数组)。而索引数组包括:offset、size、timestamp、flags、min_distance。在seek操作时,根据给定时间戳二分查找timestamp数组,seek有三种模式:previous、next、nearest,一般使用previous前向查找。具体信息如下:

 最后,要讨论的是time_base时间基。FFmpeg中的时间戳是用time_base作为单位,位于rational.h的AVRational结构体定义如下:

typedef struct AVRational{
    int num; ///< Numerator
    int den; ///< Denominator
} AVRational;

换算为真实时间,需要使用num分子与den分母相除,公式如下:

static inline double av_q2d(AVRational a){
    return a.num / (double) a.den;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

徐福记456

您的鼓励和肯定是我创作动力

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

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

打赏作者

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

抵扣说明:

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

余额充值