FFMPEG-CH1-Time

FFMPEG

Chapter 1 Time

1 Definition

1.time_base

#define AV_TIME_BASE 1000000
#define AV_TIME_BASE_Q          (AVRational){1, AV_TIME_BASE}
AV_TIME_BASE_Q指的是1微秒(1/1000000)。

2.pts & dts

PTS(Presentation Time Stamp) : 显示时间戳

DTS(Decoding Time Stamp) :解码时间戳

注意这里的显示时间并不是现实世界里的时间,不是秒、分之类的,而是ffmpeg中的时间刻度。将在下面的例子中有详细的讲解。

3.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).

在所有时间戳都能够精确显示的最小时间。

4.AVRational

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

5.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的时候,需要进行合法性判断。

6.av_rescale_q(int64_t a, AVRational bq, AVRational cq)
转化时间基,将一种时间基转化为另一种。

7.tbr,tbn,tbc

tbr: 帧率
tbn: 文件层的时间精度
tbc: 视频层的时间精度

8.av_packet_rescale_ts()


void av_packet_rescale_ts(AVPacket * pkt,AVRational tb_src, AVRational 	tb_dst )	

将包的时间基转化为另一种。

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

在进行代码分析之前首先要知道,
av_q2d(time_base)为每个时间刻度是多少秒,pts指的是第几个时间刻度。那么pts*av_q2d(time_base)就是实际显示时间戳。

  1. 第一行获取ifmt_ctx的stream的时间基。
  2. 第二行代码计算每帧多少秒。其中AV_TIME_BASE为1秒,而av_q2d对r_frame_rate计算的结果是,每个时间刻度的帧数,该帧数通常为25帧,30帧。因而用AV_TIME_BASE除以该数,可以得到每帧多少秒。
  3. 第三行,给pkt的pts赋值。其实这里的思路很简单,现在你知道每帧耗时多少秒,那么如果想获得pts是不是首先要获取每帧耗时*现在帧的序号。但是pts的定义是什么,pts决定了该视频帧什么时候显示。这个时刻并不是现在的秒或者具体时间,而是时间刻度。所以需要除以每个时间刻度多少秒。这样该式子就是,每帧所需时间数(单位为秒)/ (1个时间刻度等于的秒数)。举个更具体的例子就是,假设第二步,1帧为1/30秒,现在在ffmpeg中,1个时间刻度是10秒,那么该帧就是1/300的时间刻度。
  4. 第四行只是简单的赋值操作。
  5. 第五行获取包的时间长度。这个同理3,如果3能够理解,这个也没什么问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值