コード例 #1
0
ファイル: ImageMixer.cpp プロジェクト: DBCTRADO/TVTest
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
ファイル: dxva2dec.cpp プロジェクト: UIKit0/LAVFilters
STDMETHODIMP CDecDXVA2::PostConnect(IPin *pPin)
{
  HRESULT hr = S_OK;

  if (!m_bNative && m_pD3DDevMngr)
    return S_OK;

  DbgLog((LOG_TRACE, 10, L"CDecDXVA2::PostConnect()"));

  IMFGetService *pGetService = nullptr;
  hr = pPin->QueryInterface(__uuidof(IMFGetService), (void**)&pGetService);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> IMFGetService not available"));
    goto done;
  }

  // Release old D3D resources, we're about to re-init
  m_pCallback->ReleaseAllDXVAResources();
  FreeD3DResources();

  // Get the Direct3D device manager.
  hr = pGetService->GetService(MR_VIDEO_ACCELERATION_SERVICE, __uuidof(IDirect3DDeviceManager9), (void**)&m_pD3DDevMngr);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> D3D Device Manager not available"));
    goto done;
  }

  hr = SetD3DDeviceManager(m_pD3DDevMngr);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> Setting D3D Device Manager faield"));
    goto done;
  }

  if (m_bNative) {
    if (!m_pDecoder) {
      // If this is the first call, re-align surfaces, as the requirements may only be known now
      m_dwSurfaceWidth = GetAlignedDimension(m_pAVCtx->coded_width);
      m_dwSurfaceHeight = GetAlignedDimension(m_pAVCtx->coded_height);
    }

    CMediaType mt = m_pCallback->GetOutputMediaType();
    if (mt.subtype != MEDIASUBTYPE_NV12) {
      DbgLog((LOG_ERROR, 10, L"-> Connection is not NV12"));
      hr = E_FAIL;
      goto done;
    }
    hr = DXVA2NotifyEVR();
  }

done:
  SafeRelease(&pGetService);
  if (FAILED(hr)) {
    FreeD3DResources();
  }
  return hr;
}
コード例 #3
0
ファイル: DirectShowUtil.cpp プロジェクト: ACUVE/TVTest
// EVR専用 : ビデオプロセッサ操作用インターフェースの取得
IMFVideoProcessor* DirectShowUtil::MF_GetVideoProcessor(IBaseFilter *pEvr)
{
	IMFGetService *pService = MF_GetService(pEvr);
	if(pService) {
		IMFVideoProcessor *pVideoProcessor;
		HRESULT hr = pService->GetService(MR_VIDEO_MIXER_SERVICE,IID_IMFVideoProcessor,(void**)&pVideoProcessor);
		SAFE_RELEASE(pService);
		if(SUCCEEDED(hr)) {
			return pVideoProcessor;
			}
		}
	return NULL;
}
コード例 #4
0
ファイル: DirectShowUtil.cpp プロジェクト: ACUVE/TVTest
// EVR専用 : ディスプレイ操作用インターフェースの取得
IMFVideoDisplayControl* DirectShowUtil::MF_GetVideoDisplayControl(IBaseFilter *pEvr)
{
	IMFGetService *pService = MF_GetService(pEvr);
	if(pService) {
		IMFVideoDisplayControl *pDisplayControl;
		HRESULT hr = pService->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&pDisplayControl);
		SAFE_RELEASE(pService);
		if(SUCCEEDED(hr)){
			return pDisplayControl;
			}
		}
	return NULL;
}
コード例 #5
0
ファイル: dxva2dec.cpp プロジェクト: betaking/LAVFilters
STDMETHODIMP CDecDXVA2::PostConnect(IPin *pPin)
{
  HRESULT hr = S_OK;

  if (!m_bNative && m_pD3DDevMngr)
    return S_OK;

  DbgLog((LOG_TRACE, 10, L"CDecDXVA2::PostConnect()"));

  IMFGetService *pGetService = NULL;
  hr = pPin->QueryInterface(__uuidof(IMFGetService), (void**)&pGetService);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> IMFGetService not available"));
    goto done;
  }

  // Release old D3D resources, we're about to re-init
  m_pCallback->ReleaseAllDXVAResources();
  FreeD3DResources();

  // Get the Direct3D device manager.
  hr = pGetService->GetService(MR_VIDEO_ACCELERATION_SERVICE, __uuidof(IDirect3DDeviceManager9), (void**)&m_pD3DDevMngr);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> D3D Device Manager not available"));
    goto done;
  }

  hr = SetD3DDeviceManager(m_pD3DDevMngr);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> Setting D3D Device Manager faield"));
    goto done;
  }

  if (m_bNative) {
    CMediaType mt = m_pCallback->GetOutputMediaType();
    if (mt.subtype != MEDIASUBTYPE_NV12) {
      DbgLog((LOG_ERROR, 10, L"-> Connection is not NV12"));
      hr = E_FAIL;
      goto done;
    }
    hr = DXVA2NotifyEVR();
  }

done:
  SafeRelease(&pGetService);
  if (FAILED(hr)) {
    FreeD3DResources();
  }
  return hr;
}
コード例 #6
0
ファイル: EVRenderer.cpp プロジェクト: kento1218/TVTest
static IMFVideoDisplayControl *GetVideoDisplayControl(IBaseFilter *pRenderer)
{
	HRESULT hr;
	IMFGetService *pGetService;
	IMFVideoDisplayControl *pDisplayControl;

	hr=pRenderer->QueryInterface(IID_IMFGetService,reinterpret_cast<LPVOID*>(&pGetService));
	if (FAILED(hr))
		return NULL;
	hr=pGetService->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,reinterpret_cast<LPVOID*>(&pDisplayControl));
	pGetService->Release();
	if (FAILED(hr))
		return NULL;
	return pDisplayControl;
}
コード例 #7
0
// 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;
}
コード例 #8
0
// IMFActivate
HRESULT QEvrVideoOverlay::ActivateObject(REFIID riid, void **ppv)
{
    if (riid != __uuidof(IMFVideoPresenter)) {
        return E_NOINTERFACE;
    } else if (!ptrMFCreateVideoPresenter) {
        return E_NOINTERFACE;
    } else if (m_presenter) {
        *ppv = m_presenter;

        return S_OK;
    } else {
        IMFVideoDisplayControl *displayControl = 0;

        IMFGetService *service;
        HRESULT hr;
        if ((hr = (*ptrMFCreateVideoPresenter)(
                0,
                __uuidof(IDirect3DDevice9),
                __uuidof(IMFVideoPresenter),
                reinterpret_cast<void **>(&m_presenter))) != S_OK) {
            qWarning("failed to create video presenter");
        } else if ((hr = m_presenter->QueryInterface(
                __uuidof(IMFGetService), reinterpret_cast<void **>(&service))) != S_OK) {
            qWarning("failed to query IMFGetService interface");
        } else {
            if ((hr = service->GetService(
                    MR_VIDEO_RENDER_SERVICE,
                    __uuidof(IMFVideoDisplayControl),
                    reinterpret_cast<void **>(&displayControl))) != S_OK) {
                qWarning("failed to get IMFVideoDisplayControl service");
            }
            service->Release();
        }

        setDisplayControl(displayControl);

        if (m_presenter && hr != S_OK) {
            m_presenter->Release();
            m_presenter = 0;
        }

        *ppv = m_presenter;

        return hr;
    }
}
コード例 #9
0
ファイル: ImageMixer.cpp プロジェクト: DBCTRADO/TVTest
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;
}
コード例 #10
0
ファイル: ImageMixer.cpp プロジェクト: DBCTRADO/TVTest
void CImageMixer_EVR::Clear()
{
	if (m_hdc!=NULL) {
		IMFGetService *pGetService;

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

			if (SUCCEEDED(pGetService->GetService(MR_VIDEO_MIXER_SERVICE,
								IID_IMFVideoMixerBitmap,
								reinterpret_cast<LPVOID*>(&pMixerBitmap)))) {
				pMixerBitmap->ClearAlphaBitmap();
				pMixerBitmap->Release();
			}
			pGetService->Release();
		}
	}
}
コード例 #11
0
void TvideoCodecQuickSync::setOutputPin(IPin *pPin)
{
    if (!ok) { return; }

    if (NULL == pPin) {
        m_QuickSync->SetD3DDeviceManager(NULL);
    }

    IDirect3DDeviceManager9 *pDeviceManager = NULL;
    IMFGetService *pGetService = NULL;
    HRESULT hr = pPin->QueryInterface(__uuidof(IMFGetService), (void**)&pGetService);
    if (SUCCEEDED(hr)) {
        hr = pGetService->GetService(MR_VIDEO_ACCELERATION_SERVICE, IID_IDirect3DDeviceManager9, (void**)&pDeviceManager);
    }

    m_QuickSync->SetD3DDeviceManager((SUCCEEDED(hr)) ? pDeviceManager : NULL);

    if (pDeviceManager) { pDeviceManager->Release(); }
    if (pGetService) { pGetService->Release(); }
}
コード例 #12
0
ファイル: dxva2dec.cpp プロジェクト: betaking/LAVFilters
HRESULT CDecDXVA2::DXVA2NotifyEVR()
{
  HRESULT hr = S_OK;
  IMFGetService *pGetService = NULL;
  IDirectXVideoMemoryConfiguration *pVideoConfig = NULL;

  hr = m_pCallback->GetOutputPin()->GetConnected()->QueryInterface(&pGetService);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> IMFGetService not available"));
    goto done;
  }

  // Configure EVR for receiving DXVA2 samples
  hr = pGetService->GetService(MR_VIDEO_ACCELERATION_SERVICE, __uuidof(IDirectXVideoMemoryConfiguration), (void**)&pVideoConfig);
  if (FAILED(hr)) {
    DbgLog((LOG_ERROR, 10, L"-> IDirectXVideoMemoryConfiguration not available"));
    goto done;
  }

  // Notify the EVR about the format we're sending
  DXVA2_SurfaceType surfaceType;
  for (DWORD iTypeIndex = 0; ; iTypeIndex++) {
    hr = pVideoConfig->GetAvailableSurfaceTypeByIndex(iTypeIndex, &surfaceType);
    if (FAILED(hr)) {
      hr = S_OK;
      break;
    }

    if (surfaceType == DXVA2_SurfaceType_DecoderRenderTarget) {
      hr = pVideoConfig->SetSurfaceType(DXVA2_SurfaceType_DecoderRenderTarget);
      break;
    }
  }
done:
  SafeRelease(&pGetService);
  SafeRelease(&pVideoConfig);
  return hr;
}
コード例 #13
0
HRESULT CMpeg2DecoderDXVA2::DecodeFrame(IMediaSample **ppSample)
{
	if (ppSample) {
		*ppSample = nullptr;
	}

	if (!m_pDec || !m_pVideoDecoder) {
		return E_UNEXPECTED;
	}

	if (m_pDec->picture->flags & PIC_FLAG_SKIP) {
		return GetDisplaySample(ppSample);
	}

	m_DecodeSampleIndex = GetFBufIndex(m_pDec->fbuf[0]);

	if (!m_SliceCount || m_DecodeSampleIndex < 0) {
		return S_FALSE;
	}

	if (m_fWaitForDecodeKeyFrame) {
		if ((m_pDec->picture->flags & PIC_MASK_CODING_TYPE) != PIC_FLAG_CODING_TYPE_I) {
			return S_FALSE;
		}
		m_fWaitForDecodeKeyFrame = false;
	}

	HRESULT hr;

	hr = m_pDeviceManager->TestDevice(m_pFilter->m_hDXVADevice);
	if (FAILED(hr)) {
		if (hr == DXVA2_E_NEW_VIDEO_DEVICE) {
			DBG_TRACE(TEXT("Device lost"));
			m_fDeviceLost = true;
		}
		return hr;
	}

	switch (m_pDec->picture->flags & PIC_MASK_CODING_TYPE) {
	case PIC_FLAG_CODING_TYPE_I:
		m_PrevRefSurfaceIndex = -1;
		m_ForwardRefSurfaceIndex = -1;
		//DBG_TRACE(TEXT("I [%d]"), m_CurSurfaceIndex);
		break;
	case PIC_FLAG_CODING_TYPE_P:
		m_PrevRefSurfaceIndex = GetFBufSampleID(m_pDec->fbuf[1]);
		m_ForwardRefSurfaceIndex = -1;
		//DBG_TRACE(TEXT("P [%d]->%d"), m_CurSurfaceIndex, m_PrevRefSurfaceIndex);
		break;
	case PIC_FLAG_CODING_TYPE_B:
		m_PrevRefSurfaceIndex = GetFBufSampleID(m_pDec->fbuf[1]);
		m_ForwardRefSurfaceIndex = GetFBufSampleID(m_pDec->fbuf[2]);
		//DBG_TRACE(TEXT("B %d->[%d]->%d"), m_PrevRefSurfaceIndex, m_CurSurfaceIndex, m_ForwardRefSurfaceIndex);
		if (m_ForwardRefSurfaceIndex < 0)
			return S_FALSE;
		break;
	}

	CDXVA2MediaSample *pSample = m_Samples[m_DecodeSampleIndex].pSample;

	if (!pSample) {
		IMediaSample *pMediaSample;
		IDXVA2MediaSample *pDXVA2Sample;

		for (;;) {
			hr = m_pFilter->GetDeliveryBuffer(&pMediaSample);
			if (FAILED(hr)) {
				return hr;
			}
			hr = pMediaSample->QueryInterface(IID_PPV_ARGS(&pDXVA2Sample));
			pMediaSample->Release();
			if (FAILED(hr)) {
				return hr;
			}
			pSample = static_cast<CDXVA2MediaSample*>(pDXVA2Sample);
			if (pSample->GetSurfaceID() == m_RefSamples[0].SurfaceID) {
				m_RefSamples[0].pSample = pSample;
			} else if (pSample->GetSurfaceID() == m_RefSamples[1].SurfaceID) {
				m_RefSamples[1].pSample = pSample;
			} else {
				break;
			}
		}
		m_Samples[m_DecodeSampleIndex].pSample = pSample;
		m_Samples[m_DecodeSampleIndex].SurfaceID = pSample->GetSurfaceID();
	}

	m_CurSurfaceIndex = pSample->GetSurfaceID();

#ifdef _DEBUG
	if ((m_pDec->picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) {
		_ASSERT(m_PrevRefSurfaceIndex>=0 && m_CurSurfaceIndex != m_PrevRefSurfaceIndex);
	} else if ((m_pDec->picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B) {
		_ASSERT(m_PrevRefSurfaceIndex>=0
			&& m_CurSurfaceIndex != m_PrevRefSurfaceIndex
			&& m_ForwardRefSurfaceIndex>=0
			&& m_CurSurfaceIndex != m_ForwardRefSurfaceIndex);
	}
#endif

	IDirect3DSurface9 *pSurface;
	IMFGetService *pMFGetService;
	hr = pSample->QueryInterface(IID_PPV_ARGS(&pMFGetService));
	if (SUCCEEDED(hr)) {
		hr = pMFGetService->GetService(MR_BUFFER_SERVICE, IID_PPV_ARGS(&pSurface));
		pMFGetService->Release();
	}
	if (FAILED(hr)) {
		return hr;
	}

	int Retry = 0;
	for (;;) {
		hr = m_pVideoDecoder->BeginFrame(pSurface, nullptr);
		if (hr != E_PENDING || Retry >= 50)
			break;
		::Sleep(2);
		Retry++;
	}
	if (SUCCEEDED(hr)) {
		hr = CommitBuffers();
		if (SUCCEEDED(hr)) {
			DXVA2_DecodeExecuteParams ExecParams;
			DXVA2_DecodeBufferDesc BufferDesc[4];
			const UINT NumMBsInBuffer =
				(m_PictureParams.wPicWidthInMBminus1 + 1) * (m_PictureParams.wPicHeightInMBminus1 + 1);

			::ZeroMemory(BufferDesc, sizeof(BufferDesc));
			BufferDesc[0].CompressedBufferType = DXVA2_PictureParametersBufferType;
			BufferDesc[0].DataSize = sizeof(DXVA_PictureParameters);
			BufferDesc[1].CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType;
			BufferDesc[1].DataSize = sizeof(DXVA_QmatrixData);
			BufferDesc[2].CompressedBufferType = DXVA2_BitStreamDateBufferType;
			BufferDesc[2].DataSize = (UINT)m_SliceDataSize;
			BufferDesc[2].NumMBsInBuffer = NumMBsInBuffer;
			BufferDesc[3].CompressedBufferType = DXVA2_SliceControlBufferType;
			BufferDesc[3].DataSize = m_SliceCount * sizeof(DXVA_SliceInfo);
			BufferDesc[3].NumMBsInBuffer = NumMBsInBuffer;

			ExecParams.NumCompBuffers = 4;
			ExecParams.pCompressedBuffers = BufferDesc;
			ExecParams.pExtensionData = nullptr;

			hr = m_pVideoDecoder->Execute(&ExecParams);
			if (SUCCEEDED(hr)) {
				hr = GetDisplaySample(ppSample);
			}
		}

		m_pVideoDecoder->EndFrame(nullptr);
	}

	if ((m_pDec->picture->flags & PIC_MASK_CODING_TYPE) != PIC_FLAG_CODING_TYPE_B
			&& ppSample) {
		SafeRelease(m_RefSamples[1].pSample);
		m_RefSamples[1] = m_RefSamples[0];
		m_RefSamples[0].pSample = nullptr;
		m_RefSamples[0].SurfaceID = m_CurSurfaceIndex;
	}

	pSurface->Release();

	return hr;
}
コード例 #14
0
ファイル: EVRenderer.cpp プロジェクト: kento1218/TVTest
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;
}