Skip to content

Commit 85f9e6f

Browse files
committed
vf_d3d11vpp: allow more future/past frames
Apparently some video processors request 15-20 future frames. Fixes: #17413 (comment)
1 parent 88ac54b commit 85f9e6f

File tree

1 file changed

+24
-30
lines changed

1 file changed

+24
-30
lines changed

video/filter/vf_d3d11vpp.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ struct priv {
117117

118118
struct mp_refqueue *queue;
119119

120-
UINT past_frames;
121-
UINT future_frames;
120+
UINT num_past_views;
121+
ID3D11VideoProcessorInputView **past_views;
122+
UINT num_future_views;
123+
ID3D11VideoProcessorInputView **future_views;
122124

123125
UINT output_seq;
124126
};
125127

126-
#define D3D11VPP_MAX_FRAMES 4
127-
128128
static void flush_frames(struct mp_filter *vf)
129129
{
130130
struct priv *p = vf->priv;
@@ -347,22 +347,20 @@ static int recreate_video_proc(struct mp_filter *vf)
347347
goto fail;
348348
}
349349

350-
p->past_frames = MPMIN(rc_caps.PastFrames, D3D11VPP_MAX_FRAMES);
351-
p->future_frames = MPMIN(rc_caps.FutureFrames, D3D11VPP_MAX_FRAMES);
350+
p->num_past_views = rc_caps.PastFrames;
351+
if (p->num_past_views)
352+
MP_TARRAY_GROW(p, p->past_views, p->num_past_views - 1);
352353

353-
if (p->past_frames < rc_caps.PastFrames || p->future_frames < rc_caps.FutureFrames) {
354-
// No implementation should need more than D3D11VPP_MAX_FRAMES in practice.
355-
MP_ERR(vf, "Processor requested %u past frames and %u future frames, "
356-
"but only %u/%u are supported. Please report an issue.\n",
357-
rc_caps.PastFrames, rc_caps.FutureFrames, p->past_frames, p->future_frames);
358-
}
354+
p->num_future_views = rc_caps.FutureFrames;
355+
if (p->num_future_views)
356+
MP_TARRAY_GROW(p, p->future_views, p->num_future_views - 1);
359357

360358
// Force BOB if requested by user, this doesn't really make much sense, but
361359
// since we have an option, just allow to not use any ref frames.
362360
if (mode == D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB ||
363361
mode == D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND) {
364-
p->past_frames = 0;
365-
p->future_frames = 0;
362+
p->num_past_views = 0;
363+
p->num_future_views = 0;
366364
// Warn explicitly here, because forcing unsupported mode will cause
367365
// obviously wrong result.
368366
if ((rc_caps.ProcessorCaps & mode) != mode) {
@@ -372,7 +370,7 @@ static int recreate_video_proc(struct mp_filter *vf)
372370
}
373371
}
374372

375-
mp_refqueue_set_refs(p->queue, p->past_frames, p->future_frames);
373+
mp_refqueue_set_refs(p->queue, p->num_past_views, p->num_future_views);
376374

377375
// Note: libavcodec does not support cropping left/top with hwaccel.
378376
RECT src_rc = {
@@ -390,7 +388,7 @@ static int recreate_video_proc(struct mp_filter *vf)
390388

391389
bool half_rate = !mp_refqueue_output_fields(p->queue) && mp_refqueue_should_deint(p->queue);
392390
MP_DBG(vf, "Using %u past and %u future frames for processing at %s rate.\n",
393-
p->past_frames, p->future_frames, half_rate ? "half" : "normal");
391+
p->num_past_views, p->num_future_views, half_rate ? "half" : "normal");
394392
// None of the major GPU vendors seem to support custom rates for proper
395393
// IVTC frame dropping. Only frame reconstruction is supported.
396394
ID3D11VideoContext_VideoProcessorSetStreamOutputRate(p->video_ctx,
@@ -528,9 +526,7 @@ static struct mp_image *render(struct mp_filter *vf)
528526
struct mp_image *in = NULL, *out = NULL;
529527

530528
UINT num_past = 0;
531-
ID3D11VideoProcessorInputView *past_views[D3D11VPP_MAX_FRAMES] = {0};
532529
UINT num_future = 0;
533-
ID3D11VideoProcessorInputView *future_views[D3D11VPP_MAX_FRAMES] = {0};
534530

535531
out = alloc_out(vf);
536532
if (!out) {
@@ -579,18 +575,18 @@ static struct mp_image *render(struct mp_filter *vf)
579575
if (!in_view)
580576
goto cleanup;
581577

582-
for (int i = p->past_frames; i > 0; i--) {
578+
for (int i = p->num_past_views; i > 0; i--) {
583579
ID3D11VideoProcessorInputView *v =
584580
create_input_view(vf, mp_refqueue_get(p->queue, -i));
585581
if (v)
586-
past_views[num_past++] = v;
582+
p->past_views[num_past++] = v;
587583
}
588584

589-
for (int i = 1; i <= p->future_frames; i++) {
585+
for (int i = 1; i <= p->num_future_views; i++) {
590586
ID3D11VideoProcessorInputView *v =
591587
create_input_view(vf, mp_refqueue_get(p->queue, i));
592588
if (v)
593-
future_views[num_future++] = v;
589+
p->future_views[num_future++] = v;
594590
}
595591

596592
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outdesc = {
@@ -613,8 +609,8 @@ static struct mp_image *render(struct mp_filter *vf)
613609
.InputFrameOrField = p->output_seq * (half_rate ? 2 : 1),
614610
.PastFrames = num_past,
615611
.FutureFrames = num_future,
616-
.ppPastSurfaces = num_past ? past_views : NULL,
617-
.ppFutureSurfaces = num_future ? future_views : NULL,
612+
.ppPastSurfaces = num_past ? p->past_views : NULL,
613+
.ppFutureSurfaces = num_future ? p->future_views : NULL,
618614
};
619615
hr = ID3D11VideoContext_VideoProcessorBlt(p->video_ctx, p->video_proc,
620616
out_view, p->output_seq, 1, &stream);
@@ -626,14 +622,12 @@ static struct mp_image *render(struct mp_filter *vf)
626622
p->output_seq++;
627623
res = 0;
628624
cleanup:
629-
if (in_view)
630-
ID3D11VideoProcessorInputView_Release(in_view);
631-
if (out_view)
632-
ID3D11VideoProcessorOutputView_Release(out_view);
625+
SAFE_RELEASE(in_view);
626+
SAFE_RELEASE(out_view);
633627
for (int i = 0; i < num_past; i++)
634-
ID3D11VideoProcessorInputView_Release(past_views[i]);
628+
SAFE_RELEASE(p->past_views[i]);
635629
for (int i = 0; i < num_future; i++)
636-
ID3D11VideoProcessorInputView_Release(future_views[i]);
630+
SAFE_RELEASE(p->future_views[i]);
637631
if (res < 0)
638632
TA_FREEP(&out);
639633
return out;

0 commit comments

Comments
 (0)