時間戳和持續時間
本主題描述媒體基礎轉換 如何處理時間戳。
MFT 必須盡可能在所有輸出範例上設定時間戳和持續時間。 對於採用一個輸入緩衝區並將它完全處理到輸出緩衝區的簡單 MFT,MFT 應該只會將時間戳和持續時間直接從輸入範例複製到輸出範例。 不過,許多轉換比這個複雜,而且可能需要更複雜的輸出時間計算。 所有 MFT 都應該遵守下列基本規則:
- 如果輸入樣本上提供精確的時間戳或持續時間,MFT 應該嘗試在所有未壓縮的視訊或音訊輸出樣本上放置時間戳和持續時間。 某些輸出時間戳可能需要插補,尤其是譯碼器。
- 輸入樣本的時間戳和持續時間應該盡可能保留在輸出樣本上。
- 輸出時間戳或持續時間可能不符合輸入,因為 MFT 會阻礙數據,或將輸出分成與輸入不同的大小片段。 在此情況下,MFT 應該從最早的輸入範例計算輸出時間戳,其中包含用來建立輸出範例的數據。 若要計算輸出時間戳,請將適當輸入樣本的輸入時間戳新增至已從該範例轉換的數據持續時間。 本節結尾的第二個範例說明這個想法。
- 如果輸入樣本有持續時間,則應保留該持續時間。 如果輸入範例沒有持續時間,MFT 應該從輸出緩衝區的大小或媒體類型所提供的數據速率計算持續時間。
- 計算的工期應該截斷(無進位),而不是四捨五入為最接近的增量。 管線有足夠的寬限時間來處理稍微不準確的持續時間,但管線處理持續時間比 1% 太長的時間還要短 1% 更容易。 也就是說,除了四捨五入之外,沒有理由故意縮短持續時間。
解碼器
譯碼器會將壓縮的封包轉換成未壓縮的數據。 由於輸出未壓縮,譯碼器有特殊義務取得時間戳和持續時間正確。 某些壓縮格式,尤其是 MPEG-2,在所有輸入封包上都沒有時間戳,而且在任何封包上通常沒有任何持續時間。 針對這些格式,譯碼器會負責在每個輸出樣本上放置有效的時間戳和持續時間,方法是加總自上次時間戳輸入範例以來所有輸出的隱含持續時間。
針對視訊,如果持續時間無法使用壓縮格式,譯碼器應該將持續時間計算為幀速率的反轉,轉換為100奈秒單位,並四捨五入。
針對音訊,如果持續時間無法使用壓縮格式,譯碼器應該計算持續時間,因為音訊取樣率的反乘輸出緩衝區中的樣本數目,轉換成 100 奈秒單位,並四捨五入。
轉換應該輸出沒有時間戳的樣本唯一時間是 MFT 從未在輸入範例上收到時間戳,或是無法計算先前輸入時間戳的精確輸出時間戳時。
音訊譯碼器
針對音訊譯碼器,每個輸出取樣的持續時間是從音訊取樣率計算,以及輸出緩衝區中每個通道的 PCM 樣本數目。
計算輸出時間戳的正確方式取決於輸入範例是否包含時間戳。
如果輸入範例包含時間戳,譯碼器會從輸入時間戳計算輸出時間戳,如下所示:
- 如果每個輸入緩衝區包含一或多個完整的壓縮框架,且沒有部分框架,則輸出時間戳等於輸入時間戳,減去譯碼器的已知延遲。 例如,Dolby Digital (AC-3) 譯碼器有 256 個 PCM 樣本的延遲。 例如,在 48-kHz 取樣率時,延遲是 5.33 毫秒 (msec)。 因此,如果輸入時間戳為 1000 毫秒,輸出時間戳為 1000 – 5.33 = 994.66 毫秒。 如果輸入緩衝區包含多個整個壓縮框架,譯碼器會針對輸入範例中的每個畫面產生一個輸出範例。 所有輸出範例都會正確加上時間戳,因此沒有間距。
- 視傳輸格式而定,輸入緩衝區可能包含部分畫面格。 例如,緩衝區可能包含上一個輸入緩衝區中框架的一部分,後面接著一或多個完整的畫面格,後面接著下一個框架的開頭。 在此情況下,假設輸入時間戳對應至緩衝區內開始的第一個框架,通常是正確的。 (也就是說,在上一個緩衝區中啟動的部分框架不包含在目前緩衝區的時間戳中。據此計算輸出時間戳。
如果輸入範例未包含任何時間戳:
- 譯碼器應該產生自己的時間戳,將第一個輸出時間戳設定為零。
- 取樣持續時間是從緩衝區中的輸出樣本數目和取樣率計算而來。
- 後續時間戳是從先前的時間戳和持續時間計算而來:目前的時間戳 + 目前持續時間 = 下一個時間戳。 輸出時間戳中不應該有間距。
如果輸入數據流一開始包含時間戳,但基於某些原因,切換為沒有時間戳,譯碼器應該繼續產生自己的輸出時間戳,因此它們是連續的,而且沒有差距。
如果輸入數據流包含時間戳,但時間有間距,譯碼器只會傳播這些間距。 換句話說,譯碼器不應該嘗試修正輸入數據流中不一致的時間戳。
攪拌機
注意
在 Windows Vista 中,Media Foundation 管線不支援具有多個輸入的 MFT。 Windows 7 支援多輸入 MFT。
混音器會採用多個輸入,並將其混合成一個輸出。 如果輸入數據流未完全鎖定速率,或彼此的時間略有位移,則輸出上設定的時間可能會模棱兩可。 以下是一些指導方針,視媒體類型而定:
音訊。 在啟動時或在清空后立即,音訊混音器應該等候產生輸出樣本,直到它收到所有必要輸入數據流的輸入樣本為止。 此時,它應該選擇初始樣本最早的時間戳,以作為輸出時間戳的基準。 其他數據流應該以無聲填補,以彌補任何時間的差異。 如果在選擇性輸入數據流上收到樣本,也應該將它納入計算中。 從那一點開始,MFT 應努力產生連續且未破解的輸出時間戳鏈結。 一般而言,MFT 不應該嘗試考慮相對於另一個數據流的漂移。 相反地,它應該從基準時間戳、輸出速率和緩衝區大小計算輸出時間戳。 發生另一個清空或排清時,MFT 應該重設其基準時間戳。
視頻。 在啟動或清空之後,視訊混音器應該等候產生輸出樣本,直到它收到所有必要輸入數據流的輸入樣本為止。 此時,它應該選擇初始樣本最早的時間戳,以作為輸出時間戳的基準。 一般而言,它應該努力保留連續和一般輸出時間戳和固定持續時間,即使輸入不是一般,如有必要,重複輸入畫面格。
編碼
編碼器會將未壓縮的音訊或視訊轉換成壓縮的封包。 編碼器應遵循下列指導方針:
編碼器應遵循輸出格式的慣例。 如果格式通常不是每個範例的時間戳,如同 MPEG-2,則並非所有輸出範例都必須有時間戳和持續時間。
如果輸入時間戳具有時間戳的字段,則輸入時間戳應該以輸出格式保留,除非其他來源有更好的時間資訊可用,例如應用程式本身。
多任務器
注意
在 Windows Vista 中,Media Foundation 管線不支援具有多個輸入的 MFT。 Windows 7 支援多輸入 MFT。
多任務器會將兩個不同的音訊或視訊串流結合成一個交錯格式,例如 AVI 或 MPEG-2 傳輸數據流。 多任務器應遵循下列指導方針:
多任務器應遵循輸出格式的慣例。 如果格式通常不是每個範例的時間戳,如同 MPEG-2,則並非所有輸出範例都必須有時間戳和持續時間。
時間戳應該反映最早的時間,該時間會放在任何從該封包開始的畫面上,或從該封包譯碼的第一個音訊範例的時間。 如果它與輸出格式的慣例衝突,請忽略此指導方針。
Demultiplexers
解構器會將交錯格式,例如 AVI 或 MPEG-2 傳輸數據流分割成基礎音訊和視訊串流。
如果格式包含特定的時間戳資訊,可用來根據輸入時間戳計算精確的輸出時間戳,則應該使用該資訊。 不過,如果格式包含與輸入時間戳無關之完全不同基底中的時間,而且無法計算輸入時間戳的精確位移,則應該忽略格式自己的時間。
如果格式沒有可用時間戳資訊,則解譯器應遵循下列規則:
如果可能的話,未壓縮的輸出數據流應該具有有效的時間戳和持續時間,從最近的前一個輸入時間戳計算。
壓縮的輸出數據流應該只有衍生自具有時間戳之輸入範例的第一個輸出範例上的時間戳。 如果輸入範例沒有時間戳,則衍生自該輸入範例的輸出範例應該沒有時間戳。 如果輸入範例分成多個輸出範例,則只有第一個輸出範例應該有時間戳,其餘的則不應該有時間戳。
例子
範例 1。 假設視訊效果一律會採用未壓縮的輸入畫面、套用效果,並將它複製到輸出。 它絕不會保留任何畫面格或緩衝區任何輸入。 如果輸入範例可用,此 MFT 只會將時間戳和持續時間從輸入範例複製到輸出範例,而且完全不會進行時間計算。
範例 2. 假設音訊效果會轉換每個輸入緩衝區的 10 毫秒(毫秒),並儲存額外的 10 毫秒以結合下一個緩衝區。 它會取得所有持續時間為50毫秒的樣本串流。 下表顯示輸入時間。
樣本 | 輸入時間 | 輸入持續時間 | 輸出時間 | 輸出持續時間 |
---|---|---|---|---|
1 | 20 | 50 | 20 | 40 |
2 | 70 | 50 | 60 | 50 |
3 | 121 | 50 | 110 | 50 |
4 | 171 | 50 | 161 | 50 |
請注意,樣本 2 的實際持續時間與根據下一個時間戳 (121 ? 70 = 51) 的實際持續時間之間的 1 毫秒差異。
由於 MFT 會保留 10 毫秒,因此會將輸入樣本 1 的前 40 毫秒輸出為輸出樣本 1,時間戳為 20 毫秒,持續時間為 40 毫秒。
輸出範例 2 結合了先前保留的 10 毫秒與 40 毫秒的輸入範例 2。 此範例的時間戳為 60 毫秒(先前輸入範例的時間戳 20 毫秒,加上已從該範例處理的數據持續時間,40 毫秒)。 其持續時間為 50 毫秒。
同樣地,下一個範例的時間戳為 110 毫秒(70 毫秒 + 40 毫秒),持續時間為 50 毫秒。
下一個計算更有趣。 先前輸出時間和持續時間的隱含時間戳會是 160 毫秒(時間戳 110 毫秒 + 持續時間 50 毫秒)。 不過,輸出時間戳應該從最早輸入樣本的輸入時間戳計算,該時間戳與輸出樣本時間重疊,以及已從該範例處理的任何數據長度。 最接近的重疊輸入範例是範例 4 (時間戳 = 171),但這不是最早的。 最早的重疊範例是範例 3 (時間戳 = 121)。 新增已從該範例處理的 40 毫秒,結果為 161。
相關主題