This fixes d3d11 frame download further in filtering chain.
Unified · Split
| @@ -101,51 +101,12 @@ struct priv { · 100 unmodified lines | |||
| 101 | struct mp_image_params params, out_params; | 101 | struct mp_image_params params, out_params; |
| 102 | int c_w, c_h; | 102 | int c_w, c_h; |
| 103 | 103 | ||
| 104 | struct mp_image_pool *pool; | 104 | AVBufferRef *av_device_ref; |
| 105 | AVBufferRef *hw_pool; | ||
| 105 | 106 | ||
| 106 | struct mp_refqueue *queue; | 107 | struct mp_refqueue *queue; |
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | static void release_tex(void *arg) | ||
| 110 | { | ||
| 111 | ID3D11Texture2D *texture = arg; | ||
| 112 | |||
| 113 | ID3D11Texture2D_Release(texture); | ||
| 114 | } | ||
| 115 | |||
| 116 | static struct mp_image *alloc_pool(void *pctx, int fmt, int w, int h) | ||
| 117 | { | ||
| 118 | struct mp_filter *vf = pctx; | ||
| 119 | struct priv *p = vf->priv; | ||
| 120 | HRESULT hr; | ||
| 121 | |||
| 122 | ID3D11Texture2D *texture = NULL; | ||
| 123 | D3D11_TEXTURE2D_DESC texdesc = { | ||
| 124 | .Width = w, | ||
| 125 | .Height = h, | ||
| 126 | .Format = p->out_format, | ||
| 127 | .MipLevels = 1, | ||
| 128 | .ArraySize = 1, | ||
| 129 | .SampleDesc = { .Count = 1 }, | ||
| 130 | .Usage = D3D11_USAGE_DEFAULT, | ||
| 131 | .BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, | ||
| 132 | }; | ||
| 133 | hr = ID3D11Device_CreateTexture2D(p->vo_dev, &texdesc, NULL, &texture); | ||
| 134 | if (FAILED(hr)) | ||
| 135 | return NULL; | ||
| 136 | |||
| 137 | struct mp_image *mpi = mp_image_new_custom_ref(NULL, texture, release_tex); | ||
| 138 | MP_HANDLE_OOM(mpi); | ||
| 139 | |||
| 140 | mp_image_setfmt(mpi, IMGFMT_D3D11); | ||
| 141 | mp_image_set_size(mpi, w, h); | ||
| 142 | mpi->params.hw_subfmt = p->out_params.hw_subfmt; | ||
| 143 | |||
| 144 | mpi->planes[0] = (void *)texture; | ||
| 145 | mpi->planes[1] = (void *)(intptr_t)0; | ||
| 146 | |||
| 147 | return mpi; | ||
| 148 | } | ||
| 149 | 110 | ||
| 150 | static void flush_frames(struct mp_filter *vf) | 111 | static void flush_frames(struct mp_filter *vf) |
| 151 | { | 112 | { |
| @@ -336,6 +297,40 @@ fail: · 184 unmodified lines | |||
| 336 | return -1; | 297 | return -1; |
| 337 | } | 298 | } |
| 338 | 299 | ||
| 300 | static struct mp_image *alloc_out(struct mp_filter *vf) | ||
| 301 | { | ||
| 302 | struct priv *p = vf->priv; | ||
| 303 | |||
| 304 | if (!mp_update_av_hw_frames_pool(&p->hw_pool, p->av_device_ref, | ||
| 305 | IMGFMT_D3D11, p->out_params.hw_subfmt, | ||
| 306 | p->out_params.w, p->out_params.h, false)) | ||
| 307 | { | ||
| 308 | MP_ERR(vf, "Failed to create hw pool\n"); | ||
| 309 | return NULL; | ||
| 310 | } | ||
| 311 | |||
| 312 | AVHWFramesContext *hw_frame_ctx = (void *)p->hw_pool->data; | ||
| 313 | AVD3D11VAFramesContext *d3d11va_frames_ctx = hw_frame_ctx->hwctx; | ||
| 314 | d3d11va_frames_ctx->BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; | ||
| 315 | |||
| 316 | AVFrame *av_frame = av_frame_alloc(); | ||
| 317 | MP_HANDLE_OOM(av_frame); | ||
| 318 | if (av_hwframe_get_buffer(p->hw_pool, av_frame, 0) < 0) { | ||
| 319 | MP_ERR(vf, "Failed to allocate frame from hw pool\n"); | ||
| 320 | av_frame_free(&av_frame); | ||
| 321 | return NULL; | ||
| 322 | } | ||
| 323 | |||
| 324 | struct mp_image *img = mp_image_from_av_frame(av_frame); | ||
| 325 | av_frame_free(&av_frame); | ||
| 326 | if (!img) { | ||
| 327 | MP_ERR(vf, "Internal error when converting AVFrame\n"); | ||
| 328 | return NULL; | ||
| 329 | } | ||
| 330 | |||
| 331 | return img; | ||
| 332 | } | ||
| 333 | |||
| 339 | static struct mp_image *render(struct mp_filter *vf) | 334 | static struct mp_image *render(struct mp_filter *vf) |
| 340 | { | 335 | { |
| 341 | struct priv *p = vf->priv; | 336 | struct priv *p = vf->priv; |
| @@ -344,7 +339,7 @@ static struct mp_image *render(struct mp_filter *vf) · 2 unmodified lines | |||
| 344 | ID3D11VideoProcessorInputView *in_view = NULL; | 339 | ID3D11VideoProcessorInputView *in_view = NULL; |
| 345 | ID3D11VideoProcessorOutputView *out_view = NULL; | 340 | ID3D11VideoProcessorOutputView *out_view = NULL; |
| 346 | struct mp_image *in = NULL, *out = NULL; | 341 | struct mp_image *in = NULL, *out = NULL; |
| 347 | out = mp_image_pool_get(p->pool, IMGFMT_D3D11, p->out_params.w, p->out_params.h); | 342 | out = alloc_out(vf); |
| 348 | if (!out) { | 343 | if (!out) { |
| 349 | MP_WARN(vf, "failed to allocate frame\n"); | 344 | MP_WARN(vf, "failed to allocate frame\n"); |
| 350 | goto cleanup; | 345 | goto cleanup; |
| @@ -455,7 +450,7 @@ static void vf_d3d11vpp_process(struct mp_filter *vf) · 104 unmodified lines | |||
| 455 | 450 | ||
| 456 | struct mp_image *in_fmt = mp_refqueue_execute_reinit(p->queue); | 451 | struct mp_image *in_fmt = mp_refqueue_execute_reinit(p->queue); |
| 457 | if (in_fmt) { | 452 | if (in_fmt) { |
| 458 | mp_image_pool_clear(p->pool); | 453 | av_buffer_unref(&p->hw_pool); |
| 459 | 454 | ||
| 460 | destroy_video_proc(vf); | 455 | destroy_video_proc(vf); |
| 461 | 456 | ||
| @@ -502,7 +497,8 @@ static void uninit(struct mp_filter *vf) · 40 unmodified lines | |||
| 502 | 497 | ||
| 503 | flush_frames(vf); | 498 | flush_frames(vf); |
| 504 | talloc_free(p->queue); | 499 | talloc_free(p->queue); |
| 505 | talloc_free(p->pool); | 500 | av_buffer_unref(&p->hw_pool); |
| 501 | av_buffer_unref(&p->av_device_ref); | ||
| 506 | 502 | ||
| 507 | if (p->video_ctx) | 503 | if (p->video_ctx) |
| 508 | ID3D11VideoContext_Release(p->video_ctx); | 504 | ID3D11VideoContext_Release(p->video_ctx); |
| @@ -564,7 +560,8 @@ static struct mp_filter *vf_d3d11vpp_create(struct mp_filter *parent, · 55 unmodified lines | |||
| 564 | AV_HWDEVICE_TYPE_D3D11VA); | 560 | AV_HWDEVICE_TYPE_D3D11VA); |
| 565 | if (!hwctx || !hwctx->av_device_ref) | 561 | if (!hwctx || !hwctx->av_device_ref) |
| 566 | goto fail; | 562 | goto fail; |
| 567 | AVHWDeviceContext *avhwctx = (void *)hwctx->av_device_ref->data; | 563 | p->av_device_ref = av_buffer_ref(hwctx->av_device_ref); |
| 564 | AVHWDeviceContext *avhwctx = (void *)p->av_device_ref->data; | ||
| 568 | AVD3D11VADeviceContext *d3dctx = avhwctx->hwctx; | 565 | AVD3D11VADeviceContext *d3dctx = avhwctx->hwctx; |
| 569 | 566 | ||
| 570 | p->vo_dev = d3dctx->device; | 567 | p->vo_dev = d3dctx->device; |
| @@ -585,10 +582,6 @@ static struct mp_filter *vf_d3d11vpp_create(struct mp_filter *parent, · 14 unmodified lines | |||
| 585 | if (FAILED(hr)) | 582 | if (FAILED(hr)) |
| 586 | goto fail; | 583 | goto fail; |
| 587 | 584 | ||
| 588 | p->pool = mp_image_pool_new(f); | ||
| 589 | mp_image_pool_set_allocator(p->pool, alloc_pool, f); | ||
| 590 | mp_image_pool_set_lru(p->pool); | ||
| 591 | |||
| 592 | mp_refqueue_add_in_format(p->queue, IMGFMT_D3D11, 0); | 585 | mp_refqueue_add_in_format(p->queue, IMGFMT_D3D11, 0); |
| 593 | 586 | ||
| 594 | mp_refqueue_set_refs(p->queue, 0, 0); | 587 | mp_refqueue_set_refs(p->queue, 0, 0); |