文章目錄
- FFmpeg 編解碼——時間基(Time Base)概念
- 1. 時間基(Time Base)概念
- 1.1 定義與作用
- 1.2 表現形式
- 2. 時間基在FFmpeg中的應用
- 2.1 時間戳
- 2.2 持續時間
- 3. 理解FFmpeg中的時間基轉換
- 3.1 `av_rescale_q` 函數
- 3.2 `av_rescale_q_rnd` 函數
- 4. 時間基相關操作的代碼示例
- 5. 用時間基概念分析ffprobe查看視頻文件信息packet中的各字段
- 1. 使用ffprobe查看視頻信息
- 2. ffprobe輸出的字段解析
- 2.1 `pts` 和 `dts`
- 2.2 `duration`
- 2.3 `time_base`
- 2.4 `stream_index`
- 3. 時間基在ffprobe中的應用
- 4. 理解幀和數據包
FFmpeg 編解碼——時間基(Time Base)概念
FFmpeg是一個非常強大的開源多媒體處理工具庫。在處理視頻和音頻流時,理解其時間基(Time Base)概念至關重要。這篇文章將分析時間基在FFmpeg中的應用,并以實例代碼進行演示。
1. 時間基(Time Base)概念
1.1 定義與作用
時間基,即Time Base,是用于衡量時間的單位,在多媒體編程中被廣泛使用。對于FFmpeg,它主要用于描述幀率、持續時間和時間戳等概念。簡單地說,時間基是一種將數值時間戳轉化為真實時間(秒)的方式。
1.2 表現形式
時間基通常表現為一個分數,比如1/25,這表示每幀的持續時間為0.04秒(即1除以25)。在FFmpeg的數據結構中,AVStream->time_base
字段就用來表示時間基。
2. 時間基在FFmpeg中的應用
2.1 時間戳
在FFmpeg中,時間戳是根據特定的時間基進行計算的。時間戳可以看作是幀在媒體流中的位置或播放時間。例如,如果時間基是1/50,那么時間戳20就代表了該幀位于媒體流的0.4秒處。
2.2 持續時間
持續時間也是根據時間基來計算的。例如,一個視頻片段有50幀,如果時間基是1/25,那么這個視頻片段的持續時間就是2秒(即50乘以1/25)。
3. 理解FFmpeg中的時間基轉換
FFmpeg為我們提供了方便的API進行時間基之間的轉換,主要有av_rescale_q
和av_rescale_q_rnd
兩個函數。這兩個函數可以用于在不同時間基之間轉換時間戳。
3.1 av_rescale_q
函數
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
該函數的作用是將時間戳從一個時間基轉換到另一個時間基。它會確保結果是最接近原值的整數。
3.2 av_rescale_q_rnd
函數
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding)
這個函數和av_rescale_q
類似,但它允許用戶選擇四舍五入的方式。
4. 時間基相關操作的代碼示例
以下是一個使用FFmpeg API處理時間基的簡單示例:
AVFormatContext *fmt_ctx;
AVStream *stream;
int64_t timestamp;// 假設fmt_ctx和stream已經被正確初始化timestamp = av_rescale_q(stream->cur_dts, stream->time_base, AV_TIME_BASE_Q);
在這個示例中,av_rescale_q
函數用于將當前解碼時間戳(DTS)從流的時間基轉換為全局時間基。
5. 用時間基概念分析ffprobe查看視頻文件信息packet中的各字段
ffprobe是一個非常實用的工具,它能夠提供媒體文件(如視頻和音頻)的詳細信息。
1. 使用ffprobe查看視頻信息
要查看視頻文件的信息,我們可以使用以下命令:
ffprobe -show_packets video.mp4
這條命令將顯示視頻文件中所有包的信息。
2. ffprobe輸出的字段解析
下面是ffprobe可能輸出的一些字段,以及它們的含義:
2.1 pts
和 dts
pts
(Presentation Time Stamp)和dts
(Decoding Time Stamp)表示每個數據包應該何時被展示和解碼。它們的值都是相對于時間基的。
2.2 duration
duration
字段表示數據包的持續時間,同樣是相對于時間基的。
2.3 time_base
time_base
字段就是我們前面討論的時間基,它為上述時間戳和持續時間提供了參考。
2.4 stream_index
stream_index
字段表示當前數據包屬于哪個流。例如,對于多語言電影,可能有多個音頻流。
3. 時間基在ffprobe中的應用
時間基在ffprobe輸出中起著至關重要的作用。通過將pts
、dts
和duration
乘以時間基,我們可以得到實際的展示、解碼和持續時間。
例如,如果一個數據包的pts
是18000,time_base
是1/90000(這是很常見的視頻時間基),那么該數據包應在0.2秒處被展示。
pts (in seconds) = pts * time_base = 18000 * 1/90000 = 0.2
4. 理解幀和數據包
在FFmpeg中,數據包(packet)和幀(frame)是兩個不同的概念。一幀通常對應于一個完整的圖像,而一個數據包可能包含多個幀,或者一個幀的一部分。
這意味著我們不能僅根據數據包的數量來計算視頻的總時長。正確的做法是將每個數據包的duration
相加,然后乘以time_base
。
total_duration (in seconds) = sum(duration for each packet) * time_base