mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-10 06:00:14 +01:00
st/vdpau: use bicubic filter for scaling(v6.1)
use bicubic filtering as high quality scaling L1.
v2: fix a typo and add a newline to code
v3: -render the unscaled image on a temporary surface (Christian)
-apply noise reduction and sharpness filter on
unscaled surface
-render the final scaled surface using bicubic
interpolation
v4: support high quality scaling
v5: set dst_area and dst_clip in bicubic filter
v6: set buffer layer before setting dst_area
v6.1: add PIPE_BIND_LINEAR when creating resource
Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
parent
872dd9ad15
commit
de772bc060
3 changed files with 106 additions and 14 deletions
|
|
@ -82,7 +82,6 @@ vlVdpVideoMixerCreate(VdpDevice device,
|
|||
switch (features[i]) {
|
||||
/* they are valid, but we doesn't support them */
|
||||
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:
|
||||
|
|
@ -110,6 +109,9 @@ vlVdpVideoMixerCreate(VdpDevice device,
|
|||
vmixer->luma_key.supported = true;
|
||||
break;
|
||||
|
||||
case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
|
||||
vmixer->bicubic.supported = true;
|
||||
break;
|
||||
default: goto no_params;
|
||||
}
|
||||
}
|
||||
|
|
@ -202,6 +204,11 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
|
|||
vl_matrix_filter_cleanup(vmixer->sharpness.filter);
|
||||
FREE(vmixer->sharpness.filter);
|
||||
}
|
||||
|
||||
if (vmixer->bicubic.filter) {
|
||||
vl_bicubic_filter_cleanup(vmixer->bicubic.filter);
|
||||
FREE(vmixer->bicubic.filter);
|
||||
}
|
||||
pipe_mutex_unlock(vmixer->device->mutex);
|
||||
DeviceReference(&vmixer->device, NULL);
|
||||
|
||||
|
|
@ -230,9 +237,11 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
VdpLayer const *layers)
|
||||
{
|
||||
enum vl_compositor_deinterlace deinterlace;
|
||||
struct u_rect rect, clip, *prect;
|
||||
struct u_rect rect, clip, *prect, dirty_area;
|
||||
unsigned i, layer = 0;
|
||||
struct pipe_video_buffer *video_buffer;
|
||||
struct pipe_sampler_view *sampler_view;
|
||||
struct pipe_surface *surface;
|
||||
|
||||
vlVdpVideoMixer *vmixer;
|
||||
vlVdpSurface *surf;
|
||||
|
|
@ -325,7 +334,44 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
prect = ▭
|
||||
}
|
||||
vl_compositor_set_buffer_layer(&vmixer->cstate, compositor, layer, video_buffer, prect, NULL, deinterlace);
|
||||
vl_compositor_set_layer_dst_area(&vmixer->cstate, layer++, RectToPipe(destination_video_rect, &rect));
|
||||
|
||||
if(vmixer->bicubic.filter) {
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_resource res_tmpl, *res;
|
||||
struct pipe_sampler_view sv_templ;
|
||||
struct pipe_surface surf_templ;
|
||||
|
||||
pipe = vmixer->device->context;
|
||||
memset(&res_tmpl, 0, sizeof(res_tmpl));
|
||||
|
||||
res_tmpl.target = PIPE_TEXTURE_2D;
|
||||
res_tmpl.width0 = surf->templat.width;
|
||||
res_tmpl.height0 = surf->templat.height;
|
||||
res_tmpl.format = dst->sampler_view->format;
|
||||
res_tmpl.depth0 = 1;
|
||||
res_tmpl.array_size = 1;
|
||||
res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_LINEAR;
|
||||
res_tmpl.usage = PIPE_USAGE_DEFAULT;
|
||||
|
||||
res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
|
||||
|
||||
vlVdpDefaultSamplerViewTemplate(&sv_templ, res);
|
||||
sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ);
|
||||
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
surf_templ.format = res->format;
|
||||
surface = pipe->create_surface(pipe, res, &surf_templ);
|
||||
|
||||
vl_compositor_reset_dirty_area(&dirty_area);
|
||||
pipe_resource_reference(&res, NULL);
|
||||
} else {
|
||||
surface = dst->surface;
|
||||
sampler_view = dst->sampler_view;
|
||||
dirty_area = dst->dirty_area;
|
||||
vl_compositor_set_layer_dst_area(&vmixer->cstate, layer++, RectToPipe(destination_video_rect, &rect));
|
||||
vl_compositor_set_dst_clip(&vmixer->cstate, RectToPipe(destination_rect, &clip));
|
||||
}
|
||||
|
||||
for (i = 0; i < layer_count; ++i) {
|
||||
vlVdpOutputSurface *src = vlGetDataHTAB(layers->source_surface);
|
||||
|
|
@ -343,22 +389,29 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
++layers;
|
||||
}
|
||||
|
||||
vl_compositor_set_dst_clip(&vmixer->cstate, RectToPipe(destination_rect, &clip));
|
||||
if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter)
|
||||
if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter && !vmixer->bicubic.filter)
|
||||
vlVdpSave4DelayedRendering(vmixer->device, destination_surface, &vmixer->cstate);
|
||||
else {
|
||||
vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area, true);
|
||||
vl_compositor_render(&vmixer->cstate, compositor, surface, &dirty_area, true);
|
||||
|
||||
/* 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);
|
||||
sampler_view, surface);
|
||||
|
||||
if (vmixer->sharpness.filter)
|
||||
vl_matrix_filter_render(vmixer->sharpness.filter,
|
||||
dst->sampler_view, dst->surface);
|
||||
sampler_view, surface);
|
||||
|
||||
if (vmixer->bicubic.filter)
|
||||
vl_bicubic_filter_render(vmixer->bicubic.filter,
|
||||
sampler_view, dst->surface,
|
||||
RectToPipe(destination_video_rect, &rect),
|
||||
RectToPipe(destination_rect, &clip));
|
||||
|
||||
if(surface != dst->surface) {
|
||||
pipe_sampler_view_reference(&sampler_view, NULL);
|
||||
pipe_surface_reference(&surface, NULL);
|
||||
}
|
||||
}
|
||||
pipe_mutex_unlock(vmixer->device->mutex);
|
||||
|
||||
|
|
@ -460,6 +513,28 @@ vlVdpVideoMixerUpdateSharpnessFilter(vlVdpVideoMixer *vmixer)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the bicubic filter
|
||||
*/
|
||||
static void
|
||||
vlVdpVideoMixerUpdateBicubicFilter(vlVdpVideoMixer *vmixer)
|
||||
{
|
||||
assert(vmixer);
|
||||
|
||||
/* if present remove the old filter first */
|
||||
if (vmixer->bicubic.filter) {
|
||||
vl_bicubic_filter_cleanup(vmixer->bicubic.filter);
|
||||
FREE(vmixer->bicubic.filter);
|
||||
vmixer->bicubic.filter = NULL;
|
||||
}
|
||||
/* and create a new filter as needed */
|
||||
if (vmixer->bicubic.enabled) {
|
||||
vmixer->bicubic.filter = MALLOC(sizeof(struct vl_bicubic_filter));
|
||||
vl_bicubic_filter_init(vmixer->bicubic.filter, vmixer->device->context,
|
||||
vmixer->video_width, vmixer->video_height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve whether features were requested at creation time.
|
||||
*/
|
||||
|
|
@ -483,7 +558,6 @@ vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
|
|||
switch (features[i]) {
|
||||
/* they are valid, but we doesn't support them */
|
||||
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:
|
||||
|
|
@ -512,6 +586,10 @@ vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
|
|||
feature_supports[i] = vmixer->luma_key.supported;
|
||||
break;
|
||||
|
||||
case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
|
||||
feature_supports[i] = vmixer->bicubic.supported;
|
||||
break;
|
||||
|
||||
default:
|
||||
return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
|
||||
}
|
||||
|
|
@ -544,7 +622,6 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
|
|||
switch (features[i]) {
|
||||
/* they are valid, but we doesn't support them */
|
||||
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:
|
||||
|
|
@ -578,6 +655,11 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
|
|||
vmixer->luma_key.luma_min, vmixer->luma_key.luma_max);
|
||||
break;
|
||||
|
||||
case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
|
||||
vmixer->bicubic.enabled = feature_enables[i];
|
||||
vlVdpVideoMixerUpdateBicubicFilter(vmixer);
|
||||
break;
|
||||
|
||||
default:
|
||||
pipe_mutex_unlock(vmixer->device->mutex);
|
||||
return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
|
||||
|
|
@ -612,7 +694,6 @@ vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
|
|||
/* 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:
|
||||
|
|
@ -636,6 +717,10 @@ vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
|
|||
feature_enables[i] = vmixer->luma_key.enabled;
|
||||
break;
|
||||
|
||||
case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
|
||||
feature_enables[i] = vmixer->bicubic.enabled;
|
||||
break;
|
||||
|
||||
default:
|
||||
return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -471,6 +471,7 @@ vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature featur
|
|||
case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
|
||||
case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL:
|
||||
case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
|
||||
case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
|
||||
*is_supported = VDP_TRUE;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "os/os_thread.h"
|
||||
|
||||
#include "vl/vl_video_buffer.h"
|
||||
#include "vl/vl_bicubic_filter.h"
|
||||
#include "vl/vl_compositor.h"
|
||||
#include "vl/vl_csc.h"
|
||||
#include "vl/vl_deint_filter.h"
|
||||
|
|
@ -372,6 +373,11 @@ typedef struct
|
|||
struct vl_deint_filter *filter;
|
||||
} deint;
|
||||
|
||||
struct {
|
||||
bool supported, enabled;
|
||||
struct vl_bicubic_filter *filter;
|
||||
} bicubic;
|
||||
|
||||
struct {
|
||||
bool supported, enabled;
|
||||
unsigned level;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue