[g3dvl] make motion vector buffers a public interface
authorChristian König <deathsimple@vodafone.de>
Wed, 20 Apr 2011 11:44:26 +0000 (13:44 +0200)
committerChristian König <deathsimple@vodafone.de>
Wed, 20 Apr 2011 11:44:26 +0000 (13:44 +0200)
src/gallium/auxiliary/vl/vl_mc.c
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
src/gallium/auxiliary/vl/vl_vertex_buffers.c
src/gallium/auxiliary/vl/vl_vertex_buffers.h
src/gallium/include/pipe/p_video_context.h
src/gallium/include/pipe/p_video_state.h
src/gallium/state_trackers/xorg/xvmc/surface.c
src/gallium/state_trackers/xorg/xvmc/xvmc_private.h

index 9785327cdbe808d18d30ead0c4aa03369cef0e3b..137a1beaa0d093b93902e12ae746def35d6ffaa0 100644 (file)
@@ -136,7 +136,7 @@ create_ref_vert_shader(struct vl_mc *r)
       0.5f / r->buffer_width,
       0.5f / r->buffer_height,
       1.0f / 4.0f,
-      1.0f / 255.0f);
+      1.0f / PIPE_VIDEO_MV_WEIGHT_MAX);
 
    for (i = 0; i < 2; ++i) {
       ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos));
index 182294894c10f30ca687e5ce1e37e98e79e43d1c..f262c13e0fce4810d5683b5b045ce2df17d34dda 100644 (file)
@@ -231,6 +231,26 @@ vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer)
    map_buffers(dec, buf);
 }
 
+static unsigned
+vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer)
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
+
+   assert(buf);
+
+   return vl_vb_get_mv_stream_stride(&buf->vertex_stream);
+}
+
+static struct pipe_motionvector *
+vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame)
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
+
+   assert(buf);
+
+   return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame);
+}
+
 static void
 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
                                  unsigned num_macroblocks,
@@ -251,7 +271,6 @@ vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
    assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
 
    for ( i = 0; i < num_macroblocks; ++i ) {
-      vl_vb_add_block(&buf->vertex_stream, &mb[i]);
       upload_buffer(dec, buf, &mb[i]);
    }
 }
@@ -389,6 +408,8 @@ vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
    buffer->base.decoder = decoder;
    buffer->base.destroy = vl_mpeg12_buffer_destroy;
    buffer->base.map = vl_mpeg12_buffer_map;
+   buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride;
+   buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream;
    buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
    buffer->base.unmap = vl_mpeg12_buffer_unmap;
 
index 212ace7512a70fab07f181f0f55502c90d7cd445..e61425843ffa8b85c203483c816e25fb44028f9a 100644 (file)
@@ -38,11 +38,6 @@ struct vl_ycbcr_vertex_stream
    uint8_t field;
 };
 
-struct vl_mv_vertex_stream
-{
-   struct vertex4s mv[2];
-};
-
 /* vertices for a quad covering a block */
 static const struct vertex2f block_quad[4] = {
    {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
@@ -242,7 +237,7 @@ vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe,
          pipe->screen,
          PIPE_BIND_VERTEX_BUFFER,
          PIPE_USAGE_STREAM,
-         sizeof(struct vl_mv_vertex_stream) * size
+         sizeof(struct pipe_motionvector) * size
       );
    }
 
@@ -270,7 +265,7 @@ vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector)
 
    assert(buffer);
 
-   buf.stride = sizeof(struct vl_mv_vertex_stream);
+   buf.stride = sizeof(struct pipe_motionvector);
    buf.buffer_offset = 0;
    buf.buffer = buffer->mv[motionvector].resource;
 
@@ -324,39 +319,21 @@ void vl_vb_add_ycbcr(struct vl_vertex_buffer *buffer,
    buffer->ycbcr[component].num_instances++;
 }
 
-static void
-get_motion_vectors(enum pipe_mpeg12_motion_type mo_type, struct pipe_motionvector *src, struct vertex4s dst[2])
+unsigned
+vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer)
 {
-   if (mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
-      dst[0].x = dst[1].x = src->top.x;
-      dst[0].y = dst[1].y = src->top.y;
-      dst[0].z = dst[1].z = 0;
-
-   } else {
-      dst[0].x = src->top.x;
-      dst[0].y = src->top.y;
-      dst[0].z = src->top.field_select ? 3 : 1;
-
-      dst[1].x = src->bottom.x;
-      dst[1].y = src->bottom.y;
-      dst[1].z = src->bottom.field_select ? 3 : 1;
-   }
+   assert(buffer);
 
-   dst[0].w = src->top.wheight;
-   dst[1].w = src->bottom.wheight;
+   return buffer->width;
 }
 
-void
-vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macroblock *mb)
+struct pipe_motionvector *
+vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame)
 {
-   unsigned mv_pos;
-
    assert(buffer);
-   assert(mb);
+   assert(ref_frame < VL_MAX_REF_FRAMES);
 
-   mv_pos = mb->mbx + mb->mby * buffer->width;
-   get_motion_vectors(mb->mo_type, &mb->mv[0], buffer->mv[0].vertex_stream[mv_pos].mv);
-   get_motion_vectors(mb->mo_type, &mb->mv[1], buffer->mv[1].vertex_stream[mv_pos].mv);
+   return buffer->mv[ref_frame].vertex_stream;
 }
 
 void
index 5632eb297bd288ad72bcd3f877e7762234d7674c..6a83111b4a8c61e79a9d19d14e1dc5752145b669 100644 (file)
@@ -62,9 +62,9 @@ struct vl_vertex_buffer
    } ycbcr[VL_MAX_PLANES];
 
    struct {
-      struct pipe_resource       *resource;
-      struct pipe_transfer       *transfer;
-      struct vl_mv_vertex_stream *vertex_stream;
+      struct pipe_resource     *resource;
+      struct pipe_transfer     *transfer;
+      struct pipe_motionvector *vertex_stream;
    } mv[VL_MAX_REF_FRAMES];
 };
 
@@ -80,17 +80,19 @@ void vl_vb_init(struct vl_vertex_buffer *buffer,
                 struct pipe_context *pipe,
                 unsigned width, unsigned height);
 
-struct pipe_vertex_buffer vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component);
-
-struct pipe_vertex_buffer vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector);
-
 void vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
 
+struct pipe_vertex_buffer vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component);
+
 void vl_vb_add_ycbcr(struct vl_vertex_buffer *buffer,
                      unsigned component, unsigned x, unsigned y,
                      bool intra, enum pipe_mpeg12_dct_type type);
 
-void vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macroblock *mb);
+struct pipe_vertex_buffer vl_vb_get_mv(struct vl_vertex_buffer *buffer, int ref_frame);
+
+unsigned vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer);
+
+struct pipe_motionvector *vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame);
 
 void vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
 
index 81fc281224965107edbe830120173fc0e22e85d7..1eb96420fb7402be95ae56ba7042ce7e45917019 100644 (file)
@@ -186,6 +186,16 @@ struct pipe_video_decode_buffer
     */
    void (*map)(struct pipe_video_decode_buffer *decbuf);
 
+   /**
+    * get the stride of the mv buffer
+    */
+   unsigned (*get_mv_stream_stride)(struct pipe_video_decode_buffer *decbuf);
+
+   /**
+    * get the pointer where to put the motion vectors of a ref frame
+    */
+   struct pipe_motionvector *(*get_mv_stream)(struct pipe_video_decode_buffer *decbuf, int ref_frame);
+
 #if 0
    /**
     * decode a bitstream
index 2cf5ea4d9758a84cd9ea9f02fa7b08d11ea20e97..dcb64d3c220406be0fb088f7ac5028c98de5d2c7 100644 (file)
@@ -50,31 +50,43 @@ enum pipe_mpeg12_picture_type
    PIPE_MPEG12_PICTURE_TYPE_FRAME
 };
 
-enum pipe_mpeg12_motion_type
-{
-   PIPE_MPEG12_MOTION_TYPE_FIELD,
-   PIPE_MPEG12_MOTION_TYPE_FRAME,
-   PIPE_MPEG12_MOTION_TYPE_DUALPRIME,
-   PIPE_MPEG12_MOTION_TYPE_16x8
-};
-
 enum pipe_mpeg12_dct_type
 {
    PIPE_MPEG12_DCT_TYPE_FIELD,
    PIPE_MPEG12_DCT_TYPE_FRAME
 };
 
+enum pipe_video_field_select
+{
+   PIPE_VIDEO_FRAME = 0,
+   PIPE_VIDEO_TOP_FIELD = 1,
+   PIPE_VIDEO_BOTTOM_FIELD = 3,
+
+   /* TODO
+   PIPE_VIDEO_DUALPRIME
+   PIPE_VIDEO_16x8
+   */
+};
+
+enum pipe_video_mv_weight
+{
+   PIPE_VIDEO_MV_WEIGHT_MIN = 0,
+   PIPE_VIDEO_MV_WEIGHT_HALF = 128,
+   PIPE_VIDEO_MV_WEIGHT_MAX = 256
+};
+
 struct pipe_macroblock
 {
    enum pipe_video_codec codec;
 };
 
+/* bitfields because this is used as a vertex buffer element */
 struct pipe_motionvector
 {
    struct {
-      signed x, y;
-      bool field_select;
-      unsigned wheight:8;
+      signed x:16, y:16;
+      enum pipe_video_field_select field_select:16;
+      enum pipe_video_mv_weight weight:16;
    } top, bottom;
 };
 
@@ -84,10 +96,8 @@ struct pipe_mpeg12_macroblock
 
    unsigned mbx;
    unsigned mby;
-   enum pipe_mpeg12_motion_type mo_type;
    bool dct_intra;
    enum pipe_mpeg12_dct_type dct_type;
-   struct pipe_motionvector mv[2];
    unsigned cbp;
    short *blocks;
 };
index 9752497eb305ad1263cc1f05befdf50246edc744..567484e993db8d99b5c88c81153669f2fa0b83eb 100644 (file)
@@ -60,30 +60,84 @@ static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
    return -1;
 }
 
-static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, unsigned xvmc_picture_structure)
+static inline void
+MacroBlockTypeToPipeWeights(const XvMCMacroBlock *xvmc_mb, unsigned weights[2])
 {
-   switch (xvmc_motion_type) {
+   assert(xvmc_mb);
+
+   switch (xvmc_mb->macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) {
+   case XVMC_MB_TYPE_MOTION_FORWARD:
+      weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
+      weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
+      break;
+
+   case (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD):
+      weights[0] = PIPE_VIDEO_MV_WEIGHT_HALF;
+      weights[1] = PIPE_VIDEO_MV_WEIGHT_HALF;
+      break;
+
+   case XVMC_MB_TYPE_MOTION_BACKWARD:
+      weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
+      weights[1] = PIPE_VIDEO_MV_WEIGHT_MAX;
+      break;
+
+   default:
+      /* workaround for xines xxmc video out plugin */
+      if (!(xvmc_mb->macroblock_type & ~XVMC_MB_TYPE_PATTERN)) {
+         weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
+         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
+      } else {
+         weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
+         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
+      }
+      break;
+   }
+}
+
+static inline struct pipe_motionvector
+MotionVectorToPipe(const XvMCMacroBlock *xvmc_mb, unsigned vector,
+                   unsigned field_select_mask, unsigned weight)
+{
+   struct pipe_motionvector mv;
+
+   assert(xvmc_mb);
+
+   switch (xvmc_mb->motion_type) {
    case XVMC_PREDICTION_FRAME:
-      if (xvmc_picture_structure == XVMC_FRAME_PICTURE)
-         return PIPE_MPEG12_MOTION_TYPE_FRAME;
-      else
-         return PIPE_MPEG12_MOTION_TYPE_16x8;
+      mv.top.x = xvmc_mb->PMV[0][vector][0];
+      mv.top.y = xvmc_mb->PMV[0][vector][1];
+      mv.top.field_select = PIPE_VIDEO_FRAME;
+      mv.top.weight = weight;
+
+      mv.bottom.x = xvmc_mb->PMV[0][vector][0];
+      mv.bottom.y = xvmc_mb->PMV[0][vector][1];
+      mv.bottom.weight = weight;
+      mv.bottom.field_select = PIPE_VIDEO_FRAME;
       break;
 
    case XVMC_PREDICTION_FIELD:
-      return PIPE_MPEG12_MOTION_TYPE_FIELD;
+      mv.top.x = xvmc_mb->PMV[0][vector][0];
+      mv.top.y = xvmc_mb->PMV[0][vector][1];
+      mv.top.field_select = (xvmc_mb->motion_vertical_field_select & field_select_mask) ?
+         PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
+      mv.top.weight = weight;
+
+      mv.bottom.x = xvmc_mb->PMV[1][vector][0];
+      mv.bottom.y = xvmc_mb->PMV[1][vector][1];
+      mv.bottom.field_select = (xvmc_mb->motion_vertical_field_select & (field_select_mask << 2)) ?
+         PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
+      mv.bottom.weight = weight;
+      break;
 
-   case XVMC_PREDICTION_DUAL_PRIME:
-      return PIPE_MPEG12_MOTION_TYPE_DUALPRIME;
+   default: // TODO: Support DUALPRIME and 16x8
+      break;
    }
 
-   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with picture structure 0x%08X).\n", xvmc_motion_type, xvmc_picture_structure);
-
-   return -1;
+   return mv;
 }
 
 static void
-MacroBlocksToPipe(struct pipe_screen *screen,
+MacroBlocksToPipe(XvMCSurfacePrivate *surface,
                   unsigned int xvmc_picture_structure,
                   const XvMCMacroBlock *xvmc_mb,
                   const XvMCBlockArray *xvmc_blocks,
@@ -98,62 +152,32 @@ MacroBlocksToPipe(struct pipe_screen *screen,
    assert(num_macroblocks);
 
    for (i = 0; i < num_macroblocks; ++i) {
+      unsigned mv_pos = xvmc_mb->x + surface->mv_stride * xvmc_mb->y;
+      unsigned mv_weights[2];
+
       mb->base.codec = PIPE_VIDEO_CODEC_MPEG12;
       mb->mbx = xvmc_mb->x;
       mb->mby = xvmc_mb->y;
 
-      if (!(xvmc_mb->macroblock_type & XVMC_MB_TYPE_INTRA))
-         mb->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_picture_structure);
-      /* Get rid of Valgrind 'undefined' warnings */
-      else
-         mb->mo_type = -1;
-
       mb->dct_intra = xvmc_mb->macroblock_type & XVMC_MB_TYPE_INTRA;
       mb->dct_type = xvmc_mb->dct_type == XVMC_DCT_TYPE_FIELD ?
          PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
+      mb->cbp = xvmc_mb->coded_block_pattern;
+      mb->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
 
-      switch (xvmc_mb->macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) {
-      case XVMC_MB_TYPE_MOTION_FORWARD:
-         mb->mv[0].top.wheight = mb->mv[0].bottom.wheight = 255;
-         mb->mv[1].top.wheight = mb->mv[1].bottom.wheight = 0;
-         break;
-
-      case (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD):
-         mb->mv[0].top.wheight = mb->mv[0].bottom.wheight = 127;
-         mb->mv[1].top.wheight = mb->mv[1].bottom.wheight = 127;
-         break;
-
-      case XVMC_MB_TYPE_MOTION_BACKWARD:
-         mb->mv[0].top.wheight = mb->mv[0].bottom.wheight = 0;
-         mb->mv[1].top.wheight = mb->mv[1].bottom.wheight = 255;
-         break;
-
-      default:
-         /* workaround for xines xxmc video out plugin */
-         if (!(xvmc_mb->macroblock_type & ~XVMC_MB_TYPE_PATTERN)) {
-            mb->mv[0].top.wheight = mb->mv[0].bottom.wheight = 255;
-            mb->mv[1].top.wheight = mb->mv[1].bottom.wheight = 0;
-         } else {
-            mb->mv[0].top.wheight = mb->mv[0].bottom.wheight = 0;
-            mb->mv[1].top.wheight = mb->mv[1].bottom.wheight = 0;
-         }
-         break;
-      }
+      MacroBlockTypeToPipeWeights(xvmc_mb, mv_weights);
 
       for (j = 0; j < 2; ++j) {
-         mb->mv[j].top.x = xvmc_mb->PMV[0][j][0];
-         mb->mv[j].top.y = xvmc_mb->PMV[0][j][1];
-         mb->mv[j].bottom.x = xvmc_mb->PMV[1][j][0];
-         mb->mv[j].bottom.y = xvmc_mb->PMV[1][j][1];
-      }
+         if (!surface->ref[j].mv) continue;
 
-      mb->mv[0].top.field_select = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD;
-      mb->mv[1].top.field_select = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_BACKWARD;
-      mb->mv[0].bottom.field_select = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD;
-      mb->mv[1].bottom.field_select = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_BACKWARD;
+         surface->ref[j].mv[mv_pos] = MotionVectorToPipe
+         (
+            xvmc_mb, j,
+            j ? XVMC_SELECT_FIRST_BACKWARD : XVMC_SELECT_FIRST_FORWARD,
+            mv_weights[j]
+         );
 
-      mb->cbp = xvmc_mb->coded_block_pattern;
-      mb->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
+      }
 
       ++mb;
       ++xvmc_mb;
@@ -172,13 +196,13 @@ unmap_and_flush_surface(XvMCSurfacePrivate *surface)
    context_priv = surface->context->privData;
 
    for ( i = 0; i < 2; ++i ) {
-      if (surface->ref_surfaces[i]) {
-         XvMCSurfacePrivate *ref = surface->ref_surfaces[i]->privData;
+      if (surface->ref[i].surface) {
+         XvMCSurfacePrivate *ref = surface->ref[i].surface->privData;
 
          assert(ref);
 
          unmap_and_flush_surface(ref);
-         surface->ref_surfaces[i] = NULL;
+         surface->ref[i].surface = NULL;
          ref_frames[i] = ref->video_buffer;
       } else {
          ref_frames[i] = NULL;
@@ -225,6 +249,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
       return BadAlloc;
 
    surface_priv->decode_buffer = context_priv->decoder->create_buffer(context_priv->decoder);
+   surface_priv->mv_stride = surface_priv->decode_buffer->get_mv_stream_stride(surface_priv->decode_buffer);
    surface_priv->video_buffer = vpipe->create_buffer(vpipe, PIPE_FORMAT_YV12, //TODO
                                                      resource_formats,
                                                      context_priv->decoder->chroma_format,
@@ -262,6 +287,8 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    XvMCSurfacePrivate *future_surface_priv;
    XvMCMacroBlock *xvmc_mb;
 
+   unsigned i;
+
    struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p, with past %p and future %p\n",
@@ -319,23 +346,30 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
 
    /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
    if (target_surface_priv->mapped && (
-       target_surface_priv->ref_surfaces[0] != past_surface ||
-       target_surface_priv->ref_surfaces[1] != future_surface ||
+       target_surface_priv->ref[0].surface != past_surface ||
+       target_surface_priv->ref[1].surface != future_surface ||
        (xvmc_mb->x == 0 && xvmc_mb->y == 0))) {
 
       // If they change anyway we need to clear our surface
       unmap_and_flush_surface(target_surface_priv);
    }
 
-   MacroBlocksToPipe(vpipe->screen, picture_structure, xvmc_mb, blocks, num_macroblocks, pipe_macroblocks);
-
    if (!target_surface_priv->mapped) {
       t_buffer->map(t_buffer);
-      target_surface_priv->ref_surfaces[0] = past_surface;
-      target_surface_priv->ref_surfaces[1] = future_surface;
+
+      for (i = 0; i < 2; ++i) {
+         target_surface_priv->ref[i].surface = i == 0 ? past_surface : future_surface;
+
+         if (target_surface_priv->ref[i].surface)
+            target_surface_priv->ref[i].mv = t_buffer->get_mv_stream(t_buffer, i);
+         else
+            target_surface_priv->ref[i].mv = NULL;
+      }
       target_surface_priv->mapped = 1;
    }
 
+   MacroBlocksToPipe(target_surface_priv, picture_structure, xvmc_mb, blocks, num_macroblocks, pipe_macroblocks);
+
    t_buffer->add_macroblocks(t_buffer, num_macroblocks, &pipe_macroblocks->base);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
index 056bdfc2f3c00d8f93ca2b4b379ccecec874cec9..a85d58a519cf811bcf61742af8683ae5676bfd3c 100644 (file)
@@ -71,7 +71,12 @@ typedef struct
 
    bool mapped; // are we still mapped to memory?
 
-   XvMCSurface *ref_surfaces[2];
+   unsigned mv_stride;
+
+   struct {
+      XvMCSurface *surface;
+      struct pipe_motionvector *mv;
+   } ref[2];
 
    struct pipe_fence_handle *flush_fence;
    struct pipe_fence_handle *render_fence;