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)