[Mesa-dev] [PATCH] st/vdpau: use bicubic filter for scaling

Christian König deathsimple at vodafone.de
Fri Jun 17 15:45:44 UTC 2016


Really nice work. I now understand where your problem is with the scaled 
surface.

Please see the further comments below.

Am 16.06.2016 um 20:15 schrieb Nayan Deshmukh:
> v2: fix a typo and add a newline to code
>
> Signed-off-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
> ---
>   src/gallium/state_trackers/vdpau/mixer.c         | 53 +++++++++++++++++++++---
>   src/gallium/state_trackers/vdpau/vdpau_private.h |  6 +++
>   2 files changed, 54 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
> index 65c3ce2..751c7e5 100644
> --- a/src/gallium/state_trackers/vdpau/mixer.c
> +++ b/src/gallium/state_trackers/vdpau/mixer.c
> @@ -82,7 +82,6 @@ vlVdpVideoMixerCreate(VdpDevice device,
>         switch (features[i]) {
>         /* they are valid, but we doesn't support them */
>         case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL:
> -      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4:
> @@ -110,6 +109,9 @@ vlVdpVideoMixerCreate(VdpDevice device,
>            vmixer->luma_key.supported = true;
>            break;
>   
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
> +         vmixer->bicubic.supported = true;
> +         break;
>         default: goto no_params;
>         }
>      }
> @@ -202,6 +204,11 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
>         vl_matrix_filter_cleanup(vmixer->sharpness.filter);
>         FREE(vmixer->sharpness.filter);
>      }
> +
> +   if (vmixer->bicubic.filter) {
> +      vl_bicubic_filter_cleanup(vmixer->bicubic.filter);
> +      FREE(vmixer->bicubic.filter);
> +   }
>      pipe_mutex_unlock(vmixer->device->mutex);
>      DeviceReference(&vmixer->device, NULL);
>   
> @@ -344,7 +351,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
>      }
>   
>      vl_compositor_set_dst_clip(&vmixer->cstate, RectToPipe(destination_rect, &clip));
> -   if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter)
> +   if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter && !vmixer->bicubic.filter)
>         vlVdpSave4DelayedRendering(vmixer->device, destination_surface, &vmixer->cstate);
>      else {
>         vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area, true);
> @@ -359,6 +366,10 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
>         if (vmixer->sharpness.filter)
>            vl_matrix_filter_render(vmixer->sharpness.filter,
>                                    dst->sampler_view, dst->surface);
> +
> +      if (vmixer->bicubic.filter)
> +         vl_bicubic_filter_render(vmixer->bicubic.filter,
> +                                 dst->sampler_view, dst->surface);

What you do here is first using the compositor to merge and scale the 
surfaces and then apply bicubic filtering on the already scaled surface.

That is rather suboptimal. It would be better to let the compositor 
create an unscaled image and then scale it using bicubic filtering.

Regards,
Christian.

>      }
>      pipe_mutex_unlock(vmixer->device->mutex);
>   
> @@ -461,6 +472,28 @@ vlVdpVideoMixerUpdateSharpnessFilter(vlVdpVideoMixer *vmixer)
>   }
>   
>   /**
> + * Update the bicubic filter
> + */
> +static void
> +vlVdpVideoMixerUpdateBicubicFilter(vlVdpVideoMixer *vmixer)
> +{
> +   assert(vmixer);
> +
> +   /* if present remove the old filter first */
> +   if (vmixer->bicubic.filter) {
> +      vl_bicubic_filter_cleanup(vmixer->bicubic.filter);
> +      FREE(vmixer->bicubic.filter);
> +      vmixer->bicubic.filter = NULL;
> +   }
> +   /* and create a new filter as needed */
> +   if (vmixer->bicubic.enabled) {
> +      vmixer->bicubic.filter = MALLOC(sizeof(struct vl_bicubic_filter));
> +      vl_bicubic_filter_init(vmixer->bicubic.filter, vmixer->device->context,
> +                            vmixer->video_width, vmixer->video_height);
> +   }
> +}
> +
> +/**
>    * Retrieve whether features were requested at creation time.
>    */
>   VdpStatus
> @@ -483,7 +516,6 @@ vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
>         switch (features[i]) {
>         /* they are valid, but we doesn't support them */
>         case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL:
> -      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4:
> @@ -512,6 +544,10 @@ vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
>            feature_supports[i] = vmixer->luma_key.supported;
>            break;
>   
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
> +         feature_supports[i] = vmixer->bicubic.supported;
> +         break;
> +
>         default:
>            return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
>         }
> @@ -544,7 +580,6 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
>         switch (features[i]) {
>         /* they are valid, but we doesn't support them */
>         case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL:
> -      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4:
> @@ -578,6 +613,11 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
>                                            vmixer->luma_key.luma_min, vmixer->luma_key.luma_max);
>            break;
>   
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
> +         vmixer->bicubic.enabled = feature_enables[i];
> +         vlVdpVideoMixerUpdateBicubicFilter(vmixer);
> +         break;
> +
>         default:
>            pipe_mutex_unlock(vmixer->device->mutex);
>            return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
> @@ -612,7 +652,6 @@ vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
>         /* they are valid, but we doesn't support them */
>         case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL:
>         case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL:
> -      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3:
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4:
> @@ -636,6 +675,10 @@ vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
>            feature_enables[i] = vmixer->luma_key.enabled;
>            break;
>   
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
> +         feature_enables[i] = vmixer->bicubic.enabled;
> +         break;
> +
>         default:
>            return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
>         }
> diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
> index 8673c6a..bcd4bb1 100644
> --- a/src/gallium/state_trackers/vdpau/vdpau_private.h
> +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
> @@ -45,6 +45,7 @@
>   #include "os/os_thread.h"
>   
>   #include "vl/vl_video_buffer.h"
> +#include "vl/vl_bicubic_filter.h"
>   #include "vl/vl_compositor.h"
>   #include "vl/vl_csc.h"
>   #include "vl/vl_deint_filter.h"
> @@ -373,6 +374,11 @@ typedef struct
>      } deint;
>   
>      struct {
> +	  bool supported, enabled;
> +	  struct vl_bicubic_filter *filter;
> +   } bicubic;
> +
> +   struct {
>         bool supported, enabled;
>         unsigned level;
>         struct vl_median_filter *filter;



More information about the mesa-dev mailing list