//-------------------------------------------------------------------------------------------------
static void FillSurfaceDX9(AMFContext *context, AMFSurface *surface)
{
    HRESULT hr = S_OK;
    // fill surface with something something useful. We fill with color and color rect
    D3DCOLOR color1 = D3DCOLOR_XYUV (128, 255, 128);
    D3DCOLOR color2 = D3DCOLOR_XYUV (128, 0, 128);
    // get native DX objects
    IDirect3DDevice9 *deviceDX9 = (IDirect3DDevice9 *)context->pVtbl->GetDX9Device(context, AMF_DX9); // no reference counting - do not Release()
    AMFPlane *plane = surface->pVtbl->GetPlaneAt(surface, 0);
    IDirect3DSurface9* surfaceDX9 = (IDirect3DSurface9*)plane->pVtbl->GetNative(plane); // no reference counting - do not Release()
    hr = deviceDX9->lpVtbl->ColorFill(deviceDX9, surfaceDX9, NULL, color1);

    if(xPos + rectSize > widthIn)
    {
        xPos = 0;
    }
    if(yPos + rectSize > heightIn)
    {
        yPos = 0;
    }
    RECT rect = {xPos, yPos, xPos + rectSize, yPos + rectSize};
    hr = deviceDX9->lpVtbl->ColorFill(deviceDX9, surfaceDX9, &rect, color2);

    xPos+=2; //DX9 NV12 surfaces do not accept odd positions - do not use ++
    yPos+=2; //DX9 NV12 surfaces do not accept odd positions - do not use ++
}
HRESULT CDXVA2Allocator::Alloc()
{
	CAutoLock Lock(this);

	TRACE(TEXT("CDXVA2Allocator::Alloc()\n"));

	if (!m_pFilter->m_pD3DDeviceManager)
		return E_UNEXPECTED;

	HRESULT hr;

	IDirectXVideoDecoderService *pDecoderService;
	hr = m_pFilter->m_pD3DDeviceManager->GetVideoService(
		m_pFilter->m_hDXVADevice, IID_PPV_ARGS(&pDecoderService));
	if (FAILED(hr)) {
		TRACE(TEXT("IDirect3DDeviceManager9::GetVideoService() failed (%x)\n"), hr);
		return hr;
	}

	hr = CBaseAllocator::Alloc();

	/*
	if (hr == S_FALSE) {
		pDecoderDevice->Release();
		return S_OK;
	}
	*/

	if (SUCCEEDED(hr)) {
		Free();

		m_SurfaceList.resize(m_lCount);

		const int Width = m_pFilter->GetAlignedWidth(), Height = m_pFilter->GetAlignedHeight();
		TRACE(TEXT("Create DXVA2 surfaces : %d x [%d x %d]\n"), m_lCount, Width, Height);

		hr = pDecoderService->CreateSurface(
			Width,
			Height,
			m_lCount - 1,
			D3DFMT_NV12,
			D3DPOOL_DEFAULT,
			0,
			DXVA2_VideoDecoderRenderTarget,
			&m_SurfaceList[0],
			nullptr);
		if (FAILED(hr)) {
			TRACE(TEXT("IDirectXVideoDecoderService::CreateSurface() failed (%x)\n"), hr);
			m_SurfaceList.clear();
		} else {
			IDirect3DDevice9 *pD3DDevice;
			hr = m_SurfaceList.front()->GetDevice(&pD3DDevice);
			if (FAILED(hr))
				pD3DDevice = nullptr;

			for (int i = m_lCount - 1; i >= 0; i--) {
				IDirect3DSurface9 *pSurface = m_SurfaceList[i];

				if (pD3DDevice) {
					pD3DDevice->ColorFill(pSurface, nullptr, D3DCOLOR_XYUV(16, 128, 128));
				}

				CDXVA2MediaSample *pSample = DNew_nothrow CDXVA2MediaSample(this, &hr);

				if (!pSample) {
					hr = E_OUTOFMEMORY;
					break;
				}
				if (FAILED(hr)) {
					delete pSample;
					break;
				}

				pSample->SetSurface(i, pSurface);
				m_lFree.Add(pSample);
			}

			if (pD3DDevice)
				pD3DDevice->Release();

			if (SUCCEEDED(hr)) {
				m_lAllocated = m_lCount;
				hr = m_pFilter->OnDXVA2SurfaceCreated(&m_SurfaceList[0], m_lAllocated);
			} else {
				Free();
			}
		}
	}

	pDecoderService->Release();

	if (SUCCEEDED(hr)) {
		m_bChanged = FALSE;
	}

	return hr;
}
Esempio n. 3
0
HRESULT CDecDXVA2::CreateDXVA2Decoder(int nSurfaces, IDirect3DSurface9 **ppSurfaces)
{
  DbgLog((LOG_TRACE, 10, L"-> CDecDXVA2::CreateDXVA2Decoder"));
  HRESULT hr = S_OK;
  LPDIRECT3DSURFACE9 pSurfaces[DXVA2_MAX_SURFACES];

  if (!m_pDXVADecoderService)
    return E_FAIL;

  DestroyDecoder(false, true);

  GUID input = GUID_NULL;
  D3DFORMAT output;
  FindVideoServiceConversion(m_pAVCtx->codec_id, &input, &output);

  if (!nSurfaces) {
    m_dwSurfaceWidth = GetAlignedDimension(m_pAVCtx->coded_width);
    m_dwSurfaceHeight = GetAlignedDimension(m_pAVCtx->coded_height);

    m_NumSurfaces = GetBufferCount();
    hr = m_pDXVADecoderService->CreateSurface(m_dwSurfaceWidth, m_dwSurfaceHeight, m_NumSurfaces - 1, output, D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget, pSurfaces, nullptr);
    if (FAILED(hr)) {
      DbgLog((LOG_TRACE, 10, L"-> Creation of surfaces failed with hr: %X", hr));
      m_NumSurfaces = 0;
      return E_FAIL;
    }
    ppSurfaces = pSurfaces;
  } else {
    m_NumSurfaces = nSurfaces;
    for (int i = 0; i < m_NumSurfaces; i++) {
      ppSurfaces[i]->AddRef();
    }
  }

  if (m_NumSurfaces <= 0) {
    DbgLog((LOG_TRACE, 10, L"-> No surfaces? No good!"));
    return E_FAIL;
  }

  // get the device, for ColorFill() to init the surfaces in black
  IDirect3DDevice9 *pDev = nullptr;
  ppSurfaces[0]->GetDevice(&pDev);

  for (int i = 0; i < m_NumSurfaces; i++) {
    m_pSurfaces[i].index = i;
    m_pSurfaces[i].d3d = ppSurfaces[i];
    m_pSurfaces[i].age = 0;
    m_pSurfaces[i].used = false;

    // fill the surface in black, to avoid the "green screen" in case the first frame fails to decode.
    if (pDev) pDev->ColorFill(ppSurfaces[i], NULL, D3DCOLOR_XYUV(0, 128, 128));
  }

  // and done with the device
  SafeRelease(&pDev);

  DbgLog((LOG_TRACE, 10, L"-> Successfully created %d surfaces (%dx%d)", m_NumSurfaces, m_dwSurfaceWidth, m_dwSurfaceHeight));

  DXVA2_VideoDesc desc;
  ZeroMemory(&desc, sizeof(desc));
  desc.SampleWidth = m_pAVCtx->coded_width;
  desc.SampleHeight = m_pAVCtx->coded_height;
  desc.Format = output;

  hr = FindDecoderConfiguration(input, &desc, &m_DXVAVideoDecoderConfig);
  if (FAILED(hr)) {
    DbgLog((LOG_TRACE, 10, L"-> FindDecoderConfiguration failed with hr: %X", hr));
    return hr;
  }

  IDirectXVideoDecoder *decoder = nullptr;
  hr = m_pDXVADecoderService->CreateVideoDecoder(input, &desc, &m_DXVAVideoDecoderConfig, ppSurfaces, m_NumSurfaces, &decoder);
  if (FAILED(hr)) {
    DbgLog((LOG_TRACE, 10, L"-> CreateVideoDecoder failed with hr: %X", hr));
    return E_FAIL;
  }
  m_pDecoder = decoder;
  m_guidDecoderDevice = input;

  /* fill hwaccel_context */
  FillHWContext((dxva_context *)m_pAVCtx->hwaccel_context);

  memset(m_pRawSurface, 0, sizeof(m_pRawSurface));
  for (int i = 0; i < m_NumSurfaces; i++) {
    m_pRawSurface[i] = m_pSurfaces[i].d3d;
  }

  return S_OK;
}