本來是想寫一篇time_base的詳細(xì)文章,后來發(fā)現(xiàn)很多大神寫過,那這里我就總結(jié)一下各種time_base,方便大家理解。
一、time_base
AVStream的time_base的單位是秒。每種格式的time_base的值不一樣,根據(jù)采樣來計(jì)算,比如mpeg的pts、dts都是以90kHz來采樣的,所以采樣間隔就是1/900000秒。AVCodecContext的time_base單位同樣為秒,不過精度沒有AVStream->time_base高,大小為1/framerate。AVPacket下的pts和dts以AVStream->time_base為單位(數(shù)值比較大),時(shí)間間隔就是AVStream->time_base。AVFrame里面的pkt_pts和pkt_dts是拷貝自AVPacket,同樣以AVStream->time_base為單位;而pts是為輸出(顯示)準(zhǔn)備的,以AVCodecContex->time_base為單位。輸入流
InputStream下的pts和dts以AV_TIME_BASE為單位(微秒),至于為什么要轉(zhuǎn)化為微秒,可能是為了避免使用浮點(diǎn)數(shù)。輸出流
OutputStream涉及音視頻同步,結(jié)構(gòu)和InputStream不同,暫時(shí)只作記錄,不分析。
二、各個(gè)time_base之前的轉(zhuǎn)換
ffmpeg提供av_rescale_q函數(shù)用于time_base之間轉(zhuǎn)換,av_rescale_q(a,b,c)作用相當(dāng)于執(zhí)行a*b/c,通過設(shè)置b,c的值,可以很方便的實(shí)現(xiàn)time_base之間轉(zhuǎn)換。
** 例如 **
-
InputStream(AV_TIME_BASE)到AVPacket(AVStream->time_base)
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
{
pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base);
}
-
AVPacket(AVStream->time_base)到InputStream(AV_TIME_BASE)
static int process_input_packet(InputStream *ist, const AVPacket *pkt)
{
if (pkt->dts != AV_NOPTS_VALUE)
{
ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
}
}
三、其他
AVFrame->pts和AVPacket->pts、AVPacket->dts的值,在解碼/編碼后,會(huì)經(jīng)歷短暫的time_base不匹配的情況:
- 解碼后,
decoded_frame->pts的值使用AVStream->time_base為單位,后在AVFilter里面轉(zhuǎn)換成以AVCodecContext->time_base為單位。 - 編碼后,
pkt.pts、pkt.dts使用AVCodecContext->time_base為單位,后通過調(diào)用"av_packet_rescale_ts"轉(zhuǎn)換為AVStream->time_base為單位。
四、結(jié)束
這其實(shí)就是篇筆記,在前人的基礎(chǔ)上對(duì)time_base的進(jìn)行了大概總結(jié), 以后會(huì)繼續(xù)更新。