[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