999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

AVI文件格式及其應(yīng)用研究

2008-04-12 00:00:00徐殿武
現(xiàn)代電子技術(shù) 2008年2期

摘 要:AVI文件是Windows操作系統(tǒng)下最常用的流媒體文件格式之一,了解AVI文件格式是正確使用AVI文件的基礎(chǔ),以一個(gè)具體的AVI文件的二進(jìn)制碼為例,詳細(xì)解釋和研究AVI文件的各個(gè)字段的具體含義,并指出AVI-1文件與AVI-2文件格式的區(qū)別,在此基礎(chǔ)上,可以對(duì)AVI文件進(jìn)行各種編程操作。給出使用VFW(Video For Windows)用Visual C++編程語(yǔ)言從AVI-2文件中獲取視頻幀,轉(zhuǎn)換為BMP圖像,加以顯示并存儲(chǔ)為位圖文件的編程方法。

關(guān)鍵詞:流媒體文件;VC;AVI;VFW

中圖分類號(hào):TP311.1 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1004-373X(2008)02-119-04

Study on AVI File Format and Its Application

XU Dianwu

(Mechano-Electronic College,China University of Petroleum,Beijing,102249,China)

Abstract:Under Windows environment,AVI is a popular stream media format.To work with AVI file,it is the basic to know about AVI file format.In this paper,the example ofAVI file binary code is presented in binary code,to illustrate every chunk in the file.The format of AVI files,and especially the difference between AVI-1 and AVI-2 format is discussed.Programming method for pickup video frames from an AVI file and save it as BMP files in Visual C++ is presented.

Keywords:stream medium file;VC;AVI;VFW

1 引 言

自微軟公司推出AVI文件格式以來,AVI逐漸成為Windows 操作系統(tǒng)上最常用的流媒體文件格式之一[1]。AVI是視頻數(shù)據(jù)和音頻數(shù)據(jù)交叉編碼(Audio Video Interleaved)的一種RIFF文件,其多用于音視頻捕捉、編輯、播放等,其文件名后綴為.avi。應(yīng)用程序的開發(fā)者在編寫多媒體處理軟件時(shí),除要對(duì)AVI文件進(jìn)行播放、編輯、制作外,也經(jīng)常需要從一個(gè)AVI文件中提取一視頻幀并存儲(chǔ)為BMP圖像文件,這些都需要對(duì)AVI文件格式有深入了解,本文在對(duì)AVI文件格式進(jìn)行解析的基礎(chǔ)上,給出了從AVI文件中獲取位圖的程序設(shè)計(jì)方法。這里介紹的AVI文件格式不包括OpenDML AVI M-JPEG文件格式分委員會(huì)制定的內(nèi)容以及nAVI(一種改進(jìn)的ASF格式)的內(nèi)容。

2 RIFF文件格式簡(jiǎn)介

RIFF(Resource Interchange File Format)文件格式是一個(gè)信息交換框架[1],AVI文件格式是以RIFF為基礎(chǔ)的,所以在很多文獻(xiàn)中,AVI文件又被稱為AVI RIFF文件[2]。

RIFF文件組成的基本單元叫作“塊”(chunk),使用FOURCC碼(Four Character Code,4字符碼,Windows中的數(shù)據(jù)類型為FOURCC)來標(biāo)識(shí)文件中的每個(gè)塊。FOURCC是由4個(gè)ASCII碼組成的一個(gè)DWORD型數(shù)據(jù),高字節(jié)在后,如4字符abcd的FOURCC碼是0X64636261。RIFF就是一個(gè)FOURCC,表示這是一個(gè)RIFF塊。在一個(gè)RIFF文件中,除RIFF塊和LIST塊可以包含子塊(Sub Chunk)外,其他任何塊均不可以包含子塊。

塊的格式分為2種,可以包含子塊的塊(RIFF,LIST)的格式為:FOURCC、塊長(zhǎng)度(4字節(jié),DWORD類型,長(zhǎng)度不包括FOURCC和塊長(zhǎng)度占用的8個(gè)字節(jié))、塊數(shù)據(jù)類型、塊數(shù)據(jù)。不可以包含子塊的塊的格式是:FOURCC、塊長(zhǎng)度、塊數(shù)據(jù),沒有塊數(shù)據(jù)類型部分。

3 AVI文件格式

AVI文件是一種最復(fù)雜的RIFF文件。現(xiàn)在常用的AVI文件有2種:AVI-1和AVI-2。在AVI-2文件中,通常包含2個(gè)流,一個(gè)視頻流和一個(gè)音頻流(被稱為標(biāo)準(zhǔn)AVI格式),但只有一個(gè)視頻流或音頻流也是合法的。在AVI-1文件中只包含一個(gè)DV(digital Video)數(shù)據(jù)流(視頻采集設(shè)備的輸出數(shù)據(jù),其中既有視頻信息也有音頻信息),在文件中以單個(gè)流的形式存在,其主要優(yōu)點(diǎn)是占用較少的存儲(chǔ)空間,對(duì)AVI-1的支持主要來自DirectShow中的DV Muxer和DV Splitter篩選器(Filter)[2]。雖然目前AVI-2仍然是最常使用的格式,但AVI-1由于其自身的優(yōu)點(diǎn)和受到微軟最新技術(shù)的支持,將來可能會(huì)比AVI-2更流行。雖然這2種AVI文件不兼容,但他們都以RIFF格式為基礎(chǔ),除了實(shí)際的流數(shù)據(jù)格式不同以外,差別主要存在于文件的strh塊和strf塊。

下面為AVI文件的格式,左邊小括號(hào)處省略了4字節(jié)的文件大小或列表大小或塊大小,凡FOURCC都用4個(gè)字母表示,除RIFF和LIST外,所有的4字符碼都用單引號(hào)括起來,方括號(hào)表示可選:

RIFF (′AVI◇′[JY]//RIFF文件頭,塊的數(shù)據(jù)類型是AVI,

[JY]◇表示空格。

LIST (′hdrl′[JY]//列表,列表中的數(shù)據(jù)類型是hdrl,

[JY]下面緊跟avih子塊。

′avih′(AVI文件的全局信息,本行構(gòu)成一個(gè)AVIMAINHEADER結(jié)構(gòu),長(zhǎng)度為64個(gè)字節(jié))。

LIST (′strl′[JY]//strl列表,表示本列表是一個(gè)流的列表,

[JY]其后緊跟strh子塊。

′strh′([JY]//流的頭信息,本行構(gòu)成一個(gè)AVISTREAMHEADER

[JY]結(jié)構(gòu),長(zhǎng)度為64字節(jié))

′strf′( [JY]//流的格式信息子塊,描述流中數(shù)據(jù)的格式。)

[ ′strd′([JY]//附加的流頭數(shù)據(jù),一般為

[JY]編解碼器驅(qū)動(dòng)程序所定義) ]

[ ′strn′(以0結(jié)束的字符串,流的名字) ]

...

)

...

)[JY]//hdrl列表塊到此結(jié)束

LIST (′movi′[JY]//movi列表塊,包含了流的實(shí)際數(shù)據(jù),

[JY]數(shù)據(jù)可以是子塊,也可以將子塊組織成rec 列表,

[JY]一個(gè)rec列表中的數(shù)據(jù)應(yīng)該一次性地從磁盤讀出。

{SubChunk | LIST (′rec ′

SubChunk1

SubChunk2

...

)

...

}

...

)//movi列表塊到此結(jié)束

[′idx1′ (索引塊) ]

)//RIFF塊到此結(jié)束,這就是一個(gè)完整的AVI RIFF文件

從上面的格式可以看出,一個(gè)AVI RIFF文件由3大部分組成:RIFF文件頭;hdrl列表;movi列表。其中hdrl列表包含avih子塊和strl子列表,文件中有多少個(gè)流,hdrl列表中就有多少個(gè)strl子列表,strl子列表在hdrl中的次序就是流的序號(hào)(隱含)。

strl子列表由strh子塊、strf子塊、strd子塊(可選)、strn子塊(可選)構(gòu)成。movi列表中存儲(chǔ)的是流的實(shí)際數(shù)據(jù),movi列表中數(shù)據(jù)子塊的種類有:##db,##dc,##pc,##wb,其中##表示數(shù)據(jù)所屬的流的序號(hào),如00db,01dc。db表示未壓縮的視頻幀;dc表示壓縮的視頻幀;wb表示音頻數(shù)據(jù);pc表示調(diào)色板變化,其后的數(shù)據(jù)是一個(gè)AVIPALCHANGE結(jié)構(gòu),此時(shí)strh中的dwFlages字段必須置為AVISF_VIDEO_PALCHANGES。

movi列表最后可以有一個(gè)可選的索引塊(idxl),他指出流的數(shù)據(jù)在文件中的位置,以便于對(duì)數(shù)據(jù)進(jìn)行隨機(jī)訪問。一個(gè)AVI RIFF文件如果有索引塊,則將AVIMAINHEADER結(jié)構(gòu)中的dwFlags字段置為AVIF_HASINDEX。AVI文件中的JUNK塊為數(shù)據(jù)對(duì)齊而存在,應(yīng)用程序應(yīng)該忽略JUNK塊的內(nèi)容。

AVI-1中只有一個(gè)流(DV data stream),其AVISTREAMHEADER(strh塊)中的fccType字段是4字符碼′iavs′,fccHandler字段是′dvsd′,′dvhd′,′dvsl′三者之一(分別對(duì)應(yīng)3種DV格式),strl子列表中的strf塊是DVINFO結(jié)構(gòu)(32字節(jié))。AVI-2中一般有2個(gè)流,視頻流的AVISTREAMHEADER(strh塊)中的fccType字段是4字符碼′vids′(也可以是′dvsd′,′dvhd′,′dvsl′三者之一)[2], 音頻流的4字符碼是′auds′,其視頻流的strl子列表中的strf塊是BITMAPINFOHEADER結(jié)構(gòu)(40字節(jié)),其后可以跟隨DVINFO結(jié)構(gòu)。AVI-2中音頻流的strf塊是WAVEFORMATEX結(jié)構(gòu)。

AVI RIFF文件格式只規(guī)定了文件的組成方式,即各種數(shù)據(jù)如何在文件中排列等,對(duì)于文件中的數(shù)據(jù)并沒有做出編碼格式的約束,如MPEG-1、DivX等都可以作為文件中數(shù)據(jù)的編碼格式。數(shù)據(jù)也可以未經(jīng)壓縮。AVI文件可以看成是一個(gè)數(shù)據(jù)容器,AVI格式只規(guī)定了將數(shù)據(jù)裝入這個(gè)容器的方法,但對(duì)數(shù)據(jù)本身的編碼格式并不涉及。要操作一個(gè)AVI文件(播放、抓圖、編輯),必須在系統(tǒng)中安裝與該AVI文件中的編碼器對(duì)應(yīng)的解碼器,才能進(jìn)行正確的工作。

4 AVI-2文件格式的例

下面以AVI文件bfh.avi(風(fēng)景介紹片)為例,將該AVI文件打開,逐字節(jié)解釋其中的數(shù)據(jù)(見圖1):

52494646是RIFF的ASCII碼;7E443400是文件長(zhǎng)度,高位字節(jié)在后,(0034447E)16,(3425406)10;41564920是AVI◇的ASCII碼,◇表示空格;表示RIFF塊(文件)的數(shù)據(jù)類型是AVI。4C495354是LIST的ASCII碼,表示這是一個(gè)列表。10h開始的4字節(jié)表示本列表長(zhǎng)度,(132)16,(306)10。接著6864726C是hdrl的ASCII碼,表明這是hdrl列表,61766968是avih的ASCII碼,表明這是hdrl列表中的avih塊,第二行最后4字節(jié)是16進(jìn)制的38,十進(jìn)制的56;表示avih塊的長(zhǎng)度是56個(gè)字節(jié)(加上8正好是AVIMAINHEADER結(jié)構(gòu)的長(zhǎng)度),接下來的56個(gè)字節(jié)就是avih的內(nèi)容,描述AVI文件的整體信息,AVIMAINHEADER結(jié)構(gòu)中各個(gè)字段的內(nèi)容不再分析,avih塊到057h結(jié)束。

從0058h開始的4C495354是LIST的ASCII碼,其后4字節(jié)(74)16,即(116)10是本列表的大小。60h開始的7374726C是strl的ASCII碼,表示這是strl(流)列表,從64h到a3h的64個(gè)字節(jié)是一個(gè)AVISTREAMHEADER結(jié)構(gòu);64h開始的73747268是strh的ASCII碼,表示這是strl列表中strh塊(流的頭信息);下面的4字節(jié)是strh塊的大小(38)16,十進(jìn)制的56,76696473是vids的ASCII碼,是流的類型,表示這是一個(gè)視頻流,從上面對(duì)AVI的2種格式的分析可知,這是一個(gè)AVI-2文件,如果是AVI-1文件,此處應(yīng)該是iavs的ASCII碼。70h開始的4字節(jié)是′MSVC′(已經(jīng)注冊(cè)的解碼器的4字符碼 )的ASCII碼4D535643,AVISTREAMHEADER結(jié)構(gòu)其他字段不再羅列,90h這一行最后4個(gè)字節(jié),表示顯示窗口左上角x,y,其值為0,0。a0h開始的2字節(jié)是窗口顯示的右下角x坐標(biāo),值為十進(jìn)制的128,以象素為單位,再2字節(jié)是右下角y坐標(biāo),十進(jìn)制的112,至此,AVISTREAMHEADER結(jié)束。

a4h開始的4字節(jié)是strf的ASCII碼73747266,后跟的4字節(jié)(28)16,(40)10是strf塊的長(zhǎng)度,前面說過,在AVI-2中,如果是視頻流,strf就是一個(gè)BITMAPINFOHEADER結(jié)構(gòu),而該結(jié)構(gòu)的長(zhǎng)度是40字節(jié),再后的4字節(jié)(28)16,就是BITMAPINFOHEADER的第一個(gè)字段,指明該結(jié)構(gòu)的長(zhǎng)度,所以有2個(gè)(28)16相連。從boh開始,就是BITMAPINFOHEADER其余的內(nèi)容,(80)16是圖像的寬度,120象素。(70)16是圖像的高度,112象素,這些都與前面的信息相符合。0001兩字節(jié)是位平面數(shù),(0018)16是每象素比特?cái)?shù)(24位)。接下來4字節(jié)44495633是′DIV3′(壓縮編碼格式的四字符碼)的ASCII碼,是BITMAPINFOHEADER的biCompression域的值,指壓縮方式,這是和普通的BMP文件不同的。后面的字段不再分析。值得指出的是,這里可以后跟一個(gè)DVINFO結(jié)構(gòu)(可選),如果是AVI-1文件,這里用DVINFO結(jié)構(gòu)取代BITMAPINFOHEADER結(jié)構(gòu)。接下來的4C495344是LIST的ASCII碼,表明下面又是一個(gè)列表,列表大小是6Ah,doh行最后4字節(jié)是strl的ASCII碼,表明這是一個(gè)“流”列表。后面的數(shù)據(jù)不再分析。

5 從AVI文件中提取位圖

Windows提供的VFW和DirectShow[3]都可以處理和操作AVI文件,考慮到VFW為大多數(shù)程序員所熟悉以及AVI-2仍然是最常使用的AVI文件格式,下面給出使用VFW從AVI-2文件中提取視頻幀加以顯示并存儲(chǔ)為BMP位圖文件的程序。

VFW 提供的AVIFile動(dòng)態(tài)鏈接庫(kù)使用OLE技術(shù)實(shí)現(xiàn),在AVIFile中的API函數(shù)將AVI文件中的數(shù)據(jù)當(dāng)作“流”來處理,而不必逐一地尋找其中的塊(chunk)。使用該庫(kù)要首先調(diào)用函數(shù)AVIFileInit來初始化,使用完畢調(diào)用函數(shù)AVIFileExit后釋放。首先使用MFC AppWizard創(chuàng)建一個(gè)名為avi的單文檔項(xiàng)目,然后重載CDocument類的虛函數(shù)OnOpenDocument,在此函數(shù)中打開AVI文件,讀出其中的視頻幀,存儲(chǔ)為BMP文件并在屏幕上加以顯示(在VC++6.0中調(diào)試通過):

BOOL CAviDoc::OnOpenDocument(LPCTSTR lpszPathName) 

{ if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE;

AVIFileInit(); [JY]//初始化

AVIFileOpen(pAviFile,lpszPathName,OF_SHARE_DENY_WRITE,0l);[JY]//打開AVI文件

AVIFileGetStream(pAviFile,pAviStream,streamtypeVIDEO,0L );[JY]//打開流

AVIStreamInfo(pAviStream,aviStrInfo,sizeof(AVISTREAMINFO));[JY]//獲取流的信息

long lStreamSize;[JY]//流格式長(zhǎng)度

pBmpInfoH = new BITMAPINFOHEADER;[JY]//pBmpInfoH是文檔類的成員變量

AVIStreamFormatSize(pAviStream,0,lStreamSize);[JY]//獲取流的格式信息的長(zhǎng)度

AVIStreamReadFormat(pAviStream,0L,pBmpInfoH,lStreamSize);

PGETFRAME pgf;

pgf = AVIStreamGetFrameOpen(pAviStream,NULL);[JY]//為解壓幀做準(zhǔn)備

[JY]//解壓讀出第0幀,緊縮DIB的數(shù)據(jù)以返回值pData為起始地址

pData = (LPBYTE)AVIStreamGetFrame(pgf,0L);[JY]//文檔類的成員變量,類型為L(zhǎng)PBYTE

pBmpInfoH->biCompression = 0;

BITMAPFILEHEADER bmpFH;[JY]//位圖文件頭

bmpFH.bfType = 0x4d42;

bmpFH.bfSize = bmpInfoH.biWidth*bmpInfoH.biHeight*3 + 54;

bmpFH.bfReserved1 = 0;bmpFH.bfReserved2 = 0;

bmpFH.bfOffBits = 54;

CFileDialog dlg(FALSE);[JY]//獲取用戶要存儲(chǔ)成的位圖文件名和路徑

if(IDOK==dlg.DoModal ())str.Format (\"%s\",dlg.GetPathName() );

CFile bmp(str,CFile::modeWrite|CFile::modeCreate);

bmp.Write(bmpFH,sizeof(BITMAPFILEHEADER));[JY]//寫入位圖文件頭

bmp.WriteHuge(pData,bmpFH.bfSize-14);[JY]//寫入緊縮DIB

bmp.Close(); AVIFileExit();

UpdateAllViews(NULL);[JY]//更新視圖,在視圖類的OnDraw函數(shù)中顯示位圖

return TRUE;

}//程序中省略所有安全性檢查語(yǔ)句。位圖的顯示在視類的OnDraw函數(shù)(略)中。

圖2是程序執(zhí)行的結(jié)果:從bfh.avi中提取的第0幀轉(zhuǎn)換成的位圖的顯示。

上面程序中pAviFile,pAviStream,aviStrInfo都是文檔類的成員變量,類型分別為PAVIFILE,PAVISTREAM,AVISTREAMINFO。在文檔類的構(gòu)造函數(shù)中將所有指針初始化為NULL。還可以循環(huán)調(diào)用函數(shù)AVIStreamFindNextKey尋找所有的關(guān)鍵幀加以顯示并存儲(chǔ)為BMP文件。需要注意,函數(shù)AVIStreamGetFrame返回的是一個(gè)“緊縮DIB”的地址,即以一個(gè)位圖的BITMAPINFOHEADER開始的地址,且所需的緩沖區(qū)由該函數(shù)自己開辟,不需應(yīng)用程序動(dòng)態(tài)申請(qǐng)。程序要加入#include,且在Project->Settings->Link中鍵入vfw32.lib。

6 結(jié) 語(yǔ)

由于Windows是很流行的操作系統(tǒng),AVI是Microsoft公司大力支持的格式,因此在編寫基于Windows操作系統(tǒng)的流媒體圖像處理程序方面,AVI占有不可替代的位置。準(zhǔn)確理解AVI文件格式以及針對(duì)AVI文件的編程方法在工程實(shí)踐中具有重要的意義。AVI-1文件格式由于占用存儲(chǔ)空間小,受到DirectShow的支持,其將來會(huì)成為AVI文件中最流行的格式。

參 考 文 獻(xiàn)

[1]姜楠,王健.常用多媒體文件格式壓縮標(biāo)準(zhǔn)解析[M].北京:電子工業(yè)出版社,2005.

[2]DirectX Documentation for C++[EB/OL].Microsoft Corporation,2005.

[3]陸其明.DirectShow 開發(fā)指南[M].北京:清華大學(xué)出版社,2003.

注:本文中所涉及到的圖表、注解、公式等內(nèi)容請(qǐng)以PDF格式閱讀原文。

主站蜘蛛池模板: 亚洲午夜综合网| 久久伊人操| 亚洲性日韩精品一区二区| 欧美日韩成人| 国产精品欧美激情| 国产成年女人特黄特色毛片免| 国产三级成人| 日本亚洲国产一区二区三区| 五月婷婷欧美| 亚洲丝袜中文字幕| 久久精品国产在热久久2019| 精品一区二区三区水蜜桃| 成人免费黄色小视频| 欧美日韩国产成人高清视频| 国产午夜福利在线小视频| 亚洲欧洲自拍拍偷午夜色无码| 2021精品国产自在现线看| 色首页AV在线| 国产chinese男男gay视频网| 97精品国产高清久久久久蜜芽| 97se综合| 丁香五月激情图片| 欧美日韩国产在线播放| 欧美中文字幕在线二区| 国产成人一区免费观看| 凹凸国产熟女精品视频| 日韩欧美成人高清在线观看| 热伊人99re久久精品最新地| 亚洲伊人天堂| AV熟女乱| 亚洲三级成人| av一区二区三区高清久久| 欧美精品高清| 亚洲欧美在线综合图区| 人妻出轨无码中文一区二区| 伊人AV天堂| 国产日韩欧美精品区性色| 国产成年女人特黄特色毛片免| 国产成人8x视频一区二区| 国产www网站| 福利片91| 波多野结衣久久高清免费| 国产乱子伦一区二区=| 亚洲精品无码久久毛片波多野吉| 69综合网| 波多野结衣久久高清免费| 极品av一区二区| 在线色综合| 亚洲日韩精品欧美中文字幕 | 日韩欧美中文字幕在线精品| www.av男人.com| 天堂亚洲网| 国产尤物在线播放| 欧美日韩中文字幕二区三区| 国产成人一区免费观看| 99re视频在线| 香蕉视频在线观看www| 亚洲视屏在线观看| 日韩精品亚洲精品第一页| 红杏AV在线无码| 亚洲丝袜第一页| 狠狠亚洲婷婷综合色香| 91在线播放免费不卡无毒| 国产产在线精品亚洲aavv| 国产性爱网站| 久久香蕉欧美精品| 在线中文字幕网| 天天视频在线91频| 国产女人18水真多毛片18精品| 午夜影院a级片| 亚洲成人动漫在线观看| 国产资源免费观看| 99精品福利视频| 在线视频一区二区三区不卡| 久久精品免费看一| 亚洲国产精品日韩av专区| 精品久久久久久中文字幕女| 一区二区三区国产| 免费国产福利| 欧美亚洲国产精品第一页| 在线观看av永久| 婷婷99视频精品全部在线观看|