vl: add support for bob deinterlacing
authorChristian König <deathsimple@vodafone.de>
Fri, 10 Feb 2012 13:32:16 +0000 (14:32 +0100)
committerChristian König <deathsimple@vodafone.de>
Tue, 21 Feb 2012 10:13:27 +0000 (11:13 +0100)
v2: return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE
    for unknown picture structure.

Signed-off-by: Christian König <deathsimple@vodafone.de>
src/gallium/auxiliary/vl/vl_compositor.c
src/gallium/auxiliary/vl/vl_compositor.h
src/gallium/state_trackers/vdpau/mixer.c
src/gallium/state_trackers/xorg/xvmc/surface.c

index d41a7b412533d36a5c751022d00a0d4695f8aed1..678909583a3f54a4fd9dd4a15b5f7f7834d3f8b5 100644 (file)
@@ -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
index 2157efade1d7a84e50789aef7f907272fc94bdac..2411d9a1ec1ec711077e375323d96a47caf55145 100644 (file)
@@ -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
index f1c5a57d33e0a72307caa5b4cf48698e2070d53e..df6750d569811eafc46bd4cf92173bd493e0f14f 100644 (file)
@@ -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),
index 024612e7414460c61fa8d2ddc96099363dcd9c7b..7f7eeadcbc682fdb053ffa11cd41400c6882b3da 100644 (file)
@@ -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);