static void dump_decoder_info(struct lavc_ctx *s, GUID *device_guids, UINT n_guids) { struct priv *p = s->hwdec_priv; MP_VERBOSE(p, "%u decoder devices:\n", (unsigned)n_guids); for (UINT i = 0; i < n_guids; i++) { GUID *guid = &device_guids[i]; char *description = d3d_decoder_guid_to_desc(guid); D3DFORMAT *formats = NULL; UINT n_formats = 0; HRESULT hr = IDirectXVideoDecoderService_GetDecoderRenderTargets( p->decoder_service, guid, &n_formats, &formats); if (FAILED(hr)) { MP_ERR(p, "Failed to get render targets for decoder %s:%s\n", description, mp_HRESULT_to_str(hr)); } char fmts[256] = {0}; for (UINT j = 0; j < n_formats; j++) { mp_snprintf_cat(fmts, sizeof(fmts), " %s", mp_tag_str(formats[j])); } CoTaskMemFree(formats); MP_VERBOSE(p, "%s %s\n", description, fmts); } }
static DWORD get_dxfmt_cb(struct lavc_ctx *s, const GUID *guid, int depth) { DWORD ret = 0; struct priv *p = s->hwdec_priv; D3DFORMAT *formats = NULL; UINT n_formats = 0; HRESULT hr = IDirectXVideoDecoderService_GetDecoderRenderTargets( p->decoder_service, guid, &n_formats, &formats); if (FAILED(hr)) { MP_ERR(p, "Callback failed to get render targets for decoder %s: %s", d3d_decoder_guid_to_desc(guid), mp_HRESULT_to_str(hr)); return 0; } for (int i = 0; i < MP_ARRAY_SIZE(d3d9_formats); i++) { const struct d3d9_format *d3d9_fmt = &d3d9_formats[i]; if (d3d9_fmt->depth < depth) continue; for (UINT j = 0; j < n_formats; j++) { if (formats[i] == d3d9_fmt->format) { ret = formats[i]; MP_VERBOSE(p, "Selecting %s %s\n", d3d_decoder_guid_to_desc(guid), mp_tag_str(ret)); goto done; } } } done: CoTaskMemFree(formats); return ret; }
static void test_decoder(IDirectXVideoDecoderService *service, REFGUID const guid, UINT width, UINT height, UINT surface_count) { HRESULT hr; D3DFORMAT *formats; D3DFORMAT test_format; UINT count; if (0) /* crashes on windows */ { hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, NULL, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, &count, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, NULL, &formats); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); } hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, &GUID_NULL, &count, &formats); ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %x\n", hr); hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, &count, &formats); ok(!hr, "Failed to get formats for codec %s\n", convert_decoderguid_to_str(guid)); if (hr) return; if (!count) { skip("Decoder for %s does not support a single output format? Skipping test\n", convert_decoderguid_to_str(guid)); return; } test_format = formats[0]; CoTaskMemFree(formats); test_decoder_resolution(service, guid, test_format, width, height, surface_count); }
static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *fmt) { VLC_UNUSED(fmt); int err = VLC_EGENERIC; UINT output_count = 0; D3DFORMAT *output_list = NULL; if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va->sys->dx_sys.d3ddec, input, &output_count, &output_list))) { msg_Err(va, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed"); return VLC_EGENERIC; } for (unsigned j = 0; j < output_count; j++) { const D3DFORMAT f = output_list[j]; const d3d_format_t *format = D3dFindFormat(f); if (format) { msg_Dbg(va, "%s is supported for output", format->name); } else { msg_Dbg(va, "%d is supported for output (%4.4s)", f, (const char*)&f); } } /* */ for (unsigned pass = 0; pass < 2 && err != VLC_SUCCESS; ++pass) { for (unsigned j = 0; d3d_formats[j].name; j++) { const d3d_format_t *format = &d3d_formats[j]; /* */ bool is_supported = false; for (unsigned k = 0; !is_supported && k < output_count; k++) { is_supported = format->format == output_list[k]; } if (!is_supported) continue; if (pass == 0 && format->format != va->sys->render) continue; /* We have our solution */ msg_Dbg(va, "Using decoder output '%s'", format->name); va->sys->render = format->format; err = VLC_SUCCESS; break; } } CoTaskMemFree(output_list); return err; }
bool DXVA2Decoder::TestTarget(const GUID &guid) { if (!m_service) return false; uint output_count = 0; D3DFORMAT *output_list = nullptr; IDirectXVideoDecoderService_GetDecoderRenderTargets( m_service, guid, &output_count, &output_list); for(uint i = 0; i < output_count; i++) { if(output_list[i] == MAKEFOURCC('Y','V','1','2') || output_list[i] == MAKEFOURCC('N','V','1','2')) { m_input = guid; m_format.Format = output_list[i]; return true; } } return false; }
static bool dxva2_format_supported(struct lavc_ctx *s, const GUID *guid, const struct d3d_decoded_format *format) { bool ret = false; struct priv *p = s->hwdec_priv; D3DFORMAT *formats = NULL; UINT n_formats = 0; HRESULT hr = IDirectXVideoDecoderService_GetDecoderRenderTargets( p->decoder_service, guid, &n_formats, &formats); if (FAILED(hr)) { MP_ERR(p, "Callback failed to get render targets for decoder %s: %s", d3d_decoder_guid_to_desc(guid), mp_HRESULT_to_str(hr)); return 0; } for (int i = 0; i < n_formats; i++) { ret = formats[i] == format->dxfmt; if (ret) break; } CoTaskMemFree(formats); return ret; }
/** * Find the best suited decoder mode GUID and render format. */ static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORMAT *output) { /* Retreive supported modes from the decoder service */ UINT input_count = 0; GUID *input_list = NULL; if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(va->vs, &input_count, &input_list))) { msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed"); return VLC_EGENERIC; } for (unsigned i = 0; i < input_count; i++) { const GUID *g = &input_list[i]; const dxva2_mode_t *mode = Dxva2FindMode(g); if (mode) { msg_Dbg(va->log, "- '%s' is supported by hardware", mode->name); } else { msg_Warn(va->log, "- Unknown GUID = %08X-%04x-%04x-XXXX", (unsigned)g->Data1, g->Data2, g->Data3); } } /* Try all supported mode by our priority */ for (unsigned i = 0; dxva2_modes[i].name; i++) { const dxva2_mode_t *mode = &dxva2_modes[i]; if (!mode->codec || mode->codec != va->codec_id) continue; /* */ bool is_suported = false; for (const GUID *g = &input_list[0]; !is_suported && g < &input_list[input_count]; g++) { is_suported = IsEqualGUID(mode->guid, g); } if (!is_suported) continue; /* */ msg_Dbg(va->log, "Trying to use '%s' as input", mode->name); UINT output_count = 0; D3DFORMAT *output_list = NULL; if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va->vs, mode->guid, &output_count, &output_list))) { msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed"); continue; } for (unsigned j = 0; j < output_count; j++) { const D3DFORMAT f = output_list[j]; const d3d_format_t *format = D3dFindFormat(f); if (format) { msg_Dbg(va->log, "%s is supported for output", format->name); } else { msg_Dbg(va->log, "%d is supported for output (%4.4s)", f, (const char*)&f); } } /* */ for (unsigned j = 0; d3d_formats[j].name; j++) { const d3d_format_t *format = &d3d_formats[j]; /* */ bool is_suported = false; for (unsigned k = 0; !is_suported && k < output_count; k++) { is_suported = format->format == output_list[k]; } if (!is_suported) continue; /* We have our solution */ msg_Dbg(va->log, "Using '%s' to decode to '%s'", mode->name, format->name); *input = *mode->guid; *output = format->format; CoTaskMemFree(output_list); CoTaskMemFree(input_list); return VLC_SUCCESS; } CoTaskMemFree(output_list); } CoTaskMemFree(input_list); return VLC_EGENERIC; }
static int dxva2_create_decoder(AVCodecContext *s) { HwAccelContext *hac = s->opaque; DXVA2Context *ctx = hac->hwaccel_ctx; struct dxva_context *dxva_ctx = s->hwaccel_context; GUID *guid_list = NULL; unsigned guid_count = 0, i, j; GUID device_guid = GUID_NULL; D3DFORMAT target_format = 0; DXVA2_VideoDesc desc = { 0 }; DXVA2_ConfigPictureDecode config; HRESULT hr; int surface_alignment; int ret; hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->decoder_service, &guid_count, &guid_list); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to retrieve decoder device GUIDs\n"); goto fail; } for (i = 0; dxva2_modes[i].guid; i++) { D3DFORMAT *target_list = NULL; unsigned target_count = 0; const dxva2_mode *mode = &dxva2_modes[i]; if (mode->codec != s->codec_id) continue; for (j = 0; j < guid_count; j++) { if (IsEqualGUID(mode->guid, &guid_list[j])) break; } if (j == guid_count) continue; hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->decoder_service, mode->guid, &target_count, &target_list); if (FAILED(hr)) { continue; } for (j = 0; j < target_count; j++) { const D3DFORMAT format = target_list[j]; if (format == MKTAG('N','V','1','2')) { target_format = format; break; } } CoTaskMemFree(target_list); if (target_format) { device_guid = *mode->guid; break; } } CoTaskMemFree(guid_list); if (IsEqualGUID(&device_guid, &GUID_NULL)) { av_log(NULL, loglevel, "No decoder device for codec found\n"); goto fail; } desc.SampleWidth = s->coded_width; desc.SampleHeight = s->coded_height; desc.Format = target_format; ret = dxva2_get_decoder_configuration(s, &device_guid, &desc, &config); if (ret < 0) { goto fail; } /* decoding MPEG-2 requires additional alignment on some Intel GPUs, but it causes issues for H.264 on certain AMD GPUs..... */ if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) surface_alignment = 32; /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure all coding features have enough room to work with */ else if (s->codec_id == AV_CODEC_ID_HEVC) surface_alignment = 128; else surface_alignment = 16; /* 4 base work surfaces */ ctx->num_surfaces = 4; /* add surfaces based on number of possible refs */ if (s->codec_id == AV_CODEC_ID_H264 || s->codec_id == AV_CODEC_ID_HEVC) ctx->num_surfaces += 16; else ctx->num_surfaces += 2; /* add extra surfaces for frame threading */ if (s->active_thread_type & FF_THREAD_FRAME) ctx->num_surfaces += s->thread_count; ctx->surfaces = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surfaces)); ctx->surface_infos = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surface_infos)); if (!ctx->surfaces || !ctx->surface_infos) { av_log(NULL, loglevel, "Unable to allocate surface arrays\n"); goto fail; } hr = IDirectXVideoDecoderService_CreateSurface(ctx->decoder_service, FFALIGN(s->coded_width, surface_alignment), FFALIGN(s->coded_height, surface_alignment), ctx->num_surfaces - 1, target_format, D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget, ctx->surfaces, NULL); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to create %d video surfaces\n", ctx->num_surfaces); goto fail; } hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->decoder_service, &device_guid, &desc, &config, ctx->surfaces, ctx->num_surfaces, &ctx->decoder); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to create DXVA2 video decoder\n"); goto fail; } ctx->decoder_guid = device_guid; ctx->decoder_config = config; dxva_ctx->cfg = &ctx->decoder_config; dxva_ctx->decoder = ctx->decoder; dxva_ctx->surface = ctx->surfaces; dxva_ctx->surface_count = ctx->num_surfaces; if (IsEqualGUID(&ctx->decoder_guid, &DXVADDI_Intel_ModeH264_E)) dxva_ctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO; return 0; fail: dxva2_destroy_decoder(s); return AVERROR(EINVAL); }
static int dxva2_create_decoder(struct lavc_ctx *s, int w, int h, enum AVCodecID codec_id, int profile) { DXVA2Context *ctx = s->hwdec_priv; struct dxva_context *dxva_ctx = s->avctx->hwaccel_context; GUID *guid_list = NULL; unsigned guid_count = 0, i, j; GUID device_guid = GUID_NULL; D3DFORMAT target_format = 0; DXVA2_VideoDesc desc = { 0 }; DXVA2_ConfigPictureDecode config; HRESULT hr; int surface_alignment; int ret; hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->decoder_service, &guid_count, &guid_list); if (FAILED(hr)) { MP_ERR(ctx, "Failed to retrieve decoder device GUIDs\n"); goto fail; } // dump all decoder info MP_VERBOSE(ctx, "%d decoder devices:\n", (int)guid_count); for (j = 0; j < guid_count; j++) { GUID *guid = &guid_list[j]; const char *name = "<unknown>"; for (i = 0; dxva2_modes[i].guid; i++) { if (IsEqualGUID(dxva2_modes[i].guid, guid)) name = dxva2_modes[i].name; } D3DFORMAT *target_list = NULL; unsigned target_count = 0; hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->decoder_service, guid, &target_count, &target_list); if (FAILED(hr)) continue; char fmts[256] = {0}; for (i = 0; i < target_count; i++) mp_snprintf_cat(fmts, sizeof(fmts), " %s", mp_tag_str(target_list[i])); CoTaskMemFree(target_list); MP_VERBOSE(ctx, "%s %s %s\n", mp_GUID_to_str(guid), name, fmts); } // find a suitable decoder for (i = 0; dxva2_modes[i].guid; i++) { D3DFORMAT *target_list = NULL; unsigned target_count = 0; const dxva2_mode *mode = &dxva2_modes[i]; if (mode->codec != codec_id) continue; for (j = 0; j < guid_count; j++) { if (IsEqualGUID(mode->guid, &guid_list[j])) break; } if (j == guid_count) continue; hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->decoder_service, mode->guid, &target_count, &target_list); if (FAILED(hr)) { continue; } for (j = 0; j < target_count; j++) { const D3DFORMAT format = target_list[j]; if (format == MKTAG('N','V','1','2')) { target_format = format; break; } } CoTaskMemFree(target_list); if (target_format) { device_guid = *mode->guid; break; } } CoTaskMemFree(guid_list); if (IsEqualGUID(&device_guid, &GUID_NULL)) { MP_ERR(ctx, "No decoder device for codec found\n"); goto fail; } desc.SampleWidth = w; desc.SampleHeight = h; desc.Format = target_format; ret = dxva2_get_decoder_configuration(s, codec_id, &device_guid, &desc, &config); if (ret < 0) { goto fail; } /* decoding MPEG-2 requires additional alignment on some Intel GPUs, but it causes issues for H.264 on certain AMD GPUs..... */ if (codec_id == AV_CODEC_ID_MPEG2VIDEO) surface_alignment = 32; /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure all coding features have enough room to work with */ else if (codec_id == AV_CODEC_ID_HEVC) surface_alignment = 128; else surface_alignment = 16; /* 4 base work surfaces */ ctx->num_surfaces = 4 + ADDTIONAL_SURFACES; /* add surfaces based on number of possible refs */ if (codec_id == AV_CODEC_ID_H264 || codec_id == AV_CODEC_ID_HEVC) ctx->num_surfaces += 16; else ctx->num_surfaces += 2; ctx->surfaces = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surfaces)); ctx->surface_infos = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surface_infos)); if (!ctx->surfaces || !ctx->surface_infos) { MP_ERR(ctx, "Unable to allocate surface arrays\n"); goto fail; } hr = IDirectXVideoDecoderService_CreateSurface(ctx->decoder_service, FFALIGN(w, surface_alignment), FFALIGN(h, surface_alignment), ctx->num_surfaces - 1, target_format, D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget, ctx->surfaces, NULL); if (FAILED(hr)) { MP_ERR(ctx, "Failed to create %d video surfaces\n", ctx->num_surfaces); goto fail; } hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->decoder_service, &device_guid, &desc, &config, ctx->surfaces, ctx->num_surfaces, &ctx->decoder); if (FAILED(hr)) { MP_ERR(ctx, "Failed to create DXVA2 video decoder\n"); goto fail; } ctx->decoder_guid = device_guid; ctx->decoder_config = config; dxva_ctx->cfg = &ctx->decoder_config; dxva_ctx->decoder = ctx->decoder; dxva_ctx->surface = ctx->surfaces; dxva_ctx->surface_count = ctx->num_surfaces; if (IsEqualGUID(&ctx->decoder_guid, &DXVADDI_Intel_ModeH264_E)) dxva_ctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO; return 0; fail: dxva2_destroy_decoder(s); return -1; }
/** * Find the best suited decoder mode GUID and render format. */ static int hb_dx_find_video_service_conversion( hb_va_dxva2_t *dxva2, GUID *input, D3DFORMAT *output ) { unsigned int input_count = 0; GUID *input_list = NULL; if( FAILED( IDirectXVideoDecoderService_GetDecoderDeviceGuids( dxva2->vs, &input_count, &input_list ))) { hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderDeviceGuids failed" ); return HB_WORK_ERROR; } unsigned i, j; for( i = 0; i < input_count; i++ ) { const GUID *g = &input_list[i]; const hb_dx_mode_t *mode = hb_dx_find_mode( g ); } for( i = 0; dxva2_modes[i].name; i++ ) { const hb_dx_mode_t *mode = &dxva2_modes[i]; if( !mode->codec || mode->codec != dxva2->codec_id ) continue; int is_suported = 0; const GUID *g; for( g = &input_list[0]; !is_suported && g < &input_list[input_count]; g++ ) { is_suported = IsEqualGUID( mode->guid, g ); } if( !is_suported ) continue; unsigned int output_count = 0; D3DFORMAT *output_list = NULL; if( FAILED( IDirectXVideoDecoderService_GetDecoderRenderTargets( dxva2->vs, mode->guid, &output_count, &output_list ))) { hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderRenderTargets failed" ); continue; } for( j = 0; j < output_count; j++ ) { const D3DFORMAT f = output_list[j]; const hb_d3d_format_t *format = hb_d3d_find_format( f ); if( format ) { //hb_log( "dxva2:%s is supported for output", format->name ); } else { hb_log( "dxvar2:%d is supported for output (%4.4s)", f, (const char*)&f ); } } for( j = 0; d3d_formats[j].name; j++ ) { const hb_d3d_format_t *format = &d3d_formats[j]; int is_suported = 0; unsigned k; for( k = 0; !is_suported && k < output_count; k++ ) { is_suported = format->format == output_list[k]; } if( !is_suported ) continue; *input = *mode->guid; *output = format->format; return HB_WORK_OK; } } return HB_WORK_ERROR; }
static int dxva2_create_decoder(AVCodecContext *s) { InputStream *ist = s->opaque; int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR; DXVA2Context *ctx = ist->hwaccel_ctx; struct dxva_context *dxva_ctx = s->hwaccel_context; GUID *guid_list = NULL; unsigned guid_count = 0, i, j; GUID device_guid = GUID_NULL; const D3DFORMAT surface_format = s->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? MKTAG('P', '0', '1', '0') : MKTAG('N', 'V', '1', '2'); D3DFORMAT target_format = 0; DXVA2_VideoDesc desc = { 0 }; DXVA2_ConfigPictureDecode config; HRESULT hr; int surface_alignment, num_surfaces; int ret; AVDXVA2FramesContext *frames_hwctx; AVHWFramesContext *frames_ctx; hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->decoder_service, &guid_count, &guid_list); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to retrieve decoder device GUIDs\n"); goto fail; } for (i = 0; dxva2_modes[i].guid; i++) { D3DFORMAT *target_list = NULL; unsigned target_count = 0; const dxva2_mode *mode = &dxva2_modes[i]; if (mode->codec != s->codec_id) continue; for (j = 0; j < guid_count; j++) { if (IsEqualGUID(mode->guid, &guid_list[j])) break; } if (j == guid_count) continue; hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->decoder_service, mode->guid, &target_count, &target_list); if (FAILED(hr)) { continue; } for (j = 0; j < target_count; j++) { const D3DFORMAT format = target_list[j]; if (format == surface_format) { target_format = format; break; } } CoTaskMemFree(target_list); if (target_format) { device_guid = *mode->guid; break; } } CoTaskMemFree(guid_list); if (IsEqualGUID(&device_guid, &GUID_NULL)) { av_log(NULL, loglevel, "No decoder device for codec found\n"); goto fail; } desc.SampleWidth = s->coded_width; desc.SampleHeight = s->coded_height; desc.Format = target_format; ret = dxva2_get_decoder_configuration(s, &device_guid, &desc, &config); if (ret < 0) { goto fail; } /* decoding MPEG-2 requires additional alignment on some Intel GPUs, but it causes issues for H.264 on certain AMD GPUs..... */ if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) surface_alignment = 32; /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure all coding features have enough room to work with */ else if (s->codec_id == AV_CODEC_ID_HEVC) surface_alignment = 128; else surface_alignment = 16; /* 4 base work surfaces */ num_surfaces = 4; /* add surfaces based on number of possible refs */ if (s->codec_id == AV_CODEC_ID_H264 || s->codec_id == AV_CODEC_ID_HEVC) num_surfaces += 16; else num_surfaces += 2; /* add extra surfaces for frame threading */ if (s->active_thread_type & FF_THREAD_FRAME) num_surfaces += s->thread_count; ctx->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->hw_device_ctx); if (!ctx->hw_frames_ctx) goto fail; frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; frames_hwctx = frames_ctx->hwctx; frames_ctx->format = AV_PIX_FMT_DXVA2_VLD; frames_ctx->sw_format = s->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? AV_PIX_FMT_P010 : AV_PIX_FMT_NV12; frames_ctx->width = FFALIGN(s->coded_width, surface_alignment); frames_ctx->height = FFALIGN(s->coded_height, surface_alignment); frames_ctx->initial_pool_size = num_surfaces; frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; ret = av_hwframe_ctx_init(ctx->hw_frames_ctx); if (ret < 0) { av_log(NULL, loglevel, "Failed to initialize the HW frames context\n"); goto fail; } hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->decoder_service, &device_guid, &desc, &config, frames_hwctx->surfaces, frames_hwctx->nb_surfaces, &frames_hwctx->decoder_to_release); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to create DXVA2 video decoder\n"); goto fail; } ctx->decoder_guid = device_guid; ctx->decoder_config = config; dxva_ctx->cfg = &ctx->decoder_config; dxva_ctx->decoder = frames_hwctx->decoder_to_release; dxva_ctx->surface = frames_hwctx->surfaces; dxva_ctx->surface_count = frames_hwctx->nb_surfaces; if (IsEqualGUID(&ctx->decoder_guid, &DXVADDI_Intel_ModeH264_E)) dxva_ctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO; return 0; fail: av_buffer_unref(&ctx->hw_frames_ctx); return AVERROR(EINVAL); }