www.pudn.com > aa.rar > CFilterTitleOverlay.cpp


// 
// CFilterTitleOverlay.cpp 
// 
 
#include           // quartz, includes windows 
// Eliminate two expected level 4 warnings from the Microsoft compiler. 
// The class does not have an assignment or copy operator, and so cannot 
// be passed by value.  This is normal.  This file compiles clean at the 
// highest (most picky) warning level (-W4). 
#pragma warning(disable: 4511 4512) 
 
#include           // performance measurement (MSR_) 
#include  
 
#if (1100 > _MSC_VER) 
#include  
#else 
#include  
#endif 
 
#include "CFilterTitleOverlay.h" 
#include "CTitleOverlayProp.h" 
#include "CSysTimeOverlayController.h" 
#include "CScrollController.h" 
 
// {E3FB4BFE-8E5C-4aec-8162-7DA55BE486A1} 
DEFINE_GUID(CLSID_HQTitleOverlay,  
0xe3fb4bfe, 0x8e5c, 0x4aec, 0x81, 0x62, 0x7d, 0xa5, 0x5b, 0xe4, 0x86, 0xa1); 
 
// {E70FE57A-19AA-4a4c-B39A-408D49D73851} 
DEFINE_GUID(CLSID_HQTitleOverlayProp,  
0xe70fe57a, 0x19aa, 0x4a4c, 0xb3, 0x9a, 0x40, 0x8d, 0x49, 0xd7, 0x38, 0x51); 
 
 
// 
// setup data 
// 
const AMOVIESETUP_MEDIATYPE sudPinTypes = 
{ 
    &MEDIATYPE_NULL,            // Major type 
    &MEDIASUBTYPE_NULL          // Minor type 
}; 
 
const AMOVIESETUP_PIN psudPins[] = 
{ 
    { 
        L"Input",           // String pin name 
        FALSE,              // Is it rendered 
        FALSE,              // Is it an output 
        FALSE,              // Allowed none 
        FALSE,              // Allowed many 
        &CLSID_NULL,        // Connects to filter 
        L"Output",          // Connects to pin 
        1,                  // Number of types 
        &sudPinTypes },     // The pin details 
      { L"Output",          // String pin name 
        FALSE,              // Is it rendered 
        TRUE,               // Is it an output 
        FALSE,              // Allowed none 
        FALSE,              // Allowed many 
        &CLSID_NULL,        // Connects to filter 
        L"Input",           // Connects to pin 
        1,                  // Number of types 
        &sudPinTypes        // The pin details 
    } 
}; 
 
 
const AMOVIESETUP_FILTER sudFilter = 
{ 
    &CLSID_HQTitleOverlay,       // Filter CLSID 
    L"HQ Title Overlay Std.",    // Filter name 
    MERIT_DO_NOT_USE,        // Its merit 
    2,                       // Number of pins 
    psudPins                 // Pin details 
}; 
 
 
// List of class IDs and creator functions for the class factory. This 
// provides the link between the OLE entry point in the DLL and an object 
// being created. The class factory will call the static CreateInstance 
CFactoryTemplate g_Templates[] =  
{ 
    {  
		L"HQ Title Overlay Std.", 
		&CLSID_HQTitleOverlay, 
		CFilterTitleOverlay::CreateInstance, 
		NULL, 
		&sudFilter  
	}, 
	{  
		L"HQ Title Overlay Property Page", 
		&CLSID_HQTitleOverlayProp, 
		CTitleOverlayProp::CreateInstance  
	} 
}; 
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
 
 
 
// ---------------------------------------------------------------------------- 
//            Filter implementation 
// ---------------------------------------------------------------------------- 
CFilterTitleOverlay::CFilterTitleOverlay(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) :  
CTransInPlaceFilter(tszName, punk, CLSID_HQTitleOverlay, phr) 
{ 
	mOverlayType = OT_STATIC; 
	mOverlayController     = new COverlayController(); 
	mNeedEstimateFrameRate = FALSE; 
 
	char szTitle[] = "Hello, DirectShow!";  
	put_Title(szTitle, sizeof(szTitle)); 
} 
 
CFilterTitleOverlay::~CFilterTitleOverlay() 
{ 
	ReleaseOverlayController(); 
} 
 
void CFilterTitleOverlay::ReleaseOverlayController(void) 
{ 
	if (mOverlayController) 
	{ 
		delete mOverlayController; 
		mOverlayController = NULL; 
	} 
} 
 
// 
// CreateInstance 
// 
// Override CClassFactory method. 
// Provide the way for COM to create a CNullInPlace object 
// 
CUnknown * WINAPI CFilterTitleOverlay::CreateInstance(LPUNKNOWN punk, HRESULT *phr)  
{ 
#if 1 
	char    szCreatorPath[256], szCreatorName[256]; 
	::strcpy(szCreatorPath, ""); 
	::strcpy(szCreatorName, ""); 
	HMODULE hModule = ::GetModuleHandle(NULL); 
	::GetModuleFileName(hModule, szCreatorPath, 256); 
	char * backSlash = ::strrchr(szCreatorPath, '\\'); 
	if (backSlash) 
	{ 
		strcpy(szCreatorName, backSlash); 
	} 
	::_strlwr(szCreatorName); 
	// Please specify your app name with lowercase 
	if (::strstr(szCreatorName, "graphedt") == NULL && 
		::strstr(szCreatorName, "ourapp") == NULL) 
	{ 
		*phr = E_FAIL; 
		return NULL; 
	} 
#endif 
 
	CFilterTitleOverlay *pNewObject = new CFilterTitleOverlay(NAME("TitleOverlay"), punk, phr); 
	if (pNewObject == NULL)  
	{ 
		*phr = E_OUTOFMEMORY; 
	} 
	return pNewObject; 
}  
 
// 
// Basic COM - used here to reveal our own interfaces 
STDMETHODIMP CFilterTitleOverlay::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 
{ 
	CheckPointer(ppv, E_POINTER); 
 
	if (riid == IID_ISpecifyPropertyPages)  
	{ 
		return GetInterface((ISpecifyPropertyPages *) this, ppv); 
	} 
	else if (riid == IID_ITitleOverlay) 
	{ 
		return GetInterface((ITitleOverlay *) this, ppv); 
	} 
	else  
	{ 
		return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv); 
	} 
} // NonDelegatingQueryInterface 
 
// Only RGB 32/24/565/555 supported  
HRESULT CFilterTitleOverlay::CheckInputType(const CMediaType* mtIn) 
{ 
	// Dynamic format change will never be allowed! 
	if (IsStopped() && *mtIn->Type() == MEDIATYPE_Video) 
	{ 
		if (*mtIn->Subtype() == MEDIASUBTYPE_RGB32 || 
			*mtIn->Subtype() == MEDIASUBTYPE_RGB24 || 
			*mtIn->Subtype() == MEDIASUBTYPE_RGB555 || 
			*mtIn->Subtype() == MEDIASUBTYPE_RGB565) 
		{ 
			return NOERROR; 
		} 
	} 
	return E_INVALIDARG; 
} 
 
HRESULT CFilterTitleOverlay::Transform(IMediaSample *pSample) 
{ 
	// If we cann't read frame rate info from input pin's connection media type, 
	// We estimate it from the first sample's time stamp! 
	if (mNeedEstimateFrameRate) 
	{ 
		mNeedEstimateFrameRate = FALSE; 
		REFERENCE_TIME  startTime = 0; 
		REFERENCE_TIME  endTime   = 0; 
		double          estimated = 25; 
		if (SUCCEEDED(pSample->GetTime(&startTime, &endTime))) 
		{ 
			estimated = 1.0 * UNITS / (endTime - startTime); 
		} 
		mOverlayController->SetEstimatedFrameRate(estimated); 
	} 
 
	if (mOverlayType != OT_NONE) 
	{ 
		PBYTE  pData = NULL; 
		pSample->GetPointer(&pData); 
		mOverlayController->DoTitleOverlay(pData); 
	} 
 
	return NOERROR; 
} 
 
HRESULT CFilterTitleOverlay::SetInputVideoInfoToController(void) 
{ 
	if (mOverlayController && m_pInput && m_pInput->IsConnected()) 
	{ 
		CMediaType  mt = m_pInput->CurrentMediaType(); 
		if (mt.formattype != FORMAT_VideoInfo) 
		{ 
			return E_FAIL; 
		} 
 
		RGB_FORMAT   colorSpace = FT_NONE; 
		if (mt.subtype == MEDIASUBTYPE_RGB32)  // Determine RGB format 
		{ 
			colorSpace = FT_RGB32; 
		} 
		else if (mt.subtype == MEDIASUBTYPE_RGB24) 
		{ 
			colorSpace = FT_RGB24; 
		} 
		else if (mt.subtype == MEDIASUBTYPE_RGB555) 
		{ 
			colorSpace = FT_RGB555; 
		} 
		else if (mt.subtype == MEDIASUBTYPE_RGB565) 
		{ 
			colorSpace = FT_RGB565; 
		} 
		else if (mt.subtype == MEDIASUBTYPE_RGB8) 
		{ 
			colorSpace = FT_RGB8; 
		} 
		mOverlayController->SetInputColorSpace(colorSpace); 
		VIDEOINFOHEADER * pHeader = (VIDEOINFOHEADER *) mt.pbFormat; 
		mNeedEstimateFrameRate    = pHeader->AvgTimePerFrame > 0 ? FALSE : TRUE; 
		mOverlayController->SetInputVideoInfo(pHeader); 
		return NOERROR; 
	} 
	return E_FAIL;	 
} 
 
HRESULT CFilterTitleOverlay::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin) 
{ 
	HRESULT hr = CTransInPlaceFilter::CompleteConnect(direction, pReceivePin); 
 
	if (SUCCEEDED(hr) && direction == PINDIR_INPUT) 
	{ 
		hr = SetInputVideoInfoToController(); 
	} 
	return hr; 
} 
 
HRESULT CFilterTitleOverlay::StartStreaming() 
{ 
	BOOL pass = mOverlayController->StartTitleOverlay(); 
	return pass ? S_OK : E_FAIL; 
} 
 
HRESULT CFilterTitleOverlay::StopStreaming() 
{ 
	mOverlayController->StopTitleOverlay(); 
	return NOERROR; 
} 
 
	 
// --- ISpecifyPropertyPages --- 
STDMETHODIMP CFilterTitleOverlay::GetPages(CAUUID *pPages) 
{ 
	pPages->cElems = 1; 
	pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID)); 
	if (pPages->pElems == NULL)  
	{ 
		return E_OUTOFMEMORY; 
	} 
	*(pPages->pElems) = CLSID_HQTitleOverlayProp; 
	return NOERROR; 
} 
 
// 当字符叠加的类型改变时,需要生成新的应用逻辑控制类对象实例, 
// 并且在新生成的控制对象上设置参数信息。 
void CFilterTitleOverlay::SideEffectOverlayTypeChanged(void) 
{ 
	ReleaseOverlayController(); 
	switch (mOverlayType) 
	{ 
	case OT_SYSTIME: 
		mOverlayController = new CSysTimeOverlayController(); 
		break; 
 
	case OT_SCROLL_TOP: 
		mOverlayController = new CScrollController(); 
		((CScrollController*) mOverlayController)->SetScrollBottomOrTop(FALSE); 
		break; 
	case OT_SCROLL_BOTTOM: 
		mOverlayController = new CScrollController(); 
		((CScrollController*) mOverlayController)->SetScrollBottomOrTop(TRUE); 
		break; 
 
	case OT_NONE: 
	case OT_STATIC: 
	default: 
		mOverlayController = new COverlayController(); 
	} 
	// Make sure to set input video info to the new controller  
	SetInputVideoInfoToController(); 
} 
 
// --- ITitleOverlay methods --- 
STDMETHODIMP CFilterTitleOverlay::put_TitleOverlayType(long inOverlayType) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	// When filter graph is active, change overlay type is not allowed! 
	if (m_State != State_Stopped) 
	{ 
		return E_UNEXPECTED; 
	} 
 
	if (mOverlayType != (OVERLAY_TYPE)inOverlayType) 
	{ 
		mOverlayType = (OVERLAY_TYPE)inOverlayType; 
		SideEffectOverlayTypeChanged(); 
	} 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleOverlayType(long * outOverlayType) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	*outOverlayType = mOverlayType; 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_TitleOverlayStyle(int inUsingCover) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->SetOverlayStyle(inUsingCover); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleOverlayStyle(int * outUsingCover) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->GetOverlayStyle(outUsingCover); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_Title(const char * inTitle, int inLength) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	// When filter graph is active, change title text is not allowed! 
	if (m_State != State_Stopped) 
	{ 
		return E_UNEXPECTED; 
	} 
	mOverlayController->SetTitle(inTitle, inLength); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_Title(char * outBuffer, int * outLength) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	*outLength = mOverlayController->GetTitle(outBuffer); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_TitleColor(BYTE inR, BYTE inG, BYTE inB) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->SetTitleColor(inR, inG, inB); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleColor(BYTE * outR, BYTE * outG, BYTE * outB) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->GetTitleColor(outR, outG, outB); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_TitleStartPosition(POINT inStartPos) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->SetTitleStartPosition(inStartPos); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleStartPosition(POINT * outStartPos) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->GetTitleStartPosition(outStartPos); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_TitleFont(LOGFONT inFont) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->SetTitleFont(inFont); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleFont(LOGFONT * outFont) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->GetTitleFont(outFont); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::put_TitleDuration(double inStart, double inEnd) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->SetTitleDuration(inStart, inEnd); 
	return NOERROR; 
} 
 
STDMETHODIMP CFilterTitleOverlay::get_TitleDuration(double * outStart, double * outEnd) 
{ 
	CAutoLock   lockit(&mITitleOverlaySync); 
	mOverlayController->GetTitleDuration(outStart, outEnd); 
	return NOERROR; 
} 
 
 
 
 
 
 
 
 
 
/******************************Public Routine******************************\ 
* exported entry points for registration and 
* unregistration (in this case they only call 
* through to default implmentations). 
* 
* 
* 
* History: 
* 
\**************************************************************************/ 
STDAPI DllRegisterServer() 
{ 
	return AMovieDllRegisterServer2( TRUE ); 
} 
 
STDAPI DllUnregisterServer() 
{ 
	return AMovieDllRegisterServer2( FALSE ); 
} 
 
// Microsoft C Compiler will give hundreds of warnings about 
// unused inline functions in header files.  Try to disable them. 
#pragma warning( disable:4514)