即時通訊中音影片同步的實現
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:
Windows:
Linux:
IOS:
Web:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30004768/viewspace-1332626/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 設定在即時通訊中音影片的引數質量
- xmpp實現的即時通訊聊天(一)
- xmpp實現的即時通訊聊天(二)
- 音影片即時通訊—影片呼叫業務流程使用
- 招聘新模式—音影片即時通訊模式
- 實現在安卓平臺下的即時通訊安卓
- 實現類似QQ的即時通訊程式(十一)
- flutter 呼叫環信sdk 實現即時通訊Flutter
- 即時通訊
- iOS基於Socket.io即時通訊IM實現,WebRTC實現視訊通話iOSWeb
- WEB 即時通訊最佳實踐Web
- Java Websocket實現即時通訊功能入門教程JavaWeb
- iOS:即時通訊之iOS
- 開源 即時通訊 ?
- websocket+node實現一個最簡單的即時通訊功能Web
- 即時通訊和即時通訊的區別是什麼,都有什麼特點?
- koa-socket即時通訊
- 小程式即時通訊demo
- iOS流式即時通訊教程iOS
- xmpp即時通訊詳解
- 基於java博網即時通訊軟體的設計與實現Java
- 「實戰」搭建完整的IM(即時通訊)應用(2)
- 「實戰」搭建完整的IM(即時通訊)應用(1)
- 影片通訊近實時生成字幕專案實踐
- 透過.NET Core+Vue3 實現SignalR即時通訊功能VueSignalR
- 基於 go-Laravel-broadcast 實現 Laravel 的即時通訊(Broadcasting)GoLaravelAST
- 詳解lcs+antigen的部署與配置來實現即時通訊的安全
- 音視訊即時通訊解決方案
- eddChat即時通訊(聊天系統)
- [場景設計]即時通訊
- golang寫的即時通訊伺服器Golang伺服器
- 使用Oracle實現實時通訊(轉)Oracle
- 提取影片中音訊:優酷影片怎麼轉換成mp3?音訊
- 訊息的即時推送——net實現、websocket實現以及socket.io實現Web
- 同步通訊和非同步通訊非同步
- 即時通訊視訊聊天原理是什麼
- 如何基於Django中的WebSockets和非同步檢視來實現實時通訊功能DjangoWeb非同步
- Socket搭建即時通訊伺服器伺服器