From 5fdd4a5aef122a8aa1da91ac0555a817af0d1b06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Tue, 15 Dec 2015 21:21:50 +0100 Subject: [PATCH] vl: improve motion adaptive deinterlacer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Handle other formats than YV12 as well. Signed-off-by: Christian König Reviewed-by: Emil Velikov --- src/gallium/auxiliary/vl/vl_deint_filter.c | 69 +++++++++++++++------- src/gallium/auxiliary/vl/vl_deint_filter.h | 2 +- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.c b/src/gallium/auxiliary/vl/vl_deint_filter.c index 8fa70e84c66..f919867cc02 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.c +++ b/src/gallium/auxiliary/vl/vl_deint_filter.c @@ -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_blendB: + pipe->delete_blend_state(pipe, filter->blend[1]); + +error_blendG: + pipe->delete_blend_state(pipe, filter->blend[0]); -error_blend: +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; + } } } diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.h b/src/gallium/auxiliary/vl/vl_deint_filter.h index 3ca378b183d..49cc96c20b9 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.h +++ b/src/gallium/auxiliary/vl/vl_deint_filter.h @@ -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; -- 2.30.2