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; }
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; }