summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_decoder.c219
1 files changed, 88 insertions, 131 deletions
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index 3887cf6f1b..4337e08338 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -38,39 +38,42 @@
#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
-static const enum pipe_format const_zscan_source_formats[] = {
- PIPE_FORMAT_R16_SNORM,
- PIPE_FORMAT_R16_SSCALED
-};
+struct format_config {
+ enum pipe_format zscan_source_format;
+ enum pipe_format idct_source_format;
+ enum pipe_format mc_source_format;
-static const unsigned num_zscan_source_formats =
- sizeof(const_zscan_source_formats) / sizeof(enum pipe_format);
+ float idct_scale;
+ float mc_scale;
+};
-static const enum pipe_format const_idct_source_formats[] = {
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SSCALED
+static const struct format_config bitstream_format_config[] = {
+ { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
+ { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
+ { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
+ { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
};
-static const unsigned num_idct_source_formats =
- sizeof(const_idct_source_formats) / sizeof(enum pipe_format);
+static const unsigned num_bitstream_format_configs =
+ sizeof(bitstream_format_config) / sizeof(struct format_config);
-static const enum pipe_format const_idct_intermediate_formats[] = {
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SSCALED,
- PIPE_FORMAT_R32G32B32A32_FLOAT
+static const struct format_config idct_format_config[] = {
+ { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
+ { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
+ { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
+ { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
};
-static const unsigned num_idct_intermediate_formats =
- sizeof(const_idct_intermediate_formats) / sizeof(enum pipe_format);
+static const unsigned num_idct_format_configs =
+ sizeof(idct_format_config) / sizeof(struct format_config);
-static const enum pipe_format const_mc_source_formats[] = {
- PIPE_FORMAT_R16_SNORM,
- PIPE_FORMAT_R16_SSCALED
+static const struct format_config mc_format_config[] = {
+ //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
+ { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM }
};
-static const unsigned num_mc_source_formats =
- sizeof(const_mc_source_formats) / sizeof(enum pipe_format);
+static const unsigned num_mc_format_configs =
+ sizeof(mc_format_config) / sizeof(struct format_config);
static bool
init_zscan_buffer(struct vl_mpeg12_buffer *buffer)
@@ -627,11 +630,8 @@ init_pipe_state(struct vl_mpeg12_decoder *dec)
return true;
}
-static enum pipe_format
-find_first_supported_format(struct vl_mpeg12_decoder *dec,
- const enum pipe_format formats[],
- unsigned num_formats,
- enum pipe_texture_target target)
+static const struct format_config*
+find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs)
{
struct pipe_screen *screen;
unsigned i;
@@ -640,16 +640,32 @@ find_first_supported_format(struct vl_mpeg12_decoder *dec,
screen = dec->pipe->screen;
- for (i = 0; i < num_formats; ++i)
- if (screen->is_format_supported(dec->pipe->screen, formats[i], target, 1,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
- return formats[i];
+ for (i = 0; i < num_configs; ++i) {
+ if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D,
+ 1, PIPE_BIND_SAMPLER_VIEW))
+ continue;
+
+ if (configs[i].idct_source_format != PIPE_FORMAT_NONE) {
+ if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D,
+ 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
+ continue;
+
+ if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D,
+ 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
+ continue;
+ } else {
+ if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D,
+ 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
+ continue;
+ }
+ return &configs[i];
+ }
- return PIPE_FORMAT_NONE;
+ return NULL;
}
static bool
-init_zscan(struct vl_mpeg12_decoder *dec)
+init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
{
unsigned num_channels;
@@ -660,12 +676,7 @@ init_zscan(struct vl_mpeg12_decoder *dec)
(dec->base.width * dec->base.height) /
(BLOCK_WIDTH * BLOCK_HEIGHT);
- dec->zscan_source_format = find_first_supported_format(dec, const_zscan_source_formats,
- num_zscan_source_formats, PIPE_TEXTURE_2D);
-
- if (dec->zscan_source_format == PIPE_FORMAT_NONE)
- return false;
-
+ dec->zscan_source_format = format_config->zscan_source_format;
dec->zscan_linear = vl_zscan_layout(dec->pipe, vl_zscan_linear, dec->blocks_per_line);
dec->zscan_normal = vl_zscan_layout(dec->pipe, vl_zscan_normal, dec->blocks_per_line);
dec->zscan_alternate = vl_zscan_layout(dec->pipe, vl_zscan_alternate, dec->blocks_per_line);
@@ -684,39 +695,19 @@ init_zscan(struct vl_mpeg12_decoder *dec)
}
static bool
-init_idct(struct vl_mpeg12_decoder *dec, float *mc_scale)
+init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
{
unsigned nr_of_idct_render_targets;
enum pipe_format formats[3];
- struct pipe_sampler_view *matrix, *transpose = NULL;
- float matrix_scale, transpose_scale;
+ struct pipe_sampler_view *matrix = NULL;
nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS);
// more than 4 render targets usually doesn't makes any seens
nr_of_idct_render_targets = MIN2(nr_of_idct_render_targets, 4);
- formats[0] = formats[1] = formats[2] = find_first_supported_format(dec, const_idct_source_formats,
- num_idct_source_formats, PIPE_TEXTURE_2D);
-
- switch (formats[0]) {
- case PIPE_FORMAT_NONE:
- goto error_idct_format;
-
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- matrix_scale = SCALE_FACTOR_SSCALED;
- break;
-
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- matrix_scale = SCALE_FACTOR_SNORM;
- break;
-
- default:
- assert(0);
- return false;
- }
-
+ formats[0] = formats[1] = formats[2] = format_config->idct_source_format;
dec->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe,
dec->base.width / 4, dec->base.height, 1,
dec->base.chroma_format,
@@ -724,31 +715,7 @@ init_idct(struct vl_mpeg12_decoder *dec, float *mc_scale)
if (!dec->idct_source)
goto error_idct_source;
- formats[0] = formats[1] = formats[2] = find_first_supported_format(dec, const_idct_intermediate_formats,
- num_idct_intermediate_formats, PIPE_TEXTURE_3D);
-
- switch (formats[0]) {
- case PIPE_FORMAT_NONE:
- goto error_mc_format;
-
- case PIPE_FORMAT_R16G16B16A16_FLOAT:
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- transpose_scale = 1.0f;
- *mc_scale = 1.0f;
- break;
-
- case PIPE_FORMAT_R16_SSCALED:
- transpose_scale = matrix_scale = sqrt(matrix_scale);
- transpose_scale /= SCALE_FACTOR_SSCALED;
- *mc_scale = SCALE_FACTOR_SSCALED;
- break;
-
- default:
- transpose_scale = matrix_scale = sqrt(matrix_scale);
- *mc_scale = 1.0f;
- break;
- }
-
+ formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
dec->base.width / nr_of_idct_render_targets,
dec->base.height / 4, nr_of_idct_render_targets,
@@ -758,25 +725,18 @@ init_idct(struct vl_mpeg12_decoder *dec, float *mc_scale)
if (!dec->mc_source)
goto error_mc_source;
- if (!(matrix = vl_idct_upload_matrix(dec->pipe, matrix_scale)))
+ if (!(matrix = vl_idct_upload_matrix(dec->pipe, format_config->idct_scale)))
goto error_matrix;
- if (matrix_scale != transpose_scale) {
- if (!(transpose = vl_idct_upload_matrix(dec->pipe, transpose_scale)))
- goto error_transpose;
- } else
- pipe_sampler_view_reference(&transpose, matrix);
-
if (!vl_idct_init(&dec->idct_y, dec->pipe, dec->base.width, dec->base.height,
- nr_of_idct_render_targets, matrix, transpose))
+ nr_of_idct_render_targets, matrix, matrix))
goto error_y;
if(!vl_idct_init(&dec->idct_c, dec->pipe, dec->chroma_width, dec->chroma_height,
- nr_of_idct_render_targets, matrix, transpose))
+ nr_of_idct_render_targets, matrix, matrix))
goto error_c;
pipe_sampler_view_reference(&matrix, NULL);
- pipe_sampler_view_reference(&transpose, NULL);
return true;
@@ -784,54 +744,30 @@ error_c:
vl_idct_cleanup(&dec->idct_y);
error_y:
- pipe_sampler_view_reference(&transpose, NULL);
-
-error_transpose:
pipe_sampler_view_reference(&matrix, NULL);
error_matrix:
dec->mc_source->destroy(dec->mc_source);
error_mc_source:
-error_mc_format:
dec->idct_source->destroy(dec->idct_source);
error_idct_source:
-error_idct_format:
return false;
}
static bool
-init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, float *mc_scale)
+init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
{
enum pipe_format formats[3];
- formats[0] = formats[1] = formats[2] = find_first_supported_format(dec, const_mc_source_formats,
- num_mc_source_formats, PIPE_TEXTURE_2D);
-
- switch (formats[0]) {
- case PIPE_FORMAT_NONE:
- return false;
-
- case PIPE_FORMAT_R16_SNORM:
- *mc_scale = SCALE_FACTOR_SNORM;
- break;
-
- case PIPE_FORMAT_R16_SSCALED:
- *mc_scale = SCALE_FACTOR_SSCALED;
- break;
-
- default:
- assert(0);
- return false;
- }
-
+ formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
dec->base.width, dec->base.height, 1,
dec->base.chroma_format,
formats, PIPE_USAGE_STATIC);
- return dec->mc_source;
+ return dec->mc_source != NULL;
}
static void
@@ -885,8 +821,8 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
enum pipe_video_chroma_format chroma_format,
unsigned width, unsigned height)
{
+ const struct format_config *format_config;
struct vl_mpeg12_decoder *dec;
- float mc_scale;
assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
@@ -932,23 +868,44 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
dec->chroma_height = dec->base.height;
}
- if (!init_zscan(dec))
+ switch (entrypoint) {
+ case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
+ format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs);
+ break;
+
+ case PIPE_VIDEO_ENTRYPOINT_IDCT:
+ format_config = find_format_config(dec, idct_format_config, num_idct_format_configs);
+ break;
+
+ case PIPE_VIDEO_ENTRYPOINT_MC:
+ format_config = find_format_config(dec, mc_format_config, num_mc_format_configs);
+ break;
+
+ default:
+ assert(0);
+ return NULL;
+ }
+
+ if (!format_config)
+ return NULL;
+
+ if (!init_zscan(dec, format_config))
goto error_zscan;
if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
- if (!init_idct(dec, &mc_scale))
+ if (!init_idct(dec, format_config))
goto error_sources;
} else {
- if (!init_mc_source_widthout_idct(dec, &mc_scale))
+ if (!init_mc_source_widthout_idct(dec, format_config))
goto error_sources;
}
- if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, mc_scale,
+ if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, format_config->mc_scale,
mc_vert_shader_callback, mc_frag_shader_callback, dec))
goto error_mc_y;
// TODO
- if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, mc_scale,
+ if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, format_config->mc_scale,
mc_vert_shader_callback, mc_frag_shader_callback, dec))
goto error_mc_c;