summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian König <[email protected]>2012-02-08 19:23:33 +0100
committerChristian König <[email protected]>2012-02-10 12:10:05 +0100
commit36cd50152c76d5a5b34202887af68aab09854d5d (patch)
tree22756f14879c86cc55196b0bcbac954b8f9e77d0 /src
parentd7db6343dd330cb8eb70e65190adb24dd350facc (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.c78
-rw-r--r--src/gallium/state_trackers/vdpau/query.c1
-rw-r--r--src/gallium/state_trackers/vdpau/vdpau_private.h9
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;