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

Oliver Collyer ovcollyer at mac.com
Mon Jul 10 12:55:33 CEST 2017


> On 10 Jul 2017, at 10:02, Steve Lhomme <robux4 at gmail.com> wrote:
> 
> 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.


Yeah...that's how I had it actually, but it gave a compile error (sorry I can't remember which one now, but I'm using a self-built gcc 5.4.0 on a deliberately old version of Ubuntu - 12.04 ), so I figured something about the compiler flags was disallowing this.

> 
>>                     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
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel



More information about the vlc-devel mailing list