[Mesa-dev] [PATCH 4/4] st/vdpau: use matrix filter to blur/sharpen video

Maarten Lankhorst m.b.lankhorst at gmail.com
Mon Feb 13 00:06:47 PST 2012


Op 08-02-12 20:37, Christian König schreef:
> Signed-off-by: Christian König<deathsimple at vodafone.de>
> ---
>   src/gallium/state_trackers/vdpau/mixer.c         |   78 ++++++++++++++++++++--
>   src/gallium/state_trackers/vdpau/query.c         |    1 +
>   src/gallium/state_trackers/vdpau/vdpau_private.h |    9 ++-
>   3 files changed, 81 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
> index 87ebe97..5ce40d6 100644
> --- a/src/gallium/state_trackers/vdpau/mixer.c
> +++ b/src/gallium/state_trackers/vdpau/mixer.c
> @@ -93,7 +93,10 @@ vlVdpVideoMixerCreate(VdpDevice device,
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9:
>         case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE:
>         case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
> +         break;
> +
>         case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
> +         vmixer->sharpness.supported = true;
>            break;
>
>         case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> @@ -142,7 +145,6 @@ vlVdpVideoMixerCreate(VdpDevice device,
>      }
>      vmixer->luma_key_min = 0.f;
>      vmixer->luma_key_max = 1.f;
> -   vmixer->sharpness = 0.f;
>
>      return VDP_STATUS_OK;
>
> @@ -253,6 +255,10 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
>         vl_median_filter_render(vmixer->noise_reduction.filter,
>                                 dst->sampler_view, dst->surface);
>
> +   if (vmixer->sharpness.filter)
> +      vl_matrix_filter_render(vmixer->sharpness.filter,
> +                              dst->sampler_view, dst->surface);
> +
>      return VDP_STATUS_OK;
>   }
>
> @@ -282,6 +288,52 @@ vlVdpVideoMixerUpdateNoiseReductionFilter(vlVdpVideoMixer *vmixer)
>      }
>   }
>
> +static void
> +vlVdpVideoMixerUpdateSharpnessFilter(vlVdpVideoMixer *vmixer)
> +{
> +   assert(vmixer);
> +
> +   /* if present remove the old filter first */
> +   if (vmixer->sharpness.filter) {
> +      vl_matrix_filter_cleanup(vmixer->sharpness.filter);
> +      FREE(vmixer->sharpness.filter);
> +      vmixer->sharpness.filter = NULL;
> +   }
> +
> +   /* and create a new filter as needed */
> +   if (vmixer->sharpness.enabled&&  vmixer->sharpness.value != 0.0f) {
> +      float matrix[9];
> +      unsigned i;
> +
> +      if (vmixer->sharpness.value>  0.0f) {
> +         matrix[0] = -1.0f; matrix[1] = -1.0f; matrix[2] = -1.0f;
> +         matrix[3] = -1.0f; matrix[4] =  8.0f; matrix[5] = -1.0f;
> +         matrix[6] = -1.0f; matrix[7] = -1.0f; matrix[8] = -1.0f;
> +
> +         for (i = 0; i<  9; ++i)
> +            matrix[i] *= vmixer->sharpness.value;
> +
> +         matrix[4] += 1.0f;
> +
> +      } else {
> +         matrix[0] = 1.0f; matrix[1] = 2.0f; matrix[2] = 1.0f;
> +         matrix[3] = 2.0f; matrix[4] = 4.0f; matrix[5] = 2.0f;
> +         matrix[6] = 1.0f; matrix[7] = 2.0f; matrix[8] = 1.0f;
> +
> +         for (i = 0; i<  9; ++i)
> +               matrix[i] *= fabsf(vmixer->sharpness.value) / 16.0f;
> +
> +         matrix[4] += 1.0f - fabsf(vmixer->sharpness.value);
> +      }
> +
> +      vmixer->sharpness.filter = MALLOC(sizeof(struct vl_matrix_filter));
> +      vl_matrix_filter_init(vmixer->sharpness.filter,
> +                            vmixer->device->context->pipe,
> +                            vmixer->video_width, vmixer->video_height,
> +                            3, 3, matrix);
> +   }
> +}
> +
>   /**
>    * Retrieve whether features were requested at creation time.
>    */
> @@ -317,10 +369,13 @@ vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9:
>         case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE:
>         case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
> -      case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
>            feature_supports[i] = false;
>            break;
>
> +      case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
> +         feature_supports[i] = vmixer->sharpness.supported;
> +         break;
> +
>         case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
>            feature_supports[i] = vmixer->noise_reduction.supported;
>            break;
> @@ -368,7 +423,11 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9:
>         case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE:
>         case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
> +         break;
> +
>         case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
> +         vmixer->sharpness.enabled = feature_enables[i];
> +         vlVdpVideoMixerUpdateSharpnessFilter(vmixer);
>            break;
>
>         case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> @@ -419,12 +478,14 @@ vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
>         case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9:
>         case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE:
>         case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
> +         break;
> +
>         case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
> +         feature_enables[i] = vmixer->sharpness.enabled;
>            break;
>
>         case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> -         vmixer->noise_reduction.enabled = feature_enables[i];
> -         vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer);
> +         feature_enables[i] = vmixer->noise_reduction.enabled;
>            break;
So you did notice it was wrong in previous patch. ;)
>         default:
> @@ -500,12 +561,17 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
>               return VDP_STATUS_INVALID_VALUE;
>            vmixer->luma_key_max = val;
>            break;
> +
>         case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
> +
>            val = *(float*)attribute_values[i];
>            if (val<  -1.f || val>  1.f)
>               return VDP_STATUS_INVALID_VALUE;
> -         vmixer->sharpness = val;
> +
> +         vmixer->sharpness.value = val;
> +         vlVdpVideoMixerUpdateSharpnessFilter(vmixer);
>            break;
> +
>         case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
>            if (*(uint8_t*)attribute_values[i]>  1)
>               return VDP_STATUS_INVALID_VALUE;
> @@ -602,7 +668,7 @@ vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer,
>            *(float*)attribute_values[i] = vmixer->luma_key_max;
>            break;
>         case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
> -         *(float*)attribute_values[i] = vmixer->sharpness;
> +         *(float*)attribute_values[i] = vmixer->sharpness.value;
>            break;
>         case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
>            *(uint8_t*)attribute_values[i] = vmixer->skip_chroma_deint;
> diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c
> index 4110a87..8bb2078 100644
> --- a/src/gallium/state_trackers/vdpau/query.c
> +++ b/src/gallium/state_trackers/vdpau/query.c
> @@ -308,6 +308,7 @@ vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature featur
>         return VDP_STATUS_INVALID_POINTER;
>
>      switch (feature) {
> +   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
>      case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
>         *is_supported = VDP_TRUE;
>         break;
> diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
> index 82e6a8e..f47c0bf 100644
> --- a/src/gallium/state_trackers/vdpau/vdpau_private.h
> +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
> @@ -39,6 +39,7 @@
>   #include "util/u_debug.h"
>   #include "util/u_rect.h"
>   #include "vl/vl_compositor.h"
> +#include "vl/vl_matrix_filter.h"
>   #include "vl/vl_median_filter.h"
>
>   #include "vl_winsys.h"
> @@ -314,10 +315,16 @@ typedef struct
>         struct vl_median_filter *filter;
>      } noise_reduction;
>
> +   struct {
> +      bool supported, enabled;
> +      float value;
> +      struct vl_matrix_filter *filter;
> +   } sharpness;
> +
>      unsigned video_width, video_height;
>      enum pipe_video_chroma_format chroma_format;
>      unsigned max_layers, skip_chroma_deint, custom_csc;
> -   float luma_key_min, luma_key_max, sharpness;
> +   float luma_key_min, luma_key_max;
>      float csc[16];
>   } vlVdpVideoMixer;
>
Wouldn't it make more sense to only have a single matrix filter with 
separate matrices for each filter so you only have to run a single 
shader? And again, why dynamically allocate the filter.. make the 
destructor function handle NULL correctly where needed.

~Maarten


More information about the mesa-dev mailing list