This fixes d3d11 frame download further in filtering chain.
Unified · Split
| @@ -101,51 +101,12 @@ struct priv { · 100 unmodified lines | ||
| 101 | 101 | struct mp_image_params params, out_params; |
| 102 | 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 | 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 | 111 | static void flush_frames(struct mp_filter *vf) |
| 151 | 112 | { |
| @@ -336,6 +297,40 @@ fail: · 184 unmodified lines | ||
| 336 | 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 | 334 | static struct mp_image *render(struct mp_filter *vf) |
| 340 | 335 | { |
| 341 | 336 | struct priv *p = vf->priv; |
| @@ -344,7 +339,7 @@ static struct mp_image *render(struct mp_filter *vf) · 2 unmodified lines | ||
| 344 | 339 | ID3D11VideoProcessorInputView *in_view = NULL; |
| 345 | 340 | ID3D11VideoProcessorOutputView *out_view = NULL; |
| 346 | 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 | 343 | if (!out) { |
| 349 | 344 | MP_WARN(vf, "failed to allocate frame\n"); |
| 350 | 345 | goto cleanup; |
| @@ -455,7 +450,7 @@ static void vf_d3d11vpp_process(struct mp_filter *vf) · 104 unmodified lines | ||
| 455 | 450 | |
| 456 | 451 | struct mp_image *in_fmt = mp_refqueue_execute_reinit(p->queue); |
| 457 | 452 | if (in_fmt) { |
| 458 | − mp_image_pool_clear(p->pool); | |
| 453 | + av_buffer_unref(&p->hw_pool); | |
| 459 | 454 | |
| 460 | 455 | destroy_video_proc(vf); |
| 461 | 456 | |
| @@ -502,7 +497,8 @@ static void uninit(struct mp_filter *vf) · 40 unmodified lines | ||
| 502 | 497 | |
| 503 | 498 | flush_frames(vf); |
| 504 | 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 | 503 | if (p->video_ctx) |
| 508 | 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 | 560 | AV_HWDEVICE_TYPE_D3D11VA); |
| 565 | 561 | if (!hwctx || !hwctx->av_device_ref) |
| 566 | 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 | 565 | AVD3D11VADeviceContext *d3dctx = avhwctx->hwctx; |
| 569 | 566 | |
| 570 | 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 | 582 | if (FAILED(hr)) |
| 586 | 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 | 585 | mp_refqueue_add_in_format(p->queue, IMGFMT_D3D11, 0); |
| 593 | 586 | |
| 594 | 587 | mp_refqueue_set_refs(p->queue, 0, 0); |