History

vf_d3d11vpp: alloc output frames through AVHWFramesContext

This fixes d3d11 frame download further in filtering chain.

Kacper Michajłow committed 2 years ago

Commit a341b121 parent 421df751 file · +42 −49Browse files

Unified · Split

video/filter/vf_d3d11vpp.c+42−49
@@ -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
109static void release_tex(void *arg)
110{
111 ID3D11Texture2D *texture = arg;
112
113 ID3D11Texture2D_Release(texture);
114}
115
116static 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
150static void flush_frames(struct mp_filter *vf)111static 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
300static 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
339static struct mp_image *render(struct mp_filter *vf)334static 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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t