[g3dvl] make ycbcr stream and block data a public interface
authorChristian König <deathsimple@vodafone.de>
Sat, 23 Apr 2011 11:24:35 +0000 (13:24 +0200)
committerChristian König <deathsimple@vodafone.de>
Sat, 23 Apr 2011 11:24:35 +0000 (13:24 +0200)
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
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/vdpau/mpeg2_bitstream_parser.c
src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h
src/gallium/state_trackers/xorg/xvmc/surface.c
src/gallium/state_trackers/xorg/xvmc/xvmc_private.h

index 3b1d26d3db8a2c1b1f56cf4d2b6e6c655d42cfc5..dcef6207afd34730e4c823fbaf2207698c4e3f7a 100644 (file)
 #define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
 #define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
 
-static const unsigned const_empty_block_mask_420[3][2][2] = {
-   { { 0x20, 0x10 },  { 0x08, 0x04 } },
-   { { 0x02, 0x02 },  { 0x02, 0x02 } },
-   { { 0x01, 0x01 },  { 0x01, 0x01 } }
-};
-
 static const enum pipe_format const_zscan_source_formats[] = {
    PIPE_FORMAT_R16_SNORM,
    PIPE_FORMAT_R16_SSCALED
@@ -78,108 +72,6 @@ static const enum pipe_format const_mc_source_formats[] = {
 static const unsigned num_mc_source_formats =
    sizeof(const_mc_source_formats) / sizeof(enum pipe_format);
 
-static void
-map_buffers(struct vl_mpeg12_decoder *ctx, struct vl_mpeg12_buffer *buffer)
-{
-   struct pipe_sampler_view **sampler_views;
-   struct pipe_resource *tex;
-   unsigned i;
-
-   assert(ctx && buffer);
-
-   sampler_views = buffer->zscan_source->get_sampler_views(buffer->zscan_source);
-
-   assert(sampler_views);
-
-   for (i = 0; i < VL_MAX_PLANES; ++i) {
-      tex = sampler_views[i]->texture;
-
-      struct pipe_box rect =
-      {
-         0, 0, 0,
-         tex->width0,
-         tex->height0,
-         1
-      };
-
-      buffer->tex_transfer[i] = ctx->pipe->get_transfer
-      (
-         ctx->pipe, tex,
-         0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
-         &rect
-      );
-
-      buffer->texels[i] = ctx->pipe->transfer_map(ctx->pipe, buffer->tex_transfer[i]);
-   }
-}
-
-static void
-upload_block(struct vl_mpeg12_buffer *buffer, unsigned plane,
-             unsigned x, unsigned y, short *block,
-             bool intra, enum pipe_mpeg12_dct_type type)
-{
-   short *texels;
-   unsigned idx;
-
-   assert(buffer);
-   assert(block);
-
-   idx = vl_vb_add_ycbcr(&buffer->vertex_stream, plane, x, y, intra, type);
-
-   texels = buffer->texels[plane] + idx * BLOCK_WIDTH * BLOCK_HEIGHT;
-
-   memcpy(texels, block, BLOCK_WIDTH * BLOCK_HEIGHT * sizeof(short));
-}
-
-static void
-upload_buffer(struct vl_mpeg12_decoder *ctx,
-              struct vl_mpeg12_buffer *buffer,
-              struct pipe_mpeg12_macroblock *mb)
-{
-   short *blocks;
-   unsigned tb, x, y;
-
-   assert(ctx);
-   assert(buffer);
-   assert(mb);
-
-   blocks = mb->blocks;
-
-   for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x, ++tb) {
-         if (mb->cbp & (*ctx->empty_block_mask)[0][y][x]) {
-            upload_block(buffer, 0, mb->mbx * 2 + x, mb->mby * 2 + y, blocks,
-                         mb->dct_intra, mb->dct_type);
-            blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
-         }
-      }
-   }
-
-   /* TODO: Implement 422, 444 */
-   assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
-
-   for (tb = 1; tb < 3; ++tb) {
-      if (mb->cbp & (*ctx->empty_block_mask)[tb][0][0]) {
-         upload_block(buffer, tb, mb->mbx, mb->mby, blocks,
-                      mb->dct_intra, mb->dct_type);
-         blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
-      }
-   }
-}
-
-static void
-unmap_buffers(struct vl_mpeg12_decoder *ctx, struct vl_mpeg12_buffer *buffer)
-{
-   unsigned i;
-
-   assert(ctx && buffer);
-
-   for (i = 0; i < VL_MAX_PLANES; ++i) {
-      ctx->pipe->transfer_unmap(ctx->pipe, buffer->tex_transfer[i]);
-      ctx->pipe->transfer_destroy(ctx->pipe, buffer->tex_transfer[i]);
-   }
-}
-
 static bool
 init_zscan_buffer(struct vl_mpeg12_buffer *buffer)
 {
@@ -364,57 +256,81 @@ vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
    struct vl_mpeg12_decoder *dec;
+
+   struct pipe_sampler_view **sampler_views;
+   unsigned i;
+
    assert(buf);
 
    dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
    assert(dec);
 
    vl_vb_map(&buf->vertex_stream, dec->pipe);
-   map_buffers(dec, buf);
+
+   sampler_views = buf->zscan_source->get_sampler_views(buf->zscan_source);
+
+   assert(sampler_views);
+
+   for (i = 0; i < VL_MAX_PLANES; ++i) {
+      struct pipe_resource *tex = sampler_views[i]->texture;
+      struct pipe_box rect =
+      {
+         0, 0, 0,
+         tex->width0,
+         tex->height0,
+         1
+      };
+
+      buf->tex_transfer[i] = dec->pipe->get_transfer
+      (
+         dec->pipe, tex,
+         0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+         &rect
+      );
+
+      buf->texels[i] = dec->pipe->transfer_map(dec->pipe, buf->tex_transfer[i]);
+   }
 }
 
-static unsigned
-vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer)
+static struct pipe_ycbcr_block *
+vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
 
    assert(buf);
 
-   return vl_vb_get_mv_stream_stride(&buf->vertex_stream);
+   return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component);
 }
 
-static struct pipe_motionvector *
-vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame)
+static short *
+vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
 
    assert(buf);
+   assert(component < VL_MAX_PLANES);
 
-   return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame);
+   return buf->texels[component];
 }
 
-static void
-vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
-                                 unsigned num_macroblocks,
-                                 struct pipe_macroblock *macroblocks)
+static unsigned
+vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer)
 {
-   struct pipe_mpeg12_macroblock *mb = (struct pipe_mpeg12_macroblock*)macroblocks;
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
-   struct vl_mpeg12_decoder *dec;
-   unsigned i;
 
    assert(buf);
 
-   dec =  (struct vl_mpeg12_decoder*)buf->base.decoder;
-   assert(dec);
+   return vl_vb_get_mv_stream_stride(&buf->vertex_stream);
+}
 
-   assert(num_macroblocks);
-   assert(macroblocks);
-   assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
+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;
 
-   for ( i = 0; i < num_macroblocks; ++i ) {
-      upload_buffer(dec, buf, &mb[i]);
-   }
+   assert(buf);
+
+   return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame);
 }
 
 static void
@@ -422,13 +338,19 @@ vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
    struct vl_mpeg12_decoder *dec;
+   unsigned i;
+
    assert(buf);
 
    dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
    assert(dec);
 
    vl_vb_unmap(&buf->vertex_stream, dec->pipe);
-   unmap_buffers(dec, buf);
+
+   for (i = 0; i < VL_MAX_PLANES; ++i) {
+      dec->pipe->transfer_unmap(dec->pipe, buf->tex_transfer[i]);
+      dec->pipe->transfer_destroy(dec->pipe, buf->tex_transfer[i]);
+   }
 }
 
 static void
@@ -483,9 +405,10 @@ 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_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream;
+   buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer;
    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;
 
    vl_vb_init(&buffer->vertex_stream, dec->pipe,
@@ -550,6 +473,7 @@ error_vertex_stream:
 
 static void
 vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
+                               unsigned num_ycbcr_blocks[3],
                                struct pipe_video_buffer *refs[2],
                                struct pipe_video_buffer *dst,
                                struct pipe_fence_handle **fence)
@@ -593,34 +517,22 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
 
    dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
    for (i = 0; i < VL_MAX_PLANES; ++i) {
-      unsigned num_instances = vl_vb_restart(&buf->vertex_stream, i);
+      if (num_ycbcr_blocks[i] == 0) continue;
 
       vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
       dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
 
-      vl_zscan_render(&buf->zscan[i] , num_instances);
+      vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]);
 
       if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
-         vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_instances);
+         vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]);
 
-      vl_mc_render_ycbcr(&buf->mc[i], num_instances);
+      vl_mc_render_ycbcr(&buf->mc[i], num_ycbcr_blocks[i]);
    }
 
    dec->pipe->flush(dec->pipe, fence);
 }
 
-static void
-vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer *buffer)
-{
-   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
-   unsigned i;
-
-   assert(buf);
-
-   for (i = 0; i < VL_MAX_PLANES; ++i)
-      vl_vb_restart(&buf->vertex_stream, i);
-}
-
 static bool
 init_pipe_state(struct vl_mpeg12_decoder *dec)
 {
@@ -819,7 +731,6 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
    dec->base.destroy = vl_mpeg12_destroy;
    dec->base.create_buffer = vl_mpeg12_create_buffer;
    dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer;
-   dec->base.clear_buffer = vl_mpeg12_decoder_clear_buffer;
 
    dec->base.width = align(width, MACROBLOCK_WIDTH);
    dec->base.height = align(height, MACROBLOCK_HEIGHT);
@@ -838,7 +749,6 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
 
    /* TODO: Implement 422, 444 */
    assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
-   dec->empty_block_mask = &const_empty_block_mask_420;
 
    dec->mc_source_format = find_first_supported_format(dec, const_mc_source_formats,
                                                        num_mc_source_formats, PIPE_TEXTURE_3D);
index b94f12a9b7a850668508ec526f70ce14a86fdcf6..9d5768816fb77c8a58d7caa703e4b5dc63acfa69 100644 (file)
@@ -49,8 +49,6 @@ struct vl_mpeg12_decoder
 
    unsigned blocks_per_line;
    unsigned max_blocks;
-
-   const unsigned (*empty_block_mask)[3][2][2];
    unsigned nr_of_idct_render_targets;
 
    enum pipe_format zscan_source_format;
index d2025f76b86160011bfd0ebff364e4fa90836135..d2e03988acfbe7c1754847f74ebc7b53b3ff7a18 100644 (file)
 #include "vl_vertex_buffers.h"
 #include "vl_types.h"
 
-struct vl_ycbcr_vertex_stream
-{
-   uint8_t x;
-   uint8_t y;
-   uint8_t intra;
-   uint8_t field;
-};
-
 /* 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}
@@ -221,13 +213,12 @@ vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe,
    size = width * height;
 
    for (i = 0; i < VL_MAX_PLANES; ++i) {
-      buffer->ycbcr[i].num_instances = 0;
       buffer->ycbcr[i].resource = pipe_buffer_create
       (
          pipe->screen,
          PIPE_BIND_VERTEX_BUFFER,
          PIPE_USAGE_STREAM,
-         sizeof(struct vl_ycbcr_vertex_stream) * size * 4
+         sizeof(struct pipe_ycbcr_block) * size * 4
       );
    }
 
@@ -251,7 +242,7 @@ vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component)
 
    assert(buffer);
 
-   buf.stride = sizeof(struct vl_ycbcr_vertex_stream);
+   buf.stride = sizeof(struct pipe_ycbcr_block);
    buf.buffer_offset = 0;
    buf.buffer = buffer->ycbcr[component].resource;
 
@@ -301,23 +292,13 @@ vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
 
 }
 
-unsigned
-vl_vb_add_ycbcr(struct vl_vertex_buffer *buffer,
-                unsigned component, unsigned x, unsigned y,
-                bool intra, enum pipe_mpeg12_dct_type type)
+struct pipe_ycbcr_block *
+vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component)
 {
-   struct vl_ycbcr_vertex_stream *stream;
-
    assert(buffer);
-   assert(buffer->ycbcr[component].num_instances < buffer->width * buffer->height * 4);
-
-   stream = buffer->ycbcr[component].vertex_stream++;
-   stream->x = x;
-   stream->y = y;
-   stream->intra = intra;
-   stream->field = type == PIPE_MPEG12_DCT_TYPE_FIELD;
+   assert(component < VL_MAX_PLANES);
 
-   return buffer->ycbcr[component].num_instances++;
+   return buffer->ycbcr[component].vertex_stream;
 }
 
 unsigned
@@ -353,18 +334,6 @@ vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
    }
 }
 
-unsigned
-vl_vb_restart(struct vl_vertex_buffer *buffer, int component)
-{
-   unsigned num_instances;
-
-   assert(buffer);
-
-   num_instances = buffer->ycbcr[component].num_instances;
-   buffer->ycbcr[component].num_instances = 0;
-   return num_instances;
-}
-
 void
 vl_vb_cleanup(struct vl_vertex_buffer *buffer)
 {
index 89d455225ad2fe744ee4e5ad6821b32f005003f3..5293820ffcaa506df65201dad6bce8f454b2601d 100644 (file)
@@ -55,10 +55,9 @@ struct vl_vertex_buffer
    unsigned width, height;
 
    struct {
-      unsigned                      num_instances;
-      struct pipe_resource          *resource;
-      struct pipe_transfer          *transfer;
-      struct vl_ycbcr_vertex_stream *vertex_stream;
+      struct pipe_resource    *resource;
+      struct pipe_transfer    *transfer;
+      struct pipe_ycbcr_block *vertex_stream;
    } ycbcr[VL_MAX_PLANES];
 
    struct {
@@ -84,9 +83,7 @@ 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);
 
-unsigned vl_vb_add_ycbcr(struct vl_vertex_buffer *buffer,
-                         unsigned component, unsigned x, unsigned y,
-                         bool intra, enum pipe_mpeg12_dct_type type);
+struct pipe_ycbcr_block *vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component);
 
 struct pipe_vertex_buffer vl_vb_get_mv(struct vl_vertex_buffer *buffer, int ref_frame);
 
@@ -96,8 +93,6 @@ struct pipe_motionvector *vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, i
 
 void vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
 
-unsigned vl_vb_restart(struct vl_vertex_buffer *buffer, int component);
-
 void vl_vb_cleanup(struct vl_vertex_buffer *buffer);
 
 #endif /* vl_vertex_buffers_h */
index 1eb96420fb7402be95ae56ba7042ce7e45917019..8775bbb27056903c4b2121c6ad79f36d3436a6cd 100644 (file)
@@ -158,15 +158,10 @@ struct pipe_video_decoder
     * flush decoder buffer to video hardware
     */
    void (*flush_buffer)(struct pipe_video_decode_buffer *decbuf,
+                        unsigned num_ycbcr_blocks[3],
                         struct pipe_video_buffer *ref_frames[2],
                         struct pipe_video_buffer *dst,
                         struct pipe_fence_handle **fence);
-
-   /**
-    * clear decoder buffers todo list
-    */
-   void (*clear_buffer)(struct pipe_video_decode_buffer *decbuf);
-
 };
 
 /**
@@ -186,6 +181,16 @@ struct pipe_video_decode_buffer
     */
    void (*map)(struct pipe_video_decode_buffer *decbuf);
 
+   /**
+    * get the pointer where to put the ycbcr blocks of a component
+    */
+   struct pipe_ycbcr_block *(*get_ycbcr_stream)(struct pipe_video_decode_buffer *, int component);
+
+   /**
+    * get the pointer where to put the ycbcr dct block data of a component
+    */
+   short *(*get_ycbcr_buffer)(struct pipe_video_decode_buffer *, int component);
+
    /**
     * get the stride of the mv buffer
     */
@@ -205,13 +210,6 @@ struct pipe_video_decode_buffer
                             struct pipe_buffer **bitstream_buf);
 #endif
 
-   /**
-    * add macroblocks to decoder buffer
-    */
-   void (*add_macroblocks)(struct pipe_video_decode_buffer *decbuf,
-                           unsigned num_macroblocks,
-                           struct pipe_macroblock *macroblocks);
-
    /**
     * unmap decoder buffer before flushing
     */
index dcb64d3c220406be0fb088f7ac5028c98de5d2c7..8bd84c2846ab8a6470dc9638809a51487439891e 100644 (file)
@@ -50,10 +50,16 @@ enum pipe_mpeg12_picture_type
    PIPE_MPEG12_PICTURE_TYPE_FRAME
 };
 
+enum pipe_mpeg12_dct_intra
+{
+   PIPE_MPEG12_DCT_DELTA = 0,
+   PIPE_MPEG12_DCT_INTRA = 1
+};
+
 enum pipe_mpeg12_dct_type
 {
-   PIPE_MPEG12_DCT_TYPE_FIELD,
-   PIPE_MPEG12_DCT_TYPE_FRAME
+   PIPE_MPEG12_DCT_TYPE_FRAME = 0,
+   PIPE_MPEG12_DCT_TYPE_FIELD = 1
 };
 
 enum pipe_video_field_select
@@ -75,11 +81,6 @@ enum pipe_video_mv_weight
    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
 {
@@ -90,16 +91,12 @@ struct pipe_motionvector
    } top, bottom;
 };
 
-struct pipe_mpeg12_macroblock
+/* bitfields because this is used as a vertex buffer element */
+struct pipe_ycbcr_block
 {
-   struct pipe_macroblock base;
-
-   unsigned mbx;
-   unsigned mby;
-   bool dct_intra;
-   enum pipe_mpeg12_dct_type dct_type;
-   unsigned cbp;
-   short *blocks;
+   unsigned x:8, y:8;
+   enum pipe_mpeg12_dct_intra intra:8;
+   enum pipe_mpeg12_dct_type coding:8;
 };
 
 #if 0
index 7b285079a1932d5610595f700b7e54d0a6564515..182f3d44c45f967b43494ec431218075ee1d52e4 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include "mpeg2_bitstream_parser.h"
 
+#if 0
 int
 vlVdpMPEG2NextStartCode(struct vdpMPEG2BitstreamParser *parser)
 {
@@ -130,3 +131,4 @@ vlVdpMPEG2BitstreamToMacroblock(struct pipe_screen *screen,
    return 0;
 }
 
+#endif
index 1fa425fdcdba7ba80719c6191c1be47e63072dce..2f8a14996c5533a44ad216b6085d603d41e15da2 100644 (file)
@@ -53,11 +53,13 @@ struct vdpMPEG2BitstreamParser
    uint32_t horizontal_size_value;
 };
 
+#if 0
 int
 vlVdpMPEG2BitstreamToMacroblock(struct pipe_screen *screen,
                                 VdpBitstreamBuffer const *bitstream_buffers,
                                 uint32_t bitstream_buffer_count,
                                 unsigned int *num_macroblocks,
                                 struct pipe_mpeg12_macroblock **pipe_macroblocks);
+#endif
 
 #endif // MPEG2_BITSTREAM_PARSER_H
index 567484e993db8d99b5c88c81153669f2fa0b83eb..f8a0f3c7fd9dc5e5cf26415f5b64eafacb41b611 100644 (file)
 
 #include "xvmc_private.h"
 
+static const unsigned const_empty_block_mask_420[3][2][2] = {
+   { { 0x20, 0x10 },  { 0x08, 0x04 } },
+   { { 0x02, 0x02 },  { 0x02, 0x02 } },
+   { { 0x01, 0x01 },  { 0x01, 0x01 } }
+};
+
 static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
 {
    switch (xvmc_pic) {
@@ -136,34 +142,89 @@ MotionVectorToPipe(const XvMCMacroBlock *xvmc_mb, unsigned vector,
    return mv;
 }
 
+static inline void
+UploadYcbcrBlocks(XvMCSurfacePrivate *surface,
+                  const XvMCMacroBlock *xvmc_mb,
+                  const XvMCBlockArray *xvmc_blocks)
+{
+   enum pipe_mpeg12_dct_intra intra;
+   enum pipe_mpeg12_dct_type coding;
+
+   unsigned tb, x, y;
+   short *blocks;
+
+   assert(surface);
+   assert(xvmc_mb);
+
+   intra = xvmc_mb->macroblock_type & XVMC_MB_TYPE_INTRA ?
+           PIPE_MPEG12_DCT_INTRA : PIPE_MPEG12_DCT_DELTA;
+
+   coding = xvmc_mb->dct_type == XVMC_DCT_TYPE_FIELD ?
+            PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
+
+   blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
+
+   for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x, ++tb) {
+         if (xvmc_mb->coded_block_pattern & const_empty_block_mask_420[0][y][x]) {
+
+            struct pipe_ycbcr_block *stream = surface->ycbcr[0].stream;
+            stream->x = xvmc_mb->x * 2 + x;
+            stream->y = xvmc_mb->y * 2 + y;
+            stream->intra = intra;
+            stream->coding = coding;
+
+            memcpy(surface->ycbcr[0].buffer, blocks, BLOCK_SIZE_BYTES);
+
+            surface->ycbcr[0].num_blocks_added++;
+            surface->ycbcr[0].stream++;
+            surface->ycbcr[0].buffer += BLOCK_SIZE_SAMPLES;
+            blocks += BLOCK_SIZE_SAMPLES;
+         }
+      }
+   }
+
+   /* TODO: Implement 422, 444 */
+   //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
+
+   for (tb = 1; tb < 3; ++tb) {
+      if (xvmc_mb->coded_block_pattern & const_empty_block_mask_420[tb][0][0]) {
+
+         struct pipe_ycbcr_block *stream = surface->ycbcr[tb].stream;
+         stream->x = xvmc_mb->x;
+         stream->y = xvmc_mb->y;
+         stream->intra = intra;
+         stream->coding = PIPE_MPEG12_DCT_TYPE_FRAME;
+
+         memcpy(surface->ycbcr[tb].buffer, blocks, BLOCK_SIZE_BYTES);
+
+         surface->ycbcr[tb].num_blocks_added++;
+         surface->ycbcr[tb].stream++;
+         surface->ycbcr[tb].buffer += BLOCK_SIZE_SAMPLES;
+         blocks += BLOCK_SIZE_SAMPLES;
+      }
+   }
+
+}
+
 static void
 MacroBlocksToPipe(XvMCSurfacePrivate *surface,
                   unsigned int xvmc_picture_structure,
                   const XvMCMacroBlock *xvmc_mb,
                   const XvMCBlockArray *xvmc_blocks,
-                  unsigned int num_macroblocks,
-                  struct pipe_mpeg12_macroblock *mb)
+                  unsigned int num_macroblocks)
 {
    unsigned int i, j;
 
    assert(xvmc_mb);
    assert(xvmc_blocks);
-   assert(mb);
    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;
-
-      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;
+      UploadYcbcrBlocks(surface, xvmc_mb, xvmc_blocks);
 
       MacroBlockTypeToPipeWeights(xvmc_mb, mv_weights);
 
@@ -176,10 +237,8 @@ MacroBlocksToPipe(XvMCSurfacePrivate *surface,
             j ? XVMC_SELECT_FIRST_BACKWARD : XVMC_SELECT_FIRST_FORWARD,
             mv_weights[j]
          );
-
       }
 
-      ++mb;
       ++xvmc_mb;
    }
 }
@@ -189,7 +248,7 @@ unmap_and_flush_surface(XvMCSurfacePrivate *surface)
 {
    struct pipe_video_buffer *ref_frames[2];
    XvMCContextPrivate *context_priv;
-   unsigned i;
+   unsigned i, num_ycbcr_blocks[3];
 
    assert(surface);
 
@@ -211,7 +270,10 @@ unmap_and_flush_surface(XvMCSurfacePrivate *surface)
 
    if (surface->mapped) {
       surface->decode_buffer->unmap(surface->decode_buffer);
+      for (i = 0; i < 3; ++i)
+         num_ycbcr_blocks[i] = surface->ycbcr[i].num_blocks_added;
       context_priv->decoder->flush_buffer(surface->decode_buffer,
+                                          num_ycbcr_blocks,
                                           ref_frames,
                                           surface->video_buffer,
                                           &surface->flush_fence);
@@ -289,8 +351,6 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
 
    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",
             target_surface, past_surface, future_surface);
 
@@ -357,6 +417,12 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    if (!target_surface_priv->mapped) {
       t_buffer->map(t_buffer);
 
+      for (i = 0; i < 3; ++i) {
+         target_surface_priv->ycbcr[i].num_blocks_added = 0;
+         target_surface_priv->ycbcr[i].stream = t_buffer->get_ycbcr_stream(t_buffer, i);
+         target_surface_priv->ycbcr[i].buffer = t_buffer->get_ycbcr_buffer(t_buffer, i);
+      }
+
       for (i = 0; i < 2; ++i) {
          target_surface_priv->ref[i].surface = i == 0 ? past_surface : future_surface;
 
@@ -365,12 +431,11 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
          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);
+   MacroBlocksToPipe(target_surface_priv, picture_structure, xvmc_mb, blocks, num_macroblocks);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 
index a85d58a519cf811bcf61742af8683ae5676bfd3c..bdcda3bb56fe3a14eccbec469fbfab03753f4475 100644 (file)
@@ -71,8 +71,13 @@ typedef struct
 
    bool mapped; // are we still mapped to memory?
 
-   unsigned mv_stride;
+   struct {
+      unsigned num_blocks_added;
+      struct pipe_ycbcr_block *stream;
+      short *buffer;
+   } ycbcr[3];
 
+   unsigned mv_stride;
    struct {
       XvMCSurface *surface;
       struct pipe_motionvector *mv;