예제 #1
0
bool CImageMixer_EVR::GetMapSize(int *pWidth,int *pHeight)
{
	bool fOK=false;
	IMFGetService *pGetService;

	if (SUCCEEDED(m_pRenderer->QueryInterface(IID_IMFGetService,
								reinterpret_cast<LPVOID*>(&pGetService)))) {
		IMFVideoDisplayControl *pDisplayControl;

		if (SUCCEEDED(pGetService->GetService(MR_VIDEO_RENDER_SERVICE,
							IID_IMFVideoDisplayControl,
							reinterpret_cast<LPVOID*>(&pDisplayControl)))) {
			SIZE Size;

			if (SUCCEEDED(pDisplayControl->GetNativeVideoSize(&Size,NULL))) {
				if (pWidth)
					*pWidth=Size.cx;
				if (pHeight)
					*pHeight=Size.cy;
				fOK=true;
			}
			pDisplayControl->Release();
		}
		pGetService->Release();
	}
	return fOK;
}
예제 #2
0
bool CImageMixer_EVR::SetBitmap(HBITMAP hbm,int Opacity,COLORREF TransColor,RECT *pDestRect)
{
	IMFGetService *pGetService;
	IMFVideoDisplayControl *pDisplayControl;
	IMFVideoMixerBitmap *pMixerBitmap;
	SIZE NativeSize;
	BITMAP bm;
	MFVideoAlphaBitmap ab;
	HRESULT hr;

	if (!CreateMemDC())
		return false;
	if (FAILED(m_pRenderer->QueryInterface(IID_IMFGetService,
									reinterpret_cast<LPVOID*>(&pGetService))))
		return false;
	if (FAILED(pGetService->GetService(MR_VIDEO_MIXER_SERVICE,
									   IID_IMFVideoMixerBitmap,
									   reinterpret_cast<LPVOID*>(&pMixerBitmap)))) {
		pGetService->Release();
		return false;
	}
	if (FAILED(pGetService->GetService(MR_VIDEO_RENDER_SERVICE,
							IID_IMFVideoDisplayControl,
							reinterpret_cast<LPVOID*>(&pDisplayControl)))) {
		pMixerBitmap->Release();
		pGetService->Release();
		return false;
	}
	hr=pDisplayControl->GetNativeVideoSize(&NativeSize,NULL);
	pDisplayControl->Release();
	if (FAILED(hr)) {
		pMixerBitmap->Release();
		pGetService->Release();
		return false;
	}
	::SelectObject(m_hdc,hbm);
	ab.GetBitmapFromDC=TRUE;
	ab.bitmap.hdc=m_hdc;
	ab.params.dwFlags=MFVideoAlphaBitmap_SrcRect | MFVideoAlphaBitmap_DestRect |
					  MFVideoAlphaBitmap_Alpha;
	if (TransColor!=CLR_INVALID) {
		ab.params.dwFlags|=MFVideoAlphaBitmap_SrcColorKey;
		ab.params.clrSrcKey=TransColor;
	}
	::GetObject(hbm,sizeof(BITMAP),&bm);
	::SetRect(&ab.params.rcSrc,0,0,bm.bmWidth,bm.bmHeight);
	ab.params.nrcDest.left=(float)pDestRect->left/(float)NativeSize.cx;
	ab.params.nrcDest.top=(float)pDestRect->top/(float)NativeSize.cy;
	ab.params.nrcDest.right=(float)pDestRect->right/(float)NativeSize.cx;
	ab.params.nrcDest.bottom=(float)pDestRect->bottom/(float)NativeSize.cy;
	ab.params.fAlpha=(float)Opacity/100.0f;
	hr=pMixerBitmap->SetAlphaBitmap(&ab);
	pMixerBitmap->Release();
	pGetService->Release();
	if (FAILED(hr)) {
		::SelectObject(m_hdc,m_hbmOld);
		return false;
	}
	return true;
}
예제 #3
0
bool CVideoRenderer_EVR::Initialize(IGraphBuilder *pFilterGraph,IPin *pInputPin,HWND hwndRender,HWND hwndMessageDrain)
{
#ifdef EVR_USE_VIDEO_WINDOW
	static bool fRegistered=false;
	HINSTANCE hinst=GetWindowInstance(hwndRender);

	if (!fRegistered) {
		WNDCLASS wc;

		wc.style=CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc=VideoWndProc;
		wc.cbClsExtra=0;
		wc.cbWndExtra=0;
		wc.hInstance=hinst;
		wc.hIcon=NULL;
		wc.hCursor=NULL;
		wc.hbrBackground=CreateSolidBrush(RGB(0,0,0));
		wc.lpszMenuName=NULL;
		wc.lpszClassName=EVR_VIDEO_WINDOW_CLASS;
		if (::RegisterClass(&wc)==0) {
			SetError(TEXT("EVRウィンドウクラスを登録できません。"));
			return false;
		}
		fRegistered=true;
	}
	m_hwndVideo=::CreateWindowEx(0,EVR_VIDEO_WINDOW_CLASS,NULL,
								 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,0,0,0,0,
								 hwndRender,NULL,hinst,this);
	if (m_hwndVideo==NULL) {
		SetError(TEXT("EVRウィンドウを作成できません。"));
		return false;
	}
#endif

	HRESULT hr;

	// MFStartupは呼ばなくていいらしい
	/*
	m_hMFPlatLib=::LoadLibrary(TEXT("mfplat.dll"));
	if (m_hMFPlatLib==NULL) {
		SetError(TEXT("mfplat.dllをロードできません。"));
		return false;
	}
	MFStartupFunc pStartup=reinterpret_cast<MFStartupFunc>(::GetProcAddress(m_hMFPlatLib,"MFStartup"));
	if (pStartup==NULL) {
		SetError(TEXT("MFStartup関数のアドレスを取得できません。"));
		goto OnError;
	}
	hr=pStartup(MF_VERSION,MFSTARTUP_LITE);
	if (FAILED(hr)) {
		SetError(TEXT("Media Foundationの初期化ができません。"));
		goto OnError;
	}
	*/

	hr=::CoCreateInstance(CLSID_EnhancedVideoRenderer,NULL,CLSCTX_INPROC_SERVER,
						IID_IBaseFilter,reinterpret_cast<LPVOID*>(&m_pRenderer));
	if (FAILED(hr)) {
		SetError(hr,TEXT("EVRのインスタンスを作成できません。"),
					TEXT("システムがEVRに対応していない可能性があります。"));
		goto OnError;
	}

	IEVRFilterConfig *pFilterConfig;
	hr=m_pRenderer->QueryInterface(IID_IEVRFilterConfig,reinterpret_cast<LPVOID*>(&pFilterConfig));
	if (FAILED(hr)) {
		SetError(hr,TEXT("IEVRFilterConfigを取得できません。"));
		goto OnError;
	}
	pFilterConfig->SetNumberOfStreams(1);
	pFilterConfig->Release();

	hr=pFilterGraph->AddFilter(m_pRenderer,L"EVR");
	if (FAILED(hr)) {
		SetError(hr,TEXT("EVRをフィルタグラフに追加できません。"));
		goto OnError;
	}

	IFilterGraph2 *pFilterGraph2;
	hr=pFilterGraph->QueryInterface(IID_IFilterGraph2,
									reinterpret_cast<LPVOID*>(&pFilterGraph2));
	if (FAILED(hr)) {
		SetError(hr,TEXT("IFilterGraph2を取得できません。"));
		goto OnError;
	}
	hr=pFilterGraph2->RenderEx(pInputPin,
								AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL);
	pFilterGraph2->Release();
	if (FAILED(hr)) {
		SetError(hr,TEXT("映像レンダラを構築できません。"));
		goto OnError;
	}

	IMFGetService *pGetService;
	hr=m_pRenderer->QueryInterface(IID_IMFGetService,reinterpret_cast<LPVOID*>(&pGetService));
	if (FAILED(hr)) {
		SetError(hr,TEXT("IMFGetServiceを取得できません。"));
		goto OnError;
	}

	IMFVideoDisplayControl *pDisplayControl;
	hr=pGetService->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,reinterpret_cast<LPVOID*>(&pDisplayControl));
	if (FAILED(hr)) {
		pGetService->Release();
		SetError(hr,TEXT("IMFVideoDisplayControlを取得できません。"));
		goto OnError;
	}
#ifdef EVR_USE_VIDEO_WINDOW
	pDisplayControl->SetVideoWindow(m_hwndVideo);
#else
	pDisplayControl->SetVideoWindow(hwndRender);
#endif
	pDisplayControl->SetAspectRatioMode(MFVideoARMode_None);
	/*
	RECT rc;
	::GetClientRect(hwndRender,&rc);
	pDisplayControl->SetVideoPosition(NULL,&rc);
	*/
	pDisplayControl->SetBorderColor(RGB(0,0,0));
	pDisplayControl->Release();

	IMFVideoProcessor *pVideoProcessor;
	hr=pGetService->GetService(MR_VIDEO_MIXER_SERVICE,IID_IMFVideoProcessor,reinterpret_cast<LPVOID*>(&pVideoProcessor));
	if (FAILED(hr)) {
		pGetService->Release();
		SetError(hr,TEXT("IMFVideoProcessorを取得できません。"));
		goto OnError;
	}
	pVideoProcessor->SetBackgroundColor(RGB(0,0,0));
/*
	UINT NumModes;
	GUID *pProcessingModes;
	if (SUCCEEDED(pVideoProcessor->GetAvailableVideoProcessorModes(&NumModes,&pProcessingModes))) {
#ifdef _DEBUG
		for (UINT i=0;i<NumModes;i++) {
			DXVA2_VideoProcessorCaps Caps;

			if (SUCCEEDED(pVideoProcessor->GetVideoProcessorCaps(&pProcessingModes[i],&Caps))) {
				TRACE(TEXT("EVR Video Processor %u\n"),i);
				TRACE(TEXT("DeviceCaps : %s\n"),
					  Caps.DeviceCaps==DXVA2_VPDev_EmulatedDXVA1?
						TEXT("DXVA2_VPDev_EmulatedDXVA1"):
					  Caps.DeviceCaps==DXVA2_VPDev_HardwareDevice?
						TEXT("DXVA2_VPDev_HardwareDevice"):
					  Caps.DeviceCaps==DXVA2_VPDev_SoftwareDevice?
						TEXT("DXVA2_VPDev_SoftwareDevice"):TEXT("Unknown"));
			}
		}
#endif
		for (UINT i=0;i<NumModes;i++) {
			DXVA2_VideoProcessorCaps Caps;

			if (SUCCEEDED(pVideoProcessor->GetVideoProcessorCaps(&pProcessingModes[i],&Caps))) {
				if (Caps.DeviceCaps==DXVA2_VPDev_HardwareDevice) {
					pVideoProcessor->SetVideoProcessorMode(&pProcessingModes[i]);
					break;
				}
			}
		}
		::CoTaskMemFree(pProcessingModes);
	}
*/
	pVideoProcessor->Release();

	pGetService->Release();

	m_pFilterGraph=pFilterGraph;
	m_hwndRender=hwndRender;
#ifdef EVR_USE_VIDEO_WINDOW
	m_hwndMessageDrain=hwndMessageDrain;
#endif

	ClearError();

	return true;

OnError:
	SAFE_RELEASE(m_pRenderer);
#ifdef EVR_USE_VIDEO_WINDOW
	::DestroyWindow(m_hwndVideo);
	m_hwndVideo=NULL;
#endif
	/*
	if (m_hMFPlatLib) {
		::FreeLibrary(m_hMFPlatLib);
		m_hMFPlatLib=NULL;
	}
	*/
	return false;
}