www.pudn.com > AVChat0926.rar > CVideoCaptureFilter2.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; 
}