www.pudn.com > AudioVideoCapture.rar > CTVInputFilters.cpp


// 
// CTVInputFilters.cpp 
// 
 
/*-----------------------------------------------------*\ 
			HQ Tech, Make Technology Easy!        
 More information, please go to http://hqtech.nease.net. 
/*-----------------------------------------------------*/ 
 
#include "stdafx.h" 
#include "CTVInputFilters.h" 
#include "CVideoCaptureFilter.h" 
#include "UDsUtils.h" 
#include  
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
//////////////////////////////////////////////////////////////////////// 
CTVInputFilters::CTVInputFilters(CDXGraph * inGraph) : 
CAnalogInputFilters(inGraph) 
{ 
	mTvTuner = NULL; 
} 
 
CTVInputFilters::~CTVInputFilters() 
{ 
	Release(); 
} 
 
BOOL CTVInputFilters::Create(void) 
{ 
	BOOL pass = CAnalogInputFilters::Create(); 
	if (pass) 
	{ 
		FindTVTuner(); 
	} 
	return pass; 
} 
 
void CTVInputFilters::Release(void) 
{ 
	SAFE_RELEASE(mTvTuner); 
} 
 
BOOL CTVInputFilters::FindTVTuner(void) 
{ 
	if (mTvTuner) 
	{ 
		return TRUE; 
	} 
 
	if (mGraphBuilder) 
	{ 
		mGraphBuilder->FindInterface(&LOOK_UPSTREAM_ONLY, 
			&MEDIATYPE_Video, mVideoCapture->GetFilter(), 
			IID_IAMTVTuner, (void **)&mTvTuner); 
	} 
 
	return (mTvTuner != NULL); 
} 
 
void CTVInputFilters::ShowTVTunerPropertyPage(void) 
{ 
	if (mTvTuner) 
	{ 
		IBaseFilter * pFilter = NULL; 
		mTvTuner->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
		if (pFilter) 
		{ 
			pFilter->Release(); 
			UDsUtils::ShowFilterPropertyPage(pFilter); 
		} 
	} 
} 
 
////////////////////////// TV related operations /////////////////////// 
long CTVInputFilters::GetCountryCode(void) 
{ 
	long  code = -1; 
	if (mTvTuner) 
	{ 
		mTvTuner->get_CountryCode(&code); 
	} 
	return code; 
} 
 
BOOL CTVInputFilters::SetCountryCode(long inCode) 
{ 
	HRESULT hr = E_FAIL; 
	if (mTvTuner) 
	{ 
		hr = mTvTuner->put_CountryCode(inCode); 
		if (SUCCEEDED(hr)) 
		{ 
			mTvTuner->put_TuningSpace(inCode); 
		} 
	} 
	return SUCCEEDED(hr); 
} 
 
TunerInputType CTVInputFilters::GetTunerInputType(void) 
{ 
	TunerInputType type = TunerInputAntenna; 
	if (mTvTuner) 
	{ 
		long  inputConnect = 0; 
		if (SUCCEEDED(mTvTuner->get_ConnectInput(&inputConnect))) 
		{ 
			mTvTuner->get_InputType(inputConnect, &type); 
		} 
	} 
	return type; 
} 
 
BOOL CTVInputFilters::SetTunerInputType(TunerInputType inType) 
{ 
	HRESULT hr = E_FAIL; 
	if (mTvTuner) 
	{ 
		long  inputConnect = 0; 
		hr = mTvTuner->get_ConnectInput(&inputConnect); 
		if (SUCCEEDED(hr)) 
		{ 
			hr = mTvTuner->put_InputType(inputConnect, inType); 
		} 
	} 
	return SUCCEEDED(hr); 
} 
 
long CTVInputFilters::GetTVChannel(void) 
{ 
	if (mTvTuner) 
	{ 
		long freqIndex; 
		long videoSub, audioSub; 
		if (SUCCEEDED(mTvTuner->get_Channel(&freqIndex, &videoSub, &audioSub))) 
		{ 
			return freqIndex; 
		} 
	} 
	return 0; 
} 
 
BOOL CTVInputFilters::SetTVChannel(long inFrequencyIndex) 
{ 
	if (mTvTuner) 
	{ 
		long signalStrength  = AMTUNER_NOSIGNAL; 
		long videoSubChannel = AMTUNER_SUBCHAN_DEFAULT; 
		long audioSubChannel = AMTUNER_SUBCHAN_DEFAULT; 
		mTvTuner->put_Channel(inFrequencyIndex, videoSubChannel, audioSubChannel); 
		mTvTuner->SignalPresent(&signalStrength); 
		if (signalStrength != AMTUNER_NOSIGNAL) 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CTVInputFilters::GetChannelMinMax(long * outMin, long * outMax) 
{ 
	if (mTvTuner) 
	{ 
		if (SUCCEEDED(mTvTuner->ChannelMinMax(outMin, outMax))) 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
Signal_Resolution CTVInputFilters::GetTunerResolution(void) 
{ 
	if (mTvTuner) 
	{ 
		long resolution = 0; 
		mTvTuner->get_TVFormat(&resolution); 
 
		if (cNTSCMaskBits & resolution) 
		{ 
			return SR_NTSC; 
		} 
		else if (cPALMaskBits & resolution) 
		{ 
			return SR_PAL; 
		} 
		else if (cSECAMMaskBits & resolution) 
		{ 
			return SR_SECAM; 
		} 
	} 
	 
	return SR_UNKNOWN; 
} 
 
// Demo: how to auto-tune TV channels... 
void CTVInputFilters::DemoTVChannelAutoTune(void) 
{ 
	if (mTvTuner) 
	{ 
		long minChannel = 0, maxChannel = 0; 
		long foundSignal = AMTUNER_NOSIGNAL; 
 
		HRESULT hr = mTvTuner->ChannelMinMax(&minChannel, &maxChannel); 
		for (long i = minChannel; i <= maxChannel; i++) 
		{ 
			hr = mTvTuner->AutoTune(i, &foundSignal); 
 
			// Check the signal strength 
			// Assume AMTUNER_HASNOSIGNALSTRENGTH means tuned 
			if (foundSignal != AMTUNER_NOSIGNAL) 
			{ 
			} 
		} 
 
		// Save the fine-tuning information for all channels to the registry 
		if (SUCCEEDED(hr)) 
		{ 
			mTvTuner->StoreAutoTune();  
		} 
	} 
} 
 
////////////////////////// VBI related operations //////////////////////// 
// Render the closed captioning pin? It could be a CC or a VBI category pin, 
// depending on the capture driver 
BOOL CTVInputFilters::TryCCFilters(void) 
{ 
	if (!mGraphBuilder) 
	{ 
		return FALSE; 
	} 
 
	HRESULT hr = mGraphBuilder->RenderStream(&PIN_CATEGORY_CC, 0, 
		mVideoCapture->GetFilter(), 0, 0); 
	if (hr != NOERROR) 
	{ 
		hr = mGraphBuilder->RenderStream(&PIN_CATEGORY_VBI, 0, 
			mVideoCapture->GetFilter(), 0, 0); 
	} 
 
	return SUCCEEDED(hr); 
} 
 
BOOL CTVInputFilters::DisplayClosedCaption(BOOL inIsOn) 
{ 
	if (!mGraphBuilder) 
	{ 
		return FALSE; 
	} 
 
	IAMLine21Decoder *pLine21 = NULL; 
	HRESULT hr = mGraphBuilder->FindInterface( 
		&LOOK_DOWNSTREAM_ONLY,        // Look downstream from pCap  
		NULL,                         // No particular media type 
		mVideoCapture->GetFilter(),   // Pointer to the capture filter. 
		IID_IAMLine21Decoder,  
		(void**)&pLine21 
		); 
	if (SUCCEEDED(hr)) 
	{ 
		pLine21->SetServiceState(inIsOn ? AM_L21_CCSTATE_On : AM_L21_CCSTATE_Off); 
		pLine21->Release(); 
	} 
 
	return SUCCEEDED(hr); 
} 
 
// Support WST 
BOOL CTVInputFilters::TryWSTFilters(void) 
{ 
	if (!mGraphBuilder) 
	{ 
		return FALSE; 
	} 
 
	IBaseFilter * pKernelTee = NULL; 
	IBaseFilter * pWstCodec  = NULL; 
	HRESULT hr = NOERROR; 
	BOOL  pass = FALSE; 
 
	pKernelTee = UDsUtils::CreateHardwareFilter(AM_KSCATEGORY_SPLITTER, "Tee/Sink-to-Sink Converter"); 
	pass = (pKernelTee != 0); 
	if (pass) 
	{ 
		mGraph->GetGraph()->AddFilter(pKernelTee, L"Kernel Tee"); 
		pWstCodec  = UDsUtils::CreateHardwareFilter(AM_KSCATEGORY_VBICODEC, "WST Codec"); 
		pass = (pWstCodec != 0); 
	} 
	if (pass) 
	{ 
		mGraph->GetGraph()->AddFilter(pWstCodec, L"WST Codec"); 
		hr = mGraphBuilder->RenderStream(&PIN_CATEGORY_VBI, 0, mVideoCapture->GetFilter(),  
			pKernelTee, pWstCodec); 
		pass = SUCCEEDED(hr); 
	} 
	if (pass) 
	{ 
		hr = mGraphBuilder->RenderStream(0, 0, pWstCodec, 0, 0); 
		pass = SUCCEEDED(hr); 
	} 
	if (pass) 
	{ 
		Verify_VPVBI_Connection(); 
	} 
 
	if (pKernelTee) 
	{ 
		pKernelTee->Release(); 
		pKernelTee = 0; 
	} 
	if (pWstCodec) 
	{ 
		pWstCodec->Release(); 
		pWstCodec = 0; 
	} 
	 
	return pass; 
} 
 
// If the capture filter uses VPVBI pin, make sure that this pin has been 
// connect to "VBI Surface Allocator" filter before running. 
void CTVInputFilters::Verify_VPVBI_Connection(void) 
{ 
	if (mGraphBuilder) 
	{ 
		IPin * pVPVBI = NULL; 
		HRESULT hr = mGraphBuilder->FindPin( 
			mVideoCapture->GetFilter(),  
			PINDIR_OUTPUT, 
			&PIN_CATEGORY_VIDEOPORT_VBI,  
			NULL,  
			TRUE,  
			0,  
			&pVPVBI 
			); 
		if (hr == S_OK) 
		{ 
			// If found, connect it to the VBI Surface Allocator. 
			// Create VBI Surface Allocator filter, and add it to the filter graph. 
			IBaseFilter * pSurf = NULL; 
			hr = CoCreateInstance(CLSID_VBISurfaces, NULL, CLSCTX_INPROC_SERVER,  
				IID_IBaseFilter, (void **)&pSurf); 
			if (SUCCEEDED(hr)) 
			{ 
				hr = mGraph->GetGraph()->AddFilter(pSurf, L"VBI Surf"); 
				hr = mGraphBuilder->RenderStream(NULL, NULL, pVPVBI, 0, pSurf); 
				pSurf->Release(); 
			} 
			pVPVBI->Release(); 
		} 
	} 
} 
 
// Control the displaying status of World Standard Teletext 
BOOL CTVInputFilters::DisplayWSTText(BOOL inIsOn) 
{ 
	if (!mGraphBuilder) 
	{ 
		return FALSE; 
	} 
 
	IAMWstDecoder *pwst = NULL; 
	HRESULT hr = mGraphBuilder->FindInterface( 
		&LOOK_DOWNSTREAM_ONLY,        // Look downstream from pCap  
		NULL,                         // No particular media type 
		mVideoCapture->GetFilter(),   // Pointer to the capture filter. 
		IID_IAMWstDecoder,  
		(void**)&pwst 
		); 
	if (SUCCEEDED(hr)) 
	{ 
		pwst->SetServiceState(inIsOn ? AM_WST_STATE_On : AM_WST_STATE_Off); 
		pwst->Release(); 
	} 
	return SUCCEEDED(hr); 
}