ffmpeg關於time_base

原文鏈接:https://www.jianshu.com/p/bf323cee3b8e

本來是想寫一篇time_base的詳細文章,後來發現很多大神寫過,那這裏我就總結一下各種time_base,方便大家理解。
一、time_base

AVStreamtime_base的單位是秒。每種格式的time_base的值不一樣,根據採樣來計算,比如mpegptsdts都是以90kHz來採樣的,所以採樣間隔就是1/900000秒。
AVCodecContexttime_base單位同樣爲秒,不過精度沒有AVStream->time_base高,大小爲1/framerate
AVPacket下的ptsdtsAVStream->time_base爲單位(數值比較大),時間間隔就是AVStream->time_base
AVFrame裏面的pkt_ptspkt_dts是拷貝自AVPacket,同樣以AVStream->time_base爲單位;而pts是爲輸出(顯示)準備的,以AVCodecContex->time_base爲單位。
輸入流InputStream下的ptsdtsAV_TIME_BASE爲單位(微秒),至於爲什麼要轉化爲微秒,可能是爲了避免使用浮點數。
輸出流OutputStream涉及音視頻同步,結構和InputStream不同,暫時只作記錄,不分析。

二、各個time_base之前的轉換
ffmpeg提供av_rescale_q函數用於time_base之間轉換,av_rescale_q(a,b,c)作用相當於執行a*b/c,通過設置b,c的值,可以很方便的實現time_base之間轉換。
例如

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->ptsAVPacket->ptsAVPacket->dts的值,在解碼/編碼後,會經歷短暫的time_base不匹配的情況:

解碼後,decoded_frame->pts的值使用AVStream->time_base爲單位,後在AVFilter裏面轉換成以AVCodecContext->time_base爲單位。
編碼後,pkt.ptspkt.dts使用AVCodecContext->time_base爲單位,後通過調用"av_packet_rescale_ts"轉換爲AVStream->time_base爲單位。

四、結束
這其實就是篇筆記,在前人的基礎上對time_base的進行了大概總結, 以後會繼續更新。

作者:耕地
鏈接:https://www.jianshu.com/p/bf323cee3b8e
來源:簡書

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章