-
AMCAP
程序详解
文章原始出处
CSDN
作者
capboy
DirectShow
提供了用应用程序从适当的硬件中捕捉和预览音
/
视频
的能力。
数据源包括:
VCR
,
Camera,TV Tuner,Microphone,
或其他的
数据源。一个应用程序可以立刻显示捕捉的
数据
(
预览
)
,或是保存到一个文件中。
< br>
在这个例子中,
ICaptureGraphBuilder
接口是处理捕捉工作的主要接口。你可以在你
自己的捕捉程序中
使用同样的方法和接口。在这里主要讨论
ICaptureGraphBuilder<
/p>
如何执行
音
/
视
频的捕捉。我们假设你已经熟悉了
DirectShow
的
p>
filtergraph
的体系和一般的
c
apturefilter graph
的结构
(
可以参考
DirectShow
基础指南
)
。
ICap
tureGraphBuilder
接口提供了一个
filte
r graph builder
对象,
让你的应用程序在
p>
建立
capture filter graph
< br>时,省去处理很多单调乏味的工作,集中精力于捕捉中。它提供的
方法满足了基本
的捕捉和预览功能的要求。
FindInterface
方法,在
filter grap
h
中查找一个与捕捉有关的详细的接口。使得你可以
访问一个详
细接口的功能,而不需要你去列举
filter graph
中
的
pins
和
filters
。
Rend
erStream
方法,连接源过滤器和渲染过滤器,选择添加一些中间的过滤器。
p>
ControlStream
p>
方法,独立地精确地控制
graph
的开始
和结束帧。
既然是硬件捕捉
,当然要和硬件打交道,接着介绍设备列举和捕捉接口。
通过
ICreateDevEnum::CreateClas
sEnumerator
方法列举捕捉系统中的设备。
之后,<
/p>
实例化一个
DirectShow
的
p>
filter
去使用这个设备。
用
ICaptureGraphB
uilder::FindInterface
去获得与捕捉相关的接口指针
IAMDroppedFrames, IAMVideoCompression, IAMStreamConfig,
以及
IAMVfwCaptureDialogs
。
因为设备列举和捕捉接口比较长,
放在这会打乱结构,所有专门写
了一篇
(
参考
设备列举和
捕捉接口
)
。
NOTE
:
这个示例是
DirectShow
自带
的例子。你可以在
DirectShow SDK
的目录
SampleDSCaputre
看这个例子代码
()
。这里只是他的一些片断代码。可以说是他的中文模块的说明。
AMCap
例子中,把所有的接口指针和一些成员变量保存在一个全局结构
p>
gcap
中了。
当不在需要保存在
gcap
中的接口指
针是,
一定要释放这些接口指针,一般是在程序的析
构函数中,
或是在别的同等功能函数中。如下:
if (er)
er->Release();
er = NULL;
if ()
->Release();
= NULL;
if (gAviMux)
gAviMux->Release();
gAviMux
= NULL;
if (r)
r->Release();
r = NULL;
if ()
->Release();
= NULL;
if ()
->Release();
= NULL;
if ()
->Release();
= NULL;
设置文件名
使用普通的
OpenFile Dialog
< br>获得捕捉文件的信息。通过调用
AllocCaptureFile
函数为
捕捉文件分配空间。这一点是重要的,因为这是个巨大的空间。这样可
以提高捕捉操作的速度。
ICaptureGraphBuilder::AllocC
apFile
执行实际的文件分配,
IFileSinkFil
ter::SetFileName
指示
file
writer filter
使用用户选择的文件名保存数据。
ICaptureGraphBuilder::SetOutputFileName
把
file writer
filter
加入
filter graph(
后面
会介绍,它是
ICaptureGraphBui
lderd
自代的
)
。
SetCaptureFile
和
AllocCaptureFile
函数如下:
/*
* Put up a dialog to allow the user to
select a capture file.
*/
BOOL
SetCaptureFile(HWND hWnd)
{
if (OpenFileDialog(hWnd, ureFile,
_MAX_PAT
H))
{
OFSTRUCT os;
// We have a capture file name
/*
* if
this is a new file, then invite the user to
* allocate som
e
space
*/
if (OpenFile(ureFile, &os, OF_EXIST) ==
HFILE_ERROR)
{
// Bring up dialog, and
set new file size
BOOL f =
AllocCaptureFile(hWnd);
if (!f)
return
FALSE;
}
}
else {
return
FALSE;
}
SetAppCaption();
// need a new app
caption
// Tell the file
writer to use the new file
nam
e
if () {
WCHAR
wach[_MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
ureFile,
-1, wach, _MAX_PATH);
-
>
SetFileName(wach,
NULL);
}
return TRUE;
}
//
Preallocate the capture file
//
BOOL AllocCaptureFile(HWND
hWnd)
{
// We'll
get into an infinite loop in the dlg proc setting
a value
if (ureFile[0]
==
0)
return
FALSE;
/*
* show the
allocate file space dialog to encourage
* the user to pre-allocate space
*/
if
(DoDialog(hWnd, IDD_AllocCapFileSpace,
AllocCapFileProc, 0)) {
// Ensure
repaint after dismissing dialog before
// possibly lengthy operation
UpdateWindow(ghwndApp);
// User has hit OK. Alloc requested capture file
space
BOOL f
=
MakeBuilder();
if (!f)
return FALSE;
WCHAR wach[_MAX_PAT
H];
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED, ureFile,
-1,
wach, _MAX_PATH);
if (er
-
>
AllocCapFile(wach,leSize *
1024L * 1024L) !=
NOERROR) {
MessageBoxA(ghwndApp,
space
return FALSE;
}
return TRUE;
}
else {
return FALSE;
}
}
建立
Graph
Builder
对象
AMCap
的
MakeBui
lder
函数建立了一个
capture graph
builer
对象,通过调用
CoC
reateInstance
获得了
ICaptureGrap
hBuilder
接口指针。
AMCap
把他存储到
gcap
结
构的
pBuilder
中。
// Make a graph builder object we can
use for capture graph building
//
BOOL
MakeBuilder()
{
// We
have one already
if (er)
return TRUE;
HRESULT
hr =
CoCreateInstance((REFCLSID)CLSID_C
aptureGraphBuilder,
NULL, CLSCTX_INPROC,
(REFIID)IID_ICaptureGraphBuilder,(void
**)&er);
return (hr
==
NOERROR) ? TRUE : FALSE;
}
建立
Graph
< br>的渲染部分,并告诉它写文件
(
用先前决定的文件
)
这包括一个
multiplexer filter
和
file
writer
。
DirectShow
提供了一个
AVI
MUX(mult
iplexer)filter
。
在这里
ICaptureGraphBuilder::Set
OutputFileName
是一个关键的方法。它把
multiplexer
和
file
writer
添加到
filter graph
中,连接他们,并设置文件的名字。第一个参
数
MED
IASUBTYPE_Avi
,指出
capture
graph builder
对象将插入一个
AVI
multiplexer
filter
,因此,
file wr
iter
将以
AVI
文件格式记录捕捉
的数据。第二个参数
(wach)
是文件名。
< br>最后的两个参数指出
multiplexer filter (r)
和
file writer filter ()
,
这两个是通过
SetOutputFileNam
e
函数初始化的。
AMCap
存储这
些指针到全局结构
gcap
中。
cap
ture graph builder
对象建立了一个
filter graph
对象
(IGraphBuilder)
,把这两个
filter
加入到
filter
graph
中去。他告诉
file writer
使用指定的文件保存数据。下面的例子演示
了如何调用
SetOutputFileName
。
//
// We need a rendering
section that will write the capture file out in
AVI
// file format
//
WCHAR
wach[_MAX_PATH];
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED, ureFile, -1,
wach,
_MAX_PATH);
GUID guid =
MEDIASUBTYPE_Avi;
hr
=
er-
>
SetOutputFileName(&guid,
wach, &r,
&);
if (hr !=
NOERROR) {
ErrMsg(
goto SetupCaptureFail;
}
获得当前的
Filter Graph
因为在调用
SetOutputFileName
中,
captu
re graph builder
对象建立了一个
filter
gra
ph
,所以你必须把需要的
filter
加入同一个
filter graph
中。通过
ICaptureGraphBuilder::GetFiltergraph
< br>获得新建立的
filter graph
。返回的指针是
参数
。
//
// The graph builder created a filter
graph to do that. Find out what it is,
// and put the video capture filter in
the graph too.
//
hr =
er-
>GetFiltergraph(&);
if
(hr != NOERROR) {
-
-
-
-
-
-
-
-
-
上一篇:描写草的成语
下一篇:古代描写女子的词汇与诗句