項目記錄-”海迪康”ipcamera客戶端開發紀實

一開始拿到IPcamera是爲了在預警系統中加入一個攝像頭,正好老師帶來了一個IPcamera,但是並沒有說明書和文檔,一開始聽到這個名字還以爲只要知道了這個IP地址就可以爲所欲爲了,OK,NO,拿到了地址也並不知道怎麼操縱,上網搜了一下“海迪康”這個牌子,搜到了做監控的大廠的海康威視的論壇,裏面有海康攝像頭的開發者說明書,下了一個ActiveX插件,很迷,改了UID和密碼試了一下竟然成功連上。這時候不知道原理,只是把他嵌入到我們的網頁中,匆匆實現了一下這部分功能。

然後開始跟熊大研究如何瞭解這個攝像頭的原理,利用wireshark抓到了“官方”客戶端與攝像頭通信的包。(第一次感受到wireshark的強大)

拿到了通信的數據包,各種猜,我們得出了初步的解析。

前提條件:攝像頭,電腦連接到同一局域網

交互流程:

               

2017進展:將攝像頭獲取到的h264裸流整理保存成264文件,利用ffplay、愛奇藝萬能播放器等可以播放

思路:將收到的裸流利用ffmpeg實時編碼成yuv數據,利用SDL、OpenGL、Direct3D等底層視頻播放技術對YUV數據進行播放

需要解決的問題:首先ffmpeg的例子針對視頻的解碼都是以文件爲對象的,也就是說無法實時進行解碼,想要解碼一定要先保存成文件再進行解碼操作,看了ffmpeg源碼,他的內部是逐幀進行操作的,但是想要靈活運用ffmpeg源碼還是有難度的,不知道ffmpeg有關的函數,而且底層播放技術也不熟悉,這是個問題!下一步是學習ffmpeg的解碼處理過程以及其中用到的函數。

2018進展:利用回調方法實現了ffmpeg解碼+SDL實時播放的功能,但有明顯卡頓和延遲

過程:在找到ffmpeg回調方法之後,嘗試了利用文件作爲緩衝“實時”播放視頻,將視頻循環存儲到9個文件中,程序依次讀取文件並進行播放,第一次在實時播放上有了進展,但是畢竟存和讀不能同時進行,所以勢必會有延遲,而且打開文件的間隙會卡頓。於是在雷神的博客中找到了內存中取數據解碼利用回調函數進行解碼播放。

https://blog.csdn.net/leixiaohua1020/article/details/12980423

在做這個的過程中還加深理解了傳遞指針的意義。

回調函數方法的核心是編寫read_packet()函數,這個函數是主要是AVIOContext結構體需要,作爲解碼的數據來源使用,一旦解碼需要更多數據,便調用此函數。

我設置了一個緩衝區,一個10000*9字節的數組,接受線程將接收到的h264裸流存到數組中,解碼播放線程利用read_packet()函數讀取數組中的數據,基本上實現了功能

缺點:卡頓,延遲,失真

我發現用這個方法時,由於ffmpeg解碼需要流來判斷文件格式,判斷幀類型,判斷關於視頻的各種參數,而且經常需求>供給,按理說如果是解碼速度快與接收速度的話視頻應該不會卡,但是視頻經常卡,所以猜測有可能是它要收到一定量的碼流數纔開始解析,而大小遠超過真實的一幀的長度,或者有可能有一些碼流沒有完整解析所以造成了卡頓。

優化方法:

1.調節read_packet()讀取的buffer長度

2.優化read_packet()中buf的賦值方法

最新進展:利用 av_parser_parse2() 函數進行逐幀解碼,不用回調方法,延遲少於1秒,不卡頓,秒開屏。

果然之前卡頓大部分原因是時間損失到函數調用上,加上這次直接指定視頻格式和窗口大小,不需要找解碼器,解碼流程速度加快。

經過後來的學習發現,問題應該是在解碼參數的設置上,我並沒有設置解碼參數,比如B幀的存在,幀的延遲輸出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章