Mesa (master): vl: fix YV12 handling

Christian König deathsimple at kemper.freedesktop.org
Sun Jan 15 12:28:29 UTC 2012


Module: Mesa
Branch: master
Commit: 2eabd05b7525f081ec203747a436d597ce33eb3b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2eabd05b7525f081ec203747a436d597ce33eb3b

Author: Christian König <deathsimple at vodafone.de>
Date:   Tue Jan 10 16:56:19 2012 +0100

vl: fix YV12 handling

We actually implemented YV21 instead of YV12, so fix the plane ordering.

Signed-off-by: Christian König <deathsimple at vodafone.de>

---

 src/gallium/auxiliary/vl/vl_mpeg12_decoder.c |   13 +++++---
 src/gallium/auxiliary/vl/vl_video_buffer.c   |   37 +++++++++++++++++++++++--
 src/gallium/auxiliary/vl/vl_video_buffer.h   |    6 ++++
 src/gallium/state_trackers/vdpau/surface.c   |    2 +-
 4 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index bd98089..dae063e 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -678,6 +678,7 @@ vl_mpeg12_end_frame(struct pipe_video_decoder *decoder,
    struct pipe_vertex_buffer vb[3];
    struct vl_mpeg12_buffer *buf;
 
+   const unsigned *plane_order;
    unsigned i, j, component;
    unsigned nr_components;
 
@@ -731,24 +732,26 @@ vl_mpeg12_end_frame(struct pipe_video_decoder *decoder,
          vl_idct_flush(i ? &dec->idct_c : &dec->idct_y, &buf->idct[i], buf->num_ycbcr_blocks[i]);
    }
 
+   plane_order = vl_video_buffer_plane_order(target->buffer_format);
    mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
    for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) {
       if (!target_surfaces[i]) continue;
 
       nr_components = util_format_get_nr_components(target_surfaces[i]->texture->format);
       for (j = 0; j < nr_components; ++j, ++component) {
-         if (!buf->num_ycbcr_blocks[i]) continue;
+         unsigned plane = plane_order[component];
+         if (!buf->num_ycbcr_blocks[plane]) continue;
 
-         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component);
+         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane);
          dec->base.context->set_vertex_buffers(dec->base.context, 2, vb);
 
          if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
-            vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[component]);
+            vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]);
          else {
-            dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[component]);
+            dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[plane]);
             dec->base.context->bind_fragment_sampler_states(dec->base.context, 1, &dec->sampler_ycbcr);
          }
-         vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[component]);
+         vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[plane]);
       }
    }
    ++dec->current_buffer;
diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
index 21a2a89..c033ddd 100644
--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
+++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
@@ -50,6 +50,18 @@ const enum pipe_format const_resource_formats_NV12[3] = {
    PIPE_FORMAT_NONE
 };
 
+const unsigned const_resource_plane_order_YUV[3] = {
+   0,
+   1,
+   2
+};
+
+const unsigned const_resource_plane_order_YVU[3] = {
+   0,
+   2,
+   1
+};
+
 const enum pipe_format *
 vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
 {
@@ -65,6 +77,21 @@ vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
    }
 }
 
+const unsigned *
+vl_video_buffer_plane_order(enum pipe_format format)
+{
+    switch(format) {
+   case PIPE_FORMAT_YV12:
+      return const_resource_plane_order_YVU;
+
+   case PIPE_FORMAT_NV12:
+      return const_resource_plane_order_YUV;
+
+   default:
+      return NULL;
+   }
+}
+
 boolean
 vl_video_buffer_is_format_supported(struct pipe_screen *screen,
                                     enum pipe_format format,
@@ -215,24 +242,28 @@ vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
    struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
    struct pipe_sampler_view sv_templ;
    struct pipe_context *pipe;
+   const unsigned *plane_order;
    unsigned i, j, component;
 
    assert(buf);
 
    pipe = buf->base.context;
 
+   plane_order = vl_video_buffer_plane_order(buf->base.buffer_format);
+
    for (component = 0, i = 0; i < buf->num_planes; ++i ) {
-      unsigned nr_components = util_format_get_nr_components(buf->resources[i]->format);
+      struct pipe_resource *res = buf->resources[plane_order[i]];
+      unsigned nr_components = util_format_get_nr_components(res->format);
 
       for (j = 0; j < nr_components; ++j, ++component) {
          assert(component < VL_MAX_PLANES);
 
          if (!buf->sampler_view_components[component]) {
             memset(&sv_templ, 0, sizeof(sv_templ));
-            u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
+            u_sampler_view_default_template(&sv_templ, res, res->format);
             sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
             sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
-            buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
+            buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
             if (!buf->sampler_view_components[component])
                goto error;
          }
diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h
index a323efd..1f320dd 100644
--- a/src/gallium/auxiliary/vl/vl_video_buffer.h
+++ b/src/gallium/auxiliary/vl/vl_video_buffer.h
@@ -55,6 +55,12 @@ const enum pipe_format *
 vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format);
 
 /**
+ * get YUV plane order
+ */
+const unsigned *
+vl_video_buffer_plane_order(enum pipe_format format);
+
+/**
  * get maximum size of video buffers
  */
 unsigned
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
index 8fdfafc..85ce4c3 100644
--- a/src/gallium/state_trackers/vdpau/surface.c
+++ b/src/gallium/state_trackers/vdpau/surface.c
@@ -228,7 +228,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
       return VDP_STATUS_RESOURCES;
 
    for (i = 0; i < 3; ++i) { //TODO put nr of planes into util format
-      struct pipe_sampler_view *sv = sampler_views[i ? i ^ 3 : 0];
+      struct pipe_sampler_view *sv = sampler_views[i];
       struct pipe_box dst_box = { 0, 0, 0, sv->texture->width0, sv->texture->height0, 1 };
 
       struct pipe_transfer *transfer;




More information about the mesa-commit mailing list