⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvideocapturefilter2.cpp

📁 聊天室
💻 CPP
字号:
//
// CVideoCaptureFilter2.cpp
//

#include "stdafx.h"
#include "CVideoCaptureFilter2.h"

#include "UDsUtils.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////////////////////////////////////////
CVideoCaptureFilter2::CVideoCaptureFilter2(IGraphBuilder * inGraph) : 
CDXFilter(inGraph, GUID_NULL, "Video Capture")
{
	mDevice = NULL;
}

CVideoCaptureFilter2::~CVideoCaptureFilter2(void)
{
	ReleaseFilter();
}

void CVideoCaptureFilter2::SetDevice(CAVDevice * inDevice)
{
	mDevice = inDevice;
}

BOOL CVideoCaptureFilter2::CreateFilter(void)
{
	if (mFilter)
	{
		return TRUE;
	}

	ASSERT(mDevice);
	if (mGraph)
	{
		mFilter = UDsUtils::CreateCamera(*mDevice);
		if (mFilter)
		{
			if (SUCCEEDED(mGraph->AddFilter(mFilter, mName)))
			{
				// Settings on the capture filter of camera
				if (!mDevice->IsDVDevice())
				{					
					SetResolution();
					AdjustOutput();
				}

				return TRUE;
			}
		}
	}

	ReleaseFilter();
	return FALSE;
}

void CVideoCaptureFilter2::ReleaseFilter(void)
{
	CDXFilter::ReleaseFilter();
}

long CVideoCaptureFilter2::GetResolution(void)
{
	long resolution = 0;
	IAMAnalogVideoDecoder *	pDecoder = GetAnalogDecoder();
	if (pDecoder)
	{		
		pDecoder->get_TVFormat(&resolution);
	}
	return resolution;
}

IAMAnalogVideoDecoder * CVideoCaptureFilter2::GetAnalogDecoder(void)
{
	IAMAnalogVideoDecoder *	pDecoder = NULL;
	if (mFilter)
	{
		mFilter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)&pDecoder);
		if (pDecoder)
		{
			pDecoder->Release();
			return pDecoder;
		}
	}
	return NULL;
}

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

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

void CVideoCaptureFilter2::SetResolution(void)
{
	if (mDevice && mFilter)
	{
		IAMAnalogVideoDecoder *	pDecoder = GetAnalogDecoder();
		if (pDecoder)
		{
			pDecoder->put_TVFormat(mDevice->GetVideoResolution());
		}
	}
}

// Select a media type first!
// 16 bits is preferred: 
void CVideoCaptureFilter2::AdjustOutput(void)
{
	HRESULT  hr         = S_OK;
	AM_MEDIA_TYPE * pmt = NULL;
	LONGLONG avgTimePerFrame = 500000;  // 20fps

	pmt = SelectMediaType();
	if (pmt)
	{
		if (pmt->formattype == FORMAT_VideoInfo) 
		{
			VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pmt->pbFormat;
			pvi->AvgTimePerFrame       = avgTimePerFrame;
			pvi->bmiHeader.biWidth     = Preferred_Width;
			pvi->bmiHeader.biHeight    = Preferred_Height;
			pvi->bmiHeader.biSizeImage = Preferred_Width * Preferred_Height * pvi->bmiHeader.biBitCount / 8;
			
			IAMStreamConfig * pCfg = GetStreamConfig();
			hr = pCfg->SetFormat(pmt);
		}
		DeleteMediaType(pmt);
	}
}

AM_MEDIA_TYPE * CVideoCaptureFilter2::SelectMediaType(void)
{
	// Preferred sequence: UYVY, YUY2, RGB565, RGB555, RGB24, RGB32  
	VIDEO_STREAM_CONFIG_CAPS  pSCC;
	AM_MEDIA_TYPE * pmt = NULL;
	HRESULT hr = S_OK;
	int nCounts, nSize;
	int preferredIndex = -1;
	enum {
		UYVY = 0, YUY2, RGB565, RGB555, RGB24, RGB32, Unknown
	} currentPreferred, temp;
	currentPreferred = Unknown;

	IAMStreamConfig * pCfg = GetStreamConfig();
	pCfg->GetNumberOfCapabilities(&nCounts, &nSize);
	for (int i = 0; i < nCounts; i++)
	{
		if (pCfg->GetStreamCaps(i, &pmt, (BYTE *)&pSCC) == S_OK)
		{
			if (pmt->subtype == MEDIASUBTYPE_RGB32)
			{
				temp = RGB32;
			}
			else if (pmt->subtype == MEDIASUBTYPE_RGB24)
			{
				temp = RGB24;
			}
			else if (pmt->subtype == MEDIASUBTYPE_RGB565)
			{
				temp = RGB565;
			}
			else if (pmt->subtype == MEDIASUBTYPE_RGB555)
			{
				temp = RGB555;
			}
			else if (pmt->subtype == MEDIASUBTYPE_YUY2)
			{
				temp = YUY2;
			}
			else if (pmt->subtype == MEDIASUBTYPE_UYVY)
			{
				temp = UYVY;
			}
			else
			{
				temp = Unknown;
			}

			if (temp < currentPreferred)
			{
				currentPreferred = temp;
				preferredIndex   = i;
			}
			DeleteMediaType(pmt);
		}
	}

	// Get the preferred media type
	if (preferredIndex != -1)
	{
		hr = pCfg->GetStreamCaps(preferredIndex, &pmt, (BYTE *)&pSCC);
	}
	else
	{
		hr = pCfg->GetFormat(&pmt);
	}

	return pmt;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -