[vlc-devel] [PATCH] Fixed incorrect backward/forward reference ordering in vaapi deinterlacing
Oliver Collyer
ovcollyer at mac.com
Tue Jun 27 14:58:48 CEST 2017
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://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_deinterlace_vaapi.c <https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_deinterlace_vaapi.c>
See function deint_vaapi_filter_frame.
---
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)
--
2.11.0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170627/ae125f9e/attachment.html>
More information about the vlc-devel
mailing list