[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