d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
- hr = IDirect3D9_CreateDevice(ctx->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(),
- hr = IDirect3D9_CreateDevice(device_priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(),
++ hr = IDirect3D9_CreateDevice(device_priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
- &d3dpp, &ctx->d3d9device);
+ &d3dpp, &device_priv->d3d9device);
if (FAILED(hr)) {
av_log(NULL, loglevel, "Failed to create Direct3D device\n");
goto fail;
/* 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;
+ num_surfaces += 16;
+ else if (s->codec_id == AV_CODEC_ID_VP9)
- ctx->num_surfaces += 8;
++ num_surfaces += 8;
else
- ctx->num_surfaces += 2;
+ 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));
- ctx->surface_format = target_format;
+ num_surfaces += s->thread_count;
- if (!ctx->surfaces || !ctx->surface_infos) {
- av_log(NULL, loglevel, "Unable to allocate surface arrays\n");
+ 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;
- 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);
+ frames_ctx->format = AV_PIX_FMT_DXVA2_VLD;
- frames_ctx->sw_format = AV_PIX_FMT_NV12;
++ frames_ctx->sw_format = (target_format == MKTAG('P','0','1','0') ? 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;
}
return AVERROR(EINVAL);
}
- if (ctx->decoder)
- dxva2_destroy_decoder(s);
+ if (s->codec_id == AV_CODEC_ID_HEVC &&
+ s->profile != FF_PROFILE_HEVC_MAIN && s->profile != FF_PROFILE_HEVC_MAIN_10) {
+ av_log(NULL, loglevel, "Unsupported HEVC profile for DXVA2 HWAccel: %d\n", s->profile);
+ return AVERROR(EINVAL);
+ }
+
+ av_buffer_unref(&ctx->hw_frames_ctx);
ret = dxva2_create_decoder(s);
if (ret < 0) {