荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: scanf (carefully), 信区: Visual
标  题: [zz]视频扑获笔记(五)
发信站: 荔园晨风BBS站 (Mon Oct 27 21:55:48 2003), 站内信件

五.使用视频捕获

1.创建捕获窗口(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.连接到捕获驱动(Connecting to a Capture Driver)
下面的例子是将MSVIDEO驱动连接到句柄为hWndC的捕获窗口, 然后调用
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.列举所有已安装的捕获驱动(Enumerating Installed Capture Drivers)
下面的例子使用capGetDriverDescription函数得到已安装的捕获驱动的名称及版
本:
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.得到捕获驱动的性能(Obtaining the Capabilities of a Capture Driver)
发送WM_CAP_DRIVER_GET_CAPS消息可以得到捕获驱动的性能,并保存入一个
CAPDRIVERCAPS结构.每当程序连接一个新的捕获驱动到一个捕获窗口时, 就应该更
新CAPDRIVERCAPS结构. 下面的程序举例说明了如何使用capDriverGetCaps宏来得
到捕获驱动的性能:

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.得到捕获窗口的状态(Obtaining the Status of a Capture Window)
下面的例子使用SetWindowPos函数使捕获窗口与进来的视频流尺寸保持一致, 视频
流的基本信息是使用capGetStatus宏得到的, 保存在CAPSTATUS结构中.

CAPSTATUS CapStatus;
capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));
SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth,
CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);

6.显示对话框设置视频特征(Displaying Dialog Boxes to Set Video
Characteristics)
每个视频捕获卡一般能提供三个不同的对话框用于控制视频捕获及数字化处理. 下
面的例子说明如何显示这些对话框, 在显示这些对话框之前,使用了
capDriverGetCaps宏来检查CAPDRIVERCAPS结构, 以检测该卡是否有显示这些对话
框:

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.得到和设置视频格式(Obtaining and Setting the Video Format)
BITMAPINFO结构的长度既适应于标准的也适应于压缩的数据格式, 所有程序必须总
是询问此结构的尺寸以便在得到当前的视频格式之前分配内存. 下面的例子就是使
用capGetVideoFormatSize宏来得到缓冲区尺寸并调用capGetVideoFormat宏来得到
当前的视频格式.

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消息)发送一个
BITMAPINFO头结构给捕获窗口, 因为视频格式是设备细节, 你的程序应该检查返回
值以便确定此格式是否已被接受.

8. 预览视频(Previewing Video)
下面的例子使用capPreviewRate宏来设置每66毫秒显示一帧, 并使用capPreview宏
将它放置在捕获窗口里.

capPreviewRate(hWndC, 66); // rate, in milliseconds
capPreview(hWndC, TRUE); // starts preview
// Preview
capPreview(hWnd, FALSE); // disables preview

9.将视频设置为overlay模式(Enabling Video Overlay)
下面的例子: capDriverGetCaps宏确定此捕获卡是否有overlay功能, 如果有就使
用宏来设置它

CAPDRIVERCAPS CapDrvCaps;
capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));

if (CapDrvCaps.fHasOverlay)
capOverlay(hWndC, TRUE);

10.命名捕获文件(Naming the Capture File)
下面的例子: 使用capFileSetCaptureFile宏来指定预备文件名为:MYCAP.AVI,
capFileAlloc宏预先指定它的大小为5M.

char szCaptureFile[] = "MYCAP.AVI";
capFileSetCaptureFile( hWndC, szCaptureFile);
capFileAlloc( hWndC, (1024L * 1024L * 5));

11.格式化声频捕获(Formatting Audio Capture)
下面的例子使用capSetAudioFormat来设置声频格式为: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.改变视频捕获设置(Changing a Video Capture Setting)
下面的例子使用capCaptureGetSetup和capCaptureSetSetup宏得将捕获帧数从缺省
的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.捕获数据(Capturing Data)
下面的例子使用capCaptureSequence宏来开始捕获视频并使用capFileSaveAs宏来
将捕获的数据拷贝至NEWFILE.AVI文件中.

char szNewName[] = "NEWFILE.AVI";
// Set up the capture operation.
capCaptureSequence(hWndC);
// Capture.
capFileSaveAs(hWndC, szNewName);

14.增加一个信息块(Adding an Information Chunk)
如果你需要在你的程序捕获的声频和视频数据中加入你的其他信息, 你可以创建一
个信息块并将它们插入捕获文件中, 信息块可以包含一些典型的信息, 例如:版权
信息,视频来源, 外部定位信息等. 下面的例子使用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.在程序中加入一个回调函数(Adding Callback Functions to an
Application)
一个程序可以为捕获窗口登记一个回调函数以便在以下的这些情况下通知程序.

状态改变
错误发生
视频框架和声频缓冲区变得可用
程序应用在捕获视频流的过程中接收

下面的例子创建一个捕获窗口并登记状态,错误,视频流和框架回调函数在消息处理
对列中, 也包括了一个终止回调函数的说明.

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.创建一个状态回调函数(Creating a Status Callback Function)
下面的例子是创建一个简单的状态回调函数,登记此回调函数使用
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.创建一个错误回调函数( Creating an Error Callback Function)
下面的例子是创建一个简单的错误回调函数,登记此回调函数使用
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.创建一个框架回调函数(Creating a Frame Callback Function)
登记此回调函数使用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 ;
}

--

→我:(打劫内裤,快脱,不然,老子毙了你!)
看  ●    ○   ╮╮     看
↓  █┳  ┗█┛  \█/ 我倒!~~↓
面  ┏┓   ┛┗   ●     面
→你:(大哥,我今天没穿啊,不要~不要啊!)

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.36.110]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店