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