BMP to AVI 及其壓縮的實現

  <script type="text/javascript"> srcString = contentarea.value; srcString = ubbReplace(srcString, 'all'); document.write(srcString); srcString = signaturearea.value; showSign(srcString); </script>1.設計方案的產生
   這個設計方案是物光院嵌入式系統試驗室的基於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)實時數據讀取
現在只能讀固定文件:( 
發佈了26 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章