[vlc-devel] [vlc-commits] hw: vaapi: double framerate for Bob and X deint modes

Steve Lhomme robux4 at gmail.com
Mon Jul 10 09:02:57 CEST 2017


A little late...

On Fri, Jul 7, 2017 at 9:09 AM, Oliver Collyer <git at videolan.org> wrote:
> vlc | branch: master | Oliver Collyer <ovcollyer at mac.com> | Thu Jul  6 20:43:38 2017 +0300| [c932d06d31de5cd6161345db4ab4a284589be1a4] | committer: Thomas Guillem
>
> hw: vaapi: double framerate for Bob and X deint modes
>
> Signed-off-by: Victorien Le Couviour--Tuffet <victorien.lecouviour.tuffet at gmail.com>
> Signed-off-by: Thomas Guillem <thomas at gllm.fr>
>
>> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c932d06d31de5cd6161345db4ab4a284589be1a4
> ---
>
>  modules/hw/vaapi/filters.c | 142 +++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 124 insertions(+), 18 deletions(-)
>
> diff --git a/modules/hw/vaapi/filters.c b/modules/hw/vaapi/filters.c
> old mode 100644
> new mode 100755
> index 6d124b5ab9..091a949f24
> --- a/modules/hw/vaapi/filters.c
> +++ b/modules/hw/vaapi/filters.c
> @@ -222,16 +222,19 @@ struct  deint_mode
>  {
>      char const                  name[5];
>      VAProcDeinterlacingType     type;
> +    bool                        b_double_rate;
>  };
>
>  static struct deint_mode const  deint_modes[] =
>  {
> -    { "x",     VAProcDeinterlacingMotionAdaptive },
> -    { "x",     VAProcDeinterlacingMotionCompensated },
> -    { "bob",   VAProcDeinterlacingBob },
> -    { "mean",  VAProcDeinterlacingWeave }
> +    { "x",     VAProcDeinterlacingMotionAdaptive,     true },
> +    { "x",     VAProcDeinterlacingMotionCompensated,  true },
> +    { "bob",   VAProcDeinterlacingBob,                true },
> +    { "mean",  VAProcDeinterlacingWeave,              false }
>  };
>
> +#define METADATA_SIZE 3
> +
>  struct  deint_data
>  {
>      struct
> @@ -247,6 +250,15 @@ struct  deint_data
>          VASurfaceID *   surfaces;
>          unsigned int    sz;
>      } backward_refs, forward_refs;
> +
> +    struct
> +    {
> +        mtime_t date;
> +        int     i_nb_fields;
> +    } meta[METADATA_SIZE];
> +
> +    bool                b_double_rate;
> +    unsigned int        cur_frame;
>  };
>
>  /********************
> @@ -813,6 +825,20 @@ Deinterlace_UpdateHistory(struct deint_data * p_deint_data, picture_t * src)
>  }
>
>  static void
> +Deinterlace_UpdateFilterParams(void * p_data, void * va_params)
> +{
> +    struct deint_data *const    p_deint_data = p_data;
> +    VAProcFilterParameterBufferDeinterlacing *const      p_va_params = va_params;
> +
> +    p_va_params->flags =
> +        p_deint_data->history.pp_cur_pic[0]->b_top_field_first ?
> +        0 : VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
> +    if (p_deint_data->cur_frame ==
> +        (p_deint_data->history.pp_cur_pic[0]->b_top_field_first ? 1 : 0))
> +        p_va_params->flags |= VA_DEINTERLACING_BOTTOM_FIELD;
> +}
> +
> +static void
>  Deinterlace_UpdateReferenceFrames(void * p_data)
>  {
>      struct deint_data *const    p_deint_data = p_data;
> @@ -842,10 +868,6 @@ Deinterlace_UpdatePipelineParams
>  {
>      struct deint_data *const    p_deint_data = p_data;
>
> -    pipeline_param->filter_flags =
> -        p_deint_data->history.pp_cur_pic[0]->b_top_field_first ?
> -        0 : VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
> -
>      pipeline_param->backward_references = p_deint_data->backward_refs.surfaces;
>      pipeline_param->forward_references = p_deint_data->forward_refs.surfaces;
>      pipeline_param->num_backward_references = p_deint_data->backward_refs.sz;
> @@ -863,7 +885,8 @@ Deinterlace(filter_t * filter, picture_t * src)
>          return NULL;
>
>      picture_t *const    dest =
> -        Filter(filter, src, NULL,
> +        Filter(filter, src,
> +               Deinterlace_UpdateFilterParams,
>                 Deinterlace_UpdateReferenceFrames,
>                 Deinterlace_UpdatePipelineParams);
>
> @@ -873,6 +896,71 @@ Deinterlace(filter_t * filter, picture_t * src)
>      return dest;
>  }
>
> +static picture_t *
> +DeinterlaceX2(filter_t * filter, picture_t * src)
> +{
> +    filter_sys_t *const         filter_sys = filter->p_sys;
> +    struct deint_data *const    p_deint_data = filter_sys->p_data;
> +    const video_format_t *      fmt = &filter->fmt_out.video;
> +
> +    /* TODO: could use the meta array and calculation from deinterlace/common
> +       but then it would also be appropriate to use the picture history array
> +       too and the callback system...so a rewrite of this module basically.*/
> +    for (unsigned int i = 1; i < METADATA_SIZE; ++i)
> +        p_deint_data->meta[i-1] = p_deint_data->meta[i];
> +    p_deint_data->meta[METADATA_SIZE-1].date        = src->date;
> +    p_deint_data->meta[METADATA_SIZE-1].i_nb_fields = src->i_nb_fields;
> +
> +    picture_t * cur = Deinterlace_UpdateHistory(p_deint_data, src);
> +    if (p_deint_data->history.num_pics < p_deint_data->history.sz)
> +        return NULL;
> +
> +    mtime_t i_field_dur = 0;
> +    unsigned int i = 0;
> +    for ( ; i < METADATA_SIZE-1; i ++)
> +        if (p_deint_data->meta[i].date > VLC_TS_INVALID)
> +            break;
> +    if (i < METADATA_SIZE-1) {
> +        unsigned int i_fields_total = 0;
> +        for (unsigned int j = i; j < METADATA_SIZE-1; ++j)
> +            i_fields_total += p_deint_data->meta[j].i_nb_fields;
> +        i_field_dur = (src->date - p_deint_data->meta[i].date) / i_fields_total;
> +    }
> +    else if (fmt->i_frame_rate_base)
> +        i_field_dur = CLOCK_FREQ * fmt->i_frame_rate_base / fmt->i_frame_rate;
> +
> +    picture_t *dest[2] = {NULL, NULL};
> +    for (i = 0; i < 2; ++i)
> +    {
> +        p_deint_data->cur_frame = i;
> +        dest[i] = Filter(filter, cur,
> +                         Deinterlace_UpdateFilterParams,
> +                         Deinterlace_UpdateReferenceFrames,
> +                         Deinterlace_UpdatePipelineParams);
> +        if (!dest[i])
> +           goto error;
> +
> +        dest[i]->b_progressive = true;
> +        dest[i]->i_nb_fields = 1;
> +    }
> +
> +    dest[0]->p_next = dest[1];
> +    dest[0]->date = cur->date;
> +    if (dest[0]->date > VLC_TS_INVALID)
> +        dest[1]->date = dest[0]->date + i_field_dur;
> +    else
> +        dest[1]->date = VLC_TS_INVALID;
> +
> +    return dest[0];
> +
> +error:
> +    for (i = 0; i < 2; ++i)
> +        if (dest[i])
> +            picture_Release(dest[i]);
> +
> +    return NULL;
> +}
> +
>  static void
>  Deinterlace_Flush(filter_t *filter)
>  {
> @@ -884,6 +972,12 @@ Deinterlace_Flush(filter_t *filter)
>              p_deint_data->history.pp_pics[--p_deint_data->history.num_pics];
>          picture_Release(pic);
>      }
> +
> +    for (unsigned int i = 0; i < METADATA_SIZE; ++i)
> +    {
> +        p_deint_data->meta[i].date = VLC_TS_INVALID;
> +        p_deint_data->meta[i].i_nb_fields = 2;
> +    }
>  }
>
>  static inline bool
> @@ -901,7 +995,7 @@ OpenDeinterlace_IsValidType(filter_t * filter,
>
>  static inline int
>  OpenDeinterlace_GetMode(filter_t * filter, char const * deint_mode,
> -                        VAProcDeinterlacingType * p_deint_mode,
> +                        struct  deint_mode * p_deint_mode,
>                          VAProcDeinterlacingType const caps[],
>                          unsigned int num_caps)
>  {
> @@ -915,7 +1009,7 @@ OpenDeinterlace_GetMode(filter_t * filter, char const * deint_mode,
>                  if (OpenDeinterlace_IsValidType(filter, caps, num_caps,
>                                                  deint_modes + i))
>                  {
> -                    *p_deint_mode = deint_modes[i].type;
> +                    memcpy(p_deint_mode, &deint_modes[i], sizeof(*p_deint_mode));

*p_deint_mode = deint_modes[i] was fine. That's one good thing about structure.

>                      msg_Dbg(filter, "using %s deinterlace method",
>                              deint_modes[i].name);
>                      return VLC_SUCCESS;
> @@ -929,7 +1023,7 @@ OpenDeinterlace_GetMode(filter_t * filter, char const * deint_mode,
>          if (OpenDeinterlace_IsValidType(filter, caps, num_caps,
>                                          deint_modes + i))
>          {
> -            *p_deint_mode = deint_modes[i].type;
> +            memcpy(p_deint_mode, &deint_modes[i], sizeof(*p_deint_mode));

idem

>              if (fallback)
>                  msg_Info(filter, "%s algorithm not available, falling back to "
>                           "%s algorithm", deint_mode, deint_modes[i].name);
> @@ -952,7 +1046,8 @@ OpenDeinterlace_InitFilterParams(filter_t * filter, void * p_data,
>                                   void ** pp_va_params,
>                                   uint32_t * p_va_param_sz,
>                                   uint32_t * p_num_va_params)
> -{ VLC_UNUSED(p_data);
> +{
> +    struct deint_data *const    p_deint_data = p_data;
>      filter_sys_t *const         filter_sys = filter->p_sys;
>      VAProcDeinterlacingType     caps[VAProcDeinterlacingCount];
>      unsigned int                num_caps = VAProcDeinterlacingCount;
> @@ -964,12 +1059,12 @@ OpenDeinterlace_InitFilterParams(filter_t * filter, void * p_data,
>                                             &caps, &num_caps))
>          return VLC_EGENERIC;
>
> -    VAProcDeinterlacingType     va_mode;
> -    char *const                 psz_deint_mode =
> +    struct deint_mode   deint_mode;
> +    char *const         psz_deint_mode =
>          var_InheritString(filter, "deinterlace-mode");
>
>      int ret = OpenDeinterlace_GetMode(filter, psz_deint_mode,
> -                                      &va_mode, caps, num_caps);
> +                                      &deint_mode, caps, num_caps);
>      free(psz_deint_mode);
>      if (ret)
>          return VLC_EGENERIC;
> @@ -984,9 +1079,11 @@ OpenDeinterlace_InitFilterParams(filter_t * filter, void * p_data,
>          return VLC_ENOMEM;
>
>      p_va_param->type = VAProcFilterDeinterlacing;
> -    p_va_param->algorithm = va_mode;
> +    p_va_param->algorithm = deint_mode.type;
>      *pp_va_params = p_va_param;
>
> +    p_deint_data->b_double_rate = deint_mode.b_double_rate;
> +
>      return VLC_SUCCESS;
>  }
>
> @@ -1040,9 +1137,18 @@ OpenDeinterlace(vlc_object_t * obj)
>               OpenDeinterlace_InitFilterParams, OpenDeinterlace_InitHistory))
>          goto error;
>
> -    filter->pf_video_filter = Deinterlace;
> +    if (p_data->b_double_rate)
> +        filter->pf_video_filter = DeinterlaceX2;
> +    else
> +        filter->pf_video_filter = Deinterlace;
>      filter->pf_flush = Deinterlace_Flush;
>
> +    for (unsigned int i = 0; i < METADATA_SIZE; ++i)
> +    {
> +        p_data->meta[i].date = VLC_TS_INVALID;
> +        p_data->meta[i].i_nb_fields = 2;
> +    }
> +
>      return VLC_SUCCESS;
>
>  error:
>
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits


More information about the vlc-devel mailing list