Microsoft® Video for Windows® (VFW)提供的函数可以让应用程序去处理视频数据。 VFW 在16位Windows的时候就被引入了。它的许多重要功能已经被DirectX取代了。 要获得更多的信息,你可以参考DirectX 的文档。
下面讲介绍VFW的视频捕获:
3.视频捕获
你可以使用windows的AVICap 类轻松地完成视频捕获。AVICap 提供给应用程序一个简单的、基于消息的接口去访问视频设备和录音设备,并且可以控制处理视频流捕获。
3.1 关于视频捕获
AVICap支持实是视频流捕获和实时单帧图像捕获。另外,AVICap 提供了对视频源的控制(MCI媒体控制接口设备),因此使用者可以通过应用程序控制一个视频源开始和结束的位置,并且可以加大对帧捕获的控制。
你使用AVICap 类可以完成如下的任务:
l
l
l
l
l
l
l
l
l
3.1.1视频捕获:最简单的方法
视频捕获将数字化一个视频流和音频数据,并且将他们保存在硬盘和其他存储设备上。
这里将描述如何在应用程序中简单地应用视频捕获,它通过三句代码实现。它还介绍了如何通过发送消息给视频捕获窗口来结束或中断一个视频会话。
AVICap 捕获窗口可以把捕获的音视频信息写入一个AVI文件中。你的应用程序可以自由地处理这个AVI文件、管理缓存区的音视频数据、还可以在底层访问音视频设备的驱动器。AVICap为应用程序提供了一个灵活的接口。你可以使用下面的代码,在你的应用程序中加入视频捕获:
HWndC
SendMessage
SendMessage
宏接口同样有用,你可以选择是使用宏接口还是SendMessage 函数来实现上面的功能,不过宏接口可以让你的代码更加容易理解。下面就使用了宏接口。
HWndC
capDriverConnect
capCaptureSequence
你的应用程序创建AVICap捕获窗口,并和视频设备建立连接后。你创建的这个捕获窗口就准备捕获数据了。这时,你可以通过发送WM_CAP_SEQUENCE消息(或capCaptureSequence 宏)开始对数据进行捕获。
WM_CAP_SEQUENCE将使用默认设置,开始对视频和音频进行捕获,并把数据放在一个CAPTURE.AVI的文件中,捕获动作将一直持续,除非有下面的事件发生:
l
l
l
在应用程序中,你可以通过发送WM_CAP_STOP命令(或capCaptureStop)给捕获窗口,让它停止向文件写数据。你还可以通过发送WM_CAP_ABORT命令(或capCaptureAbort)给捕获窗口,让它中断捕获操作。
3.1.2捕获基本设置
通过对定义在CAPTUREPARMS结构中的捕获参数进行修改,你可以完成:
l
l
l
捕获的帧频率
捕获的帧频率表示在一个捕获会话中,每秒要捕获多少帧。你通过WM_CAP_GET_SEQUENCE_SETUP 消息(capCaptureGetSetup宏)可以得到当前捕获的帧频率。当前的帧频率被保存在CAPTUREPARMS结构的dwRequestMicroSecPerFram
退出数据捕获
你可以让用户按这几种方法退出一个捕获会话,按键盘上的一个键或几个组合键、或者按鼠标的左键或者是右键。如果用户退出一个实时的捕获会话,那么捕获文件中的内容将被系统丢弃掉。如果用户退出一个步帧(step-frame)捕获的会话,捕获文件将保存到退出时刻前的所有数据。
vKeyAbort 默认值是 VK_ESCAPE。在重新指定其他按键前,你必须调用RegisterHotKey 函数。fAbortLeftMouse 和 fAbortRightMouse 是TRUE。
时间限定
通过使用CAPTUREPARMS结构的fLimitEnabled 和wTimeLimit成员,你可以去限定一个捕获操作的时间周期。fLimitEnabled 表示是否要对捕获操作限定时间, wTimeLimit 用于指定限定时间的最大值。
fLimitEnabled 默认值为FALSE.
3.1.3捕获窗口
捕获窗体类似于一个标准控件(不如按钮、列表框…),它一般使用WS_CHILD 和 WS_VISIBLE窗口类型。.
创建一个AVICap捕获窗口
建立捕获窗口到捕获设备的连接
你可以动态地连接或断开捕获窗口与设备间的链接。通过使用WM_CAP_DRIVR_CONNECT消息(或capDriverConnect宏),可以实现捕获窗体与设备驱动间的连接。当捕获窗体和捕获设备驱动连接后,你就可以发送针对设备的消息给该窗体了。
如果你的系统安装了多个捕获设备,你可以通过在发送WM_CAP_DRIVER_CONNECT消息时,设置wPrarm参数(integer)。来指定捕获窗口与那个具体的视频捕获设备相连接。
WPrarm参数是一个整数,它表示一个系统已经安装的视频捕获设备列表的索引(注册表中或这System.ini [drivers]中的信息)。该列表的索引从0开始。
通过发送WM_CAP_DRIVER_GET_NAME消息(capDriverGetName宏),可以获得与指定窗体连接的捕获设备的名称。通过发送WM_CAP_DRIVER_GET_VERSION消息(capDriverGetVersion宏),可以获得与指定窗体连接的捕获设备的版本。
通过发送WM_CAP_DRIVER_DISCONNECT消息(capDriverGetDisconnect宏),可以断开连接。当捕获窗体销毁后,任何连接的视频捕获设备都将自动断开。
父子窗体交付
捕获窗体状态
通过发送WM_CAP_GET_STATUS消息(capGetStatus宏),可以获得当前捕获窗口的状态。这个消息得到一个CAPSTATUS结构体的拷贝,状态信息就在这个结构体的成员中。
CAPSTATUS 结构体包含了图形尺寸大小、滚动位置(scroll position)、是否覆盖(overlay)或者预览(preview)等信息。因为在CAPSTATUS 中的信息是动态的,你的应用程序应该随时去刷新这个结构体中的内容。
改变捕获窗口的尺寸对实际的视频流的尺寸没有影响。
3.1.4捕获和音频驱动器
视频捕获可以做这几个方面的工作:访问 视频源、显示选项、格式和压缩选项。音频捕获包括指定音频格式和选择压缩方式。
捕获驱动性能
通过发送WM_CAP_DRIVER_GET_CAPS消息(capDriverGetCaps宏),可以获得当前连接的捕获设备的性能。发送该消息后,会返回一个CAPDRIVERCAPS结构的对象。设备的性能信息,就在这个对象中。
视频对话框(Video Dialog Boxes)
每个捕获设备的驱动程序都可以为控制视频信号和捕获处理和视频压缩提供4个对话框。这些对话框中的内容都是视频捕获驱动程序定义的。
视频源对话框(Video Source dialog box)用于选择视频输入通道和视频图像的动态参数。它可以列举出当前连接视频设备的信号类型(SVHS和复合类型),并且可以通过该对话框去修改图像的色调、亮度、饱和度。你可以通过使用WM_CAP_DLG_VIDEOSOURCE 消息 (或 capDlgVideoSource 宏)来显示和刷新这个窗口。
视频格式对话框(Video Format dialog box)用于选择数字视频的框架大小和视频图像的色深,以及捕获视频图像的压缩格式。你可以通过使用WM_CAP_DLG_VIDEOFORMAT消息 (或 capDlgVideoFormat宏)来显示和刷新这个窗口。
视频显示对话框(Video Display dialog box)用于控制视频外观。在该对话框上进行了修改只是对视频显示起作用,对于实际的视频数据是不会造成改变的。比如,可以改变显示的颜色,饱和度等等....。你可以通过使用WM_CAP_DLG_VIDEODISPLAY消息 (或 capDlgVideoDisplay宏)来显示和刷新这个窗口。
视频压缩对话框(Video Compression dialog box)用于设置视频压缩的格式。通过使用WM_CAP_DLG_VIDEOCOMPRESSION消息 (或 capDlgVideoCompression宏)来显示和刷新这个窗口。
预览和覆盖模式 (Preview and Overlay )
一般,一个捕获驱动提供两种方式来观看输入的视频流:预览模式和覆盖模式。如果捕获驱动可以提供上面两种模式,那么用户就可以选择其中的模式来使用。
预览模式从捕获设备硬件传输数据帧到系统的内存中,并且在捕获窗口中使用GDI函数来显示这些数据帧。当捕获窗口的父窗体失去焦点的时候,在应用程序的视频预览的数据将变慢,如果父窗体获的焦点后,将对预览显示进行加速。因为预览处理的这种处理方式将大大提高整个系统的效率。
这里用3个消息用于控制预览操作。
l
l
l
当预览和缩放比例属性都打开后,那么视频将被缩放到和捕获窗口尺寸一样大。打开预览模式后,系统将自动关闭覆盖模式。
覆盖模式,将不占用CPU的处理资源,直接在显示器上显示视频内容。所用的处理是有捕获设备硬件来完成。发送WM_CAP_SET_OVERLAY消息(或capOverlay宏)给捕获窗口,可以打开覆盖模式。打开覆盖模式后,将自动关闭预览格式。
无论是预览模式还是覆盖模式,都可以通过发送WM_CAP_SETSCROLL消息(capSetScroollPos宏),可以设置图像的在整个视频帧的滚动位置(scroll position)。
视频格式
You can set the format of captured video da
视频捕获设置
CAPTUREPARMS 数据结构包括了视频流的控制参数。它允许完成如下的任务:
l
l
l
l
l
l
l
通过发送WM_CAP_GET_SEQENCE_SETUP消息(capCaptureGetSetup)给捕获窗体,可以获得一个CAPTUREPARMS数据结构的对象,当前视频捕获的设置信息就在这里面。
你可以改写CAPTUREPARMS对象的成员,来实现对视频捕获信息的修改。修改后,发送WM_CAP_SET_SEQUENCE_SETUP消息(capCaptureSetSetup)给捕获窗体,并把这个CAPTUREPARMS 对象发给捕获窗体,就可以实现修改。
音频格式
通过发送WM_CAP_GET_AUDIOFORMAT消息(capGetAudioFormat 和capGetAudioFormatSize宏)给捕获窗体,你就可以获得当前的音频数据格式或音频数据结构的大小。默认音频捕获格式是 mono, 8-bit, 11 kHz PCM。
当你使用WM_CAP_GET_AUDIOFORMAT消息得到音频格式后,通常会使用WAVEFORMATEX这个数据结构。
通过发送WM_CAP_SET_AUDIOFORMAT消息(capSetAudioFormat宏)给捕获窗体,你可以设置音频数据捕获格式。当设置这个音频格式时,你可以通过一个指针指向一个WAVEFORMAT ,WAVEFORMATEX,或者PCMWAVEFORMAT数据结构。
3.1.5捕获文件和缓存区
捕获文件名
AVICap默认,把音视频数据从捕获窗口保存到当前驱动得根目录下,文件名称为CAPTURE.AVI。发送WM_CAP_FILE_SET_CAPTURE_FILE消息(capFileSetCaptureFile)给捕获窗体,可以改变保存的文件名。这个消息指定文件名;它不实际创建文件,分配空间,也不能打开文件。通过发送WM_CAP_FILE_GET_CAPTURE_FILE消息(capFileFGetCaptureFile宏)给捕获窗口,就可以得到当前文件名。
保存捕获数据到一个新文件
如果用户想保存捕获数据,把数据存到另外一个文件中。可以使用WM_CAP_FILE_SAVEAS消息(capFileSaveAs宏) 。这个消息不能改变捕获文件的名称和内容。你必须去指定新建的文件名,因为捕获文件将保留原来的文件名称。
为捕获文件预分配磁盘空间
在捕获操作前,先在磁盘上为捕获文件建一个指定大小的文件。预分配空间将减少数据保存时的处理时间。可以通过WM_CAP_FILE_ALLOCATE消息(capFileAlloc宏)来预分配一个捕获文件。
你要预分配足够大的磁盘空间去保存预计最大的捕获文件。预分配磁盘空间没有限定捕获文件的大小。如果捕获的数据大于了分配的空间,文件尺寸将自动变大。对一个捕获文件进行重写数据,将对文件的已经分配的磁盘空间进行重写。
通过对捕获文件进行磁盘碎片整理可以提高捕获性能。要对文件进行碎片整理,可以使用一个碎片整理工具来完成,比如Disk Defragmenter。
通过使用没压缩的磁盘来保存数据,同样可以提高性能。因为在捕获期间压缩数据将对磁盘的吞吐量进行限制。
索引大小
通过发送WM_CAP_GET_SEQUENCE_SETUP消息(capCaptureGetSetup宏)给捕获窗口就可以得到当前的索引大小。这个索引大小就保存在CAPTUREPARMS数据结构对象的一个成员中(dwIndexSize)。你可以在dwIndexSize中指定一个新的索引大小,并通过发送消息WM_CAP_SET_SEQUENCE_SETUP(capCaptureSetSetup宏)给捕获窗口完成信息设置。索引默认大小34,952 (允许32K 帧和想匹配的声音缓存器).
音视频块的间隔尺寸(Granularity)
数据块的间隔尺寸是一个AVI文件的逻辑块大小。它用于写和读音视频数据块。当向磁盘写音视频数据时, AVICap 将在每个数据块中加入一个必须的填充块(filler chunks (RIFF "JUNK" chunks))去填充满该数据块。
你可以使用WM_CAP_GET_SEQUENC_SETUP消息(capCaptureGetSetup)去获得当前的块间隔尺寸(Granularity)。CAPTUREPARMS的wChunkGranularity 成员保存的是当前的块间隔尺寸信息。通过对该成员的改写,并发送WM_CAP_GET_SEQUENC_SETUP消息(capCaptureSetSetup),可以对其进行修改。你设置该参数为零的话,那么块间隔尺寸的值就为磁盘的扇区大小。
视频缓存区
这个缓存区将视频数据放在内存的堆中。缓存区的大小可以改变,并且它的大小是由CAPTUREPARMS的wNumVideoRequested 成员和系统可以的内存大小来决定。
你可以使用WM_CAP_GET_SEQUENC_SETUP消息(capCaptureGetSetup)去获得当前的视频缓存区的大小。CAPTUREPARMS的wNumVideoRequested 成员保存的是当前的缓存区尺寸。通过对该成员的改写,并发送WM_CAP_GET_SEQUENC_SETUP消息(capCaptureSetSetup),可以对其进行修改。
音频缓存区
你可以使用下面三种方法来控制捕获的音频数据:
l
l
l
你可以使用WM_CAP_GET_SEQUENC_SETUP消息(capCaptureGetSetup)去获得当前的音频缓存区的设置。CAPTUREPARMS的fCaptureAudio指定在这次捕获操作中是否包括对声音的捕获。WNumAudioRequested保存当前要求的音频缓存区的大小。dwAudioBufferSize 保存当前的音频缓存区的大小。
通过对该成员的改写,并发送WM_CAP_GET_SEQUENC_SETUP消息(capCaptureSetSetup),可以对其进行修改。
fCaptureAudio 默认值是TRUE。The default buffer size (the value of) can contain 0.5 seconds of audio da
3.1.6捕获变化
除了对基于持续时间间隔的流捕获外,AVICap还支持如下的捕获:
l
l
l
l
手动帧捕获
如果你向指定捕获视频流中个别帧,你可以通过WM_CAP_SINGLE_FRAME_OPEN消息、WM_CAP_SINGLE_FRAME消息、WM_CAP_SINGLE_FRMAE_CLOSE消息来控制帧序列(capCaptureSingleFrameOpe
典型应用是,这些消息用于向捕获文件添加单独的帧来创建一个动画, WM_CAP_SINGLE_FRAME_OPEN 为手动捕获操作打开一个文件,WM_CAP_SINGLE_FRAME用于捕获一个单独的帧放在文件中。
WM_CAP_SINGLE_FRMAE_CLOSE用于关闭这个捕获文件。
注:
Still-Image捕获
如果要捕获一个单独的帧作为一个静态图像,你可以使用WM_CAP_GRAB_FRAME_NOSTOP或者 WM_CAP_GRAB_FRAME 消息 ( capGrabFrameNoStop
或capGrabFrame 宏) 在一个帧缓存区中捕获一个图像。你可以通过使用下面的消息来抓获当前显示的图形WM_CAP_GRAB_FRAME ,否则,使用WM_CAP_GRAB_FRAME_NOSTOP。
一旦开始捕获,你可以拷贝图像给其他应用程序。你可以从帧缓存区拷贝一个图像到剪贴板(使用WM_CAP_EDIT_COPY 消息或capEditCopy宏)。你还可以使用如下的消息,将缓存区的一张图像拷贝到一个DIB位图中(WM_CAP_FILE_SAVEDIB消息或capFileSaveDIB宏)。
不使用磁盘存储的捕获
使用WM_CAP_SEUENCE_NOFILE消息(capCaptureSequenceNoFile
从MCI设备进行流捕获
MCI设备加强了实时捕获和步进帧(step-frame)捕获的处理操作。你可以指定一个MCI设备,比如一张影碟或者一盘录像带(VCR)来充当视频源。通过发送消息并指定你要选定的MCI设备的名称。消息:WM_CAP_SET_MCI_DEVICE (capSetMCIDeviceName宏)。获得当前使用的设备可以使用WM_CAP_GET_MCI_DEVICE(capGetMCIDeviceName)消息。
在实时捕获中, the capture window synchronizes the capture operation and compensates for delays associated with positioning the MCI video source and initializing the resources (such as capture buffers) required for capturing da
控制MCI设备的规格信息保存在CAPTRUEPARMS数据结构体的数据成员中。MCI兼容的视频源包括录像机(VCR)和光碟。如果fMCIControl数据成员为TRUE,捕获窗口采用MCI操作。捕获窗口使用dwMCIStartTime和dwMCIStopTime来获得开始和结束位置(毫秒)。如果fMCIControl数据成员的值为FALSE, dwMCIStartTime和dwMCIStopTime的值将被忽略不见。
你可以使用Media Player 去快速检查MCI设备是否正确地连接到了你的系统上,如果在视频显示显示了图像,就表示这个视频源正确连接到了捕获硬件上。
在步进帧(step-frame)捕获情况下, the capture window synchronizes the capture operation and compensates for the delays associated with positioning the MCI video source and initializing the resources required for capturing da
步进帧(step-frame)捕获控制的规格信息保存在CAPTRUEPARMS数据结构体的数据成员中。步进帧(step-frame)捕获除了使用视频捕获要用的数据成员外,还使用其他的数据成员:fStepMCIDevice, fStepCaptureAt2x, 和 wStepCaptureAverageFrame
注意:
如果指定了步进帧捕获, wStepCaptureAverageFrame
关于MCI的信息可以查看MSDN上的信息。
3.1.7高级捕获选项
这节描述在一个捕获操作中,你还可以进行的其他选择。
l
l
l
l
l