[PATCH 6/6] g3dvl: Rework the decoder interface part 6/6

Christian König deathsimple at vodafone.de
Fri Aug 12 05:16:55 PDT 2011


Let decode_macroblock handle more than one block at a time.
---
 src/gallium/auxiliary/vl/vl_mpeg12_decoder.c   |   36 ++++++++++++++---------
 src/gallium/include/pipe/p_video_decoder.h     |    3 +-
 src/gallium/state_trackers/xorg/xvmc/surface.c |   37 +++++++++++++-----------
 3 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index 709939f..b5b3c10 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -624,34 +624,42 @@ vl_mpeg12_begin_frame(struct pipe_video_decoder *decoder)
 
 static void
 vl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder,
-                            const struct pipe_macroblock *macroblock)
+                            const struct pipe_macroblock *macroblocks,
+                            unsigned num_macroblocks)
 {
    struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
-   const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblock;
+   const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks;
    struct vl_mpeg12_buffer *buf;
 
    unsigned i, mv_weights[2];
 
    assert(dec && dec->current_buffer);
-   assert(macroblock && macroblock->codec == PIPE_VIDEO_CODEC_MPEG12);
+   assert(macroblocks && macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
 
    buf = dec->current_buffer;
    assert(buf);
 
-   if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_PATTERN | PIPE_MPEG12_MB_TYPE_MOTION_INTRA))
-      UploadYcbcrBlocks(dec, buf, mb);
+   for (; num_macroblocks > 0; --num_macroblocks) {
+      if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_PATTERN | PIPE_MPEG12_MB_TYPE_MOTION_INTRA))
+         UploadYcbcrBlocks(dec, buf, mb);
 
-   MacroBlockTypeToPipeWeights(mb, mv_weights);
+      MacroBlockTypeToPipeWeights(mb, mv_weights);
 
-   for (i = 0; i < 2; ++i) {
-      if (!dec->ref_frames[i][0]) continue;
+      for (i = 0; i < 2; ++i) {
+          if (!dec->ref_frames[i][0]) continue;
 
-      buf->mv_stream[i][mb->macroblock_address] = MotionVectorToPipe
-      (
-         mb, i,
-         i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD,
-         mv_weights[i]
-      );
+         buf->mv_stream[i][mb->macroblock_address] = MotionVectorToPipe
+         (
+            mb, i,
+            i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD,
+            mv_weights[i]
+         );
+      }
+
+      // TODO: Handle skipped macroblocks correctly
+      assert(mb->num_skipped_macroblocks == 0);
+
+      ++mb;
    }
 }
 
diff --git a/src/gallium/include/pipe/p_video_decoder.h b/src/gallium/include/pipe/p_video_decoder.h
index 06b6803..2aa4001 100644
--- a/src/gallium/include/pipe/p_video_decoder.h
+++ b/src/gallium/include/pipe/p_video_decoder.h
@@ -108,7 +108,8 @@ struct pipe_video_decoder
     * decode a macroblock
     */
    void (*decode_macroblock)(struct pipe_video_decoder *decoder,
-                             const struct pipe_macroblock *macroblock);
+                             const struct pipe_macroblock *macroblocks,
+                             unsigned num_macroblocks);
 
    /**
     * decode a bitstream
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 9743893..8158cba 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -48,51 +48,50 @@ MacroBlocksToPipe(XvMCContextPrivate *context,
                   unsigned int xvmc_picture_structure,
                   const XvMCMacroBlock *xvmc_mb,
                   const XvMCBlockArray *xvmc_blocks,
+                  struct pipe_mpeg12_macroblock *mb,
                   unsigned int num_macroblocks)
 {
-   struct pipe_mpeg12_macroblock mb;
    unsigned int i, j, k;
 
    assert(xvmc_mb);
    assert(xvmc_blocks);
    assert(num_macroblocks);
 
-   mb.base.codec = PIPE_VIDEO_CODEC_MPEG12;
    for (; num_macroblocks > 0; --num_macroblocks) {
-      mb.macroblock_address = xvmc_mb->x + context->width_in_macroblocks * xvmc_mb->y;
-      mb.macroblock_type = xvmc_mb->macroblock_type;
+      mb->base.codec = PIPE_VIDEO_CODEC_MPEG12;
+      mb->macroblock_address = xvmc_mb->x + context->width_in_macroblocks * xvmc_mb->y;
+      mb->macroblock_type = xvmc_mb->macroblock_type;
 
       switch (xvmc_picture_structure) {
       case XVMC_FRAME_PICTURE:
-         mb.macroblock_modes.bits.frame_motion_type = xvmc_mb->motion_type;
-         mb.macroblock_modes.bits.field_motion_type = 0;
+         mb->macroblock_modes.bits.frame_motion_type = xvmc_mb->motion_type;
+         mb->macroblock_modes.bits.field_motion_type = 0;
          break;
 
       case XVMC_TOP_FIELD:
       case XVMC_BOTTOM_FIELD:
-         mb.macroblock_modes.bits.frame_motion_type = 0;
-         mb.macroblock_modes.bits.field_motion_type = xvmc_mb->motion_type;
+         mb->macroblock_modes.bits.frame_motion_type = 0;
+         mb->macroblock_modes.bits.field_motion_type = xvmc_mb->motion_type;
          break;
 
       default:
          assert(0);
       }
 
-      mb.macroblock_modes.bits.dct_type = xvmc_mb->dct_type;
-      mb.motion_vertical_field_select = xvmc_mb->motion_vertical_field_select;
+      mb->macroblock_modes.bits.dct_type = xvmc_mb->dct_type;
+      mb->motion_vertical_field_select = xvmc_mb->motion_vertical_field_select;
 
       for (i = 0; i < 2; ++i)
          for (j = 0; j < 2; ++j)
             for (k = 0; k < 2; ++k)
-               mb.PMV[i][j][k] = xvmc_mb->PMV[i][j][k];
+               mb->PMV[i][j][k] = xvmc_mb->PMV[i][j][k];
 
-      mb.coded_block_pattern = xvmc_mb->coded_block_pattern;
-      mb.blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
-      mb.num_skipped_macroblocks = 0;
-
-      context->decoder->decode_macroblock(context->decoder, &mb.base);
+      mb->coded_block_pattern = xvmc_mb->coded_block_pattern;
+      mb->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
+      mb->num_skipped_macroblocks = 0;
 
       ++xvmc_mb;
+      ++mb;
    }
 }
 
@@ -211,6 +210,7 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
                          XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
 )
 {
+   struct pipe_mpeg12_macroblock mb[num_macroblocks];
    struct pipe_video_decoder *decoder;
 
    XvMCContextPrivate *context_priv;
@@ -289,7 +289,10 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
       decoder->begin_frame(decoder);
    }
 
-   MacroBlocksToPipe(context_priv, target_surface_priv, picture_structure, xvmc_mb, blocks, num_macroblocks);
+   MacroBlocksToPipe(context_priv, target_surface_priv, picture_structure,
+                     xvmc_mb, blocks, mb, num_macroblocks);
+
+   context_priv->decoder->decode_macroblock(context_priv->decoder, &mb[0].base, num_macroblocks);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 
-- 
1.7.4.1


--=-E2LaaR1qGLHh7xkpYB8v--



More information about the mesa-dev mailing list