FFMPEG
Chapter 1 Time
1 Definition
-
time_base
#define AV_TIME_BASE 1000000 #define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
AV_TIME_BASE_Q指的是1微秒(1/1000000)。
-
pts & dts
PTS(Presentation Time Stamp) : 显示时间戳
DTS(Decoding Time Stamp) :解码时间戳
-
r_frame_rate
the lowest framerate with which all timestamps can be represented accurately (it is the least common multiple of all framerates in the stream).
-
AVRational
typedef struct AVRational{ int num; ///< Numerator int den; ///< Denominator } AVRational;
-
av_q2d(AVRational )
将一个AVRational变成一个浮点数,可以理解为在这里面做了一次除法。
Parameters:
a AVRational to convert
Return:
a in floating-point form
因为AVRational有两个成员,一个是den分母,一个是num分子,所以实际的计算公式如下
r e s = A V R a t i o n a l . n u m / A V R a t i o n a l . d e n res = AVRational.num / AVRational.den res=AVRational.num/AVRational.den
那为什么要使用一个函数做这件事呢?我的思考是可能存在分母为0的时候,需要进行合法性判断。 -
av_rescale_q(int64_t a, AVRational bq, AVRational cq)
转化时间基,将一种时间基转化为另一种。
2 Usage
可以看一段雷霄骅的代码,该段代码用于为裸流中的包写入pts,dts以及duration。这段代码的地址为ffmpeg推流器。
if(pkt->pts == AV_NOPTS_VALUE){
// Write PTS
AVRational time_base1 = ifmt_ctx->streams[videoIndex]->time_base;
// Duration between two frames
int64_t calc_duration = (double)AV_TIME_BASE/av_q2d(ifmt_ctx->streams[videoIndex]->r_frame_rate);
pkt->pts = (double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
pkt->dts = pkt->pts;
pkt->duration = (double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
}
注:ifmt_ctx为输入文件的AVFormatContext
- 第一行获取ifmt_ctx的stream的时间基。
- 第二行代码计算每帧的时间长度。AV_TIME_BASE相当于1s, 用这个去除以r_frame_rate
- 第三行,给pkt的pts赋值,公式为 当前帧的序号*每帧的时间长度 / 视频的总长度, 可以获取到当前包的pts。
- 第四行只是简单的赋值操作。
- 第五行获取包的时间长度。