IAMStreamConfig 设置问题/设置分辨率/准确获取filter

本文探讨了使用DirectShow在Windows平台上配置摄像头的具体方法。通过详细分析IAMStreamConfig接口的应用,解决了获取摄像头filter及设置视频流参数的问题,并给出了有效的代码示例。

        IAMStreamConfig *pConfig = NULL;
        hr = g_pCapture->FindInterface(
            &LOOK_DOWNSTREAM_ONLY,// Preview pin.
            0,// Any media type.
            pSrcFilter,
            IID_IAMStreamConfig,(void**)&pConfig);

        if (FAILED(hr)) {
            Msg(TEXT("Couldn't get the IAMStreamConfig!  hr=0x%x"), hr);
            return hr;
        }

 

//上面这段代码老是不能准确获得我所要的filter然后进行配置,即使获得了,也是枚举不出我想要的配置。

 

在网上找,有两个方面的答案,一是http://topic.youkuaiyun.com/u/20080827/17/8b2dcced-316f-4b9d-80f6-e4776931ec73.html

要在摄像头支持的参数中选取

 

二是下面这种方法,来自:http://social.msdn.microsoft.com/Forums/en/windowsdirectshowdevelopment/thread/da858fcb-6f49-4d9d-8211-5092c3974697   中kavuncu的答案


hr = pGraph->AddFilter( pSource, L"Source" );

// Tell the grabber to grab 24-bit video. Must do this

// before connecting it

//

AM_MEDIA_TYPE m;

CMediaType GrabType;

GrabType.SetType( &MEDIATYPE_Video );

GrabType.SetSubtype( &MEDIASUBTYPE_YUY2 );

hr = pGrabber->SetMediaType( &GrabType );

// Get the output pin and the input pin

//

CComPtr< IPin > pSourcePin;

CComPtr< IPin > pGrabPin;

pSourcePin = GetOutPin( pSource, 0 );

VidFormat vit={ 640, 480,60};VidFormat* vidFmt=&vit;

IAMStreamConfig* pVSC;

AM_MEDIA_TYPE *pmt = NULL;

pSourcePin->QueryInterface( IID_IAMStreamConfig, (void **) &pVSC );

VIDEO_STREAM_CONFIG_CAPS scc;

int piCount, piSize;

hr = pVSC->GetNumberOfCapabilities(&piCount, &piSize);

if(hr == S_OK)

{

for(int i = 0; i < piCount; i++)

{

pVSC->GetStreamCaps(i, &pmt, reinterpret_cast<BYTE*>(&scc));

VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);

if(pVih->bmiHeader.biWidth == vidFmt->width && pVih->bmiHeader.biHeight == vidFmt->height)

{

if( vidFmt->framerate > 0 )

pVih->AvgTimePerFrame = (LONGLONG)(10000000 / vidFmt->framerate);

pVSC->SetFormat(pmt);

/* cvcam_properties[(uint)camera].srcwidth = pVih->bmiHeader.biWidth;

cvcam_properties[(uint)camera].srcheight = abs(pVih->bmiHeader.biHeight);*/

DeleteMediaType(pmt);

 

 

 

### 如何在DirectShow中设置图像分辨率 在DirectShow框架中,设置图像分辨率通常涉及配置捕获设备的属性以及调整其支持的格式。具体来说,可以通过 `IAMStreamConfig` 接口来访问和修改视频流的格式参数[^1]。 以下是详细的说明: #### 使用 `IAMStreamConfig` 配置视频分辨率 `IAMStreamConfig` 是 DirectShow 提供的一个接口,用于管理媒体流的配置选项。对于视频捕获设备而言,该接口允许开发者指定帧大小、帧率以及其他相关参数。要更改图像分辨率,需执行以下操作: 1. **获取 `IAMStreamConfig` 接口实例** 在构建过滤器图的过程中,找到与目标视频流关联的 `IAMStreamConfig` 实例。 2. **枚举可用的媒体类型** 调用 `IAMStreamConfig::GetNumberOfCapabilities` 和 `IAMStreamConfig::GetStreamCaps` 来检索当前设备所支持的所有媒体类型及其对应的分辨率列表。 3. **选择合适的媒体类型并应用** 找到满足需求的 AM_MEDIA_TYPE 结构体(其中包含宽度、高度等信息),并通过 `IAMStreamConfig::SetFormat` 将其应用于视频流。 下面是一个简单的代码示例展示如何完成这一过程: ```cpp #include <dshow.h> // 假设已经初始化了 COM 并创建好了滤波器图表 (m_pGraph) HRESULT SetVideoResolution(IGraphBuilder* pGraph, int width, int height) { ICaptureGraphBuilder2* pBuild = nullptr; IBaseFilter* pCap = nullptr; // 创建 Capture Graph Builder HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild); if (FAILED(hr)) return hr; // 绑定到现有的 Filter Graph pBuild->SetFiltergraph(pGraph); // 添加摄像头作为源滤波器 hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap, IID_IBaseFilter, (void**)&pCap); if (FAILED(hr)) return hr; // 获取 IAMStreamConfig 接口 IAMStreamConfig* pConfig = nullptr; IPin* pPin = nullptr; hr = GetPinByName(pCap, L"Capture", &pPin); // 自定义函数:按名称查找 Pin if (SUCCEEDED(hr)) hr = pPin->QueryInterface(IID_IAMStreamConfig, (void**)&pConfig); if (FAILED(hr)) return hr; // 枚举所有可能的能力 int iCount = 0, iSize = 0; hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize); if (FAILED(hr)) return hr; VIDEO_STREAM_CONFIG_CAPS caps; AM_MEDIA_TYPE* mt = nullptr; for (int i = 0; i < iCount && !mt; ++i) { hr = pConfig->GetStreamCaps(i, &mt, (BYTE*)&caps); if (SUCCEEDED(hr) && IsMediaTypeSuitable(mt, width, height)) { break; } if (mt != nullptr) DeleteMediaType(mt), mt = nullptr; } if (!mt) return E_FAIL; // 如果找不到适合的媒体类型,则失败 // 应用选定的媒体类型 hr = pConfig->SetFormat(mt); DeleteMediaType(mt); SafeRelease(&pConfig); SafeRelease(&pPin); SafeRelease(&pCap); SafeRelease(&pBuild); return hr; } bool IsMediaTypeSuitable(const AM_MEDIA_TYPE* mt, int desiredWidth, int desiredHeight) { if (mt->majortype != MEDIATYPE_Video || mt->subtype != MEDIASUBTYPE_RGB24 || mt->formattype != FORMAT_VideoInfo) return false; VIDEOINFOHEADER* vih = reinterpret_cast<VIDEOINFOHEADER*>(mt->pbFormat); return vih->bmiHeader.biWidth == desiredWidth && vih->bmiHeader.biHeight == desiredHeight; } ``` 以上代码片段展示了如何利用 `IAMStreamConfig` 修改视频流的分辨率。需要注意的是实际项目中的错误处理应更加全面,并考虑不同硬件间的兼容性差异[^2]。 #### 性能考量 尽管 DirectShow 功能强大,但在某些场景下的表现可能会受到限制。例如当尝试将其集成至复杂的 GUI 框架如 MFC 中时,CPU 占用率较高可能是常见现象[^3]。如果发现性能瓶颈严重,可探索其他替代方案或者优化现有逻辑。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值