摘 要:提出並實現了使用AVI檔案儲存體XVID壓縮視頻流的方案,網路視頻監控伺服器將採集的視頻映像利用XVID進行視頻編碼,儲存系統將壓縮視頻流以通用AVI檔案格式儲存,以便檢索和查詢。
關鍵詞:AVI;XVID視頻轉碼器;視頻儲存;視頻播放
How to Design Recording System in Network Camera Video Server Based on AVI
Li Qunlin
(College of Electrical and Information Engineering of Hunan University, Changsha 410082)
Abstract: A Rcording System in a Network Camera Video Server which is designed with AVI files, The Video Server uses the XVID MPEG-4 Video Codec to compress image data, Then the Recording System saves the compressed video data in AVI files for query later.
Keywords: AVI;XVID MPEG-4 Video Codec;Video Record;Video Play
1. 網路視頻監控系統介紹
隨著Internet和寬頻網路技術的日益發展,具有視頻和音訊多媒體內容服務即將成為主流。同時,各種高效壓縮解壓演算法的提出,為多媒體資訊在網路上進行傳輸提供了可能。網路視頻監控以直觀、方便、資訊內容豐富等特點被廣泛應用於許多場合。
圖1 網路視頻監控系統結構圖
網路視頻監控系統是一個基於客戶機/伺服器模型的系統,由視頻伺服器端和用戶端組成。視頻伺服器是一個由SAA7113、PNX1301、RTL8139等組成的嵌入式系統,SAA7113實現視頻的採集; PNX1301是系統的核心,對視頻資料進行處理,如視頻編碼、警示檢測、雲鏡控制等;RTL8139負責資料轉送,資料通過網路與用戶端互動。
用戶端是一台通用電腦,用戶端有選擇性地串連單個或者多個伺服器,經過身分識別驗證後可以向監控伺服器發送命令,從監控伺服器擷取壓縮視頻流和其他測量資料,從而實現遠程視頻監控。
系統採用XVID視頻轉碼器對映像資料進行壓縮,因為XVID開放源碼,可以將它移植到PNX1301的PSOS作業系統中,對映像資料進行編碼;用戶端電腦從網路接收壓縮的視頻資料,使用相同版本的XVID解碼器解碼,即可得到映像資料。
2. XVID視頻壓縮格式
2.1. XVID的特點
XVID支援多種編碼模式,除了最原始單重估定碼流壓縮(1-pass CBR)之外,XVID提供了包括:單重品質模式動態碼流壓縮、單重量化(Quantization)模式動態碼流壓縮、和包括外部控制和內部控制的兩種雙重(2-pass)動態碼流壓縮模式。
XVID的運動偵測(Motion Search)特性,為需要高碼流的運動畫面可以分配更多空間、更高的碼流、更低的量化幅度來保持畫面的細節;而對於不包含太多運動資訊的靜態畫面,則消減分配預算。這是XVID做為第二代MPEG4編碼的核心內容。
XVID支援動態主要畫面格距(I-frame interval)和B幀,即雙向預測畫面。此外還支援心理視覺亮度修正、演員表選項。畫面最佳化解碼等。
2.2. XVID的編解碼實現方法
XVID源碼有三部分構成:xvidcore、vfw、dshow,可以用Microsoft Visual C++和NASM編譯。本文使用Microsoft Visual C++ 2003.net和NASM-0.98.39編譯成功,其中編譯dshow項目還需要安裝DirectX 9.0 SDK。
xvidcore工程產生XVID轉碼器的API函數庫:xvidcore.dll;vfw工程產生XVID轉碼器在Windows下的安裝檔案:xvidvfw.dll和xvid.inf;dshow產生XVID在Windows下註冊檔案:xvid.ax。
圖2 XVID庫函數的調用過程
由於本文的XVID編碼部分在PNX1301中實現,在此只介紹XVID的解碼部分。
1) 載入xvidcore.dll庫函數
使用XVID的API函數需要載入xvidcore.dll庫,並包含vfw.h和xvid.h標頭檔,調用API函數的方法如下:
HINSTANCE m_hdll = LoadLibrary("xvidcore.dll");
xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
2) 初始化轉碼器
xvid_global_func(0, XVID_GBL_INIT, &init, NULL);
3) 建立解碼器
int length = xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL);
4) 結果輸出設定
xvid_dec_frame_t結構是解碼的主要參數,其中輸出部分需要設定輸出緩衝區、步長和輸出類型,在色彩深度是24位的情況下,RGB格式的資料步長為映像寬度的3倍。
frame.output.plane[0] = ostream;
frame.output.stride[0] = CALC_BI_STRIDE(width, 24);
frame.output.csp = XVID_CSP_VFLIP | XVID_CSP_BGR;
5) 解碼
int length = xvid_decore_func(dhandle, XVID_DEC_DECODE, &frame, &stats);
3. 利用AVI格式儲存視頻
AVI(Audio Video Interleaved的縮寫)是一種RIFF(Resource Interchange File Format的縮寫)檔案格式,用於音視頻捕捉、編輯、回放等應用程式中。通常情況下,一個AVI檔案可以包含多個不同類型的媒體流(典型的情況下有一個音頻流和一個視頻流),不過含有單一音頻流或單一視頻流的AVI檔案也是合法的。AVI可以算是Windows作業系統上最基本的、也是最常用的一種媒體檔案格式。
3.1. AVI視頻檔案結構
圖3 AVI檔案結構
'avih':檔案資訊(AVIFILEINFO格式),'strh' :資料流資訊(AVISTREAMINFO格式),'strf' :格式化資訊(BITMAPINFO格式)。
3.2. 安裝XVID轉碼器
在Windows下使用XVID轉碼器,需要安裝XVID轉碼器。安裝需要前面提到xvidcore 和vfw項目產生的三個檔案xvidcore.dll 、xvidvfw.dll和xvid.inf,使用方法是右鍵點擊xvid.inf檔案選擇“安裝”命令即可。
3.3. 儲存AVI視頻檔案
微軟提供了一套API對AVI檔案進行讀寫,使用這些庫函數需要在程式中載入vfw32.lib庫和vfw.h標頭檔。本文的對AVI檔案的操作都使用此庫中的函數。
如果要對資料流進行壓縮,可以使用AVISaveOptions和AVIMakeCompressedStream函數,選擇作業系統中已經安裝的視頻轉碼器。由於本文從視頻伺服器得到的是已經編碼的XVID格式資料流,所以不需要這個步驟。
圖4 AVI讀寫過程
3.3.1. 擷取未經處理資料
首先擷取幀資料的長度,然後擷取檔案中的未經處理資料。
AVIStreamRead(pVideoStream, lFrames, AVISTREAMREAD_CONVENIENT, NULL, 0, &lSize, NULL);
AVIStreamRead(pVideoStream, lFrames, AVISTREAMREAD_CONVENIENT, pBuffer, lSize, NULL, NULL);
未經處理資料為壓縮資料,可以直接調用XVID的API函數對其進行解碼得到映像資料。
3.3.2. 獲得RGB格式的資料
使用AVI的API函數可以直接自動調用XVID解碼器,獲得RGB格式的資料。
1) 擷取格式化資訊
先擷取格式的大小,可由此判斷資料流是視頻流還是音頻流。
AVIStreamReadFormat(pVideoStream, AVIStreamStart(pVideoStream), NULL, &lSize) ;
擷取格式化資訊內容,如果是視頻流則轉化為BITMAPINFO格式,即可擷取格式化的具體資訊,像的大小,壓縮方式,色彩深度,緩衝區大小等。
AVIStreamReadFormat(pVideoStream, AVIStreamStart(pVideoStream), pChunk, &lSize) ;
LPBITMAPINFO pInfo = (LPBITMAPINFO)pChunk;
2) 設定結果的資訊頭
這裡我們想得到RGB格式的資料流,未經處理資料格式為XVID格式,這裡我們只需要改變原始格式的壓縮方式和緩衝區大小就可以了。緩衝區的大小計算公式如下,它的大小和相同大小的BMP映像資料大小是相等的。
LPBITMAPINFOHEADER pBmpih = GetStreamFormat();
pBmpih->biCompression = BI_RGB;
pBmpih->biSizeImage = ((pBmpih->biWidth * pBmpih->biBitCount + 31)/32 * 4) * pBmpih->biHeight;
3) 擷取RGB格式化資料流,如果pBmpih為空白,將到未經處理資料
PGETFRAME pVideoFrame = AVIStreamGetFrameOpen(pVideoStream, pBmpih);
4) 擷取RGB資料,獲得的RGB資料包括40位元組的映像格式資訊
LPBYTE pImage = (LPBYTE)AVIStreamGetFrame(pVideoFrame, lFrames);
pImage = pImage + sizeof(BITMAPINFOHEADER);
3.4. AVI視頻播放
如果作業系統沒有安裝XVID轉碼器,播放器無法識別XVID格式的AVI檔案。解決的方發是使用如上文的安裝方法,或者使用dshow產生的xvid.ax註冊檔案。
註冊方法是在命令列輸入:
“<path to Windows>/system/regsvr32 <path to xvid.ax>/xvid.ax”
例如:“C:/windows/system/regsvr32 C:/Program Files/xvid.ax”,然後複製xvidcore.dll到“<path to Windows>/system32”,如:“C:/ windows /system32”。測試是否安裝成功的方法是播放一段XVID片斷,看播放器是否正常工作。
本文使用三種方法對播放XVID視頻進行測試,都工作正常。一是利用xvidcore.dll 、xvidvfw.dll和xvid.inf,然後安裝xvid.inf,使用Windows Media Player播放;二是xvidcore.dll和xvid.ax,註冊xvid.ax,使用Windows Media Player播放;三是安裝暴風影音,使用暴風影音的XVID轉碼器,用暴風影音播放。
4. 結論
利用AVI檔案儲存體XVID格式視頻流完全可行,由於大部分播放器支援AVI格式,安裝XVID轉碼器後,使用者可以選用自己喜歡的播放器播放視頻監控系統的儲存記錄,運行穩定,使用方便。
原始碼:http://download1.csdn.net/down3/20070618/18111759279.rar
參考文獻
1. http://www.xvid.org/
2. How to Compile XviD with Microsoft Visual C++ 6.0, David Carroll, 11-23-2003, http://www.discdude.net/xvid/compile.html
3. Working With AVI files, Jonathan Nix, http://www.gamedev.net/reference/programming/features/avifile/
4. Microsoft Visual C++.NET 技術內幕(第6版),(美)謝菲德(Shepherd G.) 潘愛民譯,清華大學出版社
作者介紹
姓名:李群林
性別:男
職稱:研究生
研究方向:測試計量技術與儀器
郵遞區號:410082
地址:湖南大學電氣與資訊工程學院
郵箱:gooseli@163.com
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/gooseli/archive/2006/08/28/1131210.aspx