📄 simpleplayerdlg.cpp
字号:
mFilterGraph->GetDuration(&duration);
double pos = duration * mSliderGraph.GetPos() / 1000.;
mFilterGraph->SetCurrentPosition(pos);
}
}
else
{
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
}
// Deal with the graph events
LRESULT CSimplePlayerDlg::OnGraphNotify(WPARAM inWParam, LPARAM inLParam)
{
IMediaEventEx * pEvent = NULL;
if (mFilterGraph && (pEvent = mFilterGraph->GetEventHandle()))
{
LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0;
while (SUCCEEDED(pEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
{
// Spin through the events
pEvent->FreeEventParams(eventCode, eventParam1, eventParam2);
switch (eventCode)
{
case EC_COMPLETE:
OnButtonPause();
mFilterGraph->SetCurrentPosition(0);
break;
case EC_USERABORT:
case EC_ERRORABORT:
OnButtonStop();
break;
default:
break;
}
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////
// Locate a filter within the graph by searching (from renderers upstream)
// looking for a specific interface on the filter
// NOT outstanding reference!
HRESULT CSimplePlayerDlg::FindFilterByInterface(REFIID riid, IBaseFilter** ppFilter)
{
*ppFilter = NULL;
if (!mFilterGraph)
{
return E_FAIL;
}
IEnumFilters* pEnum;
HRESULT hr = mFilterGraph->GetGraph()->EnumFilters(&pEnum);
if (FAILED(hr))
{
return hr;
}
IBaseFilter* pFilter = NULL;
BOOL found = FALSE;
while (!found && pEnum->Next(1, &pFilter, NULL) == S_OK)
{
// Check for required interface
IUnknown* pUnk;
HRESULT hrQuery = pFilter->QueryInterface(riid, (void**)&pUnk);
if (SUCCEEDED(hrQuery))
{
pUnk->Release();
*ppFilter = pFilter;
found = TRUE;
}
pFilter->Release();
}
pEnum->Release();
return (*ppFilter != NULL) ? S_OK : E_FAIL;
}
void CSimplePlayerDlg::ShowVRPropertyPage(void)
{
IBaseFilter *pFilter = NULL;
if (FAILED(FindFilterByInterface(IID_IVideoWindow, &pFilter)))
{
return;
}
ISpecifyPropertyPages *pProp = NULL;
HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
if (SUCCEEDED(hr))
{
// Get the filter's name and IUnknown pointer.
FILTER_INFO FilterInfo;
hr = pFilter->QueryFilterInfo(&FilterInfo);
IUnknown *pFilterUnk;
pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
// Show the page.
CAUUID caGUID;
pProp->GetPages(&caGUID);
pProp->Release();
OleCreatePropertyFrame(
this->GetSafeHwnd(), // Parent window
0, 0, // Reserved
FilterInfo.achName, // Caption for the dialog box
1, // Number of objects (just the filter)
&pFilterUnk, // Array of object pointers.
caGUID.cElems, // Number of property pages
caGUID.pElems, // Array of property page CLSIDs
0, // Locale identifier
0, NULL // Reserved
);
// Clean up.
pFilterUnk->Release();
FilterInfo.pGraph->Release();
CoTaskMemFree(caGUID.pElems);
}
}
void CSimplePlayerDlg::OnButtonTest()
{
ShowVRPropertyPage();
}
void CSimplePlayerDlg::AddTitleOverlayFilter(void)
{
// Create title overlay filter
IBaseFilter * pFilter = NULL;
HRESULT hr = CoCreateInstance(CLSID_HQTitleOverlay, NULL,
CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void **)&pFilter);
if (SUCCEEDED(hr))
{
// Settings on the title overlay filter
ITitleOverlay * pOverlayer = NULL;
pFilter->QueryInterface(IID_ITitleOverlay, (void**)&pOverlayer);
if (pOverlayer)
{
pOverlayer->put_TitleOverlayType(OT_SCROLL_BOTTOM);
UpdateData();
pOverlayer->put_Title(mOverlayTitle, mOverlayTitle.GetLength());
pOverlayer->put_TitleColor(0xff, 0, 0);
pOverlayer->put_TitleDuration(0, 20);
pOverlayer->Release();
}
// Add to filter graph
mFilterGraph->GetGraph()->AddFilter(pFilter, L"Title Overlay");
// After add to filter graph, the filter graph manager will add
// an extra reference count, so it's safe to release now
pFilter->Release();
// Connect title overlay filter
IPin * pOut = FindPin_ConnectedToVideoRenderer();
IPin * pIn = GetPin(pFilter, TRUE);
BOOL pass = mFilterGraph->ConnectFilters(pOut, pIn);
if (pass)
{
// Render the output pin of title overlay filter
pOut = GetPin(pFilter, FALSE);
mFilterGraph->GetGraph()->Render(pOut);
}
else
{
// Build the original filter graph
mFilterGraph->GetGraph()->Render(pOut);
AfxMessageBox("Title overlay filter connection failed!");
}
}
}
IPin * CSimplePlayerDlg::FindPin_ConnectedToVideoRenderer()
{
IPin * foundPin = NULL;
// Try to find the video renderer, by looking for IVideoWindow
IBaseFilter* pVR = NULL;
HRESULT hr = FindFilterByInterface(IID_IVideoWindow, &pVR);
if (SUCCEEDED(hr))
{
IBaseFilter * pOverlayMixer = NULL;
// Further check if upstream filter is an overlay mixer?
IBaseFilter * pUpFilter = GetUpstreamFilter(pVR);
// Check to see if this is an overlay mixer?
if (IsOverlayMixer(pUpFilter))
{
pOverlayMixer = pUpFilter;
pUpFilter = GetUpstreamFilter(pOverlayMixer);
}
// Remove video renderer from the filter graph!
if (pVR)
{
mFilterGraph->GetGraph()->RemoveFilter(pVR);
}
if (pOverlayMixer)
{
mFilterGraph->GetGraph()->RemoveFilter(pOverlayMixer);
}
// Get the output pin
foundPin = GetPin(pUpFilter, FALSE);
}
return foundPin;
}
// Utilities
IPin * GetPin(IBaseFilter * inFilter, BOOL inInput, const char * inPartialName)
{
if (!inFilter)
{
return NULL;
}
PIN_DIRECTION direction = inInput ? PINDIR_INPUT : PINDIR_OUTPUT;
IPin * foundPin = NULL;
IEnumPins * pinEnum = NULL;
if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
{
pinEnum->Reset();
IPin * pin = NULL;
ULONG fetchCount = 0;
while (!foundPin && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) &&
fetchCount)
{
if (pin)
{
PIN_INFO pinInfo;
if (SUCCEEDED(pin->QueryPinInfo(&pinInfo)))
{
if (pinInfo.dir == direction)
{
// Ignore the pin name
if (!inPartialName)
{
pin->AddRef();
foundPin = pin;
}
else
{
char pinName[128];
::WideCharToMultiByte(CP_ACP, 0, pinInfo.achName,
-1, pinName, 128, NULL, NULL);
if (::strstr(pinName, inPartialName))
{
pin->AddRef();
foundPin = pin;
}
}
}
pinInfo.pFilter->Release();
}
pin->Release();
}
}
pinEnum->Release();
}
// We don't keep outstanding reference count
if (foundPin)
{
foundPin->Release();
}
return foundPin;
}
IBaseFilter * GetUpstreamFilter(IBaseFilter* inFilter)
{
if (!inFilter)
{
return NULL;
}
IBaseFilter * pUpFilter = NULL;
IEnumPins * pinEnum = NULL;
if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
{
pinEnum->Reset();
IPin * pin = NULL;
ULONG fetchCount = 0;
while (!pUpFilter && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) &&
fetchCount)
{
if (pin)
{
// Check if connected?
IPin * connectedPin = NULL;
pin->ConnectedTo(&connectedPin);
if (connectedPin)
{
connectedPin->Release();
// Check pin is an input pin
PIN_INFO pinInfo;
if (SUCCEEDED(connectedPin->QueryPinInfo(&pinInfo)))
{
pinInfo.pFilter->Release();
if (pinInfo.dir == PINDIR_OUTPUT)
{
pUpFilter = pinInfo.pFilter;
}
}
}
pin->Release();
}
}
pinEnum->Release();
}
return pUpFilter;
}
BOOL IsOverlayMixer(IBaseFilter * inFilter)
{
if (!inFilter)
{
return FALSE;
}
IAMOverlayFX * pMixer = NULL;
inFilter->QueryInterface(IID_IAMOverlayFX, (void**)&pMixer);
if (pMixer)
{
pMixer->Release();
}
return (pMixer != NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -