視訊流中的DTS/PTS到底是什麼?
DTS (解碼時間戳)和 PTS (顯示時間戳)分别是×××進行解碼和顯示幀時相對于 SCR (系統參考)的時間戳。 SCR 可以了解為×××應該開始從磁盤讀取資料時的時間。 mpeg 檔案中的每一個包都有一個 SCR 時間戳并且這個時間戳就是讀取這個資料包時的系統時間。通常情況下,×××會在它開始讀取 mpeg 流時啟動系統時鐘(系統時鐘的初始值是第一個資料包的 SCR 值,通常為 0 但也可以不從 0 開始)。 DTS 時間戳決定了×××在 SCR 時間等于 DTS 時間時進行解碼, PTS 時間戳也是類似的。通常, DTS/PTS 時間戳訓示的是晚于音視訊包中的 SCR 的一個時 間。例如,如果一個視訊資料包的 SCR 是 100ms (意味着此包是播放 100ms 以後從磁盤中讀取的),那麼 DTS/PTS 值就差不多是 200 /280ms ,表明當 SCR 到 200ms 時這個視訊資料應該被解碼并在 80ms 以後被顯示出來(視訊資料在一個 buffer 中一直儲存到開始解碼)下 溢通常發生在設定的視訊資料流相關 mux 率太高。 如果 mux 率是 1000000bits/sec (意味着×××要以 1000000bits/sec 的速率 讀取檔案),可是視訊速率是 2000000bits/sec (意味着需要以 2000000bits/sec 的速率顯示視訊資料),從磁盤中讀取視訊資料時 速度不夠快以至于 1 秒鐘内不能夠讀取足夠的視訊資料。這種情況下 DTS/PTS 時間戳就會訓示視訊在從硬碟中讀出來之前進行解碼或顯示( DTS/PTS 時間戳就要比包含它們的資料包中的 SCR 時間要早了)。 如今依靠×××,這基本已經不是什麼問題了(盡管 MPEG 檔案因為應該沒有下溢而并不完全符合 MPEG 标準)。一些×××(很多著名的基于 PC 的播放器)盡可能快的讀取檔案以便顯示視訊,可以的話直接忽略 SCR 。 注意在你提供的清單中,平均的視訊流速率為~ 3Mbps ( 3000000bits/sec )但是它的峰值達到了 14Mbps (相當大, DVD 限制在 9.8Mbps 内)。這意味着 mux 率需要調整足夠大以處理 14Mbps 的部分, bbMPEG 計算出來的 mux 率有時候太低而導緻下溢。 你計劃讓視訊流速率這麼高麼?這已經超過了 DVD 的說明了,而且很可能在大多數獨立播放其中都不能播放。如果你不是這麼計劃,我會從 1 增加 mquant 的值并且在視訊設定中将最大碼流設定為 9Mbps 以保持一個小一點的碼流。 如果你确實想讓視訊碼率那麼高,你需要增大 mux 率。從提供的清單可以得出 bbMPEG 使用 14706800bits/sec 或者 1838350bytes /sec 的 mux 率(總資料速率為: 1838350bytes/sec ( 14706800bits/sec )行)。你在強制 mux 率字段設定的值應該是以 bytes/sec 為機關并被 50 整除。是以我會從 36767 ( 1838350/50 )開始,一直增加直到不會再出現下溢錯誤為止。
音視訊同步原理[ffmpeg]
ffmpeg 對視訊檔案進行解碼的大緻流程: 1. 注冊所有容器格式和 CODEC: av_register_all() 2. 打開檔案 : av_open_input_file() 3. 從檔案中提取流資訊 : av_find_stream_info() 4. 窮舉所有的流,查找其中種類為 CODEC_TYPE_VIDEO 5. 查找對應的××× : avcodec_find_decoder() 6. 打開編××× : avcodec_open() 7. 為解碼幀配置設定記憶體 : avcodec_alloc_frame() 8. 不停地從碼流中提取中幀資料 : av_read_frame() 9. 判斷幀的類型,對于視訊幀調用 : avcodec_decode_video() 10. 解碼完後,釋放××× : avcodec_close() 11. 關閉輸入檔案 :av_close_input_file() output_example.c 中 AV 同步的代碼如下 ( 我的代碼有些修改 ) ,這個實作相當簡單,不過挺說明問題。
音視訊同步-時間戳
媒體内容在播放時,最令人頭痛的就是音視訊不同步。從技術上來說,解決音視訊同步問題的最佳方案就是時間戳:首先選擇一個參考時鐘(要求參考時鐘上的時間是線性遞增的);生成資料流時依據參考時鐘上的時間給每個資料塊都打上時間戳(一般包括開始時間和結束時間);在播放時,讀取資料塊上的時間戳,同時參考目前參考時鐘上的時間來安排播放(如果資料塊的開始時間大于目前參考時鐘上的時間,則不急于播放該資料塊,直到參考時鐘達到資料塊的開始時間;如果資料塊的開始時間小于目前參考時鐘上的時間,則 “ 盡快 ” 播放這塊資料或者索性将這塊資料 “ 丢棄 ” ,以使播放進度追上參考時鐘)。 可見,避免音視訊不同步現象有兩個關鍵 —— 一是在生成資料流時要打上正确的時間戳。如果資料塊上打的時間戳本身就有問題,那麼播放時再怎麼調整也于事無補。假如,視訊流内容是從 0s 開始的,假設 10s 時有人開始說話,要求配上音頻流,那麼音頻流的起始時間應該是 10s ,如果時間戳從 0s 或其它時間開始打,則這個混合的音視訊流在時間同步上本身就出了問題。打時間戳時,視訊流和音頻流都是參考參考時鐘的時間,而資料流之間不會發生參考關系;也就是說,視訊流和音頻流是通過一個中立的第三方(也就是參考時鐘)來實作同步的。第二個關鍵的地方,就是在播放時基于時間戳對資料流的控制,也就是對資料塊早到或晚到采取不同的處理方法。圖 2.8 中,參考時鐘時間在 0-10s 内播放視訊流内容過程中,即使收到了音頻流資料塊也不能立即播放它,而必須等到參考時鐘的時間達到 10s 之後才可以,否則就會引起音視訊不同步問題。 基于時間戳的播放過程中,僅僅對早到的或晚到的資料塊進行等待或快速處理,有時候是不夠的。如果想要更加主動并且有效地調節播放性能,需要引入一個回報機制,也就是要将目前資料流速度太快或太慢的狀态回報給 “ 源 ” ,讓源去放慢或加快資料流的速度。熟悉 DirectShow 的讀者一定知道, DirectShow 中的品質控制( Quality Control )就是這麼一個回報機制。 DirectShow 對于音視訊同步的解決方案是相當出色的。但 WMF SDK 在播放時隻負責将 ASF 資料流讀出并解碼,而并不負責音視訊内容的最終呈現,是以它也缺少這樣的一個回報機制。 音視訊同步通訊 SDK 源碼包分享: Android : http://down.51cto.com/data/711001 Windows : http://down.51cto.com/data/715497 Linux : http://download.csdn.net/detail/weixiaowenrou/5169796 IOS : http://down.51cto.com/data/715486 WEB : http://down.51cto.com/data/710983
轉載于:https://blog.51cto.com/6352513/1180742