[Mesa-dev] [PATCH 3/3] vl: add support for bob deinterlacing

Maarten Lankhorst m.b.lankhorst at gmail.com
Mon Feb 13 07:09:09 PST 2012


Op 13-02-12 14:36, Christian König schreef:
> Signed-off-by: Christian König<deathsimple at vodafone.de>
> ---
>   src/gallium/auxiliary/vl/vl_compositor.c       |   41 +++++++++++++++++++-----
>   src/gallium/auxiliary/vl/vl_compositor.h       |   13 ++++++-
>   src/gallium/state_trackers/vdpau/mixer.c       |   19 ++++++++++-
>   src/gallium/state_trackers/xorg/xvmc/surface.c |    3 +-
>   4 files changed, 64 insertions(+), 12 deletions(-)
>
> diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
> index d41a7b4..6789095 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 2157efa..2411d9a 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 60ceb3f..685eed9 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,24 @@ 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:
> +   default:
> +      deinterlace = VL_COMPOSITOR_WEAVE;
> +      break;
> +   };
return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE for default?

>      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 024612e..7f7eead 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);



More information about the mesa-dev mailing list