@@ -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-
128128static 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 ;
628624cleanup :
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