⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleplayerdlg.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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 + -