From 36cd50152c76d5a5b34202887af68aab09854d5d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Wed, 8 Feb 2012 19:23:33 +0100 Subject: [PATCH] st/vdpau: use matrix filter to blur/sharpen video MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- 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; 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; -- 2.7.4