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) :解码时间戳

  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)

    转化时间基,将一种时间基转化为另一种。

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

  1. 第一行获取ifmt_ctx的stream的时间基。
  2. 第二行代码计算每帧的时间长度。AV_TIME_BASE相当于1s, 用这个去除以r_frame_rate
  3. 第三行,给pkt的pts赋值,公式为 当前帧的序号*每帧的时间长度 / 视频的总长度, 可以获取到当前包的pts。
  4. 第四行只是简单的赋值操作。
  5. 第五行获取包的时间长度。
上一篇:Linux Sendos7.+安装coturn


下一篇:作为一个有点小洁癖的程序员,不允许给我扣上抄袭的帽子