音視頻問題匯總--vlc調(diào)試優(yōu)化
共 8464字,需瀏覽 17分鐘
·
2022-02-09 17:35
1 vlc截圖異常
1.1 4x vlc 截圖異常
修復需求bug時,發(fā)現(xiàn)vlc沒有開啟硬件編解碼器時,截圖就會失敗,如下log:
經(jīng)過一步步排查,發(fā)現(xiàn)是無法構建video converter,應該是構建相關組件時構建失敗了。
失敗時log并不足以顯示,只能一步一步排查代碼。后來對比發(fā)現(xiàn)8x V2.6的庫推進去竟然可以截圖,之后對比一下代碼,構建options時候,開啟了MediaCodec的硬件編解碼。但是4X沒有用到,所以暫時關閉就可以了。
猜測原因可能:
(1)優(yōu)先用了硬解編解碼,但是視頻用的iomx的codec,導致無法進行轉換,;
(2)可能4x的MediaCodec庫和40X的不一樣,需要進行調(diào)試;
root cause目前沒有時間繼續(xù)跟進,暫時沒有周到,臨時方案移除MediaCodec的codec選項,有時間再進行跟蹤。
2 vlc監(jiān)控概率失敗問題
Android平臺的話機和室內(nèi)機統(tǒng)一用的vlc進行rtsp監(jiān)控的,深圳某客戶項目部署時出現(xiàn)一個問題,所以投入兩周時間進行排查和優(yōu)化,相關內(nèi)容總結如下:
2.1 問題背景
深圳客戶項目部署多臺4X作為管理機,每個門口2X作為門口機的一整套智能云監(jiān)控系統(tǒng),在部署過程中碰到一個問題:
(1)客戶現(xiàn)場用4X作為管理機,但是4X通過wifi接入網(wǎng)絡;這時視頻通話和監(jiān)控都非常卡頓;同時視頻質(zhì)量有下降趨勢;
(2)由于門口機和管理機在不同的網(wǎng)段,所有的通話和監(jiān)控都需要經(jīng)過云端服務器進行轉發(fā)通信;這時如果進行視頻監(jiān)控,則加載時會概率等待很久黑屏的現(xiàn)象(有時候超過10s);
(3)4X之前的設計規(guī)劃并沒有增加主動嘗試的動作,一旦加載失敗,就直接黑屏或者關閉當前會話;使用體驗不佳。
出現(xiàn)問題后,第一時間銷售端提供一個臨時方案:將所有2X增加為本地監(jiān)控的方式,繞過云端進行監(jiān)控;該方案可以一定程度上減少和云端的交互,縮短加載時間,但是并非最終解決方案;畢竟部署項目設計的樓層和樓棟還是蠻多的,這種修改需要增加客戶的維護成本,同時不利于大面積部署。
第二種臨時方案:銷售端建議客戶將4X通過有線的方式接入網(wǎng)絡,畢竟有線比無線速率、帶寬、通信質(zhì)量等有很大的提升,這樣也可以最大程度減少加載失敗的概率;然而客戶環(huán)境限制,同時為了后續(xù)大面積部署就要每臺都重新布線,增加客戶成本。
嘗試多個方案仍然被客戶投訴,前端反饋給研發(fā)中心,之后和Y神一起承擔問題修復的工作。
2.2 問題復現(xiàn)
由于問題時鏈接云系統(tǒng)才可以復現(xiàn)的,不過客戶還比較好說話,協(xié)商后客戶也允許鏈接測試機到實際環(huán)境下,因此增加三臺設備到客戶實際環(huán)境中驗證和調(diào)試。
由于當時掌握的資料比較少,采用盲猜和測試驗證的方法快速定位問題發(fā)生在哪個階段:門口機到云階段;云到話機階段;話機本身問題;
之后采用測試驗證逐步排查方法。經(jīng)過第一輪公司內(nèi)部測試和結合客戶反饋的現(xiàn)場情況,所以籠統(tǒng)的做了一下對比實驗,得出如下測試結果:
| 客戶端 | 是否有鑒權 | 結果 |
|---|---|---|
| 4X話機 | 有 | 測試50次,概率加載10s+是后才可以加載,也有概率失敗 |
| VLC PC端 | 有 | 測試50次,概率加載10s+是后才可以加載,也有概率失敗 |
| 4X話機 | 無 | 50次OK |
| VLC PC端 | 無 | 50次OK |
| iOS app+ 4G | 有 | 50次OK |
| Android app | 有 | 測試50次,概率等待10s+后加載 |
| 31X | 有 | 測試10次,概率等待10s+后加載 |
| 30X | 有 | 測試10次,每次都是timeout,無法連接 |
當時看到這樣結果,第一時間懷疑肯定是VLC源碼的問題,畢竟PC端也是異常的,而iOS和Android APP的RTSP監(jiān)控方案是公司內(nèi)部開發(fā)。之后開始了漫長的vlc代碼跟蹤之旅。
2.3 問題分析
2.3.1 VLC端問題排查
話機端VLC 異常log如下,connect失敗了
[17:16:12]I/( 1417): MonitorShowFragment.java: startVideo(136): start rtsp video rtsp://user:[email protected]:554/0C1105079740
[17:16:12]D/( 1417): VLCVideoView.java: stop(310): start stop media
[17:16:12]E/adtest ( 1417): VLCVideoView.java: changeMediaPlayerLayout(207): setAspectRatio653*496
[17:16:17]E/VLC ( 1417): [b8652ec8/5539] libvlc demux: Failed to connect with rtsp://12X.7X.14X.18X:554/0C1105079740
[17:16:22]E/VLC ( 1417): [b88336a8/5539] libvlc stream: Failed to connect to RTSP server 12X.7X.14X.18X:554
[17:16:27]D/R47 ( 1417): PhoneWhole pid1417,tid1572,l3: open misc ioctl device failed.
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: cannot connect to 12X.7X.14X.18X:554
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: Connection failed
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: VLC could not connect to "12X.7X.14X.18X:554".
[17:16:27]E/VLC ( 1417): [b85561a8/5539] libvlc input: Your input can't be opened
[17:16:27]E/VLC ( 1417): [b85561a8/5539] libvlc input: VLC is unable to open the MRL 'rtsp://user:[email protected]:554/0C1105079740'. Check the log for details.
[17:16:27]W/art ( 1417): Native thread exiting without having called DetachCurrentThread (maybe it's going to use a pthread_key_create destructor?): Thread[53,tid=21817,Native,Thread*=0xb87b8870,peer=0x131e60a0,"VlcObject"]
[17:16:27]D/( 1417): VLCVideoView.java: stop(310): start stop media
[17:16:27]D/( 1417): VLCVideoView.java: stop(332): stop media successfulpc VLC 異常log如下:connect失敗了。
main debug: processing request item: rtsp://12X.7X.14X.18X:554/0C1105079740, node: 播放列表, skip: 0
main debug: rebuilding array of current - root 播放列表
main debug: rebuild done - 2 items, index 1
main debug: starting playback of new item
main debug: resyncing on rtsp://12X.7X.14X.18X:554/0C1105079740
main debug: rtsp://12X.7X.14X.18X:554/0C11050DD646 is at 1
main debug: creating new input thread
main debug: Creating an input for 'rtsp://12X.7X.14X.18X:554/0C1105079740'
main debug: requesting art for new input thread
main debug: looking for meta fetcher module matching "any": 1 candidates
main debug: using timeshift granularity of 50 MiB
main debug: using timeshift path: D:\AppData\Temp
main debug: `rtsp://user:[email protected]:554/0C1105079740' gives access `rtsp' demux `any' path `user:[email protected]:554/0C1105079740'
main debug: creating demux: access='rtsp' demux='any' location='user:[email protected]:554/0C1105079740' file='\\user:[email protected]:554\0C1105079740'
main debug: looking for access_demux module matching "rtsp": 15 candidates
live555 debug: version 2016.11.28
lua debug: Trying Lua scripts in C:\Users\Administrator\AppData\Roaming\vlc\lua\meta\fetcher
main warning: Password in a URI is DEPRECATED
lua debug: Trying Lua scripts in D:\Program Files\VideoLAN\VLC\lua\meta\fetcher
main debug: no meta fetcher modules matched
main debug: looking for art finder module matching "any": 2 candidates
main debug: no art finder modules matched
main debug: looking for meta fetcher module matching "any": 1 candidates
main debug: no meta fetcher modules matched
main debug: looking for art finder module matching "any": 2 candidates
main debug: no art finder modules matched
qt debug: IM: Setting an input
live555 debug: connection timeout
live555 error: Failed to connect with rtsp://12X.7X.14X.18X554/0C1105079740
main debug: no access_demux modules matched
main debug: creating access: rtsp://user:[email protected]:554/0C1105079740
main debug: (path: \\user:[email protected]:554\0C1105079740)
main debug: looking for access module matching "rtsp": 27 candidates
satip debug: try to open 'rtsp://user:[email protected]:554/0C1105079740'
satip debug: connect to host '12X.7X.14X.18X'
main debug: net: connecting to 12X.7X.14X.18X port 554
main debug: incoming request - stopping current input
satip error: Failed to connect to RTSP server 12X.7X.14X.18X:554
main debug: net: connecting to 12X.7X.14X.18X port 554
access_realrtsp error: cannot connect to 12X.7X.14X.18X:554這么看應該就是VLC connect的異常問題了,當時還在想,這么快就找到原因了。來,安排,盤它。
2.3.2 VLC代碼框架
但是vlc的代碼跟蹤了一圈,一直跟蹤到live555,增加了很多l(xiāng)og,嘗試了多個辦法,仍然有概率connect失敗,vlc的代碼跟蹤流程部分關鍵節(jié)點:
//input.c -> InitPrograms -> es_out_SetMode
//es_out.c -> EsOutControlLocked -> EsOutSelect -> EsCreateDecoder
//decoder.c -> input_DecoderNew -> decoder_New -> CreateDecoder -> vlc_custom_create -> LoadDecoder
//modules.c 這里設計到 VLC 模塊加載的很多細節(jié),
//大概原理就是根據(jù) cap(視頻解碼cap: video decoder) 去找對應模塊(mediacodec(系統(tǒng)支持), avcodec(ffmpeg)。。。)列表,
//然后匹配 name 值(在解碼模塊這里可以理解成具體的解碼器), 如果有多個模塊被匹配到這個name, 則根據(jù)模塊的 score 來決定加載哪個模塊。 -> module_need -> vlc_module_load -> module_match_name -> module_load -> module_Map
把live555log打印出來之后,顯示如下,sendOptionsCommand階段就異常了:
2.3.3 問題總結
經(jīng)過分析、測試、以及和云端的調(diào)試,目前定位到的問題點如下:
(1)有概率出現(xiàn)4X通過VLC新啟動一次監(jiān)控時,鏈接不上上服務的問題。該問題點是話機connect失敗的;
(2)有概率出現(xiàn)live555鏈接失敗,用real-rtsp進行嘗試
(3)有概率出現(xiàn)4X和云交互式,4X發(fā)送TCP握手,但是握手不成功的問題;
發(fā)送了三次SYN TCP,但是在云端抓包,云并沒有收到;
(4)有概率出現(xiàn)4X發(fā)送的穿透包無法到達云端;
發(fā)送兩個穿透包,但是云端有概率沒有收到;
(5)在4X鏈接失敗只有彈框提醒,之后一直顯示黑屏;
因為建立不起來RTSP鏈接,導致一直黑屏,之后顯示加載失敗。
2.4 解決方案
和Y神一起通過抓包確認了一些問題,并協(xié)商對應的解決方案:
(1)話機connect失敗的,分析后應該是公司網(wǎng)絡異常導致;
通過4G手機熱點測試,是正常的;一旦工作時段在公司測試就有概率異常(正好這段時間公司裝修,網(wǎng)絡線路有出現(xiàn)波動,網(wǎng)絡變慢了,也容易丟包)
(2)有概率出現(xiàn)4X和云交互式,4X發(fā)送TCP握手不成功的問題,應該也和公司網(wǎng)絡有關系,同時移除real-rtsp發(fā)包請求的處理機制;
同時將live555超時從5s縮減到2s,減弱超時對于建立鏈接的影響,修改內(nèi)容:
移除real-rtsp配置項:
直接刪除,或者設置成disable
(3)4X發(fā)送的穿透包無法到達云端:增加穿透包為4個。
對應的修改位置如下:
(4)為了提升體驗,在4X黑屏時,增加動畫效果顯示正在加載或者其他字樣,防止黑屏的現(xiàn)象:這部分和需求以及UI溝通,完成界面優(yōu)化。
(5)增加5次監(jiān)控建立失敗后的重試優(yōu)化,防止無法加載現(xiàn)象出現(xiàn)。
第四點和第五點一起修改,對應的修改如下:
2.5 優(yōu)化結果
白天時間段:鏈接wifi,一共測試20次
| 5s以內(nèi)加載 | 10s以內(nèi)加載 | 無法加載或者大于30s沒有畫面 | ||
|---|---|---|---|---|
| 1 | 4X優(yōu)化前 | 9次 | 3次 | 8次 |
| 2 | 4X優(yōu)化后 | 11次 | 4次 | 5次 |
| 3 | iOS | 16次 | 0次 | 4次 |
| 4 | 31X | 5次 | 6次 | 9次 |
| 5 | Android app | 16次 | 1次 | 3次 |
白天時間段:有線,一共測試20次
| 5s以內(nèi)加載 | 10s以內(nèi)加載 | 無法加載或者大于30s沒有畫面 | ||
|---|---|---|---|---|
| 1 | 4X優(yōu)化前 | 9次 | 5次 | 6次 |
| 2 | 4X優(yōu)化后 | 14次 | 3次 | 3次 |
| 3 | iOS + 4G | 16次 | 0次 | 4次 |
| 4 | 31X | 5次 | 6次 | 9次 |
早上時間段:鏈接wifi, 一共測試20次
| 5s以內(nèi)加載 | 10s以內(nèi)加載 | 無法加載或者大于30s沒有畫面 | ||
|---|---|---|---|---|
| 1 | 4X優(yōu)化前 | 10次 | 3次 | 7次 |
| 2 | 4X優(yōu)化后 | 10次 | 6次 | 3次 |
| 3 | iOS app | 1次 | 0次 | 3次(沒有重新嘗試加載) |
| 4 | 31X | 5次 | 6次 | 9次 |
| 5 | Android app | 17次 | 0次 | 3次(沒有重新嘗試加載) |
早上時間段:4X鏈接有線網(wǎng)絡,一共測試50次
| 5s以內(nèi)加載 | 10s以內(nèi)加載 | 無法加載或者大于30s沒有畫面 | ||
|---|---|---|---|---|
| 1 | 4X優(yōu)化前 | 50次 | 0次 | 0次 |
| 2 | 4X優(yōu)化后 | 50次 | 0次 | 0次 |
| 3 | iOS + 4G | 50次 | 0次 | 0次 |
| 4 | 31X 有線 | 50次 | 0次 | 0次 |
3 vlc編譯相關
參考之前文章:音視頻應用--VLC-Android截圖和錄制 - 知乎 (zhihu.com)
3.1 live555 編譯
vlc 工程中, 會發(fā)現(xiàn)默認只有一個 \src\emb_android\vlc\src\vlc-android\vlc\contrib\src\live555 的目錄:
該路徑下,并沒有真實的代碼,而是一些patch路徑,通過patch編譯時候獲取對應節(jié)點,在重新拉去,然后再編譯。
通過查看rules.mak可以得知,需要從官網(wǎng)上down一個固定節(jié)點的內(nèi)容,然后再單獨編譯各個模塊
編譯的方法,進入需要編譯的子模塊中,make, 然后再make install,
拉去的文件存放在\vlc\src\vlc-android\vlc\contrib\contrib-android-arm-linux-androideabi\live555。路徑下
要編譯該路徑的內(nèi)容,直接編譯,make;make install即可
之后再通過./compile-libvlc.sh \-a arm \-\-no\-ml,完成vlc的編譯。
3.2 vlc log放開
3.2.1 log等級放開
在Android.c中將verbosity的值分別加上info、warn、dbg就可以把log等級放開,方便不熟悉的人進行流程跟蹤
3.2.2 live555 log打印
在live555中通過p_sys->env->getResultMsg()將live555模塊中的log輸出到console端進行查看:
在RTSPClient中通過envir()輸出log,并將log傳輸?shù)絜nv中,通過getresultMsg輸出。
以上是這周時間做的一次問題排查和優(yōu)化內(nèi)容,當然這些都是為了特殊場景下解決一些問題,不一定是最優(yōu)結果,周末會進行壓測,通過自動化腳本的方式進行不斷重連,到時候看看壓測效果。
參考文獻:
官方下載:VLC media player,最棒的開源播放器 - VideoLAN
歡迎點贊、評論、關注、轉發(fā);隨時探討,持續(xù)輸出。ZGNB
