-
DirectShow
的中文资料之设备列举和捕捉接口
这篇解释和示例如何通过
DirectShow
的接口去初始化和访问系统的硬件设备。代表性的,
DirectShow
应用程序使用下面类型的硬件。
音
/
视频捕捉卡
< br>
音频或视频回放卡
音频或视
频压缩或解压卡
(
象
MPEG
解码器
)
下面将以
A
V
设备作参考。
如何列举设备
包括在
DirectShow SDK
中的接口,类,和例子提供了音
/
视频捕捉和回放的功能。因为
文件
源过滤器和
filter graph manager<
/p>
处理了内在的工作,所有,添加捕捉功能到一个应用程序
中,
p>
只需添加很少的代码。
你可以通过列举系统硬件设备和得到设备列表
完成特别的任务
(
例如:
所有的视频捕
捉卡的列表
)
。
DirectShow
自动为
win32
和
< br>Video for Windows
设备实例化
过滤器。
要
AV
设备工作,
首先,
p>
你必须检测当前系统存在的设备。
ICreateDevEnum<
/p>
接口建立指定类
型的列表。提供你需要的检测和设置硬件的功能。
访问一个指定的设备有三步,详细的说明和
代码如下:
建立系统硬件设备的列表
首先
,
申明一个列表指针,
然后通过
CoCreateInstance
建立。
p>
CLSID_SystemDeviceEnum
是我们想建立对象
的类型,
IID_ICreateDevEnum
是接口的
p>
GUID
。
ICreateDevEnum *pCreateDevEnum
CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
其
次,建立一个特别类型的硬件设备的列表
(
例如视频捕捉卡
p>
)
申明一个
IEnumMoniker<
/p>
接口,并把他传给
ICreateDevEnum::Creat
eClassEnumerator
方法。你就可以使用他访问新得到的列表了。
IEnumMoniker *pEnumMon
pCreateDevEnum->CreateClassEnumerator(
[specify
device
GUID
here],
&pEnumMon,
0);
最后,列举列表直到你得到你想要的设备为止。
如果先前的
CreateClassEnumerator
< br>调用成功了,你可以用
IEnumMoniker::Next
< br>得到设
备。
调用
IMonike
r::BindToObject
建立一个和选择的
devic
e
联合的
filter
,
并且装载
filter
的属性
(CLSID,FriendlyName, and DevicePath)
。<
/p>
不需要为
if
语句的
(1 == cFetched)
困
惑,在测试合法性之
前,
pEnumMon->Next(1, &pMon, &cFetched)
p>
方法会设置他为返回
对象的数字
(
如果成功了为
1)
。
ULONG cFetched = 0;
IMoniker *pMon
if
(S_OK == (pEnumMon->Next(1, &pMon, &cFetched)) &&
(1 == cFetched))
{
pMon->BindToObject(0, 0, IID_IBaseFilter, (void
**)&[desired interface
here])
;
好,现在你有了一个
IMonik
er
指针,你可以添加设备的
filter
到
filter graph
。一旦你添加
了
filter
,你就不需要
IMoniker
指针,设备列表,或系统设备列表。
pGraph->AddFilter([desired
interface here], L
pMon->Release() // Release moniker
}
pEnumMon->Release() // Release
the class enumerator
}
pCreateDevEnum->Release();
实
例:
AMCap
中的设备列表代码
<
/p>
AMCap
例子中,把所有的接口指针和一些成员变量保存在一个
全局结构
gcap
中了。
定义如下:
struct
_capstuff {
char
szCaptureFile[_MAX_PATH];
WORD
wCapFileSize; // size in Meg
ICaptureGraphBuilder *pBuilder;
IVideoWindow *pVW;
IMediaEventEx *pME;
IAMDroppedFrames *pDF;
IAMVideoCompression *pVC;
IAMVfwCaptureDialogs *pDlg;
IAMStreamConfig *pASC; // for audio cap
IAMStreamConfig *pVSC; //
for video cap
IBaseFilter
*pRender;
IBaseFilter
*pVCap, *pACap;
IGraphBuilder
*pFg;
IFileSinkFilter *pSink;
IConfigAviMux
*pConfigAviMux;
int
iMasterStream;
BOOL
fCaptureGraphBuilt;
BOOL
fPreviewGraphBuilt;
BOOL
fCapturing;
BOOL
fPreviewing;
BOOL
fCapAudio;
int
iVideoDevice;
int
iAudioDevice;
double
FrameRate;
BOOL
fWantPreview;
long
lCapStartTime;
long
lCapStopTime;
char
achFriendlyName[120];
BOOL
fUseTimeLimit;
DWORD
dwTimeLimit;
} gcap;
例子用
uIndex
变量循环列举系统的硬件设备。
BOOL
InitCapFilters()
{
HRESULT hr;
BOOL f;
UINT uIndex = 0;
MakeBuilder
函数建立了一个
filter graph builder(
参考建立一个捕捉程序
)
。
f =
MakeBuilder();
建立设备列表对象,得到
p>
ICreateDevEnum
接口
ICreateDevEnum *pCreateDevEnum;
hr =
CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
建立
一个特别类型的硬件设备的列表,类的
ID
是
< br>CLSID_VideoInputDeviceCategory
。现
在有了一个
IEnumMoniker
指针,可
以访问捕捉设备的列表了。
IEnumMoniker *pEm;
hr = pCreateDevE
num->CreateClassEnumerator(CLSID_VideoInputDeviceC
ategory,
&pEm, 0);
pCreateDevEnum->Release(); // We don't need the
device enumerator anymore
pEm->Reset(); // Go to the start of the
enumerated list
现在需要实际的设备了
,调用
IEnumMoniker::Next
,然后用得到
的指针
pM
调用
IMoniker::
BindToObject
,绑定
filter
到设备。如果你不想建立联合的
filter
,使用<
/p>
IMoniker::BindToStorage
代替
IMoniker::BindToObject
。
< br>
ULONG cFetched;
IMoniker *pM; // This will access the actual
devices
= NULL;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)