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; }
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; }
// IMFActivate HRESULT DX11VideoRenderer::CActivate::ActivateObject(__RPC__in REFIID riid, __RPC__deref_out_opt void** ppvObject) { HRESULT hr = S_OK; IMFGetService* pSinkGetService = NULL; IMFVideoDisplayControl* pSinkVideoDisplayControl = NULL; do { if (m_pMediaSink == NULL) { hr = CMediaSink::CreateInstance(IID_PPV_ARGS(&m_pMediaSink)); if (FAILED(hr)) { break; } hr = m_pMediaSink->QueryInterface(IID_PPV_ARGS(&pSinkGetService)); if (FAILED(hr)) { break; } hr = pSinkGetService->GetService(MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&pSinkVideoDisplayControl)); if (FAILED(hr)) { break; } hr = pSinkVideoDisplayControl->SetVideoWindow(m_hwnd); if (FAILED(hr)) { break; } } hr = m_pMediaSink->QueryInterface(riid, ppvObject); if (FAILED(hr)) { break; } } while (FALSE); SafeRelease(pSinkGetService); SafeRelease(pSinkVideoDisplayControl); return hr; }
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; }