vl_mpeg12_decoder.c revision 8ea416f35de0c664ef47b71841756758f22d7faa
125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/**************************************************************************
225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *
325b3c049e70834cf33790a28643ab058b507b35cBen Cheng * Copyright 2009 Younes Manton.
425b3c049e70834cf33790a28643ab058b507b35cBen Cheng * All Rights Reserved.
525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *
625b3c049e70834cf33790a28643ab058b507b35cBen Cheng * Permission is hereby granted, free of charge, to any person obtaining a
725b3c049e70834cf33790a28643ab058b507b35cBen Cheng * copy of this software and associated documentation files (the
825b3c049e70834cf33790a28643ab058b507b35cBen Cheng * "Software"), to deal in the Software without restriction, including
925b3c049e70834cf33790a28643ab058b507b35cBen Cheng * without limitation the rights to use, copy, modify, merge, publish,
1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng * distribute, sub license, and/or sell copies of the Software, and to
1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng * permit persons to whom the Software is furnished to do so, subject to
1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng * the following conditions:
1325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *
1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng * The above copyright notice and this permission notice (including the
1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng * next paragraph) shall be included in all copies or substantial portions
1625b3c049e70834cf33790a28643ab058b507b35cBen Cheng * of the Software.
1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *
1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *
2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng **************************************************************************/
2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <math.h>
2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h>
3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "util/u_memory.h"
3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "util/u_rect.h"
3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "util/u_sampler.h"
3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "util/u_video.h"
3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "vl_mpeg12_decoder.h"
3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "vl_defines.h"
3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4225b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct format_config {
4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   enum pipe_format zscan_source_format;
4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   enum pipe_format idct_source_format;
4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   enum pipe_format mc_source_format;
4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   float idct_scale;
4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   float mc_scale;
4925b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct format_config bitstream_format_config[] = {
5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned num_bitstream_format_configs =
5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sizeof(bitstream_format_config) / sizeof(struct format_config);
6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
6125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct format_config idct_format_config[] = {
6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng//   { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
6425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM },
6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM }
6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
6825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned num_idct_format_configs =
6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sizeof(idct_format_config) / sizeof(struct format_config);
7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct format_config mc_format_config[] = {
7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM }
7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned num_mc_format_configs =
7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sizeof(mc_format_config) / sizeof(struct format_config);
7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned const_empty_block_mask_420[3][2][2] = {
8025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { { 0x20, 0x10 },  { 0x08, 0x04 } },
8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { { 0x02, 0x02 },  { 0x02, 0x02 } },
8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   { { 0x01, 0x01 },  { 0x01, 0x01 } }
8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
8525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
8625b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_zscan_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer)
8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_resource *res, res_tmpl;
8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_view sv_tmpl;
9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_surface **destination;
9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && buffer);
9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&res_tmpl, 0, sizeof(res_tmpl));
9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.target = PIPE_TEXTURE_2D;
9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.format = dec->zscan_source_format;
9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.width0 = dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT;
10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.height0 = align(dec->num_blocks, dec->blocks_per_line) / dec->blocks_per_line;
10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.depth0 = 1;
10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.array_size = 1;
10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.usage = PIPE_USAGE_STREAM;
10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   res = dec->base.context->screen->resource_create(dec->base.context->screen, &res_tmpl);
10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!res)
10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_source;
10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   u_sampler_view_default_template(&sv_tmpl, res, res->format);
11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_RED;
11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buffer->zscan_source = dec->base.context->create_sampler_view(dec->base.context, res, &sv_tmpl);
11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_resource_reference(&res, NULL);
11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!buffer->zscan_source)
11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_sampler;
11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      destination = dec->idct_source->get_surfaces(dec->idct_source);
12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   else
12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      destination = dec->mc_source->get_surfaces(dec->mc_source);
12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!destination)
12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_surface;
12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i)
12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c,
12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                &buffer->zscan[i], buffer->zscan_source, destination[i]))
13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         goto error_plane;
13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13425b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_plane:
13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (; i > 0; --i)
13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]);
13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13825b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_surface:
13925b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_sampler:
14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&buffer->zscan_source, NULL);
14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14225b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_source:
14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return false;
14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
14725b3c049e70834cf33790a28643ab058b507b35cBen Chengcleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer)
14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buffer);
15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i)
15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_cleanup_buffer(&buffer->zscan[i]);
15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&buffer->zscan_source, NULL);
15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
16025b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_idct_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer)
16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_view **idct_source_sv, **mc_source_sv;
16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && buffer);
16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source);
16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!idct_source_sv)
17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_source_sv;
17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!mc_source_sv)
17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc_source_sv;
17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < 3; ++i)
17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c,
17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                               &buffer->idct[i], idct_source_sv[i],
17925b3c049e70834cf33790a28643ab058b507b35cBen Cheng                               mc_source_sv[i]))
18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         goto error_plane;
18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
18425b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_plane:
18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (; i > 0; --i)
18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_cleanup_buffer(&buffer->idct[i - 1]);
18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
18825b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc_source_sv:
18925b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_source_sv:
19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return false;
19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
19325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
19425b3c049e70834cf33790a28643ab058b507b35cBen Chengcleanup_idct_buffer(struct vl_mpeg12_buffer *buf)
19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < 3; ++i)
20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_cleanup_buffer(&buf->idct[0]);
20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
20425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
20525b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_mc_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buf)
20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && buf);
20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0]))
21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc_y;
21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1]))
21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc_cb;
21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2]))
21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc_cr;
21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
22025b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc_cr:
22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_mc_cleanup_buffer(&buf->mc[1]);
22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
22325b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc_cb:
22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_mc_cleanup_buffer(&buf->mc[0]);
22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
22625b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc_y:
22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return false;
22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
23025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
23125b3c049e70834cf33790a28643ab058b507b35cBen Chengcleanup_mc_buffer(struct vl_mpeg12_buffer *buf)
23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i)
23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_mc_cleanup_buffer(&buf->mc[i]);
23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
24125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic INLINE void
24225b3c049e70834cf33790a28643ab058b507b35cBen ChengMacroBlockTypeToPipeWeights(const struct pipe_mpeg12_macroblock *mb, unsigned weights[2])
24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(mb);
24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   switch (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {
24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case PIPE_MPEG12_MB_TYPE_MOTION_FORWARD:
24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD):
25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[0] = PIPE_VIDEO_MV_WEIGHT_HALF;
25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[1] = PIPE_VIDEO_MV_WEIGHT_HALF;
25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD:
25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      weights[1] = PIPE_VIDEO_MV_WEIGHT_MAX;
26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   default:
26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) {
26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng         weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN;
26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      } else {
26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         /* no motion vector, but also not intra mb ->
26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng            just copy the old frame content */
26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX;
27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN;
27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
27625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic INLINE struct vl_motionvector
27725b3c049e70834cf33790a28643ab058b507b35cBen ChengMotionVectorToPipe(const struct pipe_mpeg12_macroblock *mb, unsigned vector,
27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                   unsigned field_select_mask, unsigned weight)
27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_motionvector mv;
28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(mb);
28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {
28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      switch (mb->macroblock_modes.bits.frame_motion_type) {
28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      case PIPE_MPEG12_MO_TYPE_FRAME:
28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.x = mb->PMV[0][vector][0];
28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.y = mb->PMV[0][vector][1];
28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.field_select = PIPE_VIDEO_FRAME;
29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.weight = weight;
29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.x = mb->PMV[0][vector][0];
29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.y = mb->PMV[0][vector][1];
29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.weight = weight;
29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.field_select = PIPE_VIDEO_FRAME;
29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng         break;
29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      case PIPE_MPEG12_MO_TYPE_FIELD:
29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.x = mb->PMV[0][vector][0];
30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.y = mb->PMV[0][vector][1];
30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.field_select = (mb->motion_vertical_field_select & field_select_mask) ?
30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng            PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.top.weight = weight;
30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.x = mb->PMV[1][vector][0];
30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.y = mb->PMV[1][vector][1];
30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.field_select = (mb->motion_vertical_field_select & (field_select_mask << 2)) ?
30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng            PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         mv.bottom.weight = weight;
31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         break;
31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      default: // TODO: Support DUALPRIME and 16x8
31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         break;
31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else {
31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.top.x = mv.top.y = 0;
31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.top.field_select = PIPE_VIDEO_FRAME;
31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.top.weight = weight;
31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.bottom.x = mv.bottom.y = 0;
32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.bottom.field_select = PIPE_VIDEO_FRAME;
32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      mv.bottom.weight = weight;
32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return mv;
32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
32725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic INLINE void
32825b3c049e70834cf33790a28643ab058b507b35cBen ChengUploadYcbcrBlocks(struct vl_mpeg12_decoder *dec,
32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng                  struct vl_mpeg12_buffer *buf,
33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng                  const struct pipe_mpeg12_macroblock *mb)
33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned intra;
33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned tb, x, y, num_blocks = 0;
33425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
33525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && buf);
33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(mb);
33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!mb->coded_block_pattern)
33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return;
34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ? 1 : 0;
34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (y = 0; y < 2; ++y) {
34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (x = 0; x < 2; ++x) {
34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (mb->coded_block_pattern & const_empty_block_mask_420[0][y][x]) {
34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng            struct vl_ycbcr_block *stream = buf->ycbcr_stream[0];
34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng            stream->x = mb->x * 2 + x;
34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng            stream->y = mb->y * 2 + y;
35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng            stream->intra = intra;
35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng            stream->coding = mb->macroblock_modes.bits.dct_type;
35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng            stream->block_num = buf->block_num++;
35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng            buf->num_ycbcr_blocks[0]++;
35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng            buf->ycbcr_stream[0]++;
35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng            num_blocks++;
35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         }
35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   /* TODO: Implement 422, 444 */
36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (tb = 1; tb < 3; ++tb) {
36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (mb->coded_block_pattern & const_empty_block_mask_420[tb][0][0]) {
36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         struct vl_ycbcr_block *stream = buf->ycbcr_stream[tb];
36925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         stream->x = mb->x;
37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         stream->y = mb->y;
37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         stream->intra = intra;
37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         stream->coding = 0;
37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         stream->block_num = buf->block_num++;
37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         buf->num_ycbcr_blocks[tb]++;
37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng         buf->ycbcr_stream[tb]++;
37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         num_blocks++;
37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memcpy(buf->texels, mb->blocks, 64 * sizeof(short) * num_blocks);
38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf->texels += 64 * num_blocks;
38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
38625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
38725b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_destroy_buffer(void *buffer)
38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buf = buffer;
39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   cleanup_zscan_buffer(buf);
39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   cleanup_idct_buffer(buf);
39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   cleanup_mc_buffer(buf);
39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_vb_cleanup(&buf->vertex_stream);
39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   FREE(buf);
39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
40125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
40225b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_destroy(struct pipe_video_decoder *decoder)
40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(decoder);
40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   /* Asserted in softpipe_delete_fs_state() for some reason */
41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->bind_vs_state(dec->base.context, NULL);
41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->bind_fs_state(dec->base.context, NULL);
41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->delete_depth_stencil_alpha_state(dec->base.context, dec->dsa);
41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->delete_sampler_state(dec->base.context, dec->sampler_ycbcr);
41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_mc_cleanup(&dec->mc_y);
41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_mc_cleanup(&dec->mc_c);
41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->mc_source->destroy(dec->mc_source);
41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_cleanup(&dec->idct_y);
42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_cleanup(&dec->idct_c);
42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->idct_source->destroy(dec->idct_source);
42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_zscan_cleanup(&dec->zscan_y);
42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_zscan_cleanup(&dec->zscan_c);
42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_ycbcr);
43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_mv);
43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_resource_reference(&dec->quads.buffer, NULL);
43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_resource_reference(&dec->pos.buffer, NULL);
43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&dec->zscan_linear, NULL);
43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&dec->zscan_normal, NULL);
43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&dec->zscan_alternate, NULL);
43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < 4; ++i)
44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (dec->dec_buffers[i])
44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vl_mpeg12_destroy_buffer(dec->dec_buffers[i]);
44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   FREE(dec);
44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
44625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct vl_mpeg12_buffer *
44725b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder *dec, struct pipe_video_buffer *target)
44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buffer;
45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec);
45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buffer = vl_video_buffer_get_associated_data(target, &dec->base);
45425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (buffer)
45525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return buffer;
45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buffer = dec->dec_buffers[dec->current_buffer];
45825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (buffer)
45925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return buffer;
46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (buffer == NULL)
46325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return NULL;
46425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
46525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!vl_vb_init(&buffer->vertex_stream, dec->base.context,
46625b3c049e70834cf33790a28643ab058b507b35cBen Cheng                   dec->base.width / MACROBLOCK_WIDTH,
46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng                   dec->base.height / MACROBLOCK_HEIGHT))
46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_vertex_buffer;
46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!init_mc_buffer(dec, buffer))
47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc;
47225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
47325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!init_idct_buffer(dec, buffer))
47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         goto error_idct;
47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!init_zscan_buffer(dec, buffer))
47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_zscan;
47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_mpg12_bs_init(&buffer->bs, &dec->base);
48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->expect_chunked_decode)
48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_video_buffer_set_associated_data(target, &dec->base,
48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                          buffer, vl_mpeg12_destroy_buffer);
48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   else
48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->dec_buffers[dec->current_buffer] = buffer;
48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return buffer;
49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49125b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_zscan:
49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   cleanup_idct_buffer(buffer);
49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49425b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_idct:
49525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   cleanup_mc_buffer(buffer);
49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49725b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc:
49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_vb_cleanup(&buffer->vertex_stream);
49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
50025b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_vertex_buffer:
50125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   FREE(buffer);
50225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return NULL;
50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
50525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
50625b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_begin_frame(struct pipe_video_decoder *decoder,
50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng                      struct pipe_video_buffer *target,
50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                      struct pipe_picture_desc *picture)
50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buf;
51325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
51425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_resource *tex;
51525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_box rect = { 0, 0, 0, 1, 1, 1 };
51625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   uint8_t intra_matrix[64];
51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   uint8_t non_intra_matrix[64];
51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
52125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && target && picture);
52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf = vl_mpeg12_get_decode_buffer(dec, target);
52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      memcpy(intra_matrix, desc->intra_matrix, sizeof(intra_matrix));
52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      memcpy(non_intra_matrix, desc->non_intra_matrix, sizeof(non_intra_matrix));
53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      intra_matrix[0] = 1 << (7 - desc->intra_dc_precision);
53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else {
53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      memset(intra_matrix, 0x10, sizeof(intra_matrix));
53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      memset(non_intra_matrix, 0x10, sizeof(non_intra_matrix));
53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i) {
53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      struct vl_zscan *zscan = i == 0 ? &dec->zscan_y : &dec->zscan_c;
53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_upload_quant(zscan, &buf->zscan[i], intra_matrix, true);
53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_upload_quant(zscan, &buf->zscan[i], non_intra_matrix, false);
54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_vb_map(&buf->vertex_stream, dec->base.context);
54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
54425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   tex = buf->zscan_source->texture;
54525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   rect.width = tex->width0;
54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   rect.height = tex->height0;
54725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
54825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf->tex_transfer = dec->base.context->get_transfer
54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context, tex,
55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      &rect
55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf->block_num = 0;
55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf->texels = dec->base.context->transfer_map(dec->base.context, buf->tex_transfer);
55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
55825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i) {
55925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      buf->ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i);
56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      buf->num_ycbcr_blocks[i] = 0;
56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_REF_FRAMES; ++i)
56425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint >= PIPE_VIDEO_ENTRYPOINT_IDCT) {
56725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (i = 0; i < VL_MAX_PLANES; ++i)
56825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear);
56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
57225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
57325b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder,
57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng                            struct pipe_video_buffer *target,
57525b3c049e70834cf33790a28643ab058b507b35cBen Cheng                            struct pipe_picture_desc *picture,
57625b3c049e70834cf33790a28643ab058b507b35cBen Cheng                            const struct pipe_macroblock *macroblocks,
57725b3c049e70834cf33790a28643ab058b507b35cBen Cheng                            unsigned num_macroblocks)
57825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
57925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
58025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks;
58125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
58225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buf;
58325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
58425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i, j, mv_weights[2];
58525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
58625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && target && picture);
58725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(macroblocks && macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
58825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
58925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf = vl_mpeg12_get_decode_buffer(dec, target);
59025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
59125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
59225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (; num_macroblocks > 0; --num_macroblocks) {
59325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      unsigned mb_addr = mb->y * dec->width_in_macroblocks + mb->x;
59425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
59525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_PATTERN | PIPE_MPEG12_MB_TYPE_INTRA))
59625b3c049e70834cf33790a28643ab058b507b35cBen Cheng         UploadYcbcrBlocks(dec, buf, mb);
59725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
59825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      MacroBlockTypeToPipeWeights(mb, mv_weights);
59925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
60025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (i = 0; i < 2; ++i) {
60125b3c049e70834cf33790a28643ab058b507b35cBen Cheng          if (!desc->ref[i]) continue;
60225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
60325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         buf->mv_stream[i][mb_addr] = MotionVectorToPipe
60425b3c049e70834cf33790a28643ab058b507b35cBen Cheng         (
60525b3c049e70834cf33790a28643ab058b507b35cBen Cheng            mb, i,
60625b3c049e70834cf33790a28643ab058b507b35cBen Cheng            i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD,
60725b3c049e70834cf33790a28643ab058b507b35cBen Cheng            mv_weights[i]
60825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         );
60925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
61025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
61125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* see section 7.6.6 of the spec */
61225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (mb->num_skipped_macroblocks > 0) {
61325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         struct vl_motionvector skipped_mv[2];
61425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
61525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (desc->ref[0] && !desc->ref[1]) {
61625b3c049e70834cf33790a28643ab058b507b35cBen Cheng            skipped_mv[0].top.x = skipped_mv[0].top.y = 0;
61725b3c049e70834cf33790a28643ab058b507b35cBen Cheng            skipped_mv[0].top.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
61825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         } else {
61925b3c049e70834cf33790a28643ab058b507b35cBen Cheng           skipped_mv[0] = buf->mv_stream[0][mb_addr];
62025b3c049e70834cf33790a28643ab058b507b35cBen Cheng           skipped_mv[1] = buf->mv_stream[1][mb_addr];
62125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         }
62225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         skipped_mv[0].top.field_select = PIPE_VIDEO_FRAME;
62325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         skipped_mv[1].top.field_select = PIPE_VIDEO_FRAME;
62425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
62525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         skipped_mv[0].bottom = skipped_mv[0].top;
62625b3c049e70834cf33790a28643ab058b507b35cBen Cheng         skipped_mv[1].bottom = skipped_mv[1].top;
62725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
62825b3c049e70834cf33790a28643ab058b507b35cBen Cheng         ++mb_addr;
62925b3c049e70834cf33790a28643ab058b507b35cBen Cheng         for (i = 0; i < mb->num_skipped_macroblocks; ++i, ++mb_addr) {
63025b3c049e70834cf33790a28643ab058b507b35cBen Cheng            for (j = 0; j < 2; ++j) {
63125b3c049e70834cf33790a28643ab058b507b35cBen Cheng               if (!desc->ref[j]) continue;
63225b3c049e70834cf33790a28643ab058b507b35cBen Cheng               buf->mv_stream[j][mb_addr] = skipped_mv[j];
63325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63425b3c049e70834cf33790a28643ab058b507b35cBen Cheng            }
63525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         }
63625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
63725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      ++mb;
63925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
64025b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
64125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
64225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
64325b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_decode_bitstream(struct pipe_video_decoder *decoder,
64425b3c049e70834cf33790a28643ab058b507b35cBen Cheng                           struct pipe_video_buffer *target,
64525b3c049e70834cf33790a28643ab058b507b35cBen Cheng                           struct pipe_picture_desc *picture,
64625b3c049e70834cf33790a28643ab058b507b35cBen Cheng                           unsigned num_buffers,
64725b3c049e70834cf33790a28643ab058b507b35cBen Cheng                           const void * const *buffers,
64825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                           const unsigned *sizes)
64925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
65025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
65125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
65225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buf;
65325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
65425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
65525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
65625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && target && picture);
65725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
65825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf = vl_mpeg12_get_decode_buffer(dec, target);
65925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(buf);
66025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
66125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i)
66225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_set_layout(&buf->zscan[i], desc->alternate_scan ?
66325b3c049e70834cf33790a28643ab058b507b35cBen Cheng                          dec->zscan_alternate : dec->zscan_normal);
66425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
66525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_mpg12_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes);
66625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
66725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
66825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
66925b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_end_frame(struct pipe_video_decoder *decoder,
67025b3c049e70834cf33790a28643ab058b507b35cBen Cheng                    struct pipe_video_buffer *target,
67125b3c049e70834cf33790a28643ab058b507b35cBen Cheng                    struct pipe_picture_desc *picture)
67225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
67325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder;
67425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
67525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_view **ref_frames[2];
67625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_view **mc_source_sv;
67725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_surface **target_surfaces;
67825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_vertex_buffer vb[3];
67925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_buffer *buf;
68025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
68125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i, j, component;
68225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned nr_components;
68325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
68425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec && target && picture);
68525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
68625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   buf = vl_mpeg12_get_decode_buffer(dec, target);
68725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
68825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_vb_unmap(&buf->vertex_stream, dec->base.context);
68925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->transfer_unmap(dec->base.context, buf->tex_transfer);
69125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->transfer_destroy(dec->base.context, buf->tex_transfer);
69225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vb[0] = dec->quads;
69425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vb[1] = dec->pos;
69525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   target_surfaces = target->get_surfaces(target);
69725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
69925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (desc->ref[i])
70025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         ref_frames[i] = desc->ref[i]->get_sampler_view_planes(desc->ref[i]);
70125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      else
70225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         ref_frames[i] = NULL;
70325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
70425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
70525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_mv);
70625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i) {
70725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!target_surfaces[i]) continue;
70825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
70925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_mc_set_surface(&buf->mc[i], target_surfaces[i]);
71025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
71125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (j = 0; j < VL_MAX_REF_FRAMES; ++j) {
71225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (!ref_frames[j] || !ref_frames[j][i]) continue;
71325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
71425b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
71525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         dec->base.context->set_vertex_buffers(dec->base.context, 3, vb);
71625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
71725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]);
71825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
71925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
72025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_ycbcr);
72225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < VL_MAX_PLANES; ++i) {
72325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!buf->num_ycbcr_blocks[i]) continue;
72425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
72625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context->set_vertex_buffers(dec->base.context, 2, vb);
72725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]);
72925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
73025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
73125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vl_idct_flush(i ? &dec->idct_c : &dec->idct_y, &buf->idct[i], buf->num_ycbcr_blocks[i]);
73225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
73325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
73425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source);
73525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) {
73625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!target_surfaces[i]) continue;
73725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
73825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      nr_components = util_format_get_nr_components(target_surfaces[i]->texture->format);
73925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (j = 0; j < nr_components; ++j, ++component) {
74025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (!buf->num_ycbcr_blocks[i]) continue;
74125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
74225b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component);
74325b3c049e70834cf33790a28643ab058b507b35cBen Cheng         dec->base.context->set_vertex_buffers(dec->base.context, 2, vb);
74425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
74525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
74625b3c049e70834cf33790a28643ab058b507b35cBen Cheng            vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[component]);
74725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         else {
74825b3c049e70834cf33790a28643ab058b507b35cBen Cheng            dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[component]);
74925b3c049e70834cf33790a28643ab058b507b35cBen Cheng            dec->base.context->bind_fragment_sampler_states(dec->base.context, 1, &dec->sampler_ycbcr);
75025b3c049e70834cf33790a28643ab058b507b35cBen Cheng         }
75125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[component]);
75225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
75325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
75425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   ++dec->current_buffer;
75525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->current_buffer %= 4;
75625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
75725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
75825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
75925b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_mpeg12_flush(struct pipe_video_decoder *decoder)
76025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
76125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(decoder);
76225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   //Noop, for shaders it is much faster to flush everything in end_frame
76425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
76525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
76725b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_pipe_state(struct vl_mpeg12_decoder *dec)
76825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
76925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_depth_stencil_alpha_state dsa;
77025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_state sampler;
77125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
77225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
77325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec);
77425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
77525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&dsa, 0, sizeof dsa);
77625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.depth.enabled = 0;
77725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.depth.writemask = 0;
77825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.depth.func = PIPE_FUNC_ALWAYS;
77925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < 2; ++i) {
78025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].enabled = 0;
78125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
78225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
78325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
78425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
78525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].valuemask = 0;
78625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dsa.stencil[i].writemask = 0;
78725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
78825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.alpha.enabled = 0;
78925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.alpha.func = PIPE_FUNC_ALWAYS;
79025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dsa.alpha.ref_value = 0;
79125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->dsa = dec->base.context->create_depth_stencil_alpha_state(dec->base.context, &dsa);
79225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context->bind_depth_stencil_alpha_state(dec->base.context, dec->dsa);
79325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
79425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&sampler, 0, sizeof(sampler));
79525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
79625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
79725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
79825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
79925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
80025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
80125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
80225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.compare_func = PIPE_FUNC_ALWAYS;
80325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   sampler.normalized_coords = 1;
80425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->sampler_ycbcr = dec->base.context->create_sampler_state(dec->base.context, &sampler);
80525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!dec->sampler_ycbcr)
80625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return false;
80725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
80825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
80925b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
81025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
81125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct format_config*
81225b3c049e70834cf33790a28643ab058b507b35cBen Chengfind_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs)
81325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
81425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_screen *screen;
81525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned i;
81625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
81725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec);
81825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
81925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   screen = dec->base.context->screen;
82025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
82125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   for (i = 0; i < num_configs; ++i) {
82225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D,
82325b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                       1, PIPE_BIND_SAMPLER_VIEW))
82425b3c049e70834cf33790a28643ab058b507b35cBen Cheng         continue;
82525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
82625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (configs[i].idct_source_format != PIPE_FORMAT_NONE) {
82725b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D,
82825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
82925b3c049e70834cf33790a28643ab058b507b35cBen Cheng            continue;
83025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
83125b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D,
83225b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
83325b3c049e70834cf33790a28643ab058b507b35cBen Cheng            continue;
83425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      } else {
83525b3c049e70834cf33790a28643ab058b507b35cBen Cheng         if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D,
83625b3c049e70834cf33790a28643ab058b507b35cBen Cheng                                          1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
83725b3c049e70834cf33790a28643ab058b507b35cBen Cheng            continue;
83825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
83925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return &configs[i];
84025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
84125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
84225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return NULL;
84325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
84425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
84525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
84625b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
84725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
84825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned num_channels;
84925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
85025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec);
85125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
85225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->zscan_source_format = format_config->zscan_source_format;
85325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->zscan_linear = vl_zscan_layout(dec->base.context, vl_zscan_linear, dec->blocks_per_line);
85425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->zscan_normal = vl_zscan_layout(dec->base.context, vl_zscan_normal, dec->blocks_per_line);
85525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->zscan_alternate = vl_zscan_layout(dec->base.context, vl_zscan_alternate, dec->blocks_per_line);
85625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
85725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1;
85825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
85925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!vl_zscan_init(&dec->zscan_y, dec->base.context, dec->base.width, dec->base.height,
86025b3c049e70834cf33790a28643ab058b507b35cBen Cheng                      dec->blocks_per_line, dec->num_blocks, num_channels))
86125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return false;
86225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
86325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!vl_zscan_init(&dec->zscan_c, dec->base.context, dec->chroma_width, dec->chroma_height,
86425b3c049e70834cf33790a28643ab058b507b35cBen Cheng                      dec->blocks_per_line, dec->num_blocks, num_channels))
86525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return false;
86625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
86725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
86825b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
86925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
87025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
87125b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
87225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
87325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   unsigned nr_of_idct_render_targets, max_inst;
87425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   enum pipe_format formats[3];
87525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_video_buffer templat;
87625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
87725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_sampler_view *matrix = NULL;
87825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
87925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   nr_of_idct_render_targets = dec->base.context->screen->get_param
88025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
88125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context->screen, PIPE_CAP_MAX_RENDER_TARGETS
88225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
88325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
88425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   max_inst = dec->base.context->screen->get_shader_param
88525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
88625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
88725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
88825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
88925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   // Just assume we need 32 inst per render target, not 100% true, but should work in most cases
89025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4)
89125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      // more than 4 render targets usually doesn't makes any seens
89225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      nr_of_idct_render_targets = 4;
89325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   else
89425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      nr_of_idct_render_targets = 1;
89525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
89625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   formats[0] = formats[1] = formats[2] = format_config->idct_source_format;
89725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&templat, 0, sizeof(templat));
89825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.width = dec->base.width / 4;
89925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.height = dec->base.height;
90025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.chroma_format = dec->base.chroma_format;
90125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->idct_source = vl_video_buffer_create_ex
90225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
90325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context, &templat,
90425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      formats, 1, PIPE_USAGE_STATIC
90525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
90625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
90725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!dec->idct_source)
90825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_idct_source;
90925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
91025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
91125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&templat, 0, sizeof(templat));
91225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.width = dec->base.width / nr_of_idct_render_targets;
91325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.height = dec->base.height / 4;
91425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.chroma_format = dec->base.chroma_format;
91525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->mc_source = vl_video_buffer_create_ex
91625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
91725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context, &templat,
91825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      formats, nr_of_idct_render_targets, PIPE_USAGE_STATIC
91925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
92025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
92125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!dec->mc_source)
92225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_mc_source;
92325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
92425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!(matrix = vl_idct_upload_matrix(dec->base.context, format_config->idct_scale)))
92525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_matrix;
92625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
92725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!vl_idct_init(&dec->idct_y, dec->base.context, dec->base.width, dec->base.height,
92825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                     nr_of_idct_render_targets, matrix, matrix))
92925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_y;
93025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
93125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if(!vl_idct_init(&dec->idct_c, dec->base.context, dec->chroma_width, dec->chroma_height,
93225b3c049e70834cf33790a28643ab058b507b35cBen Cheng                    nr_of_idct_render_targets, matrix, matrix))
93325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_c;
93425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
93525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&matrix, NULL);
93625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
93725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return true;
93825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
93925b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_c:
94025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   vl_idct_cleanup(&dec->idct_y);
94125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
94225b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_y:
94325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   pipe_sampler_view_reference(&matrix, NULL);
94425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
94525b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_matrix:
94625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->mc_source->destroy(dec->mc_source);
94725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
94825b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_mc_source:
94925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->idct_source->destroy(dec->idct_source);
95025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
95125b3c049e70834cf33790a28643ab058b507b35cBen Chengerror_idct_source:
95225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return false;
95325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
95425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
95525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
95625b3c049e70834cf33790a28643ab058b507b35cBen Chenginit_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config)
95725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
95825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   enum pipe_format formats[3];
95925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct pipe_video_buffer templat;
96025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
96125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   formats[0] = formats[1] = formats[2] = format_config->mc_source_format;
96225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   memset(&templat, 0, sizeof(templat));
96325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.width = dec->base.width;
96425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.height = dec->base.height;
96525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   templat.chroma_format = dec->base.chroma_format;
96625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->mc_source = vl_video_buffer_create_ex
96725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   (
96825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context, &templat,
96925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      formats, 1, PIPE_USAGE_STATIC
97025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
97125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
97225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   return dec->mc_source != NULL;
97325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
97425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
97525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
97625b3c049e70834cf33790a28643ab058b507b35cBen Chengmc_vert_shader_callback(void *priv, struct vl_mc *mc,
97725b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        struct ureg_program *shader,
97825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        unsigned first_output,
97925b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        struct ureg_dst tex)
98025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
98125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = priv;
98225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct ureg_dst o_vtex;
98325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
98425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(priv && mc);
98525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(shader);
98625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
98725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
98825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
98925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_stage2_vert_shader(idct, shader, first_output, tex);
99025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else {
99125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output);
99225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex));
99325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
99425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
99525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
99625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
99725b3c049e70834cf33790a28643ab058b507b35cBen Chengmc_frag_shader_callback(void *priv, struct vl_mc *mc,
99825b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        struct ureg_program *shader,
99925b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        unsigned first_input,
100025b3c049e70834cf33790a28643ab058b507b35cBen Cheng                        struct ureg_dst dst)
100125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
100225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec = priv;
100325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct ureg_src src, sampler;
100425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
100525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(priv && mc);
100625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(shader);
100725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
100825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
100925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c;
101025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      vl_idct_stage2_frag_shader(idct, shader, first_input, dst);
101125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else {
101225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR);
101325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      sampler = ureg_DECL_sampler(shader, 0);
101425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler);
101525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
101625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
101725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
101825b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct pipe_video_decoder *
101925b3c049e70834cf33790a28643ab058b507b35cBen Chengvl_create_mpeg12_decoder(struct pipe_context *context,
102025b3c049e70834cf33790a28643ab058b507b35cBen Cheng                         enum pipe_video_profile profile,
102125b3c049e70834cf33790a28643ab058b507b35cBen Cheng                         enum pipe_video_entrypoint entrypoint,
102225b3c049e70834cf33790a28643ab058b507b35cBen Cheng                         enum pipe_video_chroma_format chroma_format,
102325b3c049e70834cf33790a28643ab058b507b35cBen Cheng                         unsigned width, unsigned height, unsigned max_references,
102425b3c049e70834cf33790a28643ab058b507b35cBen Cheng                         bool expect_chunked_decode)
102525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
102625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   const unsigned block_size_pixels = BLOCK_WIDTH * BLOCK_HEIGHT;
102725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   const struct format_config *format_config;
102825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   struct vl_mpeg12_decoder *dec;
102925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
103025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
103125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
103225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec = CALLOC_STRUCT(vl_mpeg12_decoder);
103325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
103425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!dec)
103525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return NULL;
103625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
103725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.context = context;
103825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.profile = profile;
103925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.entrypoint = entrypoint;
104025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.chroma_format = chroma_format;
104125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.width = width;
104225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.height = height;
104325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.max_references = max_references;
104425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
104525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.destroy = vl_mpeg12_destroy;
104625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.begin_frame = vl_mpeg12_begin_frame;
104725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.decode_macroblock = vl_mpeg12_decode_macroblock;
104825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.decode_bitstream = vl_mpeg12_decode_bitstream;
104925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.end_frame = vl_mpeg12_end_frame;
105025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->base.flush = vl_mpeg12_flush;
105125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
105225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4);
105325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels;
105425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->width_in_macroblocks = align(dec->base.width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
105525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->expect_chunked_decode = expect_chunked_decode;
105625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
105725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   /* TODO: Implement 422, 444 */
105825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
105925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
106025b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
106125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_width = dec->base.width / 2;
106225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_height = dec->base.height / 2;
106325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->num_blocks = dec->num_blocks * 2;
106425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
106525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_width = dec->base.width;
106625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_height = dec->base.height / 2;
106725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->num_blocks = dec->num_blocks * 2 + dec->num_blocks;
106825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   } else {
106925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_width = dec->base.width;
107025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->chroma_height = dec->base.height;
107125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->num_blocks = dec->num_blocks * 3;
107225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
107325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
107425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->quads = vl_vb_upload_quads(dec->base.context);
107525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->pos = vl_vb_upload_pos(
107625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.context,
107725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.width / MACROBLOCK_WIDTH,
107825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      dec->base.height / MACROBLOCK_HEIGHT
107925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   );
108025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
108125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->base.context);
108225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   dec->ves_mv = vl_vb_get_ves_mv(dec->base.context);
108325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
108425b3c049e70834cf33790a28643ab058b507b35cBen Cheng   switch (entrypoint) {
108525b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
108625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs);
108725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
108825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
108925b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case PIPE_VIDEO_ENTRYPOINT_IDCT:
109025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      format_config = find_format_config(dec, idct_format_config, num_idct_format_configs);
109125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
109225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
109325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   case PIPE_VIDEO_ENTRYPOINT_MC:
109425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      format_config = find_format_config(dec, mc_format_config, num_mc_format_configs);
109525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
109625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
109725b3c049e70834cf33790a28643ab058b507b35cBen Cheng   default:
109825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      assert(0);
109925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      FREE(dec);
110025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return NULL;
110125b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
110225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
110325b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!format_config) {
110425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      FREE(dec);
110525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return NULL;
110625b3c049e70834cf33790a28643ab058b507b35cBen Cheng   }
110725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
110825b3c049e70834cf33790a28643ab058b507b35cBen Cheng   if (!init_zscan(dec, format_config))
110925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      goto error_zscan;
111025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
1111   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
1112      if (!init_idct(dec, format_config))
1113         goto error_sources;
1114   } else {
1115      if (!init_mc_source_widthout_idct(dec, format_config))
1116         goto error_sources;
1117   }
1118
1119   if (!vl_mc_init(&dec->mc_y, dec->base.context, dec->base.width, dec->base.height,
1120                   MACROBLOCK_HEIGHT, format_config->mc_scale,
1121                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
1122      goto error_mc_y;
1123
1124   // TODO
1125   if (!vl_mc_init(&dec->mc_c, dec->base.context, dec->base.width, dec->base.height,
1126                   BLOCK_HEIGHT, format_config->mc_scale,
1127                   mc_vert_shader_callback, mc_frag_shader_callback, dec))
1128      goto error_mc_c;
1129
1130   if (!init_pipe_state(dec))
1131      goto error_pipe_state;
1132
1133   return &dec->base;
1134
1135error_pipe_state:
1136   vl_mc_cleanup(&dec->mc_c);
1137
1138error_mc_c:
1139   vl_mc_cleanup(&dec->mc_y);
1140
1141error_mc_y:
1142   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
1143      vl_idct_cleanup(&dec->idct_y);
1144      vl_idct_cleanup(&dec->idct_c);
1145      dec->idct_source->destroy(dec->idct_source);
1146   }
1147   dec->mc_source->destroy(dec->mc_source);
1148
1149error_sources:
1150   vl_zscan_cleanup(&dec->zscan_y);
1151   vl_zscan_cleanup(&dec->zscan_c);
1152
1153error_zscan:
1154   FREE(dec);
1155   return NULL;
1156}
1157