【转】FFmpeg中的时间

FFmpeg中有Video, Audio, Subtitle等各种数据,它们根据自己的特性有不同的时间单位。FFmpeg还有基本的接口,也有自己的时间单位。这里说明了各种时间单位,和各种单位之间的转换。

1. 使用者惯用的时间

使用者习惯用1秒作为时间单位。

2. AV_TIME_BASE

FFmpeg使用AV_TIME_BASE度量时间,它的倒数AV_TIME_BASE_Q是它的时间单位。FFmpeg将AV_TIME_BASE_Q定义为1微秒。

#define  AV_TIME_BASE   1000000
#define  AV_TIME_BASE_Q   (AVRational){1, AV_TIME_BASE}

typedef struct AVRational 
{
    int num; //numerator
    int den; //denominator
} AVRational;

使用AV_TIME_BASE的接口如:

  • AVFormatContext.duration
  • AVStream.duration
  • avformat_seek_file()

3. 帧的pts

有些时间依赖具体的封装格式。

如MP4格式中,有专门的字段规定了pts的度量基础,如:

  • Movie Header Box(mvhd)中的time scale字段
  • Media Header Box(mdhd)中的time scale字段
    都用来规定1秒内的时间单元数,也就是时间单位是1 / time scale。FFmpeg把这个值保存在AVStream.time_base中。

使用av_read_frame()读到帧AVPacket。AVPacket.pts是FFmpeg从MP4文件中读来的,没有转换,所以时间单位是AVStream.time_base。

时间也依赖封装的数据类型。不同数据类型的Stream,它的time_base不同,比如Subtitle stream就与Video stream不同。

4. 时间转换

av_rescale_q ()用于把时间从一种时间单位调整到另外一个时间单位。这个函数的实质是计算(a * bq / cq)。它可以避免溢出的情况。

int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)

如下的例子将帧的pts从MP4文件的时间转换成微秒:

AVPacket* pkt = ...;
AVStream* st = ...;
pkt->pts = av_rescale_q (pkt->pts, st->time_base, AV_TIME_BASE_Q);

参考资料

ffmpeg中的时间
https://www.cnblogs.com/yinxiangpei/articles/3892982.html

mp4文件格式解析
https://www.cnblogs.com/ranson7zop/p/7889272.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容