1、time_base的定义:
time_base
的意思是时间刻度
,即给定一个时间,比如1秒
,然后分成25等份
,那么这个时间刻度就是1/25秒
。
2、time_base的结构体
/**
* 分数 (分子与分母的组合).
*/
typedef struct AVRational{
int num; ///< 分子
int den; ///< 分母
} AVRational;
3、time_base的常用转换函数
// 创建一个time_base
static inline AVRational av_make_q(int num, int den)
{
AVRational r = { num, den };
return r;
}
// time_base转换为浮点数
static inline double av_q2d(AVRational a){
return a.num / (double) a.den;
}
// 浮点数转换为time_base
AVRational av_d2q(double d, int max) av_const;
// time_base取反
static av_always_inline AVRational av_inv_q(AVRational q)
{
AVRational r = { q.den, q.num };
return r;
}
4、ffmpeg中常用的时间刻度
ffmpeg内部使用的时间刻度(以微秒为单位)
// 表示为整数的内部使用的时间刻度(1秒=1000000微秒)
#define AV_TIME_BASE 1000000
// 表示为分数的内部使用的时间刻度(以微秒为时间刻度)
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
AVStream使用的时间刻度(以秒为单位)
/**
* 这是表示帧时间戳的基本时间单位(秒)。
*
* 解码:由libavformat设置
* 编码:可以由调用方在avformat_write_header()之前设置,以便向编码器提供有关所需时基的提示。
* 在avformat_write_header()中,编码器将会重新估值,有可能变成更高的精度,如(1, 90000)。
*/
AVRational time_base;
注:AVStream的time_base强制设置为1/10000000,即0.1微秒。
AVCodecContext使用的时间刻度(以秒为单位)
/**
* 这是表示帧时间戳的基本时间单位(秒)。
*
* 对于固定fps的视频帧,时间刻度为帧率取反,时间刻度的增量梯步为1。
* 对非固定fps的视频帧,该时间刻度只表示平均值。
*
* 解码:不建议使用,请使用framerate进行替代。
* 编码:需要用户设置,一般为帧率取反。
*/
AVRational time_base;
二、AVPacket与AVFrame的pts与dts
1、pts与dts的定义
pts是帧显示
的时间戳,dts是帧解码
的时间戳,所以dtstime_base为刻度的显示的时间戳;
* 如果文件中没有定义,那么就是AV_NOPTS_VALUE.
* pts一定是大于等于dts的,因为显示不可能发生在解码之前.
* 在存储到文件中之前,必须以AVStream->time_base为刻度进行正确转换。
*/
int64_t pts;
/**
* 以AVStream->time_base为刻度的解码的时间戳;
* 如果文件中没有定义,那么就是AV_NOPTS_VALUE.
*/
int64_t dts;
PS:编码后
,必须调用av_packet_rescale_ts
进行pts与dts的转换,然后再写入文件。
3、AVFrame相关
/**
* 以AVCodecContext->time_base为时间刻度的显示的时间戳.
*/
int64_t pts;
/**
* 从packet中拷贝来的pts
*/
int64_t pkt_pts;
/**
* 从packet中拷贝来的dts
*/
int64_t pkt_dts;
PS:解码后
,必须调用av_rescale_q
进行pts的转换成以AVCodecContext->time_base为基的正确的显示时间戳。
转自:FFMPEG4.1 - 时间戳相关的pts、dts与time_base_暗黑程序员的博客-CSDN博客