【VC++开源代码栏目提醒】:网学会员为需要VC++开源代码的朋友们搜集整理了AVI录像机开发 - 技术总结相关资料,希望对各位网友有所帮助!
201.0引言AVI文件是微软公司开发的一种多媒体文件格式。
视频和音频数据交错存储在文件中其中的图像和声音数据大都经过编码后进行存放。
AV文件的使用非常广泛大多数媒体播放器都支持此类文件。
下面将开发一个V录像机程序可实现AV文件的录像功能。
视频部分宽度为640高度为480每秒帧数为2编码采用XVD。
音频部分声道数为1采样位数为8采样频率为8编码采用PCM。
使用vfw32.lib进行视频捕获。
该库是
VC中自带的库提供了对VI视频进行处理的功能。
使用winmm.lib进行音频捕获。
该库也是V中自带的库提供了对声音进行处理的功能。
进行图像编码需用到xvidcore.dll动态链接库。
这是一个
开源的XVID编码解码库可以从www.xvid.org下载该库的源
代码。
2AVI文件结构要开发VI录像机程序需要对VI文件格式有比较清楚的了解。
VI文件是微软公司推出的一种多媒体文件格式。
该文件通常包括一个视频流和一个音频流。
VI文件由一个RFF头两个列表hdrl用于描述媒体流格式和movi列表用于保存媒体流数据以及一个可选的索引块组成整个V文件结构如表1所示。
AVI录像机开发江洪摘要使用微软的vfw32.lib进行视频捕获使用winmm.lib进行音频捕获使用XVID编解码库xvidcore.dll进行视频编码结合AVI文件的结构开发了可以实现录像功能的实用程序录像存储在AVI文件中。
关键词AVI录像机XVID视频音频字段名长度说明段名hdrl列表Flag4值为’hdrl’表示这是一个V头段设为94fccType4流类型视频流为’vids’cb4流头大小不包括fcc和cb两字段设56视频流头fcc4值为’strh’表示这是V流头Flag4值为’strl’表示这是V流列表Size4该列表长度不包括’LST’和列表长度字段设16视频流子列表hunkd4值为’LST’这是一个子列表dwReserved16保留设dwHeight4视频图像的高以像素为单位设48dwWidth4视频图像的宽以像素为单位设64dwSuggestedBufferSize4建议读取本文件的缓存大小可设dwStreams4V文件包含的流的个数通常为即个视频流个音频流dwnitialFrames4为交互格式指定初始帧数非交互格式为dwTotalFrames4总帧数dwFlags4V全局标记设为xdwPaddingGranularity4数据填充的粒度可设dwMaxBytesPerSec4V文件的最大数据率可设dwMicroSecPerFrame4视频帧间隔时间以微秒为单位设5Cb4主信息头大小不包括fcc和cb两个字段设为56主信息头Fcc4值为’avih’表示这是V主信息头fccHandler4流的处理者视频流设为’XVD’bottom视频流下坐标设图像高48right视频流右坐标设图像宽64top视频流上坐标设left视频流左坐标设dwSampleSize4采样大小设dwQuality4流数据的质量指标可设dwSuggestedBufferSize4读取这个流数据建议使用的缓存大小可设dwLength4流的长度视频流设为总帧数dwStart4流的开始时间设dwRate4流速率视频流设为每秒帧数dwScale4时间尺度设dwnitialrames4初始帧数设wLanguage流的语言设wPriority流的优先级设dwFlags4标记设段名字段名长度说明RFF头Chunkd4值为’RFF’表示这是一个RFF文件Size4整个V文件大小-8Flag4值为’V‘表示这是一个V文件hdrl列表Chunkid4值为’LST’表示这是一个列表Size4该列表长度不包括’LST’和列表长度字段设为94表169201.0字段名长度说明段名视频流描述头biSize4本结构大小设40Size4流描述头大小设40视频流描述列表Chunkid4值为’strf’表示这是流的具体格式biWidth4图像宽设640Cb4流头大小不包括fcc和cb两字段设56音频流头Fcc4值为’strh’表示这是AVI流头Flag4值为’strl’表示这是AVI流列表Size4该列表长度不包括’LIST’和列表长度字段设94音频流子列表ChunkId4值为’LIST’这是一个子列表biClrUsed4使用颜色数设0biClrImportant4重要颜色数设0biYPelsPerMeter4纵向分辨率设0biXPelsPerMeter4横向分辨率设0biSizeImage4图像大小可设0biCompression4压缩方式设’XVID’biBitCount2颜色位数设4biPlanes位平面数设1biHeight4图像高设48fccType4流类型音频流为’auds’top保留设0left保留设0dwSampleSize4采样大小设1dwQuality4流数据的质量指标可设0dwSuggestedBuffer-Size4读取这个流数据建议使用的缓存大小可设0dwLength4流的长度音频流设为总音频数据大小dwStart4流的开始时间设0dwRate4流速率音频流设为每秒字节数dwScale4时间尺度设1dwInitialFrames4初始帧数设0wLanguage流的语言设0wPriority流的优先级设0dwFlags4标记设0fccHandler4流的处理者音频流设0right保留设0音频流描述头wFormatTag编码格式设为1即PCMSize4流描述头大小设18音频流描述列表Chunkid4值为’strf’表示这是流的具体格式bottom保留设0nChannels声道数设1视频/音频数据若干Chunkid4值为’1wb’表示音频数据值为’00dc’表示视频数据Flag4值为’movi’此列表保存视频和音频数据Size4该列表长度不包括’LIST’和列表长度字段movi列表ChunkId4值为’LIST’这是一个列表cbSize附加字节数设0wBitsPerSample采样位数设8nBlockAlign每个采样占字节数设1nAvgBytesPerSec4每秒字节数设8000nSamplesPerSec4采样频率设8000Size4本数据块大小Data实际的视频或音频数据如数据块大小为奇数需在数据块末尾补1字节0视频流和音频流子列表中包括一些基本的视频和音频参数如编码格式、声道数、采样频率等。
movi列表中保存实际的视频和音频数据。
其中视频和音频数据都是交错存放的。
视频数据以00dc开头其后4个字节是该块数据长度然后是实际的视频数据。
音频数据以01wb开头其后4个字节是该块数据长度然后是实际的音频数据。
索引段以idx1开头用于保存movi列表中各块的索引信息。
3vfw32.lib库微软提供了vfw3.lib库头文件名为vfw.h。
该库提供了对视频处理的支持可以利用该库进行视频捕获。
4微软多媒体开发库微软提供了winmm.lib头文件名为mmsystem.h。
该库提供了对声音处理的支持。
其中waveIn系列函数用于声音输入。
可以利用该库进行音频捕获。
5XVID编码解码库XVID库中提供了XVID数据的编码操作。
编码前首先调用xvid_globalNULLXVID_GBL_INITampxvid_gbl_initNULL进行初始化。
其中XVID_GBL_INIT表示进行初始化。
xvid_gbl_init是一个xvid_gbl_init_t类型的变量该类型用于XVID初始化。
然后调用xvid_encoreNULLXVID_ENC_CREATEampxvid_enc_createNULL创建一个编码实例。
其中XVID_ENC_CREATE表示创建编码实例。
xvid_enc_create是一个xvid_enc_create_t类型的变量该类型用于建立编码实例。
如果xvid_encore返回则可从xvid_enc_create中取得编码实例的句柄。
xvid_enc_create_t结构定义如下typedefstructintversion//版本号intprofile//XVID级别intwidth//图像宽度intheight//图像高度intnum_zonesxvid_enc_zone_tzones字段名长度说明段名索引若干dwChunkId4值为’wb’表示音频数据值为’dc’表示视频数据Cb4该列表长度不包括’idx’和列表长度字段索引列表Fcc4值为’idx’表示这是索引列表dwFlags4块标志x为关键帧x为非关键帧dwSize4本数据块的大小dwOffset4相对于movi列表的偏移量7201.0intnum_pluginsxvidenc_pluintpluginsintnumthradsintmaxbframsintloalintfincr//帧率增量intfase//帧间隔时间intmaxkeyintervalintframedropratiointquantratiointquantoffsetintminquant3intmaxquantvoidhandlexvidenccreatet调用xvid_encoreen_handleXVID_ENCENCODEampxvid_en_frameampxvid_en_stats进行XVID编码。
其中XVID_ENC_ENCODE表示进行XVID编码。
xvid_en_frame是一个xvid_en_frame_t类型的变量该类型用于描述要进行编码的帧。
xvid_en_frame_t定义如下typedefstructintversion版本号intvolflasunsinedcharquantintramatrixunsinedcharquantintermatrixintparintparwithintparheihtintfinrintvopflasintmotionxvidimaetinput输入图像inttype编码类型一般设XVIDTYPEAUTOintquant帧量化器intframethresholvoiitstream输出缓冲区intlenth输出缓冲区长度intoutflasxvidenframet其中xvid_imaget是另一个结构用于表示输入图像其定义如下typedefstrutintsp使用的色场空间voidplane4图像平面最多4个一般只使用plane0intstride4表示每行像素占用字节数xvidimaetxvidenstats是一个xvidenstatst类型的变量该类型用于表示编码帧的状态。
xvidenstatst定义如下typedefstrutintversion版本号inttypeintquantintvolflasintvopflasintlenthinthlenthintklksintmlksintulksintsseyintsseuintssevxvidenstatst调用xvidenoreenhandleXVIDENCDESTROYNULLNULL结束一个编码实例。
其中enhndle是先前得到的编码实例句柄XVIDENCDESTROY表示撤销编码实例。
6
代码解析使用如下
代码段进行录像预览显示捕获窗口mywndnewCWndmywnd-gtCreateNULLquotquotSCHILSVISIBLECRt0vieowithvieoheihtthis124mywndgtShowinowSSmywngtGtinowRtrthCapnapCratCapturinowquotMyOwnCaptureinowquotSCSVSBLret.rihtret.leftret.ottomret.topmywndgtGetSafewnd125apriverConnethCapnd0apCaptureGetSetuphCapndampCapParmssizeofCAP-TURPARSCapParms.dwRequestiroSePerFrameLvide-oframesCapParms.fLimitnaledFALSCapParms.fCIControlFALSCapParms.fYieldTRUCapParms.vKeyAortVKSCAPCapParms.fAortLeftouseFALSCapParms.fAortRihtouseFALSapCaptureSetSetuphCapndCapParmssizeofCAP-TURPARScapPreviewRatehCapndvideoframes/2capPreviewScalehCapndTRUcapPreviewhCapndTRU使用如下
代码将捕获到图像转换为HBITMAPHBITAPCopyindowToBitmapvoid//复制捕获窗口图像7201.0//到HBITMAPHDChScrDChMemDCintnXnYnX2nY2intnWidthnHeightintxScrnyScrnRECTrect1:GetWindowRectghCapWndampRect::GetWindowRectfxGetMainWnd-gtm_hWndamprectifIsRectEmptyampRectreturnNULLhScrDCCreateDCquotDISPLAYquotNULLNULLNULLhMemDCCreateCompatibleDChScrDCnXrect.left3nYrecttop3nX2RectrightnY2RectbottomxScrnGetDeviceCapshScrDCHORZRESyScrnGetDeviceCapshScrDCVERTRESifnXlt0nX0ifnY0nY0ifnX2xScrnnX2xScrnifnY2yScrnnY2yScrnnWidthnX2nXnHeightnY2nYifhitmapNULLhitmapCreateCompatibleitmaphScrDCnWidthnHeighthOlditmapHITMAPSelectObjecthMemDChitmapitlthMemDC00nWidthnHeighthScrDCnXnYSRC-COPYhitmapHITMAPSelectObjecthMemDChOlditmapDeleteDChScrDCDeleteDChMemDCreturnhitmap使用如下
代码将HBITMAP转换到内存HITMAP复制到buf内存OOLCopympToMemoryHITMAPhitmapLPSTRbufHDChDCintiitsWORDwitCountDWORDdwPaletteSize0dwmitsSize0dwDISize0dwWritten0ITMAPitmapITMAPFILEHEADERbmfHdrITMAPINFOHEADERbiLPITMAPINFOHEADERlpbiHANDLEhDibhPalhOldPalNULLhDCCreateDCquotDISPLAYquotNULLNULLNULLiitsGetDeviceCapshDCITSPIXELGetDeviceCapshDCPLANESDeleteDChDCifiitswitCountelseifiits4witCount4elseifiits8witCount8elsewitCount24GetObjecthitmapsizeofitmapLPSTRampitmapbibiSizesizeofITMAPINFOHEADERbibiWidthitmapbmWidthbibiHeightitmapbmHeightbibiPlanesbibiitCountwitCountbibiCompressionI_RGbibiSizeImage0bibiXPelsPerMeter0bibiYPelsPerMeter0bibiClrImportant0bibiClrUsed0dwmitsSizeitmapbmWidthwitCount3324itmapbmHeighthDibGlobalAllocGHNDdwmitsSizedwPaletteSizesizeofITMAPINFOHEADERlpbiLPITMAPINFOHEADERGlobalLockhDiblpbibihPalGetStockObjectDEFAULT_PALETTEifhPalhDCGetDCNULLhOldPalSelectPalettehDCHPALETTEhPalFALSERealizePalettehDCGetDIitshDChitmap0UINTitmapbmHeightLPSTRlpbisizeofITMAPINFOHEADERdw-PaletteSizeITMAPINFOlpbiDI_RG_COLORSifhOldPalSelectPalettehDCHPALETTEhOldPalTRUERealizePalettehDCReleaseDCNULLhDCbmfHdrbfType0x4D42dwDISizesizeofITMAPFILEHEADERsizeofITMAP-INFOHEADERdwPaletteSizedwmitsSizebmfHdrbfSizedwDISizebmfHdrbfReserved0bmfHdrbfReserved2072201.0bmfHdr.bOBitsDWORDsizeofITMAPFILEHEADERDWORDsizeoITMPINFOHEDERdw-PaletteSizememcpyuLPSTRampmHdr14memcpyu14LPSTRlpiwDISizeGloalUnlockhDiGloalFrhDirturnTRUE使用如下
代码写AVI头voiWriteviHeaervoi//写VI文件头charu000structVIMINHEDERahstructVISTREMHEDERashITMPINFOHEDERihunsignlonglnWVEFORMTEXwskavip0SEEK_SETu0RuIu2Fuf3Ffwriteuf14avifp//写入RIFF标记uf00uf10uf0uf30fwriteuf14avifp//写入文件总长度uf0uf1VufIuf3fwriteuf14avifpuf0Luf1IufSuf3Tfwriteuf14avifplen94fwriteamplen4avifpuf0hufufruf3lfwriteuf4avifpmemsetampah0sizeofahahcc0aahcc1vahcciahcc3hahcsizeoah-8ah.wMicroScPrFram1L/vioramsahwFlagsx11ahwStramsahwWithviowithahwHightviohightwritampah1sizoahavip//写入主信息头uLu1IuSu3Twritu14avipux74u1uu3writu14avipusu1turu3lwritu14avipmmstampashsizoashashccsashcc1tashccrashcc3hashcsizoash-8ashccTypvashccTyp1iashccTypashccTyp3sashccHanlrXashccHanlr1VashccHanlrIashccHanlr3DashwScal1ashwRatvioramsashwLngthashrcFramltashrcFramtopashrcFramrightviowithashrcFramottomvio-hightwritampash1sizoashavip//写入视频流头usu1turu3writu14avipux8u1uu3writu14avipmmstampihsizoihihiSizx8ihiWithviowithihiHightviohightihiPlans1ihiitCountx18ihiComprssion114565690Lwritampih1sizoihavip//写入视频流信息头u0Lu1IuSu3Twritu14avipu00x5u10u0u30writu14avipu0su1turu3lwritu14avipmmstampash0sizoashashcc0sashcc1tashccrashcc3hashcsizoash-8ashccTyp0aashccTyp1uashccTypashccTyp3sashccHanlr00ashccHanlr10ashccHanlr0ashccHanlr30ashwScal1ashwRatauiochannlsauioits/8auioratashwSamplSiz1writampash1sizoashavip//写入音频流头usu1turu3writu14avipux1u1uu3writu14avipmmstampwsizowwwFormatTag1wnChannlsauiochannlswnSamplsPrScauioratwnvgytsPrScauiochannlsauioits/8auioratwnlocklignauiochannlsauioits/8wwitsPrSamplauioitswcSizwritampw1sizowavip//写入音频流信息头//写入movi列表uLu1IuSu3Twritu14avipuu1uu3writu14avipumu1ouvu3iwritu14avip使用如下
代码写AV索引使用一个链表存储索引信息。
voiWritviInxvoi//写VI文件索引73201.0charbuf1000unsignedlongindexsizeAVIINDEXpfseekavifp0SEEK_ENDbuf0ibuf1dbuf2xbuf31fwritebuf14avifp//写入索引标记indexsize16indexcountfwriteampindexsize14avifp//写入索引段长度ifaviindexlist-gtnextNULLpaviindexlist-gtnextwhile1//将链表中记录写入索引fwriteampp-gtdwChunkId14avifpfwriteampp-gtdwFlags14avifpfwriteampp-gtdwOffset14avifpfwriteampp-gtdwSize14avifpifp-gtnextNULLbreakpp.
上一篇:
ESC/JAVA & Theorem Proving
下一篇:
关于大学英语教学