vl: improve motion adaptive deinterlacer

Handle other formats than YV12 as well.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Christian König 2015-12-15 21:21:50 +01:00
parent e945235aed
commit 5fdd4a5aef
2 changed files with 49 additions and 22 deletions

View File

@ -47,6 +47,7 @@
#include "util/u_draw.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "vl_types.h"
#include "vl_video_buffer.h"
@ -214,8 +215,9 @@ create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field,
ureg_imm4f(shader, -0.02353f, 0, 0, 0));
ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)),
ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0));
ureg_LRP(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X), ureg_src(t_diff),
ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff),
ureg_src(t_linear), ureg_src(t_weave));
ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X));
ureg_release_temporary(shader, t_tex);
ureg_release_temporary(shader, t_comp_top);
@ -271,10 +273,20 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe,
goto error_rs_state;
memset(&blend, 0, sizeof blend);
blend.rt[0].colormask = PIPE_MASK_RGBA;
filter->blend = pipe->create_blend_state(pipe, &blend);
if (!filter->blend)
goto error_blend;
blend.rt[0].colormask = PIPE_MASK_R;
filter->blend[0] = pipe->create_blend_state(pipe, &blend);
if (!filter->blend[0])
goto error_blendR;
blend.rt[0].colormask = PIPE_MASK_G;
filter->blend[1] = pipe->create_blend_state(pipe, &blend);
if (!filter->blend[1])
goto error_blendG;
blend.rt[0].colormask = PIPE_MASK_B;
filter->blend[2] = pipe->create_blend_state(pipe, &blend);
if (!filter->blend[2])
goto error_blendB;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@ -349,9 +361,15 @@ error_quad:
pipe->delete_sampler_state(pipe, filter->sampler);
error_sampler:
pipe->delete_blend_state(pipe, filter->blend);
pipe->delete_blend_state(pipe, filter->blend[2]);
error_blend:
error_blendB:
pipe->delete_blend_state(pipe, filter->blend[1]);
error_blendG:
pipe->delete_blend_state(pipe, filter->blend[0]);
error_blendR:
pipe->delete_rasterizer_state(pipe, filter->rs_state);
error_rs_state:
@ -367,7 +385,9 @@ vl_deint_filter_cleanup(struct vl_deint_filter *filter)
assert(filter);
filter->pipe->delete_sampler_state(filter->pipe, filter->sampler[0]);
filter->pipe->delete_blend_state(filter->pipe, filter->blend);
filter->pipe->delete_blend_state(filter->pipe, filter->blend[0]);
filter->pipe->delete_blend_state(filter->pipe, filter->blend[1]);
filter->pipe->delete_blend_state(filter->pipe, filter->blend[2]);
filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state);
filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves);
pipe_resource_reference(&filter->quad.buffer, NULL);
@ -420,12 +440,14 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
struct pipe_sampler_view **next_sv;
struct pipe_sampler_view *sampler_views[4];
struct pipe_surface **dst_surfaces;
int j;
const unsigned *plane_order;
int i, j;
assert(filter && prevprev && prev && cur && next && field <= 1);
/* set up destination and source */
dst_surfaces = filter->video_buffer->get_surfaces(filter->video_buffer);
plane_order = vl_video_buffer_plane_order(filter->video_buffer->buffer_format);
cur_sv = cur->get_sampler_view_components(cur);
prevprev_sv = prevprev->get_sampler_view_components(prevprev);
prev_sv = prev->get_sampler_view_components(prev);
@ -433,7 +455,6 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
/* set up pipe state */
filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state);
filter->pipe->bind_blend_state(filter->pipe, filter->blend);
filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
filter->pipe->bind_vs_state(filter->pipe, filter->vs);
@ -449,12 +470,13 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
fb_state.nr_cbufs = 1;
/* process each plane separately */
for (j = 0; j < 3; j++) {
/* select correct YV12 surfaces */
int k = j == 1 ? 2 :
j == 2 ? 1 : 0;
struct pipe_surface *blit_surf = dst_surfaces[2 * k + field];
struct pipe_surface *dst_surf = dst_surfaces[2 * k + 1 - field];
for (i = 0, j = 0; i < VL_NUM_COMPONENTS; ++i) {
struct pipe_surface *blit_surf = dst_surfaces[field];
struct pipe_surface *dst_surf = dst_surfaces[1 - field];
int k = plane_order[i];
/* bind blend state for this component in the plane */
filter->pipe->bind_blend_state(filter->pipe, filter->blend[j]);
/* update render target state */
viewport.scale[0] = blit_surf->texture->width0;
@ -463,10 +485,10 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
fb_state.height = blit_surf->texture->height0;
/* update sampler view sources */
sampler_views[0] = prevprev_sv[j];
sampler_views[1] = prev_sv[j];
sampler_views[2] = cur_sv[j];
sampler_views[3] = next_sv[j];
sampler_views[0] = prevprev_sv[k];
sampler_views[1] = prev_sv[k];
sampler_views[2] = cur_sv[k];
sampler_views[3] = next_sv[k];
filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT, 0, 4, sampler_views);
/* blit current field */
@ -479,11 +501,16 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
/* blit or interpolate other field */
fb_state.cbufs[0] = dst_surf;
filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
if (j > 0 && filter->skip_chroma) {
if (i > 0 && filter->skip_chroma) {
util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
} else {
filter->pipe->bind_fs_state(filter->pipe, field ? filter->fs_deint_top : filter->fs_deint_bottom);
util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
}
if (++j >= util_format_get_nr_components(dst_surf->format)) {
dst_surfaces += 2;
j = 0;
}
}
}

View File

@ -38,7 +38,7 @@ struct vl_deint_filter
struct pipe_vertex_buffer quad;
void *rs_state;
void *blend;
void *blend[3];
void *sampler[4];
void *ves;
void *vs;