時間基、時間戳
時間基:表示時間單位的分數,用來定義視頻或音頻流中時間的精度。其形式是一個分數,分子通常為 1,而分母則表示每秒的單位數。
時間戳:代表在時間軸里占了多少個格子,是特定的時間點。
時間基是時間戳的單位,時間戳值乘以時間基,就可得到實際的時刻值。
typedef struct AVRational{int num; //numeratorint den; //denominator
} AVRational;
FFmpeg 中的幾種時間基
- tbn:視頻流的時間基,time base of stream,AVStream.time_base 的倒數
typedef struct AVStream {.../*** This is the fundamental unit of time (in seconds) in terms* of which frame timestamps are represented.** decoding: set by libavformat* encoding: May be set by the caller before avformat_write_header() to* provide a hint to the muxer about the desired timebase. In* avformat_write_header(), the muxer will overwrite this field* with the timebase that will actually be used for the timestamps* written into the file (which may or may not be related to the* user-provided one, depending on the format).*/AVRational time_base;
}
- tbr:幀率,time base of rate
- tbc:視頻解碼的時間基,time base of codec,AVCodecContext.time_base 的倒數
typedef struct AVCodecContext {
/*** This is the fundamental unit of time (in seconds) in terms* of which frame timestamps are represented. For fixed-fps content,* timebase should be 1/framerate and timestamp increments should be* identically 1.* This often, but not always is the inverse of the frame rate or field rate* for video. 1/time_base is not the average frame rate if the frame rate is not* constant.** Like containers, elementary streams also can store timestamps, 1/time_base* is the unit in which these timestamps are specified.* As example of such codec time base see ISO/IEC 14496-2:2001(E)* vop_time_increment_resolution and fixed_vop_rate* (fixed_vop_rate == 0 implies that it is different from the framerate)** - encoding: MUST be set by user.* - decoding: the use of this field for decoding is deprecated.* Use framerate instead.*/AVRational time_base;
}
- FFmpeg 內部時間基 AV_TIME_BASE
#define AV_TIME_BASE 1000000
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
使用此時間基計算得到的時間值表示的單位是微秒。
時間值的形式轉換
/*** Convert an AVRational to a `double`.* @param a AVRational to convert* @return `a` in floating-point form* @see av_d2q()*/
static inline double av_q2d(AVRational a){return a.num / (double) a.den;
}
將時間從 AVRational 形式轉換為 double 形式。將不同時間基的值轉成按秒為單位的運算如下:
timestamp(秒) = pts * av_q2d(time_base)
時間基轉換函數
/*** Rescale a 64-bit integer by 2 rational numbers.** The operation is mathematically equivalent to `a * bq / cq`.** This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF.** @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd()*/
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;
將時間值從一種時間基轉換為另一種時間基,其計算公式為 a * bq / cq
/*** Rescale a 64-bit integer by 2 rational numbers with specified rounding.** The operation is mathematically equivalent to `a * bq / cq`.** @see av_rescale(), av_rescale_rnd(), av_rescale_q()*/
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,enum AVRounding rnd) av_const;
同 av_rescale_q 相比增加了一個指定舍入方式的參數
/*** Convert valid timing fields (timestamps / durations) in a packet from one* timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be* ignored.** @param pkt packet on which the conversion will be performed* @param tb_src source timebase, in which the timing fields in pkt are* expressed* @param tb_dst destination timebase, to which the timing fields will be* converted*/
void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);
用于將 AVPacket 中各種時間值從一種時間基轉換為另一種時間基