查询摄像头支持的格式-IAMStreamConfig 接口

一、IAMStreamConfig 接口

1、接口方法

2、在什么情况下获得此接口?

二、应用示例

1、ICaptureGraphBuilder2::FindInterface 接口示例

2 、IPIN::QueryInterface 接口示例

3 、获得过滤器的输出PIN

4、获得IAMStreamConfig*

5、测试IPIN 是否支持指定的格式


一、IAMStreamConfig 接口

The IAMStreamConfig interface sets the output format on certain capture and compression filters, for both audio and video. Applications can use this interface to set format properties, such as the output dimensions and frame rate (for video) or the sample rate and number of channels (for audio).

IAMStreamConfig 可获得或设置 设备的输出格式、比如视频设备的分辨率、帧速率等 或 音频设备的采样率和通道数等。

1、接口方法

IAMStreamConfig::GetFormat                             检索当前或首选的输出格式。

IAMStreamConfig::GetNumberOfCapabilities     检索此引脚支持的格式功能的数量。

IAMStreamConfig::GetStreamCaps                    检索一组格式功能。

IAMStreamConfig::SetFormat                             设置引脚上的输出格式。
 

2、在什么情况下获得此接口?

ilters expose this interface on their output pins. To use the interface, enumerate the filter's pins and query for IAMStreamConfig

 Or, if you are using the Capture Graph Builder object to build the filter graph, you can call the ICaptureGraphBuilder2::FindInterface method. 

Note that a capture filter might have separate pins for capture and preview.

有两种方式,一是过滤器的输出引脚上,query此接口

另一种方式,使用ICaptureGraphBuilder2::FindInterface 获得此接口

二、应用示例

1、ICaptureGraphBuilder2::FindInterface 接口示例

	HRESULT hr;

	IAMStreamConfig *pConfig = 0;

	hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, 0, pDeviceFilter, IID_IAMStreamConfig, (void**)&pConfig);

		int iCount = 0, iSize = 0;
		hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

		// Check the size to make sure we pass in the correct structure.
		if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
		{
			// Use the video capabilities structure.

			for (int iFormat = 0; iFormat < iCount; iFormat++)
			{
				VIDEO_STREAM_CONFIG_CAPS scc;
				AM_MEDIA_TYPE *pmtConfig;
				hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
				if (SUCCEEDED(hr))
				{
					/* Examine the format, and possibly use it. */
					if ((pmtConfig->majortype == MEDIATYPE_Video) &&
						(pmtConfig->subtype == MEDIASUBTYPE_RGB24) &&
						(pmtConfig->formattype == FORMAT_VideoInfo) &&
						(pmtConfig->cbFormat >= sizeof (VIDEOINFOHEADER)) &&
						(pmtConfig->pbFormat != NULL))
					{
						VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
						// pVih contains the detailed format information.
						LONG lWidth = pVih->bmiHeader.biWidth;
						LONG lHeight = pVih->bmiHeader.biHeight;
						if( lWidth == 1280 )
						{ //2 = '1280x720YUV' YUV, 22 = '1280x800YUV', 26 = '1280x720RGB'
							hr = pConfig->SetFormat(pmtConfig);
						}
					}
					// Delete the media type when you are done.
					DeleteMediaType(pmtConfig);
				}
			}
		}

2 IPIN::QueryInterface 接口示例

HRESULT SetCaptureSize(IPin* capPreviewOutputPin, int width, int height, int avgTimePerFrame)
{
	HRESULT hr = S_OK;
	IAMStreamConfig *streamConfig;
	hr = capPreviewOutputPin->QueryInterface(IID_IAMStreamConfig, (void**)&streamConfig);
	if(FAILED(hr))
	{
		ErrorPrint("Get stream config interface error", hr);
		return hr;
	}
	AM_MEDIA_TYPE *mediaType;
	VIDEO_STREAM_CONFIG_CAPS configCaps;
	hr = streamConfig->GetStreamCaps(0, &mediaType, (BYTE*)&configCaps);
	if (FAILED(hr))
	{
		ErrorPrint("Get stream caps error");
		return hr;
	}
	VIDEOINFOHEADER* videoHeader = (VIDEOINFOHEADER*)mediaType->pbFormat;
	videoHeader->bmiHeader.biWidth = width;
	videoHeader->bmiHeader.biHeight = height;
	videoHeader->bmiHeader.biSizeImage = DIBSIZE(videoHeader->bmiHeader);
	videoHeader->AvgTimePerFrame = avgTimePerFrame;
	streamConfig->SetFormat(mediaType);
	DeleteMediaType(mediaType);
	return S_OK;
}

3 、获得过滤器的输出PIN

IPin* GetPin(void)
{
	IPin * foundPin = NULL;

	if( m_pBaseFilter )
	{
		//创建枚举
		IEnumPins * pinEnum = NULL;
		if (m_pBaseFilter->EnumPins(&pinEnum)==S_OK)
		{
			//复位
			pinEnum->Reset();

			//循环每个PIN
			ULONG fetchCount = 0;
			IPin * pin = NULL;
			while ( !foundPin && S_OK==(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount )
			{
				if (pin)
				{
					//得到PIN信息
					PIN_INFO pinInfo;
					if (S_OK==pin->QueryPinInfo(&pinInfo))
					{
						//检测是否是输出PIN
						if (pinInfo.dir == PINDIR_OUTPUT)
						{
//							pin->AddRef(); //加一引用
							foundPin = pin; //返回PIN
						}
						pinInfo.pFilter->Release();
					}
					pin->Release();
				}
			}
			pinEnum->Release();
		}
	}
    return foundPin;
}

4、获得IAMStreamConfig*

IAMStreamConfig * GetStreamConfig(void)
{
	IAMStreamConfig * pConfig = NULL;
	if (m_pBaseFilter)
	{
		// Get the capture output pin first
		IPin * pCapture = GetPin();
		if (pCapture)
		{
			pCapture->QueryInterface(IID_IAMStreamConfig, (void **)&pConfig);
		}

		if (pConfig)
		{
			pConfig->Release();
		}
	}
	return pConfig;
}

5、测试IPIN 是否支持指定的格式

/* checks to see if a pin's config caps have a specific media type */
static bool PinConfigHasMajorType(IPin *pin, const GUID &type)
{
	HRESULT hr;
	ComPtr<IAMStreamConfig> config;
	int count, size;

	hr = pin->QueryInterface(IID_IAMStreamConfig, (void**)&config);
	if (FAILED(hr))
		return false;

	hr = config->GetNumberOfCapabilities(&count, &size);
	if (FAILED(hr))
		return false;

	vector<BYTE> caps;
	caps.resize(size);

	for (int i = 0; i < count; i++) {
		MediaTypePtr mt;
		if (SUCCEEDED(config->GetStreamCaps(i, &mt, caps.data())))
			if (mt->majortype == type)
				return true;
	}

	return false;
}

参考资料:IAMStreamConfig (strmif.h) - Win32 apps | Microsoft Docs

上一篇:WPF教程二:理解WPF的布局系统和常用的Panel布局


下一篇:JScrollPane+JPanel —— 组件纵向(或垂直)滑动