FFmpeg源码分析: AVStream码流

在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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值