?? cfiltertitleoverlay.cpp
字號:
//
// CFilterTitleOverlay.cpp
//
#include "streams.h" // 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 <measure.h> // performance measurement (MSR_)
#include <initguid.h>
#if (1100 > _MSC_VER)
#include <olectlid.h>
#else
#include <olectl.h>
#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;
}
// 當(dāng)字符疊加的類型改變時,需要生成新的應(yīng)用邏輯控制類對象實例,
// 并且在新生成的控制對象上設(shè)置參數(shù)信息。
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)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -