目 錄
一. 視頻捕獲快速入門
二.基本的捕獲設(shè)置
1.設(shè)置捕獲速度:
2.設(shè)置終止捕獲
3.捕獲的時間限制
三.關(guān)于捕獲窗口
1.創(chuàng)建一個AVICAP捕獲窗口
2.將一個捕獲窗口連接至捕獲設(shè)備
3. 父窗口與子窗口的交互
4.捕獲窗口的狀態(tài)
四.視頻捕獲驅(qū)動和音頻驅(qū)動
1.視頻捕獲驅(qū)動的性能:
2.視頻對話框:
3.PREVIEW 和 OVERLAY模式:
4.視頻格式
5.視頻捕獲設(shè)置
6.聲頻格式
五.使用視頻捕獲
1.創(chuàng)建捕獲窗口(CREATING A CAPTURE WINDOW)
2.連接到捕獲驅(qū)動(CONNECTING TO A CAPTURE DRIVER)
3.列舉所有已安裝的捕獲驅(qū)動(ENUMERATING INSTALLED CAPTURE DRIVERS)
4.得到捕獲驅(qū)動的性能(OBTAINING THE CAPABILITIES OF A CAPTURE DRIVER)
5.得到捕獲窗口的狀態(tài)(OBTAINING THE STATUS OF A CAPTURE WINDOW)
6.顯示對話框設(shè)置視頻特征(DISPLAYING DIALOG BOXES TO SET VIDEO CHARACTERISTICS)
7.得到和設(shè)置視頻格式(OBTAINING AND SETTING THE VIDEO FORMAT)
8. 預(yù)覽視頻(PREVIEWING VIDEO)
9.將視頻設(shè)置為OVERLAY模式(ENABLING VIDEO OVERLAY)
10.命名捕獲文件(NAMING THE CAPTURE FILE)
11.格式化聲頻捕獲(FORMATTING AUDIO CAPTURE)
12.改變視頻捕獲設(shè)置(CHANGING A VIDEO CAPTURE SETTING)
13.捕獲數(shù)據(jù)(CAPTURING DATA)
14.增加一個信息塊(ADDING AN INFORMATION CHUNK)
15.在程序中加入一個回調(diào)函數(shù)(ADDING CALLBACK FUNCTIONS TO AN APPLICATION)
16.創(chuàng)建一個狀態(tài)回調(diào)函數(shù)(CREATING A STATUS CALLBACK FUNCTION)
17.創(chuàng)建一個錯誤回調(diào)函數(shù)( CREATING AN ERROR CALLBACK FUNCTION)
18.創(chuàng)建一個框架回調(diào)函數(shù)(CREATING A FRAME CALLBACK FUNCTION)
六.將四個標(biāo)準(zhǔn)對話框改成函數(shù)調(diào)用形式
AUDIOFORMAT對話框
VIDEOFORMAT對話框
VIDEOSOURCE對話框
VIDEO COMPRESSION對話框
前 言
視頻捕獲是指由專用的視頻采集卡捕獲聲頻和視頻信息,然后將其進(jìn)行數(shù)據(jù)化處理,再經(jīng)過軟件的壓縮進(jìn)行處理,這時就可對這些數(shù)據(jù)進(jìn)行保存、回放、傳輸?shù)雀鞣N操作。
Windows專門提供了Video for Windows來對視頻處理進(jìn)行支持,提供的接口可以被大多數(shù)的視頻采集卡支持,并有多種視頻壓縮驅(qū)動供選擇(當(dāng)然視頻壓縮可以自己開發(fā)),采集卡支持?jǐn)z像頭,TV等多種輸入。
一. 視頻捕獲快速入門
視頻捕捉將一個視頻流和音頻流數(shù)字化, 然后存儲在硬盤或其他存儲介質(zhì)上.
一個AVICap視窗口句柄描述了聲頻與視頻流的細(xì)節(jié), 這樣就使你的應(yīng)用程序從AVI文件格式, 聲頻視頻緩沖管理, 低層聲頻視頻驅(qū)動訪問等等解脫出來, AVICap為應(yīng)用程序提供了一個靈活的介面, 你可以僅僅使用如下幾行代碼就可以將視頻捕捉加入你的程序:
hWndC = capCreateCaptureWindow ( "My Own Capture Window",
WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID);
SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0 /* wIndex */, 0L);
SendMessage (hWndC, WM_CAP_SEQUENCE, 0, 0L);
一個宏其實也是使用SendMessage, 只不過提供給程序一個更易讀的代碼而已, 下面的這些示例就是使用宏的方法將視頻捕捉加入程序:
hWndC = capCreateCaptureWindow ( "My Own Capture Window",
WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID);
capDriverConnect (hWndC, 0);
capCaptureSequence (hWndC);
當(dāng)你創(chuàng)建了一個AVICap類的捕捉窗口并將它連接到一個視頻驅(qū)動時, 此捕捉窗口即可以開始捕捉數(shù)據(jù), 你的程序可以簡單的發(fā)送WM_CAP_SEQUENCE消息(或者使用capCaptureSequence宏)來開始捕捉.
如果是缺省的設(shè)置, WM_CAP_SEQUENCE會開始捕捉視頻音頻流到CAPTURE.AVI文件中, 直到下面的某一事件發(fā)生為止:
用戶按下了ESC鍵或者一個鼠標(biāo)鍵
你的應(yīng)用程序終止或異常中斷捕捉操作
磁盤已滿
在一個應(yīng)用程序里, 你可以發(fā)送WM_CAP_STOP消息來終止捕捉數(shù)據(jù)(或者使用capCaptureStop宏), 你也可以發(fā)送WM_CAP_ABORT消息(或者使用capCaptureAbort宏)來終止.
二.基本的捕獲設(shè)置
基本的捕獲設(shè)置包括:設(shè)置捕獲速度(每秒捕獲多少幀),是否同時捕獲聲頻,捕獲緩沖,允許最大丟失多少幀,是否使用DOS內(nèi)存,以及用鍵盤的哪個鍵或鼠標(biāo)的哪個鍵來終止捕獲等等。這些基本的設(shè)置都可以使用CAPTUREPARAMS結(jié)構(gòu)來描述,你可以使用capCaptureGetSetup宏來得到當(dāng)前的設(shè)置,然后改變此結(jié)構(gòu)的成員變量,再使用capCaptureSetSetup宏設(shè)置新的設(shè)置。
例如:
1.設(shè)置捕獲速度:
捕捉速度是指捕捉任務(wù)每秒鐘捕獲的幀數(shù), 你可以發(fā)送WM_CAP_GET_SEQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來得到當(dāng)前的捕捉速度, 當(dāng)前的捕捉速度保存在CAPTUREPARAMS結(jié)構(gòu)的dwRequestMicroSecPerFrame成員變量中, 你可以通過設(shè)置此變量來改變當(dāng)前設(shè)置, 單位是每毫秒連續(xù)的幀數(shù), 你可以發(fā)送WM_CAP_SET_SEQUENCE_SETUP消息(或者使用capCaptureSetSetup宏), dwRequestMicroSecPerFrame的值是66667, 相當(dāng)于每秒15幀.
2.設(shè)置終止捕獲
你可以允許用戶按下某鍵或某組合鍵或者鼠標(biāo)的左右鍵來終止一個捕獲任務(wù), 如果是實時的捕獲, 則捕獲的文件將會被丟棄; 如果是單步捕獲, 在終止之前所捕獲的內(nèi)容將會被保存.
你可以通過發(fā)送WM_CAP_GETQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來得到當(dāng)前的設(shè)置, 當(dāng)前的按鍵設(shè)置保存在CAPTUREPARAMS的vKeyAbort成員中, 當(dāng)前的鼠標(biāo)設(shè)置保存在fAbortLeftMouse和fAbortRightMouse成員中. 你可以設(shè)置新的按鍵或按鍵組合, 或者鼠標(biāo)左右鍵, 當(dāng)你修改的CAPTUREPARAMS后,應(yīng)該發(fā)送WM_CAP_SET_SEQUENCE_SETUP消息來進(jìn)行更新(或者使用capCaptureSetSetup宏). 缺省的按鍵是VK_ESCAPE. 你必須在指定按鍵之前使用RegisterHotKey函數(shù), 鼠標(biāo)缺省的值是fAbortLeftMouse和fAbortRightMouse都為TRUE.
3.捕獲的時間限制
CAPTUREPARAMS結(jié)構(gòu)中的fLimitEnabled指示是否有時間限度, wTimeLimit指示最大的持續(xù)時間, 單位為秒.
得到fLimitEnabled和wTimeLimit的值可以發(fā)送WM_CAP_GET_SEQUENCE_SETUP消息(或使用capCatureGetSetup宏), 當(dāng)設(shè)置了這些成員變量后, 應(yīng)該發(fā)送消息WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)來更新CAPTUREPARAMS結(jié)構(gòu).
三.關(guān)于捕獲窗口
在捕獲之前必須創(chuàng)建一個捕獲窗口(capture window),在發(fā)送消息或使用宏的過程中都需要使用此窗口。
1.創(chuàng)建一個AVICap捕獲窗口
你可以使用capCreateCaptureWindow函數(shù)來創(chuàng)建一個AVICap捕獲窗口, 此函數(shù)將會返回一個句柄, 此句柄以后在發(fā)送消息時要用.
你可以在一個程序里創(chuàng)建一個或多個捕獲窗口, 然后給每一個窗口連接不同的捕獲設(shè)置.
2.將一個捕獲窗口連接至捕獲設(shè)備
你可以動態(tài)的在一個捕獲窗口與一個捕獲設(shè)備之前連接或斷接, 你可以發(fā)送WM_CAP_DRIVER_CONNECT消息來使一個捕獲窗口與一個捕獲設(shè)備連接或關(guān)聯(lián). 當(dāng)連接上以后, 你就可以通過捕獲窗口向捕獲設(shè)備發(fā)送各種消息.
如果你的系統(tǒng)里裝有多個捕獲設(shè)備, 你可以在發(fā)送WM_CAP_DRIVER_CONNECT消息時用wParam參數(shù)指定使用哪一個, 此參數(shù)是登記在SYSTEM.INI文件的[drivers]一節(jié)里的列表中的某一項, 0為第一個.
你可以使用capGetDriverDescription函數(shù)來得到已安裝的捕獲設(shè)備的名稱及版本, 這樣你的程序就可以列舉所有已安裝的捕獲設(shè)備和驅(qū)動, 這樣用戶就可以選擇其中的一個來與你的捕獲窗口連接.
你可以發(fā)送WM_CAP_DRIVER_GET_NAME消息(或capDriverGetName宏)來得到連接到捕獲窗口的捕獲設(shè)備的名稱, 得到版本發(fā)送WM_CAP_DRIVER_GET_VERSION消息(或capDriverGetVersion宏)
你可以發(fā)送WM_CAP_DRIVER_DISCONNECT消息(或capDriverDisconnect宏)來斷接.
3. 父窗口與子窗口的交互
一些象WM_PALETTECHANGED和WM_QUERYNEWPALETTE的系統(tǒng)級消息只能發(fā)送到頂級窗口或OVERLAPPED窗口, 如果一個捕獲窗口是子窗口,就必須通過父窗口轉(zhuǎn)送.
同樣的, 如果父窗口的尺寸改變了, 它就需要通知捕獲窗口, 相反地, 如果捕獲窗口的尺寸改變了, 捕獲窗口就需要發(fā)送消息給父窗口, 一個簡單的方法就是始終保持捕獲窗口的尺寸與視頻流的尺寸一致, 并隨時將尺寸的改變通知父窗口.
4.捕獲窗口的狀態(tài)
你可以發(fā)送WM_CAP_GET_STATUS消息(或capGetStatus宏)來得到當(dāng)前捕獲窗口的狀態(tài), 得到的是一個CAPSTATUS結(jié)構(gòu)的拷貝, 它包含圖片的尺寸, 卷軸的當(dāng)前位置, overlay和preview是否已設(shè)置.
因為CAPSTATUS信息是動態(tài)的, 你的程序應(yīng)該只要捕獲的視頻流的尺寸或格式可能發(fā)生了改變就應(yīng)該進(jìn)行刷新(例如: 顯示了捕獲設(shè)備的視頻格式以后).
改變捕獲窗口的尺寸并不影響實際的捕獲的視頻流的尺寸, 視頻捕獲設(shè)備的格式對話框捕獲頻流的尺寸.
四.視頻捕獲驅(qū)動和音頻驅(qū)動
1.視頻捕獲驅(qū)動的性能:
你可以通過發(fā)送WM_CAP_DRIVER_GET_CAPS消息(或者capDriverGetCaps宏)來得到當(dāng)前連接的視頻驅(qū)動的硬件性能. 得到的信息保存在CAPDRIVERCAPS結(jié)構(gòu)中.
2.視頻對話框:
每一個視頻驅(qū)動能夠提供四個對話框來控制視頻捕獲和數(shù)字化處理, 定義壓縮品質(zhì)等, 這些對話框都定義在視頻捕獲驅(qū)動中.
Video Source對話框用于控制選擇視頻來源, 此對話框列舉了此視頻捕獲卡連接的所有視頻源(典型的例如:SVHS和合成輸入), 并提供了改變色調(diào), 對比度, 飽和度. 如果視頻驅(qū)動支持此對話框, 你就可以顯示并更新它, 使用WM_CAP_DLG_VIDEOSOURCE消息(或capDlgVideoSource宏).
Video Format對話框定義視頻幀的尺寸以及精度, 視頻捕獲卡的壓縮設(shè)置. 如果卡支持的話, 可以發(fā)送消息WM_CAP_DLG_VIDEOFORMAT消息或(capDlgVideoFormat宏).
Video Display對話框控制在視頻捕獲期間在顯示器上的顯示, 此控制不會影響視頻數(shù)字?jǐn)?shù)據(jù), 但是他們可能會影響數(shù)字信號的表現(xiàn)形式, 例如: 如果捕獲設(shè)備支持overlay, 可能允許改變色調(diào)和飽和度, 關(guān)鍵色彩 或者overlay隊列. 如果卡支持, 你可以發(fā)送WM_CAP_DLG_VIDEODISPLAY消息(或者使用capDlgVideoDisplay宏).
Video Compression對話框控制壓縮品質(zhì), 如果卡支持, 發(fā)送消息WM_CAP_DLG_VIDEOCOMPRESSION(或capDlgVideoCompression宏).
3.Preview 和 Overlay模式:
一個視頻捕獲驅(qū)動對進(jìn)入的視頻流有兩種工作模式: Preview模式和overlay模式, 如果一個捕獲驅(qū)動能夠執(zhí)行兩種方法, 用戶可以在其中選擇一種.
Preview模式把從捕獲硬件傳來的數(shù)據(jù)送入系統(tǒng)內(nèi)存并使用圖形設(shè)備介面(GDI)將數(shù)字化幀顯示在捕獲窗口內(nèi). 應(yīng)用程序可以在父窗口失去焦點(diǎn)時減緩顯示速度, 當(dāng)重新又得到焦點(diǎn)后加快顯示速度, 此種模式要占用大量CPU時間.
有三種消息控制Preview操作:
WM_CAP_SET_PREIVEW消息(capPreview宏)允許或禁止preview模式
WM_CAP_SET_PREVIEWRATE(capPreviewRate宏)當(dāng)幀在preview模式顯示時設(shè)置速度.
WM_CAP_SET_SCALE(capPreviewScale宏)允許或禁止preview視頻的縮放比例.
當(dāng)preview和scaling同時使用, 捕獲的視頻幀將會根據(jù)捕獲窗口的尺寸自動縮放, 允許preview模式會自動關(guān)閉overlay模式.
overlay模式是一個硬件函數(shù)它將數(shù)據(jù)送入捕獲緩沖區(qū)中因而不占用CPU資源. 你可以發(fā)送消息WM_CAP_SET_OVERLAY(或capOverlay宏)給捕獲窗口來啟用或終止overlay模式, 允許overlay模式會自動禁止preview模式.
你同時也可以在preview模式或overlay模式里發(fā)送WM_CAP_SET_SCROLL消息(或capSetScrollPos宏)來設(shè)置視頻幀的客戶區(qū)卷軸位置.
4.視頻格式
你可以通過發(fā)送WM_CAP_GET_VIDEOFORMAT消息(或capGetVideoFormat和capGetVideoFormatSize宏)來得到視頻格式的結(jié)構(gòu)或結(jié)構(gòu)的尺寸. 你可以通過發(fā)送CAP_SET_VIDEOFORMAT消息(或capSetVideoFormat宏)來設(shè)置視頻格式.
5.視頻捕獲設(shè)置
CAPTUREPARMS結(jié)構(gòu)包含了對視頻捕獲流的控制參數(shù), 你可以完成以下這些任務(wù):
指定幀數(shù)
指定分配多少視頻緩沖
允許或禁止聲頻捕獲
指定捕獲的時間間隔
指定在捕獲的過程中是否使用MCI設(shè)置(VCR或者videodisc)
指定終止流的鍵盤或鼠標(biāo)
specify the type of video averaging applied during capture.
得到:WM_CAP_GET_SEQUENCE_SETUP消息(或capCaptureGetSetup宏)
設(shè)置:WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)
6.聲頻格式
你可以通過發(fā)送WM_CAP_GET_AUDIOFORMAT消息(或capGetAudioFormat宏和capGetAudioFormatSize宏)來得到當(dāng)前捕獲音頻數(shù)據(jù)的格式或尺寸格式。缺省的聲頻格式是:單聲道、8位、11kHz PCM。 當(dāng)你使用WM_CAP_GET_AUDIOFORMAT時,總是使用WAVEFORMATEX結(jié)構(gòu)。
設(shè)置發(fā)送消息WM_CAP_SET_AUDIOFORMAT消息(或capSetAudioFormat宏),可以傳送WAVEFORMAT,WAVEFORMATEX,PCMWAVEFORMAT結(jié)構(gòu)指針。
五.使用視頻捕獲
1.創(chuàng)建捕獲窗口(Creating a Capture Window)
hWndC = capCreateCaptureWindow (
(LPSTR) "My Capture Window", // window name if pop-up
WS_CHILD | WS_VISIBLE, // window style
0, 0, 160, 120, // window position and dimensions
(HWND) hwndParent,
(int) nID /* child ID */);
2.連接到捕獲驅(qū)動(Connecting to a Capture Driver)
下面的例子是將MSVIDEO驅(qū)動連接到句柄為hWndC的捕獲窗口, 然后調(diào)用capDriverDisconnect宏來斷接.
fOK = SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L);
//
// Or, use the macro to connect to the MSVIDEO driver:
// fOK = capDriverConnect(hWndC, 0);
//
// Place code to set up and capture video here.
//
capDriverDisconnect (hWndC);
3.列舉所有已安裝的捕獲驅(qū)動(Enumerating Installed Capture Drivers)
下面的例子使用capGetDriverDescription函數(shù)得到已安裝的捕獲驅(qū)動的名稱及版本:
char szDeviceName[80];
char szDeviceVersion[80];
for (wIndex = 0; wIndex < 10; wIndex++)
{
if (capGetDriverDescription (wIndex, szDeviceName,
sizeof (szDeviceName), szDeviceVersion,
sizeof (szDeviceVersion))
{
// Append name to list of installed capture drivers
// and then let the user select a driver to use.
}
}
4.得到捕獲驅(qū)動的性能(Obtaining the Capabilities of a Capture Driver)
發(fā)送WM_CAP_DRIVER_GET_CAPS消息可以得到捕獲驅(qū)動的性能,并保存入一個CAPDRIVERCAPS結(jié)構(gòu).每當(dāng)程序連接一個新的捕獲驅(qū)動到一個捕獲窗口時, 就應(yīng)該更新CAPDRIVERCAPS結(jié)構(gòu). 下面的程序舉例說明了如何使用capDriverGetCaps宏來得到捕獲驅(qū)動的性能:
CAPDRIVERCAPS CapDrvCaps;
SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS,
sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDrvCaps);
// Or, use the macro to retrieve the driver capabilities.
// capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));
5.得到捕獲窗口的狀態(tài)(Obtaining the Status of a Capture Window)
下面的例子使用SetWindowPos函數(shù)使捕獲窗口與進(jìn)來的視頻流尺寸保持一致, 視頻流的基本信息是使用capGetStatus宏得到的, 保存在CAPSTATUS結(jié)構(gòu)中.
CAPSTATUS CapStatus;
capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));
SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth,
CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);
6.顯示對話框設(shè)置視頻特征(Displaying Dialog Boxes to Set Video Characteristics)
每個視頻捕獲卡一般能提供三個不同的對話框用于控制視頻捕獲及數(shù)字化處理. 下面的例子說明如何顯示這些對話框, 在顯示這些對話框之前,使用了capDriverGetCaps宏來檢查CAPDRIVERCAPS結(jié)構(gòu), 以檢測該卡是否有顯示這些對話框:
CAPDRIVERCAPS CapDrvCaps;
capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));
// Video source dialog box.
if (CapDriverCaps.fHasDlgVideoSource)
capDlgVideoSource(hWndC);
// Video format dialog box.
if (CapDriverCaps.fHasDlgVideoFormat)
{
capDlgVideoFormat(hWndC);
// Are there new image dimensions?
capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));
// If so, notify the parent of a size change.
}
// Video display dialog box.
if (CapDriverCaps.fHasDlgVideoDisplay)
capDlgVideoDisplay(hWndC);
7.得到和設(shè)置視頻格式(Obtaining and Setting the Video Format)
BITMAPINFO結(jié)構(gòu)的長度既適應(yīng)于標(biāo)準(zhǔn)的也適應(yīng)于壓縮的數(shù)據(jù)格式, 所有程序必須總是詢問此結(jié)構(gòu)的尺寸以便在得到當(dāng)前的視頻格式之前分配內(nèi)存. 下面的例子就是使用capGetVideoFormatSize宏來得到緩沖區(qū)尺寸并調(diào)用capGetVideoFormat宏來得到當(dāng)前的視頻格式.
LPBITMAPINFO lpbi;
DWORD dwSize;
dwSize = capGetVideoFormatSize(hWndC);
lpbi = GlobalAllocPtr (GHND, dwSize);
capGetVideoFormat(hWndC, lpbi, dwSize);
// Access the video format and then free the allocated memory.
程序可以使用capSetVideoFormat宏(或WM_CAP_SET_VIDEOFORMAT消息)發(fā)送一個BITMAPINFO頭結(jié)構(gòu)給捕獲窗口, 因為視頻格式是設(shè)備細(xì)節(jié), 你的程序應(yīng)該檢查返回值以便確定此格式是否已被接受.
8. 預(yù)覽視頻(Previewing Video)
下面的例子使用capPreviewRate宏來設(shè)置每66毫秒顯示一幀, 并使用capPreview宏將它放置在捕獲窗口里.
capPreviewRate(hWndC, 66); // rate, in milliseconds
capPreview(hWndC, TRUE); // starts preview
// Preview
capPreview(hWnd, FALSE); // disables preview
9.將視頻設(shè)置為overlay模式(Enabling Video Overlay)
下面的例子: capDriverGetCaps宏確定此捕獲卡是否有overlay功能, 如果有就使用宏來設(shè)置它
CAPDRIVERCAPS CapDrvCaps;
capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));
if (CapDrvCaps.fHasOverlay)
capOverlay(hWndC, TRUE);
10.命名捕獲文件(Naming the Capture File)
下面的例子: 使用capFileSetCaptureFile宏來指定預(yù)備文件名為:MYCAP.AVI, capFileAlloc宏預(yù)先指定它的大小為5M.
char szCaptureFile[] = "MYCAP.AVI";
capFileSetCaptureFile( hWndC, szCaptureFile);
capFileAlloc( hWndC, (1024L * 1024L * 5));
11.格式化聲頻捕獲(Formatting Audio Capture)
下面的例子使用capSetAudioFormat來設(shè)置聲頻格式為:11kHz, PCM 8位, 立體聲
WAVEFORMATEX wfex;
wfex.wFormatTag = WAVE_FORMAT_PCM;
wfex.nChannels = 2; // Use stereo
wfex.nSamplesPerSec = 11025;
wfex.nAvgBytesPerSec = 22050;
wfex.nBlockAlign = 2;
wfex.wBitsPerSample = 8;
wfex.cbSize = 0;
capSetAudioFormat(hWndC, &wfex, sizeof(WAVEFORMATEX));
12.改變視頻捕獲設(shè)置(Changing a Video Capture Setting)
下面的例子使用capCaptureGetSetup和capCaptureSetSetup宏得將捕獲幀數(shù)從缺省的15幀改成每秒10幀.
CAPTUREPARMS CaptureParms;
float FramesPerSec = 10.0;
capCaptureGetSetup(hWndC, &CaptureParms, sizeof(CAPTUREPARMS));
CaptureParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 /FramesPerSec);
capCaptureSetSetup(hWndC, &CaptureParms, sizeof (CAPTUREPARMS));
13.捕獲數(shù)據(jù)(Capturing Data)
下面的例子使用capCaptureSequence宏來開始捕獲視頻并使用capFileSaveAs宏來將捕獲的數(shù)據(jù)拷貝至NEWFILE.AVI文件中.
char szNewName[] = "NEWFILE.AVI";
// Set up the capture operation.
capCaptureSequence(hWndC);
// Capture.
capFileSaveAs(hWndC, szNewName);
14.增加一個信息塊(Adding an Information Chunk)
如果你需要在你的程序捕獲的聲頻和視頻數(shù)據(jù)中加入你的其他信息, 你可以創(chuàng)建一個信息塊并將它們插入捕獲文件中, 信息塊可以包含一些典型的信息, 例如:版權(quán)信息,視頻來源, 外部定位信息等. 下面的例子使用capFileSetInfoChunk宏來插入一個信息塊, 里面包含了一個SMPTE的時間代碼.
// This example assumes the application controls
// the video source for preroll and postroll.
CAPINFOCHUNK cic;
// .
// .
// .
cic.fccInfoID = infotypeSMPTE_TIME;
cic.lpData = "00:20:30:12";
cic.cbData = strlen (cic.lpData) + 1;
capFileSetInfoChunk (hwndC, &cic);
15.在程序中加入一個回調(diào)函數(shù)(Adding Callback Functions to an Application)
一個程序可以為捕獲窗口登記一個回調(diào)函數(shù)以便在以下的這些情況下通知程序.
狀態(tài)改變
錯誤發(fā)生
視頻框架和聲頻緩沖區(qū)變得可用
程序應(yīng)用在捕獲視頻流的過程中接收
下面的例子創(chuàng)建一個捕獲窗口并登記狀態(tài),錯誤,視頻流和框架回調(diào)函數(shù)在消息處理對列中, 也包括了一個終止回調(diào)函數(shù)的說明.
case WM_CREATE:
{
char achDeviceName[80]
char achDeviceVersion[100]
char achBuffer[100]
WORD wDriverCount = 0
WORD wIndex
WORD wError
HMENU hMenu
// Create a capture window using the capCreateCaptureWindow macro.
ghWndCap = capCreateCaptureWindow((LPSTR)"Capture Window",
WS_CHILD | WS_VISIBLE, 0, 0, 160, 120, (HWND) hWnd, (int) 0);
// Register the error callback function using the
// capSetCallbackOnError macro.
capSetCallbackOnError(ghWndCap, fpErrorCallback);
// Register the status callback function using the
// capSetCallbackOnStatus macro.
capSetCallbackOnStatus(ghWndCap, fpStatusCallback);
// Register the video-stream callback function using the
// capSetCallbackOnVideoStream macro.
capSetCallbackOnVideoStream(ghWndCap, fpVideoCallback);
// Register the frame callback function using the
// capSetCallbackOnFrame macro.
capSetCallbackOnFrame(ghWndCap, fpFrameCallback);
// Connect to a capture driver
break;
}
case WM_CLOSE:
{
// Use the capSetCallbackOnFrame macro to
// disable the frame callback. Similar calls exist for the other
// callback functions.
capSetCallbackOnFrame(hWndC, NULL);
break;
}
16.創(chuàng)建一個狀態(tài)回調(diào)函數(shù)(Creating a Status Callback Function)
下面的例子是創(chuàng)建一個簡單的狀態(tài)回調(diào)函數(shù),登記此回調(diào)函數(shù)使用capSetCallbackOnStatus宏.
// StatusCallbackProc: status callback function
// hWnd: capture window handle
// nID: status code for the current status
// lpStatusText: status text string for the current status
//
LRESULT PASCAL StatusCallbackProc(HWND hWnd, int nID,
LPSTR lpStatusText)
{
if (!ghWndMain)
return FALSE;
if (nID == 0) { // Clear old status messages.
SetWindowText(ghWndMain, (LPSTR) gachAppName);
return (LRESULT) TRUE;
}
// Show the status ID and status text...
wsprintf(gachBuffer, "Status# %d: %s", nID, lpStatusText);
SetWindowText(ghWndMain, (LPSTR)gachBuffer);
return (LRESULT) TRUE;
}
17.創(chuàng)建一個錯誤回調(diào)函數(shù)( Creating an Error Callback Function)
下面的例子是創(chuàng)建一個簡單的錯誤回調(diào)函數(shù),登記此回調(diào)函數(shù)使用capsetCallbackOnError宏:
// ErrorCallbackProc: error callback function
// hWnd: capture window handle
// nErrID: error code for the encountered error
// lpErrorText: error text string for the encountered error
//
LRESULT PASCAL ErrorCallbackProc(HWND hWnd, int nErrID,
LPSTR lpErrorText)
{
if (!ghWndMain)
return FALSE;
if (nErrID == 0) // Starting a new major function.
return TRUE; // Clear out old errors.
// Show the error identifier and text.
wsprintf(gachBuffer, "Error# %d", nErrID);
MessageBox(hWnd, lpErrorText, gachBuffer,
MB_OK | MB_ICONEXCLAMATION);
return (LRESULT) TRUE;
}
18.創(chuàng)建一個框架回調(diào)函數(shù)(Creating a Frame Callback Function)
登記此回調(diào)函數(shù)使用capSetCallbackOnFrame宏:
// FrameCallbackProc: frame callback function
// hWnd: capture window handle
// lpVHdr: pointer to struct containing captured
// frame information
//
LRESULT PASCAL FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
{
if (!ghWndMain)
return FALSE;
wsprintf(gachBuffer, "Preview frame# %ld ", gdwFrameNum++);
SetWindowText(ghWndMain, (LPSTR)gachBuffer);
return (LRESULT) TRUE
}
六.將四個標(biāo)準(zhǔn)對話框改成函數(shù)調(diào)用形式
系統(tǒng)提供了四個標(biāo)準(zhǔn)的對話框:AudioFormat, VideoFormat, VideoSource, Video Compression,但有時程序希望通過函數(shù)控制它們,而不是使用系統(tǒng)提供的那個單一的對話框,此時就應(yīng)該使用函數(shù)調(diào)用的方法:
AudioFormat對話框
可以通過使用capSetAudioFormat來實現(xiàn),此時要使用WAVEFORMATEX結(jié)構(gòu)。
例如:改成PCM格式,立體聲,16聲道,12.05kHz,則:
WAVEFORMATEX audioFormat;
// 確定寬度
acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT,&dwSize);
dwSize = max (dwSize, capGetAudioFormatSize (m_hwCapCapturing));
// 設(shè)置參數(shù)
audioFormat.wFormatTag = WAVE_FORMAT_PCM;
audioFormat.nChannels = 2;
audioFormat.nSamplesPerSec = 120500;
audioFormat.wBitsPerSample =16;
audioFormat.nBlockAlign = nBitsPerSample * nChannels / 8;
audioFormat.nAvgBytesPerSec =
audioFormat.nBlockAlign * nSamplesPerSec;
// 更新
capSetAudioFormat(ghCapWnd,&audioFormat,dwSize);
VideoFormat對話框
可以通過使用capSetVideoFormat來實現(xiàn),此時要使用BITMAPINFOHEADER結(jié)構(gòu)。
例如:設(shè)置圖片大小為RGB24位歲,大小為230X160
BITMAPINFOHEADER bi;
DWORD dwSize,dw;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = 320; // 起作用
bi.biHeight = 160; // 起作用
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 176;
bi.biYPelsPerMeter = 144;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwSize = bi.biSize + ((bi.biBitCount > 8 || bi.biClrUsed) ? (bi.biClrUsed * sizeof(PALETTEENTRY)) : (2 ^ bi.biBitCount * sizeof(PALETTEENTRY)));
dw = capSetVideoFormat(m_hwCapCapturing, &bi, dwSize);
VideoSource對話框
沒有找到現(xiàn)成的方法,但視頻捕獲卡提供的CD里面有一個動態(tài)鏈接庫可以實現(xiàn)。
Video Compression對話框
可以通過使用ICOpen,ICInfo等函數(shù)聯(lián)合起來,得到當(dāng)前系統(tǒng)里面的視頻壓縮驅(qū)動的列表,并可選擇其一,MSDN里面有一個程序示范了此用戶,程序名叫:ICWalk。