目錄
1、國產化系統概述
1.1、國產化操作系統與國產化CPU
1.2、國產化服務器操作系統?
1.3、當前國產化系統的主流配置
2、視頻解碼花屏與卡頓問題
2.1、視頻解碼花屏
2.2、視頻解碼卡頓
2.3、關于I幀和P幀的說明
3、國產顯卡處理速度慢導致圖像卡頓問題
3.1、視頻延時和卡頓原因分析
3.2、SDL2庫跑在景嘉微國產顯卡上效率很低
3.3、采用抽幀播放的方式來解決這類問題
3.4、關于音視頻播放中的唇音不同步問題
3.5、國產化芯片的問題
4、最后
VC++常用功能開發匯總(專欄文章列表,歡迎訂閱,持續更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++軟件異常排查從入門到精通系列教程(專欄文章列表,歡迎訂閱,持續更新...)
https://blog.csdn.net/chenlycly/article/details/125529931C++軟件分析工具從入門到精通案例集錦(專欄文章正在更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795C/C++基礎與進階(專欄文章,持續更新中...)
https://blog.csdn.net/chenlycly/category_11931267.html? ? ? ?近些年來,隨著國產化進程的持續深入,多個IT廠商都相繼推出了支持國產化系統的軟件產品與系統,我們也不例外,我們也相繼參與了多個國產化項目,先后推出了支持國產化系統的一整套解決方案。最近在國產化桌面系統中測試國產化軟件時,遇到了多個視頻編解碼及播放問題,我參與了這類問題的討論與排查,在此做一個詳細的記錄和總結,也希望能給大家提供一個借鑒或參考。
1、國產化系統概述
? ? ? ?本文中的問題出在國產化PC上,所以先來給大家詳細介紹一下國產化系統相關的內容。
1.1、國產化操作系統與國產化CPU
? ? ? ?提到國產化系統,一般主要涉及兩大塊,一塊是國產化操作系統,一塊是國產化CPU,這兩大塊均取得了較大的進展,并涌現了一批國產化廠商。目前主流的國產化操作系統主要有麒麟公司的中標麒麟與銀河麒麟系統、統信軟件的UOS系統等。這些系統廠商均提供了桌面版本和服務器版本的操作系統。這些國產化操作系統均是從Linux系統發展而來,本質上均是Linux系統。
? ? ? ?主流的CPU則有龍芯CPU(基于國產自研的LoogArch架構)、飛騰CPU(基于ARM架構)、兆芯CPU(基于授權的X86架構)以及華為鯤鵬CPU(基于ARM架構)等,這些CPU廠商也提供了桌面版本和服務器版本的CPU。下面給出幾個主流國產化CPU的信息:
1)龍芯CPU:早期采用MIPS架構,后來自研了LoogArch架構,目前最強的一款是龍芯3A5000系列,12nm工藝,早期由意法半導體代工,后來12nm的交給臺積電代工。
2)飛騰CPU:采用ARM架構,有桌面版,也有服務器版,最新桌面版型號是D2000系列,采用16nm工藝,由臺積電代工。
3)華為鯤鵬CPU:采用ARM架構,主要也用于服務器方面,最新型號是鯤鵬920,7nm工藝,由臺積電代工。
4)兆芯CPU:采用X86架構,目前最強的是KX-U6780A 處理器,16nm工藝,由臺積電代工。
5)海光CPU:采用X86架構,主要用于服務器方面,最新的是海光7000系列,14nm工藝,代工方是三星、格芯。
6)申威CPU:采用Alpha架構,后面又自研了SW指令集,目前最新的是申威SW26010系列,采用28nm工藝,主要用于超級計算機,由中芯國際代工。
1.2、國產化服務器操作系統?
? ? ? ? 對于國產化服務器的部署,主要使用內置國產化系統和國產化CPU的長城服務器。華為也提供了支持國產化的泰山服務器,該系列服務器主要使用華為自研的歐拉(Eular)服務器操作系統以及華為鯤鵬CPU。對于國產化服務器系統,除了麒麟、統信UOS和華為歐拉(Eular)系統之外,還可以選擇使用騰訊的TencentOS系統以及阿里的龍蜥(Annolis)系統。
? ? ? ?多年來,大多數IT廠商的服務器操作系統都會選擇開源免費的CentOS系統,但紅帽公司之前宣布停止維護CentOS,這就意味著CentOS不再迭代更新,在使用CentOS時遇到系統及內核方面的問題時,也不再有團隊去維護和解決了。
? ? ? ?為了應對CentOS停止維護帶來的窘境,國內的三大IT廠商華為、騰訊和阿里站了出來,相繼推出了從開源Linux與開源CentOS演進而來的國產免費開源的服務器操作系統:華為歐拉(Eular)系統、騰訊TencentOS系統和阿里龍蜥(Annolis)系統。這些服務器操作系統在原有的開源系統代碼的基礎上做了大量的優化與改進,并成立了開源社區,與國內產商一起合作將系統生態發展壯大起來。目前很多IT廠商已經將服務器操作系統遷移到這些國產的系統上,比如不少廠商現在都在用華為的歐拉服務器系統。
1.3、當前國產化系統的主流配置
? ? ? ?當前主流的桌面國產化PC主要使用中標麒麟/銀河麒麟/UOS桌面操作系統 + 飛騰CPU/龍芯CPU的方案。
? ? ? ?主流的國產化服務器則使用中標麒麟/銀河麒麟/UOS/歐拉服務器系統 + 龍芯CPU/飛騰CPU/鯤鵬CPU的組合方式。其中,鯤鵬CPU是華為專用的,不對外開放使用的(只用在華為的產品中),是和華為泰山服務器綁定在一起的。要使用鯤鵬CPU,則需要購買華為的泰山服務器,服務器中使用的是華為歐拉系統。
對于國產服務器CPU而言,通過實測,華為鯤鵬CPU的性能要高一些,在一些對性能要求較高的項目中,會選用華為內置鯤鵬CPU和歐拉系統的泰山服務器。
2、視頻解碼花屏與卡頓問題
? ? ? ? 在國產化桌面PC上測試客戶端軟件時,發現視頻解碼播放時有明顯的花屏問題,這個問題比較嚴重。
當前的國產化軟件運行在國產化系統中,主要使用開源的SDL2去實現視頻的繪制渲染,在Linux國產化系統平臺上,SDL2內部使用opengl去進行渲染。
2.1、視頻解碼花屏
? ? ? ?通過查看打印日志發現,USB攝像頭采集出來的視頻圖像有明顯的丟幀問題,對視頻進行解碼播放時默認使用強解模式(視頻丟幀時不等待I幀直接解碼播放),因為采集出來的圖像有丟幀,所以出現了花屏問題。將當前使用的USB攝像頭插到Windows PC上,使用amcap工具查看該攝像頭的視頻采集參數,發現該攝像頭內部采集到圖像后會對圖像數據進行編碼壓縮,支持MJPG和H264兩種編碼格式,如下所示:
出問題的場景下,使用的是默認的H264編碼格式,這種編碼格式下輸出的視頻數據有丟幀的問題。
2.2、視頻解碼卡頓
? ? ? ? 為了解決這個由視頻丟幀引起的花屏問題,將強解模式改成等待I幀播放模式。在等I幀播放模式中,如果發現視頻有丟幀,則不會解碼繪制,直到收到新的I幀時才會繪制。改成等待I幀模式后,雖然沒有花屏問題了,但有嚴重的視頻卡頓問題。因為視頻有丟幀時,視頻圖像不再解碼顯示,直到收到新的I幀才會繪制,在這個時間段內始終顯示的是之前的圖像,收到新的I幀才會繪制新的圖像,所以導致了該時間段的視頻卡頓問題。遠端在接收本端發出去的視頻數據時發現丟幀,會主動向本端請求I幀,但這個請求I幀只是臨時補救手段,在頻繁丟幀時還是會有明顯的卡頓問題。
? ? ? ?導致視頻花屏和卡頓的根本原因,是USB攝像頭輸出的視頻有頻繁的丟幀導致的,所以要解決這兩個問題,還是要從源頭(攝像頭)上找解決辦法。于是嘗試將攝像頭的視頻編碼格式改成MJPG,重新運行后發現該編碼格式下輸出的圖像質量比較好,沒有丟幀問題,這樣解碼播放視頻時就不再有花屏、卡頓的問題了。
2.3、關于I幀和P幀的說明
? ? ? ?I幀是幀內編碼,一個I幀就是一張完整的圖像;P幀是幀間編碼,P幀中存放的是相對上一幀變化的內容,在繪制每一幀圖像時需要將當前的P幀和上一次疊加后的完整的圖像再疊加,才能形成當前完整的一幀圖像(疊加獲取完整的視頻圖像后再去繪制)。每次疊加后的完整圖像要保存在內存中,以便收到下一個P幀時能疊加出完整的圖像。
? ? ? ?如果中間有P幀丟了,收到下一個P幀后可能就無法疊加出完整的圖像了,在強制解碼的模式下,可能就會出現花屏的問題。對于等待I幀模式,視頻幀數據接收端發現有丟幀,則停止繪制圖像,等收到新的I幀才進行繪制。并且視頻接收端在發現有視頻丟幀時,會主動像視頻發送端請求I幀,以便能盡快收到I幀,盡快將新的圖像繪制上去,保持圖像播放的連續性。 ??
? ? ? ?關于I幀和P幀的詳細說明,可以參見這篇文章:
H264 (一) I/P/B幀 GOP/IDR/等參數https://blog.csdn.net/weixin_39369053/article/details/105747624https://blog.csdn.net/weixin_39369053/article/details/105747624
3、國產顯卡處理速度慢導致圖像卡頓問題
? ? ? ?本來以為上述問題到此就結束了,結果后來經過觀察發現,視頻圖像還是有卡頓問題,而且有明顯的延時。
3.1、視頻延時和卡頓原因分析
? ? ? ?通過打印得知,從接收到視頻數據(接收到的是遠端編碼壓縮后的視頻數據),到解碼繪制完成大概需要好幾秒鐘,這個延時有點夸張了(對著攝像頭揮手就能看出來視頻有明顯的延時)!通過分析代碼發現,延時可能是因為顯卡性能不足導致解碼繪制速度慢導致的,而視頻卡頓可能是由視頻丟幀導致的。
? ? ? ?那為什么會出現視頻幀數據丟失呢?進一步分析代碼找到了答案,視頻數據處理模塊開啟了兩個線程,一個線程用于接收視頻數據幀,收到后放到一個緩沖隊列中,另一個線程從緩沖隊列中取出視頻數據幀(編碼壓縮后的視頻數據),對數據先進行解碼,然后將解出的視頻數據繪制到視頻窗口中(在視頻窗口中顯示視頻),兩個線程操作數據隊列的效果圖如下所示:
? ? ? ?因為顯卡性能有限,影響到了解碼顯示的速度(繪制視頻圖像時底層會用到顯卡去渲染繪制),導致處理解碼顯示的線程速度很慢,同時視頻幀接收線程一直在不斷地接收數據,而隊列長度是有限的(比如存放幀數據的個數上限為100多幀,或者緩沖隊列的內存是有限的),導致隊列中的視頻幀數據來不及被處理就被丟棄掉了(丟棄老的視頻幀數據,為新的視頻幀數據騰出存放空間)。因為有視頻幀丟失,當前使用的是等待I幀解碼模式,導致一小段時間內不再解碼播放,直到收到下一幀才播放繪制,所以產生了視頻卡頓。
? ? ? ? 此處是如何知道解碼播放線程處理速度慢的呢?其實很簡單,添加時間相關打印日志即可看出來。在日志打印系統中,一般每條打印中都會攜帶時間信息的,方便分析問題,比如方便查看代碼執行時長和速度的、快速查看發生異常時間點附近的打印日志等。
3.2、SDL2庫跑在景嘉微國產顯卡上效率很低
? ? ? ?之前在一個國產項目中也遇到視頻解碼播放有明顯卡頓延遲的問題,當時問題排查了很久,最后懷疑是顯卡性能不足導致的。當時的場景是,客戶環境中幾乎所有的國產化電腦都沒問題,但有一臺國產化電腦會有這個視頻卡頓延時問題。后來客戶的國產化電腦提供商主動給客戶更換了顯卡,就不再有問題的。這臺出問題的國產化電腦,之前使用的景嘉微公司的國產顯卡,后來換成AMD的顯卡就沒問題了,看來國產的顯卡和頂級的AMD顯卡在性能上還是有明顯的差距的!
? ? ? ? 對于這個視頻播放延時卡頓的問題,如果好復現,在公司的測試環境中應該早就暴露出來了(測試人員在測試過程中應該會復現出來),但之前一直沒有出過這個問題。通過客戶的這個問題案例,我們知道為啥在公司測試環境沒有暴露這個問題的原因了,因為我們公司測試環境中之前用的國產化電腦中的顯卡都是AMD的。而此次我們測試環境中遇到的視頻播放延時卡頓問題,是因為這次使用的國產化設備比較特殊,使用的是景嘉微的國產JM7200顯卡,所以出現了和項目客戶一樣的問題。
? ? ? ?在Terminal命令行中使用lshw命令即可查看當前國產化機器上使用的顯卡信息,具體的命令格式為:Ishw -c display,比如AMD的顯卡信息如下:
description:?VGA?compatible?control
product:?Caicos?[Radeon?HD?6450/7450/8450R5?230?0EM]?[1002:6779]
vendor:?Advanced?Micro?Devices,?Inc.??[AMD/ATI]??[1002]
景嘉微的顯卡信息如下:
description:?VGA?compatible?controller
product:?JM7200?[731:7200]
vendor:?JingJla?Micro,?Inc.?[JJM]?[731]
對應的景嘉微顯卡型號為JM7200,出問題的這臺電腦用的就是景嘉微的顯卡,結合之前項目中遇到的類似的情況,基本可以斷定是當前用于視頻繪制渲染的SDL2開源庫在景嘉微顯卡上運行效率低導致的。
從運行現象上看,應該是開源的SDL2在景嘉微國產顯卡上運行效率低導致的,可能是景嘉微對Linux上的OpenGL框架支持不好,或者景嘉微顯卡驅動存在問題,或者是景嘉微顯卡性能不夠,亦或是SDL2開源庫對國產化顯卡的支持不夠,具體是哪種原因,后面需要花時間進行研究。也可以將這個問題反饋給景嘉微公司,讓他們給分析一下原因!
3.3、采用抽幀播放的方式來解決這類問題
? ? ? ?當前的問題是因為解碼播放線程處理速度明顯慢于視頻數據接收線程(慢很多),導致視頻幀數據緩沖隊列滿,導致部分較早收到的、還未來得及處理的視頻幀數據從隊列中踢出丟棄了:
解碼播放線程執行速度慢,是因為景嘉微國產顯卡的性能不足導致的。
? ? ? ?為了解決當前的視頻卡頓延時問題,討論后決定采用抽幀播放的辦法,如果視頻幀數據緩沖隊列達到某個上限(設定一個閾值,比如10)時,就開啟抽幀播放模式,每收到兩幀數據,只播放一幀,降低對顯卡處理能力的占用。可以根據測試的效果的去調整這個隊列上限閾值,以達到一個比較好的播放效果。但目前這種處理方法只是一種規避的方法,不是根本的解決辦法,但對于這類特殊的國產化機器,讓他們將顯卡更換成非國產的AMD顯卡似乎也不太現實,也只能使用這種折中的辦法。
? ? ? ?此外,抽幀播放視頻也會有一定的問題,比如視頻幀率較低(可能是網絡不好導致的)時,比如幀率只有10幀,只播放5幀視頻,也會出現圖像不連續卡頓的問題。但這也是沒辦法的事情,抽幀播放是為了保證視頻播放的實時性,實時性比視頻卡頓更重要。
3.4、關于音視頻播放中的唇音不同步問題
? ? ? ?其實還存在另一個問題,即唇音不同步的問題,因為視頻播放線程執行的比較慢,音頻播放線程執行的很快,導致視頻播放速度明顯慢于音頻播放速度,如果不對音頻和視頻做同步播放的控制,就可能會出現唇音不同步的問題。
? ? ? ? 這個唇音同步的問題,在不同的應用場景中關注度是不一樣的。比如在視頻播放器和直播領域,比較會關注視頻和聲音,如果出現唇音不同步的問題,看著會很難受,體驗會很差,比如我們在看電影視頻時,如果唇音不同步,看著會很痛苦。但在視頻會議中,更注重的是各個參會方的語音交流,視頻關注度不是非常高,即使出現唇音不同步的問題,也是可以忍受的。但如果將會議中的視頻錄制成視頻文件,如果錄制的視頻中出現唇音不同步,則看著會很難受。
? ? ? ?所以在很多播放器中會根據時間戳進行嚴格的唇音同步控制(開源FFmpeg中的ffplay播放器就做了唇音同步控制),而在一些音視頻軟件中不做唇音同步控制,音頻和視頻來了,就解碼播放,一般視頻解碼播放速度要明顯慢于音頻解碼播放(視頻編解碼算法及視頻播放比音頻復雜很多,處理時間要長很多),一般較容易出現唇音不同步的問題。
3.5、國產化芯片的問題
? ? ? ?這個問題也顯現了國產化顯卡芯片(景嘉微顯卡)和國外頂級顯卡芯片(AMD顯卡)的差距,無論是性能,還是穩定性,亦或是成熟度,應該都有一定的差距。所以,國產化芯片的路還很長!國內目前在芯片領域做的最好的還是華為海思,無論是功能完備性,還是性能,亦或是成熟度,都是國內頂級的存在。
? ? ? ?以前音視頻應用領域基本都在用華為海思的主控芯片,后來因為被制裁導致華為海思芯片無法生產無法供貨,只能轉投國內二線廠商,比如寒武紀和瑞芯微,但這些廠商限于技術水平和行業經驗,在多個方面和華為海思有著明顯的差距,比如穩定性比較差、性能不足、功能完備性不夠、處理問題的速度緩慢等,這些我們深有感觸。
沒辦法,沒法用到華為海思的芯片,只能和這些二三流廠商一起去優化和改進他們的芯片,這個過程是痛苦的,但從長遠來看,對國產芯片的發展是有很大好處的,國產芯片需要大家來支持使用,這樣才能持續地進行優化、改進和完善。
4、最后
? ? ? ?本文從一個非音視頻編解碼開發者的角度記錄了國產化項目中遇到的視頻播放問題,旨在把這些內容作為音視頻基礎知識和常識來了解,難免會出現不嚴謹或用詞不準確的問題,歡迎大家在評論區批評指正,也歡迎大家在評論區對相關細節進行補充。
我們開發的是音視頻相關的業務軟件,經常和音視頻編解碼開發人員打交道,時常和他們一起排查各種與音視頻相關的問題及軟件崩潰問題,對音視頻領域的基礎知識和業務流程比較感興趣,也希望通過與音視頻編解碼開發同事協同排查問題去接觸學習一些音視頻相關的知識。??