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

Oliver Collyer ovcollyer at mac.com
Mon Jul 10 13:23:16 CEST 2017


Sorry, yes, just tried it again and it was related to the const char[] in the deint structure but I can see that the suggested patch addresses that.

I should have realised that at the time. My bad.

> On 10 Jul 2017, at 13:55, Oliver Collyer <ovcollyer at mac.com> wrote:
> 
>> 
>> 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
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel <https://mailman.videolan.org/listinfo/vlc-devel>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170710/c7127eb8/attachment.html>


More information about the vlc-devel mailing list