mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-22 08:48:07 +02:00
[g3dvl] make ycbcr stream and block data a public interface
This commit is contained in:
parent
f0819a22f3
commit
2e6274fc3b
10 changed files with 191 additions and 250 deletions
|
|
@ -38,12 +38,6 @@
|
|||
#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,13 +256,61 @@ 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 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_ycbcr_stream(&buf->vertex_stream, component);
|
||||
}
|
||||
|
||||
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 buf->texels[component];
|
||||
}
|
||||
|
||||
static unsigned
|
||||
|
|
@ -394,41 +334,23 @@ vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_
|
|||
}
|
||||
|
||||
static void
|
||||
vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
|
||||
unsigned num_macroblocks,
|
||||
struct pipe_macroblock *macroblocks)
|
||||
vl_mpeg12_buffer_unmap(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);
|
||||
|
||||
assert(num_macroblocks);
|
||||
assert(macroblocks);
|
||||
assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
|
||||
|
||||
for ( i = 0; i < num_macroblocks; ++i ) {
|
||||
upload_buffer(dec, buf, &mb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -30,14 +30,6 @@
|
|||
#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);
|
||||
assert(component < VL_MAX_PLANES);
|
||||
|
||||
stream = buffer->ycbcr[component].vertex_stream++;
|
||||
stream->x = x;
|
||||
stream->y = y;
|
||||
stream->intra = intra;
|
||||
stream->field = type == PIPE_MPEG12_DCT_TYPE_FIELD;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@
|
|||
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue