[Mesa-dev] [PATCH 2/4] st/vdpau: use median filter for noise reduction

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


Op 08-02-12 20:37, Christian König schreef:
> And while at it implement the rest of the feature
> querying also.
>
> Signed-off-by: Christian König<deathsimple at vodafone.de>
> ---
>   src/gallium/state_trackers/vdpau/mixer.c         |  286 +++++++++++++++++-----
>   src/gallium/state_trackers/vdpau/query.c         |   12 +-
>   src/gallium/state_trackers/vdpau/vdpau_private.h |   10 +-
>   3 files changed, 248 insertions(+), 60 deletions(-)
>
> diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
> index 898c50e..87ebe97 100644
> --- a/src/gallium/state_trackers/vdpau/mixer.c
> +++ b/src/gallium/state_trackers/vdpau/mixer.c
> @@ -70,15 +70,40 @@ vlVdpVideoMixerCreate(VdpDevice device,
>      if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
>         vl_compositor_set_csc_matrix(&vmixer->compositor, vmixer->csc);
>
> -   /*
> -    * TODO: Handle features
> -    */
> -
>      *mixer = vlAddDataHTAB(vmixer);
>      if (*mixer == 0) {
>         ret = VDP_STATUS_ERROR;
>         goto no_handle;
>      }
> +
> +   ret = VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
> +   for (i = 0; i<  feature_count; ++i) {
> +      switch (features[i]) {
> +      /* 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:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8:
> +      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:
> +         break;
> +
> +      case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> +         vmixer->noise_reduction.supported = true;
> +         break;
> +
> +      default: goto no_params;
> +      }
> +   }
> +
>      vmixer->chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
>      ret = VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
>      for (i = 0; i<  parameter_count; ++i) {
> @@ -117,8 +142,8 @@ vlVdpVideoMixerCreate(VdpDevice device,
>      }
>      vmixer->luma_key_min = 0.f;
>      vmixer->luma_key_max = 1.f;
> -   vmixer->noise_reduction_level = 0.f;
>      vmixer->sharpness = 0.f;
> +
>      return VDP_STATUS_OK;
>
>   no_params:
> @@ -146,32 +171,12 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
>
>      vl_compositor_cleanup(&vmixer->compositor);
>
> -   FREE(vmixer);
> -
> -   return VDP_STATUS_OK;
> -}
> -
> -/**
> - * Enable or disable features.
> - */
> -VdpStatus
> -vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
> -                                 uint32_t feature_count,
> -                                 VdpVideoMixerFeature const *features,
> -                                 VdpBool const *feature_enables)
> -{
> -   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Setting VideoMixer features\n");
> -
> -   if (!(features&&  feature_enables))
> -      return VDP_STATUS_INVALID_POINTER;
> -
> -   vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
> -   if (!vmixer)
> -      return VDP_STATUS_INVALID_HANDLE;
> +   if (vmixer->noise_reduction.filter) {
> +      vl_median_filter_cleanup(vmixer->noise_reduction.filter);
> +      FREE(vmixer->noise_reduction.filter);
> +   }
>
> -   /*
> -    * TODO: Set features
> -    */
> +   FREE(vmixer);
>
>      return VDP_STATUS_OK;
>   }
> @@ -241,6 +246,192 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
>                           RectToPipe(destination_rect,&dst_clip),
>                           &dst->dirty_area);
>
> +   /* applying the noise reduction after scaling is actually not very
> +      clever, but currently we should avoid to copy around the image
> +      data once more. */
> +   if (vmixer->noise_reduction.filter)
> +      vl_median_filter_render(vmixer->noise_reduction.filter,
> +                              dst->sampler_view, dst->surface);
> +
> +   return VDP_STATUS_OK;
> +}
> +
> +/**
> + * Update the noise reduction setting
> + */
> +static void
> +vlVdpVideoMixerUpdateNoiseReductionFilter(vlVdpVideoMixer *vmixer)
> +{
> +   assert(vmixer);
> +
> +   /* if present remove the old filter first */
> +   if (vmixer->noise_reduction.filter) {
> +      vl_median_filter_cleanup(vmixer->noise_reduction.filter);
> +      FREE(vmixer->noise_reduction.filter);
> +      vmixer->noise_reduction.filter = NULL;
> +   }
> +
> +   /* and create a new filter as needed */
> +   if (vmixer->noise_reduction. enabled&&  vmixer->noise_reduction.level>  0.0f) {
> +      vmixer->noise_reduction.filter = MALLOC(sizeof(struct vl_median_filter));
> +      vl_median_filter_init(vmixer->noise_reduction.filter,
> +                            vmixer->device->context->pipe,
> +                            vmixer->video_width, vmixer->video_height,
> +                            9 * vmixer->noise_reduction.level,
> +                            VL_MEDIAN_FILTER_CROSS);
> +   }
> +}
Is dynamically allocating vmixer->noise_reduction.filter really needed?
Wouldn't it make more sense to make it a static member, and making
the cleanup member set things to null again as needed.

> +/**
> + * Retrieve whether features were requested at creation time.
> + */
> +VdpStatus
> +vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
> +                                 uint32_t feature_count,
> +                                 VdpVideoMixerFeature const *features,
> +                                 VdpBool *feature_supports)
> +{
> +   vlVdpVideoMixer *vmixer;
> +   unsigned i;
> +
> +   if (!(features&&  feature_supports))
> +      return VDP_STATUS_INVALID_POINTER;
> +
> +   vmixer = vlGetDataHTAB(mixer);
> +   if (!vmixer)
> +      return VDP_STATUS_INVALID_HANDLE;
> +
> +   for (i = 0; i<  feature_count; ++i) {
> +      switch (features[i]) {
> +      /* 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:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8:
> +      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_NOISE_REDUCTION:
> +         feature_supports[i] = vmixer->noise_reduction.supported;
> +         break;
> +
> +      default:
> +         return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
> +      }
> +   }
> +
> +   return VDP_STATUS_OK;
> +}
> +
> +/**
> + * Enable or disable features.
> + */
> +VdpStatus
> +vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
> +                                 uint32_t feature_count,
> +                                 VdpVideoMixerFeature const *features,
> +                                 VdpBool const *feature_enables)
> +{
> +   vlVdpVideoMixer *vmixer;
> +   unsigned i;
> +
> +   if (!(features&&  feature_enables))
> +      return VDP_STATUS_INVALID_POINTER;
> +
> +   vmixer = vlGetDataHTAB(mixer);
> +   if (!vmixer)
> +      return VDP_STATUS_INVALID_HANDLE;
> +
> +   for (i = 0; i<  feature_count; ++i) {
> +      switch (features[i]) {
> +      /* 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:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8:
> +      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:
> +         break;
> +
> +      case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> +         vmixer->noise_reduction.enabled = feature_enables[i];
> +         vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer);
> +         break;
> +
> +      default:
> +         return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
> +      }
> +   }
> +
> +   return VDP_STATUS_OK;
> +}
> +
> +/**
> + * Retrieve whether features are enabled.
> + */
> +VdpStatus
> +vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
> +                                 uint32_t feature_count,
> +                                 VdpVideoMixerFeature const *features,
> +                                 VdpBool *feature_enables)
> +{
> +   vlVdpVideoMixer *vmixer;
> +   unsigned i;
> +
> +   if (!(features&&  feature_enables))
> +      return VDP_STATUS_INVALID_POINTER;
> +
> +   vmixer = vlGetDataHTAB(mixer);
> +   if (!vmixer)
> +      return VDP_STATUS_INVALID_HANDLE;
> +
> +   for (i = 0; i<  feature_count; ++i) {
> +      switch (features[i]) {
> +      /* 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:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7:
> +      case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8:
> +      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:
> +         break;
> +
> +      case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
> +         vmixer->noise_reduction.enabled = feature_enables[i];
> +         vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer);
This is a get function, not a set?
> +         break;
> +
> +      default:
> +         return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
> +      }
> +   }
> +
>      return VDP_STATUS_OK;
>   }
>
>
> ...
~Maarten


More information about the mesa-dev mailing list