Пример #1
0
STDMETHODIMP CDecD3D11::FindVideoServiceConversion(AVCodecID codec, int profile, DXGI_FORMAT surface_format, GUID *input )
{
  AVD3D11VADeviceContext *pDeviceContext = (AVD3D11VADeviceContext *)((AVHWDeviceContext *)m_pDevCtx->data)->hwctx;
  HRESULT hr = S_OK;

  UINT nProfiles = pDeviceContext->video_device->GetVideoDecoderProfileCount();
  GUID *guid_list = (GUID *)av_malloc_array(nProfiles, sizeof(*guid_list));

  DbgLog((LOG_TRACE, 10, L"-> Enumerating supported D3D11 modes (count: %d)", nProfiles));
  for (UINT i = 0; i < nProfiles; i++)
  {
    hr = pDeviceContext->video_device->GetVideoDecoderProfile(i, &guid_list[i]);
    if (FAILED(hr)) {
      DbgLog((LOG_ERROR, 10, L"Error retrieving decoder profile"));
      av_free(guid_list);
      return hr;
    }

#ifdef DEBUG
    const dxva_mode_t *mode = get_dxva_mode_from_guid(&guid_list[i]);
    if (mode) {
      DbgLog((LOG_TRACE, 10, L"  -> %S", mode->name));
    }
    else {
      DbgLog((LOG_TRACE, 10, L"  -> Unknown GUID (%s)", WStringFromGUID(guid_list[i]).c_str()));
    }
#endif
  }

  /* Iterate over our priority list */
  for (unsigned i = 0; dxva_modes[i].name; i++) {
    const dxva_mode_t *mode = &dxva_modes[i];
    if (!check_dxva_mode_compatibility(mode, codec, profile))
      continue;

    BOOL supported = FALSE;
    for (UINT g = 0; !supported && g < nProfiles; g++) {
      supported = IsEqualGUID(*mode->guid, guid_list[g]);
    }
    if (!supported)
      continue;

    DbgLog((LOG_TRACE, 10, L"-> Trying to use '%S'", mode->name));
    hr = pDeviceContext->video_device->CheckVideoDecoderFormat(mode->guid, surface_format, &supported);
    if (SUCCEEDED(hr) && supported) {
      *input = *mode->guid;

      av_free(guid_list);
      return S_OK;
    }
  }

  av_free(guid_list);
  return E_FAIL;
}
Пример #2
0
HRESULT CDecDXVA2::FindVideoServiceConversion(AVCodecID codec, GUID *input, D3DFORMAT *output)
{
  HRESULT hr = S_OK;

  UINT count = 0;
  GUID *input_list = NULL;

  /* Gather the format supported by the decoder */
  hr = m_pDXVADecoderService->GetDecoderDeviceGuids(&count, &input_list);
  if (FAILED(hr)) {
    DbgLog((LOG_TRACE, 10, L"-> GetDecoderDeviceGuids failed with hr: %X", hr));
    goto done;
  }

  DbgLog((LOG_TRACE, 10, L"-> Enumerating supported DXVA2 modes (count: %d)", count));
  for(unsigned i = 0; i < count; i++) {
    const GUID *g = &input_list[i];
    const dxva2_mode_t *mode = DXVA2FindMode(g);
    if (mode) {
      DbgLog((LOG_TRACE, 10, L"  -> %S", mode->name));
    } else {
      DbgLog((LOG_TRACE, 10, L"  -> Unknown GUID (%s)", WStringFromGUID(*g).c_str()));
    }
  }

  /* Iterate over our priority list */
  for (unsigned i = 0; dxva2_modes[i].name; i++) {
    const dxva2_mode_t *mode = &dxva2_modes[i];
     if (!mode->codec || mode->codec != codec)
       continue;

     BOOL supported = FALSE;
     for (const GUID *g = &input_list[0]; !supported && g < &input_list[count]; g++) {
       supported = IsEqualGUID(*mode->guid, *g);
     }
     if (!supported)
       continue;

     DbgLog((LOG_TRACE, 10, L"-> Trying to use '%S'", mode->name));
     UINT out_count = 0;
     D3DFORMAT *out_list = NULL;
     hr = m_pDXVADecoderService->GetDecoderRenderTargets(*mode->guid, &out_count, &out_list);
     if (FAILED(hr)) {
       DbgLog((LOG_TRACE, 10, L"-> Retrieving render targets failed with hr: %X", hr));
       continue;
     }

     BOOL hasNV12 = FALSE;
     DbgLog((LOG_TRACE, 10, L"-> Enumerating render targets (count: %d)", out_count));
     for (unsigned j = 0; j < out_count; j++) {
       const D3DFORMAT f = out_list[j];
       DbgLog((LOG_TRACE, 10, L"  -> %d is supported (%4.4S)", f, (const char *)&f));
       if (f == FOURCC_NV12) {
         hasNV12 = TRUE;
       }
     }
     if (hasNV12) {
       DbgLog((LOG_TRACE, 10, L"-> Found NV12, finished setup"));
       *input = *mode->guid;
       *output = (D3DFORMAT)FOURCC_NV12;

       SAFE_CO_FREE(out_list);
       SAFE_CO_FREE(input_list);
       return S_OK;
     }

     SAFE_CO_FREE(out_list);
  }

done:
  SAFE_CO_FREE(input_list);
  return E_FAIL;
}