From 37f97e1753af20a7161f61e99cb203b214e00641 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Fri, 10 Feb 2012 14:32:16 +0100 Subject: [PATCH] vl: add support for bob deinterlacing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE for unknown picture structure. Signed-off-by: Christian König --- src/gallium/auxiliary/vl/vl_compositor.c | 41 +++++++++++++++---- src/gallium/auxiliary/vl/vl_compositor.h | 13 +++++- src/gallium/state_trackers/vdpau/mixer.c | 21 +++++++++- .../state_trackers/xorg/xvmc/surface.c | 3 +- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index d41a7b41253..678909583a3 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -579,7 +579,8 @@ calc_src_and_dst(struct vl_compositor_layer *layer, unsigned width, unsigned hei layer->src.br = calc_bottomright(size, src); layer->dst.tl = calc_topleft(size, dst); layer->dst.br = calc_bottomright(size, dst); - layer->size = size; + layer->zw.x = 0.0f; + layer->zw.y = size.y; } static void @@ -591,25 +592,25 @@ gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer) vb[ 0].y = layer->dst.tl.y; vb[ 1].x = layer->src.tl.x; vb[ 1].y = layer->src.tl.y; - vb[ 2] = layer->size; + vb[ 2] = layer->zw; vb[ 3].x = layer->dst.br.x; vb[ 3].y = layer->dst.tl.y; vb[ 4].x = layer->src.br.x; vb[ 4].y = layer->src.tl.y; - vb[ 5] = layer->size; + vb[ 5] = layer->zw; vb[ 6].x = layer->dst.br.x; vb[ 6].y = layer->dst.br.y; vb[ 7].x = layer->src.br.x; vb[ 7].y = layer->src.br.y; - vb[ 8] = layer->size; + vb[ 8] = layer->zw; vb[ 9].x = layer->dst.tl.x; vb[ 9].y = layer->dst.br.y; vb[10].x = layer->src.tl.x; vb[10].y = layer->src.br.y; - vb[11] = layer->size; + vb[11] = layer->zw; } static INLINE struct u_rect @@ -801,7 +802,8 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c, unsigned layer, struct pipe_video_buffer *buffer, struct pipe_video_rect *src_rect, - struct pipe_video_rect *dst_rect) + struct pipe_video_rect *dst_rect, + enum vl_compositor_deinterlace deinterlace) { struct pipe_sampler_view **sampler_views; unsigned i; @@ -811,8 +813,6 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c, assert(layer < VL_COMPOSITOR_MAX_LAYERS); c->used_layers |= 1 << layer; - c->layers[layer].fs = buffer->interlaced ? c->fs_weave : c->fs_video_buffer; - sampler_views = buffer->get_sampler_view_components(buffer); for (i = 0; i < 3; ++i) { c->layers[layer].samplers[i] = c->sampler_linear; @@ -822,6 +822,31 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c, calc_src_and_dst(&c->layers[layer], buffer->width, buffer->height, src_rect ? *src_rect : default_rect(&c->layers[layer]), dst_rect ? *dst_rect : default_rect(&c->layers[layer])); + + if (buffer->interlaced) { + float half_a_line = 0.5f / c->layers[layer].zw.y; + switch(deinterlace) { + case VL_COMPOSITOR_WEAVE: + c->layers[layer].fs = c->fs_weave; + break; + + case VL_COMPOSITOR_BOB_TOP: + c->layers[layer].zw.x = 0.25f; + c->layers[layer].src.tl.y += half_a_line; + c->layers[layer].src.br.y += half_a_line; + c->layers[layer].fs = c->fs_video_buffer; + break; + + case VL_COMPOSITOR_BOB_BOTTOM: + c->layers[layer].zw.x = 0.75f; + c->layers[layer].src.tl.y -= half_a_line; + c->layers[layer].src.br.y -= half_a_line; + c->layers[layer].fs = c->fs_video_buffer; + break; + } + + } else + c->layers[layer].fs = c->fs_video_buffer; } void diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index 2157efade1d..2411d9a1ec1 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -44,6 +44,14 @@ struct pipe_context; #define VL_COMPOSITOR_MAX_LAYERS 16 +/* deinterlace allgorithem */ +enum vl_compositor_deinterlace +{ + VL_COMPOSITOR_WEAVE, + VL_COMPOSITOR_BOB_TOP, + VL_COMPOSITOR_BOB_BOTTOM +}; + struct vl_compositor_layer { bool clearing; @@ -56,7 +64,7 @@ struct vl_compositor_layer struct { struct vertex2f tl, br; } src, dst; - struct vertex2f size; + struct vertex2f zw; }; struct vl_compositor @@ -148,7 +156,8 @@ vl_compositor_set_buffer_layer(struct vl_compositor *compositor, unsigned layer, struct pipe_video_buffer *buffer, struct pipe_video_rect *src_rect, - struct pipe_video_rect *dst_rect); + struct pipe_video_rect *dst_rect, + enum vl_compositor_deinterlace deinterlace); /** * set a paletted sampler as a layer to render diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c index f1c5a57d33e..df6750d5698 100644 --- a/src/gallium/state_trackers/vdpau/mixer.c +++ b/src/gallium/state_trackers/vdpau/mixer.c @@ -204,6 +204,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer, VdpLayer const *layers) { struct pipe_video_rect src_rect, dst_rect, dst_clip; + enum vl_compositor_deinterlace deinterlace; unsigned layer = 0; vlVdpVideoMixer *vmixer; @@ -242,8 +243,26 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer, } vl_compositor_clear_layers(&vmixer->compositor); + + switch (current_picture_structure) { + case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD: + deinterlace = VL_COMPOSITOR_BOB_TOP; + break; + + case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: + deinterlace = VL_COMPOSITOR_BOB_BOTTOM; + break; + + case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME: + deinterlace = VL_COMPOSITOR_WEAVE; + break; + + default: + return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE; + }; vl_compositor_set_buffer_layer(&vmixer->compositor, layer++, surf->video_buffer, - RectToPipe(video_source_rect, &src_rect), NULL); + RectToPipe(video_source_rect, &src_rect), NULL, + deinterlace); vl_compositor_render(&vmixer->compositor, dst->surface, RectToPipe(destination_video_rect, &dst_rect), RectToPipe(destination_rect, &dst_clip), diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 024612e7414..7f7eeadcbc6 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -406,7 +406,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, context_priv->decoder->flush(context_priv->decoder); vl_compositor_clear_layers(compositor); - vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer, &src_rect, NULL); + vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer, + &src_rect, NULL, VL_COMPOSITOR_WEAVE); if (subpicture_priv) { XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture); -- 2.30.2