FFmpeg開發之pts、dts、time_base概念理解


PTS:Presentation Time Stamp。PTS 主要用於度量解碼后的視頻幀什么時候被顯示出來。
DTS:Decode Time Stamp。DTS 主要是標識讀入內存中的Bit流在什么時候開始送入解碼器中進行解碼。

一、時間基的概念

PTS 反映幀什么時候開始顯示,DTS 反映數據流什么時候開始解碼。

怎么理解這里的“什么時候”呢?如果有某一幀,假設它是第10秒開始顯示。那么它的pts是多少呢。是10?還是10s?還是兩者都不是。

為了回答這個問題,先引入FFmpeg中時間基的概念,也就是time_base。它也是用來度量時間的。如果把1秒分為25等份,你可以理解就是一把尺,那么每一格表示的就是1/25秒。此時的time_base={1,25}。如果你是把1秒分成90000份,每一個刻度就是1/90000秒,此時的time_base={1,90000}。所謂時間基表示的就是每個刻度是多少秒。此時你應該不難理解 pts*av_q2d(time_base)才是幀的顯示時間戳。

二、時間基的轉換

下面我們來理解一下時間基的轉換,為什么要有時間基轉換。

首先,不同的封裝格式的timebase是不一樣的。另外,整個轉碼過程中,不同數據狀態對應的時間基也是不一致的。拿MPEG-TS封裝格式25fps來說(主要是視頻),非壓縮時候的數據(即YUV數據或者其它格式數據),在FFmpeg中對應的結構體為AVFrame,它的時間基為AVCodecContext 的time_base,AVRational{1,25}。 壓縮后的數據(對應的結構體為AVPacket)對應的時間基為AVStream的time_base,AVRational{1,90000}。 因為數據狀態不同,時間基不一樣,所以我們必須轉換,在1/25時間刻度下占10格,在1/90000下是占多少格,這就是pts的轉換。

根據pts來計算一楨在整個視頻中的時間位置: timestamp(秒) = pts * av_q2d(st->time_base),duration和pts單位一樣,duration表示當前幀的持續時間占多少格。或者理解是兩幀的間隔時間是占多少格。一定要理解單位, pts:格子數,常用方法 av_q2d(st->time_base): 秒/格,計算視頻長度: 

time(秒) = st->duration * av_q2d(st->time_base)

FFmpeg內部的時間與標准的時間轉換方法如下:

FFmpeg內部的時間戳 = AV_TIME_BASE * time(秒),其中 AV_TIME_BASE_Q = 1 / AV_TIME_BASE。

av_rescale_q(int64_t a, AVRational bq, AVRational cq) 函數,這個函數的作用是計算 a * bq / cq 來把時間戳從一個時間基調整到另外一個時間基。在進行時間基轉換的時候,應該首先這個函數,因為它可以避免溢出的情況發生。

函數表示在bq下的占a個格子,在cq下是多少。

三、音頻pts計算

音頻 sample_rate : samples per second,即采樣率,表示每秒采集多少采樣點。 比如44100HZ,就是一秒采集44100個sample。即每個sample的時間是1/44100秒。

一個音頻幀的AVFrame有nb_samples個sample,所以一個AVFrame耗時是nb_samples*(1/44100)秒,即標准時間下duration_s=nb_samples*(1/44100)秒, 轉換成AVStream時間基下duration=duration_s / av_q2d(st->time_base)
基於st->time_base的num值一般等於采樣率,所以duration=nb_samples。pts=n*duration=n*nb_samples

補充:next_pts-current_pts=current_duration,根據數學等差公式an=a1+(n-1)*d可得pts=n*d。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM