diff options
author | Christian König <[email protected]> | 2012-02-08 19:23:33 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2012-02-10 12:10:05 +0100 |
commit | 36cd50152c76d5a5b34202887af68aab09854d5d (patch) | |
tree | 22756f14879c86cc55196b0bcbac954b8f9e77d0 /src | |
parent | d7db6343dd330cb8eb70e65190adb24dd350facc (diff) |
st/vdpau: use matrix filter to blur/sharpen video
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/state_trackers/vdpau/mixer.c | 78 | ||||
-rw-r--r-- | src/gallium/state_trackers/vdpau/query.c | 1 | ||||
-rw-r--r-- | 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 87ebe978e5f..5ce40d619ed 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 4110a877400..8bb2078e0a5 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 82e6a8e84d2..f47c0bf1a31 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; |