這個設計方案是物光院嵌入式系統試驗室的基於CDMA技術的無線視頻傳輸監控系統的設計的一部分。我簡要說明此係統的原理。系統單片機部分主要模塊由CDMA、DSP與ARM處理器、FLASH、ROM組成。此單片機用來獲取監控所在地視頻圖像,經過DSP中的H264協議壓縮,通過arm再到CDMA,最後把數據包發送到主機端的網卡。最後通過主機端的函數接口:
LONG WINAPI Decode(void *DecHeap,void *CodBuf,int CodLen,void *ResBuf,int *imgtype,int *imgw,int *imgh);把壓縮視頻包解碼存儲於ResBuf。
2.爲什麼要用到BMP to AVI
單片機提供的本地存儲圖像函數接口:LONG API SaveImgToBmpFile(CHAR *BmpFileName,
void *ImgBuf,LONG Img_Width,LONG Img_Height,LONG Img_ClrBits);是將圖像幀按BITMAP格式文件存盤。而我們實際的目標是要把實時視頻錄製成AVI文件格式,並且實現壓縮。這樣才不至於在錄了幾十分鐘硬盤就多了好幾個G。
3.BMP to AVI方案的具體實施
本來以爲可以很輕鬆的找到例子。可是我翻閱了百度的幾乎所有相關中文網站,沒有找到BMP 轉換成 AVI的例子。唯一的一個例子是用VB寫的,它的缺點是張數有限,不支持動態添加,而且沒有壓縮,數據量很大。最後,我在參考了國外網站上的兩個類似的AVI類,經過我的修改,於是有了現在這個程序。
步驟(1)瞭解AVI (定義在AVIFMT.H文件中)
微軟公司的AVI格式是一種由RIFF指定的應用程序,用來對音頻/視頻流進行捕捉、編輯和播放的文件格式。大體上,AVI文件包含不同類型的多重數據流。大多數的AVI文件裏都包含音頻和視頻流。有些簡單的AVI文件裏只包含視頻流而不包含音頻流。而有些更特殊的AVI文件可能包括一個控制通道或MIDI道作爲一個附加的數據流。控制道可以控制如MCI影碟播放器的外部器件,MIDI聲道可以爲視頻流播放背景音樂。要完全播放出這種特殊的數據流效果,需要播放程序有特殊的插件,但一般的播放程序也可以播放,只不過把特殊數據忽略AVI文件使用AVI RIFF格式。AVI的RIFF格式通過文件開始的”AVI ”字符來識別。所有的AVI文件包括兩個必須的LIST塊。這些數據塊定義了視頻和音頻流的格式數據。AVI文件也可能包括一個索引數據塊。這個可選塊包含了可選數據在文件中的位置。一個AVI文件具有以下形式:
RIFF(’AVI ’
LIST (‘hdrl’) //定義數據格式
LIST(‘movi’) //包含AVI流數據
[‘idx1’<AVI Index>]//索引
)
LIST塊和索引數據塊是RIFF”AVI”數據塊的子數據塊。“AVI”數據塊用來辨認文件是一個AVI RIFF文件。LIST“hdrl”數據塊定義數據的格式,它被放在第一個位置。LIST “movi”數據塊包含AVI流的數據,它被放在第二個位置。LIST“idx1”數據塊是可選擇的索引數據塊。AVI文件一定要以適當的順序保存這三個分量。LIST”hdrl”和LIST”movi”又使用子數據塊作爲它們的數據。
RIFF('AVI'
* LIST(‘hdrl‘//多上數據流存在
* avih(<MainAVIHeader>)//AVI主首部
* LIST ('strl'
* strh(<Stream header>)//流首部
* strf(<Stream format>)//流格式
* ... additional header data//格式由壓縮解壓驅動器定義
* LIST(‘movi‘//數據直接位於數據塊中
* { LIST(‘rec’ //編組成REC數據塊放入movi
* SubChunk...//用於磁盤存取文件
* )
* | SubChunk } ....
* )
* [ <AVIIndex> ]
* )
LIST”movi”數據塊包含一個用於標示數據塊類型的四字符編碼,由二字符流編號和定義信息類型的二字符組成
數據流一些塊定義:
* Video Streams:
* ##db: RGB DIB bits(未壓縮)
* ##dc: RLE8 compressed DIB bits
* ##pc: Palette Change
*
* Audio Streams:
* ##wb: waveform audio bytes
AVI主首部定義:
typedef struct
{
DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
DWORD dwMaxBytesPerSec; // max. transfer rate
DWORD dwPaddingGranularity; // pad to multiples of this
// size; normally 2K.
DWORD dwFlags; // the ever-present flags
DWORD dwTotalFrames; // # frames in file
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwReserved[4];
} MainAVIHeader;
AVI流首部:
typedef struct {
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags; /* Contains AVITF_* flags */
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate;/* dwRate / dwScale == samples/second */
DWORD dwStart;
DWORD dwLength; /* In units above... */
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT rcFrame;
} AVIStreamHeader;
步驟(2)BMP to AVI流程(定義在AVIFILE文件中)
主要有6步:
遍歷文件夾-->建立AVI文件-->取得位圖句柄
設置壓縮參數-->壓縮-->裝幀-->釋放位圖句柄
相關函數接口和類接口:
IAVIFile AVIFileInit(); AVIFileOpen(); AVIFileExit();
DIBSECTION AVISTREAMINFO
AVICOMPRESSOPTIONS AVISaveOptions
AVISaveOptionsFree AVIMakeCompressedStream
AVIStreamSetFormat
步驟(3)實時數據讀取
現在只能讀固定文件:(