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); }