[vlc-commits] hw: vaapi-deint: fix incorrect backward/forward reference ordering

Oliver Collyer git at videolan.org
Tue Jun 27 16:21:55 CEST 2017


vlc | branch: master | Oliver Collyer <ovcollyer at mac.com> | Tue Jun 27 15:58:48 2017 +0300| [b2f8170a64adc83213c02804ba292544b3617fea] | committer: Thomas Guillem

hw: vaapi-deint: fix incorrect backward/forward reference ordering

After testing the Motion Adaptive deinterlacing mode and finding it produced
lots of flicker/judder and not much deinterlacing I traced the error back to
the below.

Although it seems a little counter-intuitive, the "forward_refs" are actually
the frames older than the current one, and the "backward_refs" are those later.

In addition, the forward_refs (previously the backward_refs) have to be ordered
such that [0] is most recent, [1] older, etc; before this patch it was the
opposite.

Just to be 100% sure, I have also cross-referenced this approach with how
FFmpeg does it:

https://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavfilter/vf_deinterlace_vaapi.c;hb=HEAD

See function deint_vaapi_filter_frame.

Signed-off-by: Thomas Guillem <thomas at gllm.fr>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b2f8170a64adc83213c02804ba292544b3617fea
---

 modules/hw/vaapi/filters.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/modules/hw/vaapi/filters.c b/modules/hw/vaapi/filters.c
index b63b7ae312..efb1583f1b 100644
--- a/modules/hw/vaapi/filters.c
+++ b/modules/hw/vaapi/filters.c
@@ -752,13 +752,17 @@ Deinterlace_UpdateReferenceFrames(void * p_data)
 
     if (p_deint_data->backward_refs.sz)
         for (unsigned int i = 0; i < p_deint_data->backward_refs.sz; ++i)
+        {
+            unsigned int const  idx = p_deint_data->forward_refs.sz + 1 + i;
+
             p_deint_data->backward_refs.surfaces[i] =
-                vlc_vaapi_PicGetSurface(p_deint_data->history.pp_pics[i]);
+                vlc_vaapi_PicGetSurface(p_deint_data->history.pp_pics[idx]);
+        }
 
     if (p_deint_data->forward_refs.sz)
         for (unsigned int i = 0; i < p_deint_data->forward_refs.sz; ++i)
         {
-            unsigned int const  idx = p_deint_data->backward_refs.sz + 1 + i;
+            unsigned int const  idx = p_deint_data->forward_refs.sz - 1 - i;
 
             p_deint_data->forward_refs.surfaces[i] =
                 vlc_vaapi_PicGetSurface(p_deint_data->history.pp_pics[idx]);
@@ -923,20 +927,20 @@ OpenDeinterlace_InitHistory(void * p_data, VAProcPipelineCaps const * pipeline_c
         return VLC_ENOMEM;
 
     p_deint_data->history.pp_cur_pic =
-        p_deint_data->history.pp_pics + sz_backward_refs;
+        p_deint_data->history.pp_pics + sz_forward_refs;
     p_deint_data->history.num_pics = 0;
     p_deint_data->history.sz = history_sz;
 
     if (history_sz - 1)
     {
-        p_deint_data->backward_refs.surfaces =
+        p_deint_data->forward_refs.surfaces =
             malloc((history_sz - 1) * sizeof(VASurfaceID));
-        if (!p_deint_data->backward_refs.surfaces)
+        if (!p_deint_data->forward_refs.surfaces)
             return VLC_ENOMEM;
     }
 
-    p_deint_data->forward_refs.surfaces =
-        p_deint_data->backward_refs.surfaces + sz_backward_refs;
+    p_deint_data->backward_refs.surfaces =
+        p_deint_data->forward_refs.surfaces + sz_forward_refs;
 
     p_deint_data->backward_refs.sz = sz_backward_refs;
     p_deint_data->forward_refs.sz = sz_forward_refs;
@@ -962,8 +966,8 @@ OpenDeinterlace(vlc_object_t * obj)
     return VLC_SUCCESS;
 
 error:
-    if (p_data->backward_refs.surfaces)
-        free(p_data->backward_refs.surfaces);
+    if (p_data->forward_refs.surfaces)
+        free(p_data->forward_refs.surfaces);
     if (p_data->history.pp_pics)
         free(p_data->history.pp_pics);
     free(p_data);
@@ -977,8 +981,8 @@ CloseDeinterlace(vlc_object_t * obj)
     filter_sys_t *const         filter_sys = filter->p_sys;
     struct deint_data *const    p_data = filter_sys->p_data;
 
-    if (p_data->backward_refs.surfaces)
-        free(p_data->backward_refs.surfaces);
+    if (p_data->forward_refs.surfaces)
+        free(p_data->forward_refs.surfaces);
     if (p_data->history.pp_pics)
     {
         while (p_data->history.num_pics)



More information about the vlc-commits mailing list