1d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König/************************************************************************** 2d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * 3d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * Copyright 2009 Younes Manton. 4d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * All Rights Reserved. 5d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * 6d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * Permission is hereby granted, free of charge, to any person obtaining a 7d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * copy of this software and associated documentation files (the 8d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * "Software"), to deal in the Software without restriction, including 9d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * without limitation the rights to use, copy, modify, merge, publish, 10d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * distribute, sub license, and/or sell copies of the Software, and to 11d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * permit persons to whom the Software is furnished to do so, subject to 12d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * the following conditions: 13d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * 14d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * The above copyright notice and this permission notice (including the 15d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * next paragraph) shall be included in all copies or substantial portions 16d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * of the Software. 17d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * 18d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König * 26d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König **************************************************************************/ 27d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 28fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König#include <math.h> 29fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König#include <assert.h> 30d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 3119bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_memory.h" 3219bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_rect.h" 3319bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_sampler.h" 3419bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_video.h" 35d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 36d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include "vl_mpeg12_decoder.h" 37d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include "vl_defines.h" 38d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 39ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König#define SCALE_FACTOR_SNORM (32768.0f / 256.0f) 40ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König#define SCALE_FACTOR_SSCALED (1.0f / 256.0f) 41fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König 42311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstruct format_config { 43311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König enum pipe_format zscan_source_format; 44311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König enum pipe_format idct_source_format; 45311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König enum pipe_format mc_source_format; 46f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 47311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König float idct_scale; 48311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König float mc_scale; 49311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König}; 50f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 51311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config bitstream_format_config[] = { 5286f97f7dc015092aa7fa1b0bdc4fe0a9f696d418Christian König// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 5386f97f7dc015092aa7fa1b0bdc4fe0a9f696d418Christian König// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 54311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 55311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 56bad3085c7839de734f6b883088f91ae55db61a35Christian König}; 57bad3085c7839de734f6b883088f91ae55db61a35Christian König 58311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_bitstream_format_configs = 59311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König sizeof(bitstream_format_config) / sizeof(struct format_config); 60bad3085c7839de734f6b883088f91ae55db61a35Christian König 61311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config idct_format_config[] = { 6286f97f7dc015092aa7fa1b0bdc4fe0a9f696d418Christian König// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 6386f97f7dc015092aa7fa1b0bdc4fe0a9f696d418Christian König// { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 64311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 65311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 66bad3085c7839de734f6b883088f91ae55db61a35Christian König}; 67bad3085c7839de734f6b883088f91ae55db61a35Christian König 68311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_idct_format_configs = 69311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König sizeof(idct_format_config) / sizeof(struct format_config); 70bad3085c7839de734f6b883088f91ae55db61a35Christian König 71311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config mc_format_config[] = { 72311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED }, 73311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM } 74bad3085c7839de734f6b883088f91ae55db61a35Christian König}; 75bad3085c7839de734f6b883088f91ae55db61a35Christian König 76311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const unsigned num_mc_format_configs = 77311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König sizeof(mc_format_config) / sizeof(struct format_config); 78bad3085c7839de734f6b883088f91ae55db61a35Christian König 79d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian Königstatic const unsigned const_empty_block_mask_420[3][2][2] = { 80d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König { { 0x20, 0x10 }, { 0x08, 0x04 } }, 81d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König { { 0x02, 0x02 }, { 0x02, 0x02 } }, 82d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König { { 0x01, 0x01 }, { 0x01, 0x01 } } 83d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König}; 84d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 85f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool 861d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königinit_zscan_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer) 87f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{ 8831096e13f858daf896c0c53077fb25e92da089a6Christian König struct pipe_resource *res, res_tmpl; 8931096e13f858daf896c0c53077fb25e92da089a6Christian König struct pipe_sampler_view sv_tmpl; 90f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König struct pipe_surface **destination; 91f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 92f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König unsigned i; 93f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 941d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(dec && buffer); 95f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 9631096e13f858daf896c0c53077fb25e92da089a6Christian König memset(&res_tmpl, 0, sizeof(res_tmpl)); 9731096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.target = PIPE_TEXTURE_2D; 9831096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.format = dec->zscan_source_format; 9970a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König res_tmpl.width0 = dec->blocks_per_line * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; 10031096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.height0 = align(dec->num_blocks, dec->blocks_per_line) / dec->blocks_per_line; 10131096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.depth0 = 1; 10231096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.array_size = 1; 10331096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.usage = PIPE_USAGE_STREAM; 10431096e13f858daf896c0c53077fb25e92da089a6Christian König res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 10531096e13f858daf896c0c53077fb25e92da089a6Christian König 10631096e13f858daf896c0c53077fb25e92da089a6Christian König res = dec->base.context->screen->resource_create(dec->base.context->screen, &res_tmpl); 10731096e13f858daf896c0c53077fb25e92da089a6Christian König if (!res) 108f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_source; 109f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 11031096e13f858daf896c0c53077fb25e92da089a6Christian König 11131096e13f858daf896c0c53077fb25e92da089a6Christian König memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 11231096e13f858daf896c0c53077fb25e92da089a6Christian König u_sampler_view_default_template(&sv_tmpl, res, res->format); 11331096e13f858daf896c0c53077fb25e92da089a6Christian König sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_RED; 11431096e13f858daf896c0c53077fb25e92da089a6Christian König buffer->zscan_source = dec->base.context->create_sampler_view(dec->base.context, res, &sv_tmpl); 11531096e13f858daf896c0c53077fb25e92da089a6Christian König pipe_resource_reference(&res, NULL); 11631096e13f858daf896c0c53077fb25e92da089a6Christian König if (!buffer->zscan_source) 117f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_sampler; 118f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 119f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 1200121aae967d3d1366cccc8946cf89ad22818365eChristian König destination = dec->idct_source->get_surfaces(dec->idct_source); 121f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König else 1220121aae967d3d1366cccc8946cf89ad22818365eChristian König destination = dec->mc_source->get_surfaces(dec->mc_source); 123f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 124f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (!destination) 125f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_surface; 126f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1278abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) 128f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c, 12931096e13f858daf896c0c53077fb25e92da089a6Christian König &buffer->zscan[i], buffer->zscan_source, destination[i])) 130f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_plane; 131f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 132f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return true; 133f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 134f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_plane: 135f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König for (; i > 0; --i) 136f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]); 137f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 138f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_surface: 139f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_sampler: 14031096e13f858daf896c0c53077fb25e92da089a6Christian König pipe_sampler_view_reference(&buffer->zscan_source, NULL); 141f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 142f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_source: 143f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return false; 144f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König} 145f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 146f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic void 147f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königcleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer) 148f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{ 149f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König unsigned i; 150f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 151f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König assert(buffer); 152f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1538abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) 154f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König vl_zscan_cleanup_buffer(&buffer->zscan[i]); 15531096e13f858daf896c0c53077fb25e92da089a6Christian König 15631096e13f858daf896c0c53077fb25e92da089a6Christian König pipe_sampler_view_reference(&buffer->zscan_source, NULL); 157f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König} 158f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 159f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool 1601d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königinit_idct_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer) 161f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{ 1627f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct pipe_sampler_view **idct_source_sv, **mc_source_sv; 163f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 164f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König unsigned i; 165f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1661d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(dec && buffer); 167f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1680121aae967d3d1366cccc8946cf89ad22818365eChristian König idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source); 169f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (!idct_source_sv) 170f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_source_sv; 171f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1720121aae967d3d1366cccc8946cf89ad22818365eChristian König mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 1737f04fe5338d0846ec9a6003033da5357d2785c8bChristian König if (!mc_source_sv) 1747f04fe5338d0846ec9a6003033da5357d2785c8bChristian König goto error_mc_source_sv; 175f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 176f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König for (i = 0; i < 3; ++i) 177f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, 178f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König &buffer->idct[i], idct_source_sv[i], 179ae56a1dd67040dc5d53f4a1622f775462f0fec05Christian König mc_source_sv[i])) 180f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König goto error_plane; 181f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 182f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return true; 183f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 184f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_plane: 185f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König for (; i > 0; --i) 1867c48575402e8c384db2fab24e4dd0fc72bef0451Christian König vl_idct_cleanup_buffer(&buffer->idct[i - 1]); 187f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1887f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königerror_mc_source_sv: 189f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königerror_source_sv: 190f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return false; 191f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König} 192f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1939d2e630cd02362bfa8f090640a55cf2dea9d64b3Christian Königstatic void 194ad4ed0e7f642a536618be183b293286fff1b206bChristian Königcleanup_idct_buffer(struct vl_mpeg12_buffer *buf) 195ad4ed0e7f642a536618be183b293286fff1b206bChristian König{ 1967c48575402e8c384db2fab24e4dd0fc72bef0451Christian König unsigned i; 1977c48575402e8c384db2fab24e4dd0fc72bef0451Christian König 198ad4ed0e7f642a536618be183b293286fff1b206bChristian König assert(buf); 199ad4ed0e7f642a536618be183b293286fff1b206bChristian König 2007c48575402e8c384db2fab24e4dd0fc72bef0451Christian König for (i = 0; i < 3; ++i) 2017c48575402e8c384db2fab24e4dd0fc72bef0451Christian König vl_idct_cleanup_buffer(&buf->idct[0]); 202ad4ed0e7f642a536618be183b293286fff1b206bChristian König} 203ad4ed0e7f642a536618be183b293286fff1b206bChristian König 20424d76d2966a5c666c9627034e6751621b17024c8Christian Königstatic bool 2051d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königinit_mc_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buf) 20624d76d2966a5c666c9627034e6751621b17024c8Christian König{ 2071d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(dec && buf); 20824d76d2966a5c666c9627034e6751621b17024c8Christian König 2093ea7e2713c836f23d59c4034385609e371a94c8dChristian König if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0])) 21024d76d2966a5c666c9627034e6751621b17024c8Christian König goto error_mc_y; 21124d76d2966a5c666c9627034e6751621b17024c8Christian König 2123ea7e2713c836f23d59c4034385609e371a94c8dChristian König if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1])) 21324d76d2966a5c666c9627034e6751621b17024c8Christian König goto error_mc_cb; 21424d76d2966a5c666c9627034e6751621b17024c8Christian König 2153ea7e2713c836f23d59c4034385609e371a94c8dChristian König if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2])) 21624d76d2966a5c666c9627034e6751621b17024c8Christian König goto error_mc_cr; 21724d76d2966a5c666c9627034e6751621b17024c8Christian König 21824d76d2966a5c666c9627034e6751621b17024c8Christian König return true; 21924d76d2966a5c666c9627034e6751621b17024c8Christian König 22024d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_cr: 22124d76d2966a5c666c9627034e6751621b17024c8Christian König vl_mc_cleanup_buffer(&buf->mc[1]); 22224d76d2966a5c666c9627034e6751621b17024c8Christian König 22324d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_cb: 22424d76d2966a5c666c9627034e6751621b17024c8Christian König vl_mc_cleanup_buffer(&buf->mc[0]); 22524d76d2966a5c666c9627034e6751621b17024c8Christian König 22624d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_mc_y: 22724d76d2966a5c666c9627034e6751621b17024c8Christian König return false; 22824d76d2966a5c666c9627034e6751621b17024c8Christian König} 22924d76d2966a5c666c9627034e6751621b17024c8Christian König 23024d76d2966a5c666c9627034e6751621b17024c8Christian Königstatic void 23124d76d2966a5c666c9627034e6751621b17024c8Christian Königcleanup_mc_buffer(struct vl_mpeg12_buffer *buf) 23224d76d2966a5c666c9627034e6751621b17024c8Christian König{ 23324d76d2966a5c666c9627034e6751621b17024c8Christian König unsigned i; 23424d76d2966a5c666c9627034e6751621b17024c8Christian König 23524d76d2966a5c666c9627034e6751621b17024c8Christian König assert(buf); 23624d76d2966a5c666c9627034e6751621b17024c8Christian König 2378abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) 23824d76d2966a5c666c9627034e6751621b17024c8Christian König vl_mc_cleanup_buffer(&buf->mc[i]); 23924d76d2966a5c666c9627034e6751621b17024c8Christian König} 24024d76d2966a5c666c9627034e6751621b17024c8Christian König 241005aea891ec5814c3c05f20e5a65ca61db3b1b10Brian Paulstatic INLINE void 242d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian KönigMacroBlockTypeToPipeWeights(const struct pipe_mpeg12_macroblock *mb, unsigned weights[2]) 243d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König{ 244d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(mb); 245d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 246d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König switch (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) { 247d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König case PIPE_MPEG12_MB_TYPE_MOTION_FORWARD: 248d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX; 249d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; 250d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 251d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 252d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König case (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD): 253d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[0] = PIPE_VIDEO_MV_WEIGHT_HALF; 254d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[1] = PIPE_VIDEO_MV_WEIGHT_HALF; 255d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 256d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 257d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König case PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD: 258d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN; 259d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[1] = PIPE_VIDEO_MV_WEIGHT_MAX; 260d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 261d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 262d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König default: 2637b181d16c3b954bf567563e90e5e94bda833fab8Christian König if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) { 2647b181d16c3b954bf567563e90e5e94bda833fab8Christian König weights[0] = PIPE_VIDEO_MV_WEIGHT_MIN; 265d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; 266d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } else { 2677b181d16c3b954bf567563e90e5e94bda833fab8Christian König /* no motion vector, but also not intra mb -> 2687b181d16c3b954bf567563e90e5e94bda833fab8Christian König just copy the old frame content */ 2697b181d16c3b954bf567563e90e5e94bda833fab8Christian König weights[0] = PIPE_VIDEO_MV_WEIGHT_MAX; 270d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König weights[1] = PIPE_VIDEO_MV_WEIGHT_MIN; 271d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 272d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 273d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 274d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König} 275d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 276005aea891ec5814c3c05f20e5a65ca61db3b1b10Brian Paulstatic INLINE struct vl_motionvector 277d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian KönigMotionVectorToPipe(const struct pipe_mpeg12_macroblock *mb, unsigned vector, 278d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König unsigned field_select_mask, unsigned weight) 279d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König{ 280d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_motionvector mv; 281d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 282d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(mb); 283d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 284d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) { 285d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König switch (mb->macroblock_modes.bits.frame_motion_type) { 286d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König case PIPE_MPEG12_MO_TYPE_FRAME: 287d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.x = mb->PMV[0][vector][0]; 288d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.y = mb->PMV[0][vector][1]; 289d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.field_select = PIPE_VIDEO_FRAME; 290d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.weight = weight; 291d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 292d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.x = mb->PMV[0][vector][0]; 293d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.y = mb->PMV[0][vector][1]; 294d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.weight = weight; 295d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.field_select = PIPE_VIDEO_FRAME; 296d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 297d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 298d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König case PIPE_MPEG12_MO_TYPE_FIELD: 299d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.x = mb->PMV[0][vector][0]; 300d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.y = mb->PMV[0][vector][1]; 301d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.field_select = (mb->motion_vertical_field_select & field_select_mask) ? 302d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD; 303d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.weight = weight; 304d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 305d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.x = mb->PMV[1][vector][0]; 306d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.y = mb->PMV[1][vector][1]; 307d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.field_select = (mb->motion_vertical_field_select & (field_select_mask << 2)) ? 308d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD; 309d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.weight = weight; 310d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 311d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 312d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König default: // TODO: Support DUALPRIME and 16x8 313d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König break; 314d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 315d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } else { 316d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.x = mv.top.y = 0; 317d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.field_select = PIPE_VIDEO_FRAME; 318d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.top.weight = weight; 319d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 320d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.x = mv.bottom.y = 0; 321d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.field_select = PIPE_VIDEO_FRAME; 322d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv.bottom.weight = weight; 323d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 324d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König return mv; 325d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König} 326d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 327005aea891ec5814c3c05f20e5a65ca61db3b1b10Brian Paulstatic INLINE void 328d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian KönigUploadYcbcrBlocks(struct vl_mpeg12_decoder *dec, 329d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_mpeg12_buffer *buf, 330d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König const struct pipe_mpeg12_macroblock *mb) 331d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König{ 332d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König unsigned intra; 33331096e13f858daf896c0c53077fb25e92da089a6Christian König unsigned tb, x, y, num_blocks = 0; 334d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 335d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(dec && buf); 336d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(mb); 337d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 338d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (!mb->coded_block_pattern) 339d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König return; 340d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 341d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ? 1 : 0; 342d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 34331096e13f858daf896c0c53077fb25e92da089a6Christian König for (y = 0; y < 2; ++y) { 3448a7e645c9befb8578c8a571ccc951ed908d177aeChristian König for (x = 0; x < 2; ++x) { 345d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (mb->coded_block_pattern & const_empty_block_mask_420[0][y][x]) { 346d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 347d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_ycbcr_block *stream = buf->ycbcr_stream[0]; 348d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->x = mb->x * 2 + x; 349d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->y = mb->y * 2 + y; 350d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->intra = intra; 351d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->coding = mb->macroblock_modes.bits.dct_type; 35231096e13f858daf896c0c53077fb25e92da089a6Christian König stream->block_num = buf->block_num++; 353d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 354d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->num_ycbcr_blocks[0]++; 355d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->ycbcr_stream[0]++; 356d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 35731096e13f858daf896c0c53077fb25e92da089a6Christian König num_blocks++; 358d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 359d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 360d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 361d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 362d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König /* TODO: Implement 422, 444 */ 363d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 364d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 365d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (tb = 1; tb < 3; ++tb) { 366d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (mb->coded_block_pattern & const_empty_block_mask_420[tb][0][0]) { 367d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 368d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_ycbcr_block *stream = buf->ycbcr_stream[tb]; 369d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->x = mb->x; 370d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->y = mb->y; 371d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->intra = intra; 372d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König stream->coding = 0; 37331096e13f858daf896c0c53077fb25e92da089a6Christian König stream->block_num = buf->block_num++; 374d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 375d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->num_ycbcr_blocks[tb]++; 376d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->ycbcr_stream[tb]++; 377d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 37831096e13f858daf896c0c53077fb25e92da089a6Christian König num_blocks++; 379d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 380d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 38131096e13f858daf896c0c53077fb25e92da089a6Christian König 38231096e13f858daf896c0c53077fb25e92da089a6Christian König memcpy(buf->texels, mb->blocks, 64 * sizeof(short) * num_blocks); 38331096e13f858daf896c0c53077fb25e92da089a6Christian König buf->texels += 64 * num_blocks; 384d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König} 385d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 386ad4ed0e7f642a536618be183b293286fff1b206bChristian Königstatic void 3878c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königvl_mpeg12_destroy_buffer(void *buffer) 3888c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König{ 3898c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König struct vl_mpeg12_buffer *buf = buffer; 3908c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 3918c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König assert(buf); 3928c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 3938c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König cleanup_zscan_buffer(buf); 3948c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König cleanup_idct_buffer(buf); 3958c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König cleanup_mc_buffer(buf); 3968c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König vl_vb_cleanup(&buf->vertex_stream); 3978c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 3988c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König FREE(buf); 3998c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König} 4008c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 4018c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königstatic void 4021d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königvl_mpeg12_destroy(struct pipe_video_decoder *decoder) 403d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{ 4041d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 4058c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König unsigned i; 40610c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König 4071d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(decoder); 4081d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4091d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König /* Asserted in softpipe_delete_fs_state() for some reason */ 4101d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->bind_vs_state(dec->base.context, NULL); 4111d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->bind_fs_state(dec->base.context, NULL); 4121d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4131d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->delete_depth_stencil_alpha_state(dec->base.context, dec->dsa); 4141d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->delete_sampler_state(dec->base.context, dec->sampler_ycbcr); 4151d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4161d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_mc_cleanup(&dec->mc_y); 4171d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_mc_cleanup(&dec->mc_c); 4181d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->mc_source->destroy(dec->mc_source); 4191d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4201d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 4211d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_idct_cleanup(&dec->idct_y); 4221d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_idct_cleanup(&dec->idct_c); 4231d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->idct_source->destroy(dec->idct_source); 4241d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König } 4251d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4261d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_zscan_cleanup(&dec->zscan_y); 4271d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_zscan_cleanup(&dec->zscan_c); 4281d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4291d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_ycbcr); 4301d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_mv); 4311d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4321d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König pipe_resource_reference(&dec->quads.buffer, NULL); 4331d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König pipe_resource_reference(&dec->pos.buffer, NULL); 4341d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4351d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König pipe_sampler_view_reference(&dec->zscan_linear, NULL); 4361d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König pipe_sampler_view_reference(&dec->zscan_normal, NULL); 4371d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König pipe_sampler_view_reference(&dec->zscan_alternate, NULL); 4381d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4398c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König for (i = 0; i < 4; ++i) 4408c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König if (dec->dec_buffers[i]) 4418c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König vl_mpeg12_destroy_buffer(dec->dec_buffers[i]); 4428c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 4431d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König FREE(dec); 4441d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König} 4451d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4468c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königstatic struct vl_mpeg12_buffer * 4478ea416f35de0c664ef47b71841756758f22d7faaChristian Königvl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder *dec, struct pipe_video_buffer *target) 4481d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König{ 4491d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_buffer *buffer; 450ad4ed0e7f642a536618be183b293286fff1b206bChristian König 451ad4ed0e7f642a536618be183b293286fff1b206bChristian König assert(dec); 452ad4ed0e7f642a536618be183b293286fff1b206bChristian König 4538ea416f35de0c664ef47b71841756758f22d7faaChristian König buffer = vl_video_buffer_get_associated_data(target, &dec->base); 4548c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König if (buffer) 4558c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König return buffer; 4568c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 4578c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König buffer = dec->dec_buffers[dec->current_buffer]; 4588c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König if (buffer) 4598c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König return buffer; 4608c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 4611d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König buffer = CALLOC_STRUCT(vl_mpeg12_buffer); 4621d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (buffer == NULL) 4631d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König return NULL; 4641d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4651d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (!vl_vb_init(&buffer->vertex_stream, dec->base.context, 46670a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König dec->base.width / VL_MACROBLOCK_WIDTH, 46770a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König dec->base.height / VL_MACROBLOCK_HEIGHT)) 4681d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König goto error_vertex_buffer; 4691d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4701d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (!init_mc_buffer(dec, buffer)) 4711d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König goto error_mc; 4721d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4731d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 4741d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (!init_idct_buffer(dec, buffer)) 4751d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König goto error_idct; 4761d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4771d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (!init_zscan_buffer(dec, buffer)) 4781d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König goto error_zscan; 4791d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4801d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) 4818c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König vl_mpg12_bs_init(&buffer->bs, &dec->base); 4828c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König 4838c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König if (dec->expect_chunked_decode) 4848ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_video_buffer_set_associated_data(target, &dec->base, 4858c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König buffer, vl_mpeg12_destroy_buffer); 4868c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König else 4878c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König dec->dec_buffers[dec->current_buffer] = buffer; 4881d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4891d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König return buffer; 4901d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4911d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königerror_zscan: 4928c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König cleanup_idct_buffer(buffer); 4931d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4941d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königerror_idct: 4951d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König cleanup_mc_buffer(buffer); 4961d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 4971d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königerror_mc: 4981d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König vl_vb_cleanup(&buffer->vertex_stream); 4991d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 5001d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königerror_vertex_buffer: 5011d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König FREE(buffer); 5021d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König return NULL; 5031d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König} 5041d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 5051d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königstatic void 5068ea416f35de0c664ef47b71841756758f22d7faaChristian Königvl_mpeg12_begin_frame(struct pipe_video_decoder *decoder, 5078ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_video_buffer *target, 5088ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_picture_desc *picture) 5091d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König{ 5101d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; 5118ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; 5121d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_buffer *buf; 51331096e13f858daf896c0c53077fb25e92da089a6Christian König 51431096e13f858daf896c0c53077fb25e92da089a6Christian König struct pipe_resource *tex; 51531096e13f858daf896c0c53077fb25e92da089a6Christian König struct pipe_box rect = { 0, 0, 0, 1, 1, 1 }; 51631096e13f858daf896c0c53077fb25e92da089a6Christian König 5178ea416f35de0c664ef47b71841756758f22d7faaChristian König uint8_t intra_matrix[64]; 5188ea416f35de0c664ef47b71841756758f22d7faaChristian König uint8_t non_intra_matrix[64]; 5198ea416f35de0c664ef47b71841756758f22d7faaChristian König 5202e6274fc3b123e7de695038054b5cbd20b11559aChristian König unsigned i; 5212e6274fc3b123e7de695038054b5cbd20b11559aChristian König 5228ea416f35de0c664ef47b71841756758f22d7faaChristian König assert(dec && target && picture); 5231d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 5248ea416f35de0c664ef47b71841756758f22d7faaChristian König buf = vl_mpeg12_get_decode_buffer(dec, target); 525d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König assert(buf); 526d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 5278ea416f35de0c664ef47b71841756758f22d7faaChristian König if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) { 5288ea416f35de0c664ef47b71841756758f22d7faaChristian König memcpy(intra_matrix, desc->intra_matrix, sizeof(intra_matrix)); 5298ea416f35de0c664ef47b71841756758f22d7faaChristian König memcpy(non_intra_matrix, desc->non_intra_matrix, sizeof(non_intra_matrix)); 5308ea416f35de0c664ef47b71841756758f22d7faaChristian König intra_matrix[0] = 1 << (7 - desc->intra_dc_precision); 5318ea416f35de0c664ef47b71841756758f22d7faaChristian König } else { 5328ea416f35de0c664ef47b71841756758f22d7faaChristian König memset(intra_matrix, 0x10, sizeof(intra_matrix)); 5338ea416f35de0c664ef47b71841756758f22d7faaChristian König memset(non_intra_matrix, 0x10, sizeof(non_intra_matrix)); 5348ea416f35de0c664ef47b71841756758f22d7faaChristian König } 5352e62b30826679e9d5e1a783dc19baabec4fc8dfaChristian König 5368abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) { 537bce506ffc09c44552c3d1053c6a0450b8f010292Christian König struct vl_zscan *zscan = i == 0 ? &dec->zscan_y : &dec->zscan_c; 5388ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_zscan_upload_quant(zscan, &buf->zscan[i], intra_matrix, true); 5398ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_zscan_upload_quant(zscan, &buf->zscan[i], non_intra_matrix, false); 5401d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König } 541d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 542ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König vl_vb_map(&buf->vertex_stream, dec->base.context); 5432e6274fc3b123e7de695038054b5cbd20b11559aChristian König 54431096e13f858daf896c0c53077fb25e92da089a6Christian König tex = buf->zscan_source->texture; 54531096e13f858daf896c0c53077fb25e92da089a6Christian König rect.width = tex->width0; 54631096e13f858daf896c0c53077fb25e92da089a6Christian König rect.height = tex->height0; 54731096e13f858daf896c0c53077fb25e92da089a6Christian König 54831096e13f858daf896c0c53077fb25e92da089a6Christian König buf->tex_transfer = dec->base.context->get_transfer 54931096e13f858daf896c0c53077fb25e92da089a6Christian König ( 55031096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context, tex, 5517cd1c62b6be88072e3d937b67c499592490927f1Marek Olšák 0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE, 55231096e13f858daf896c0c53077fb25e92da089a6Christian König &rect 55331096e13f858daf896c0c53077fb25e92da089a6Christian König ); 5542e6274fc3b123e7de695038054b5cbd20b11559aChristian König 55531096e13f858daf896c0c53077fb25e92da089a6Christian König buf->block_num = 0; 55631096e13f858daf896c0c53077fb25e92da089a6Christian König buf->texels = dec->base.context->transfer_map(dec->base.context, buf->tex_transfer); 5572e6274fc3b123e7de695038054b5cbd20b11559aChristian König 5588abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) { 55931096e13f858daf896c0c53077fb25e92da089a6Christian König buf->ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i); 560d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->num_ycbcr_blocks[i] = 0; 5612e6274fc3b123e7de695038054b5cbd20b11559aChristian König } 562c888fe027c338f337123de4da2de1ac73b0f7587Christian König 563d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (i = 0; i < VL_MAX_REF_FRAMES; ++i) 564d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i); 565c888fe027c338f337123de4da2de1ac73b0f7587Christian König 5668ea416f35de0c664ef47b71841756758f22d7faaChristian König if (dec->base.entrypoint >= PIPE_VIDEO_ENTRYPOINT_IDCT) { 5678abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) 5686ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear); 569c888fe027c338f337123de4da2de1ac73b0f7587Christian König } 570d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 571d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 572d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian Königstatic void 573d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian Königvl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder, 5748ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_video_buffer *target, 5758ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_picture_desc *picture, 576d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König const struct pipe_macroblock *macroblocks, 577d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König unsigned num_macroblocks) 578b7acf83d523563cde613fe805bd8edaa02f64b53Christian König{ 5791d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; 580d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks; 5818ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; 582d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_mpeg12_buffer *buf; 583d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 584d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König unsigned i, j, mv_weights[2]; 585b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 5868ea416f35de0c664ef47b71841756758f22d7faaChristian König assert(dec && target && picture); 587d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(macroblocks && macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); 588b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 5898ea416f35de0c664ef47b71841756758f22d7faaChristian König buf = vl_mpeg12_get_decode_buffer(dec, target); 590d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König assert(buf); 591b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 592d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (; num_macroblocks > 0; --num_macroblocks) { 593d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König unsigned mb_addr = mb->y * dec->width_in_macroblocks + mb->x; 594b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 595d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_PATTERN | PIPE_MPEG12_MB_TYPE_INTRA)) 596d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König UploadYcbcrBlocks(dec, buf, mb); 597b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 598d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König MacroBlockTypeToPipeWeights(mb, mv_weights); 599b7acf83d523563cde613fe805bd8edaa02f64b53Christian König 600d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (i = 0; i < 2; ++i) { 6018ea416f35de0c664ef47b71841756758f22d7faaChristian König if (!desc->ref[i]) continue; 602d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 603d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->mv_stream[i][mb_addr] = MotionVectorToPipe 604d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König ( 605d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mb, i, 606d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König i ? PIPE_MPEG12_FS_FIRST_BACKWARD : PIPE_MPEG12_FS_FIRST_FORWARD, 607d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König mv_weights[i] 608d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König ); 609d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 610d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 611d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König /* see section 7.6.6 of the spec */ 612d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (mb->num_skipped_macroblocks > 0) { 613d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König struct vl_motionvector skipped_mv[2]; 614d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 6158ea416f35de0c664ef47b71841756758f22d7faaChristian König if (desc->ref[0] && !desc->ref[1]) { 616d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[0].top.x = skipped_mv[0].top.y = 0; 617d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[0].top.weight = PIPE_VIDEO_MV_WEIGHT_MAX; 618d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } else { 619d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[0] = buf->mv_stream[0][mb_addr]; 620d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[1] = buf->mv_stream[1][mb_addr]; 621d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 622d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[0].top.field_select = PIPE_VIDEO_FRAME; 623d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[1].top.field_select = PIPE_VIDEO_FRAME; 624d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 625d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[0].bottom = skipped_mv[0].top; 626d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König skipped_mv[1].bottom = skipped_mv[1].top; 627d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 628d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König ++mb_addr; 629d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (i = 0; i < mb->num_skipped_macroblocks; ++i, ++mb_addr) { 630d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König for (j = 0; j < 2; ++j) { 6318ea416f35de0c664ef47b71841756758f22d7faaChristian König if (!desc->ref[j]) continue; 632d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König buf->mv_stream[j][mb_addr] = skipped_mv[j]; 6332e6274fc3b123e7de695038054b5cbd20b11559aChristian König 634d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 635d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 636d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 637d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König 638d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König ++mb; 639d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König } 640d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 641d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 642d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void 6431d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königvl_mpeg12_decode_bitstream(struct pipe_video_decoder *decoder, 6448ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_video_buffer *target, 6458ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_picture_desc *picture, 6467ac114f94a8fac5fa7cc0e99bf6a3c03ec194650Christian König unsigned num_buffers, 6477ac114f94a8fac5fa7cc0e99bf6a3c03ec194650Christian König const void * const *buffers, 6487ac114f94a8fac5fa7cc0e99bf6a3c03ec194650Christian König const unsigned *sizes) 649c888fe027c338f337123de4da2de1ac73b0f7587Christian König{ 6501d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; 6518ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; 6521d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_buffer *buf; 65313da00f07c35d78b7ba8bc5d30e8c4b0b001744cChristian König 6546ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König unsigned i; 6556ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König 6568ea416f35de0c664ef47b71841756758f22d7faaChristian König assert(dec && target && picture); 6576ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König 6588ea416f35de0c664ef47b71841756758f22d7faaChristian König buf = vl_mpeg12_get_decode_buffer(dec, target); 6591d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(buf); 6606ad846ee78d9d8ba93dcecdefbf89f2b981333efChristian König 6618abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) 6628ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_zscan_set_layout(&buf->zscan[i], desc->alternate_scan ? 6631d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->zscan_alternate : dec->zscan_normal); 664c888fe027c338f337123de4da2de1ac73b0f7587Christian König 6658ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_mpg12_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes); 666c888fe027c338f337123de4da2de1ac73b0f7587Christian König} 667c888fe027c338f337123de4da2de1ac73b0f7587Christian König 668c888fe027c338f337123de4da2de1ac73b0f7587Christian Königstatic void 6698ea416f35de0c664ef47b71841756758f22d7faaChristian Königvl_mpeg12_end_frame(struct pipe_video_decoder *decoder, 6708ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_video_buffer *target, 6718ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_picture_desc *picture) 672d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{ 6731d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; 6748ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture; 6758ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_sampler_view **ref_frames[2]; 6761d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct pipe_sampler_view **mc_source_sv; 6778ea416f35de0c664ef47b71841756758f22d7faaChristian König struct pipe_surface **target_surfaces; 6781d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct pipe_vertex_buffer vb[3]; 6791d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König struct vl_mpeg12_buffer *buf; 6802e6274fc3b123e7de695038054b5cbd20b11559aChristian König 6812eabd05b7525f081ec203747a436d597ce33eb3bChristian König const unsigned *plane_order; 6821d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König unsigned i, j, component; 6831d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König unsigned nr_components; 684d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 6858ea416f35de0c664ef47b71841756758f22d7faaChristian König assert(dec && target && picture); 686900168284615e61e13b6511c655b29e9ddb025b3Christian König assert(!target->interlaced); 6871d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 6888ea416f35de0c664ef47b71841756758f22d7faaChristian König buf = vl_mpeg12_get_decode_buffer(dec, target); 689d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 690ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König vl_vb_unmap(&buf->vertex_stream, dec->base.context); 6912e6274fc3b123e7de695038054b5cbd20b11559aChristian König 69231096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context->transfer_unmap(dec->base.context, buf->tex_transfer); 69331096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context->transfer_destroy(dec->base.context, buf->tex_transfer); 694d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 695b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König vb[0] = dec->quads; 696b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König vb[1] = dec->pos; 697d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 6988ea416f35de0c664ef47b71841756758f22d7faaChristian König target_surfaces = target->get_surfaces(target); 6998ea416f35de0c664ef47b71841756758f22d7faaChristian König 7008ea416f35de0c664ef47b71841756758f22d7faaChristian König for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 7018ea416f35de0c664ef47b71841756758f22d7faaChristian König if (desc->ref[i]) 7028ea416f35de0c664ef47b71841756758f22d7faaChristian König ref_frames[i] = desc->ref[i]->get_sampler_view_planes(desc->ref[i]); 7038ea416f35de0c664ef47b71841756758f22d7faaChristian König else 7048ea416f35de0c664ef47b71841756758f22d7faaChristian König ref_frames[i] = NULL; 7058ea416f35de0c664ef47b71841756758f22d7faaChristian König } 7068ea416f35de0c664ef47b71841756758f22d7faaChristian König 707ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_mv); 7088abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) { 7098ea416f35de0c664ef47b71841756758f22d7faaChristian König if (!target_surfaces[i]) continue; 7103ea7e2713c836f23d59c4034385609e371a94c8dChristian König 7118ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_mc_set_surface(&buf->mc[i], target_surfaces[i]); 71210c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König 7133ea7e2713c836f23d59c4034385609e371a94c8dChristian König for (j = 0; j < VL_MAX_REF_FRAMES; ++j) { 7148ea416f35de0c664ef47b71841756758f22d7faaChristian König if (!ref_frames[j] || !ref_frames[j][i]) continue; 71510c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König 716b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);; 717ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->set_vertex_buffers(dec->base.context, 3, vb); 718b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König 7198ea416f35de0c664ef47b71841756758f22d7faaChristian König vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]); 72010c49b28752f5f2d822dfb1e2e6a1ec213cc44daChristian König } 721b8a6e0e6fc451096d684a1e18529ab4879cdba0aChristian König } 722b88fa924009b5cc572187d3ca6a395d5226aa1c3Christian König 723ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_ycbcr); 7248abbdb8865890e1a39ebbbfae38422014f80072aChristian König for (i = 0; i < VL_NUM_COMPONENTS; ++i) { 725d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König if (!buf->num_ycbcr_blocks[i]) continue; 726849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König 727849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); 72831096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context->set_vertex_buffers(dec->base.context, 2, vb); 729849bc838e81f930e6f090e6c6597bb92e822b4c9Christian König 730bce506ffc09c44552c3d1053c6a0450b8f010292Christian König vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]); 731f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 732fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 733bce506ffc09c44552c3d1053c6a0450b8f010292Christian König vl_idct_flush(i ? &dec->idct_c : &dec->idct_y, &buf->idct[i], buf->num_ycbcr_blocks[i]); 7343ea7e2713c836f23d59c4034385609e371a94c8dChristian König } 7353ea7e2713c836f23d59c4034385609e371a94c8dChristian König 7362eabd05b7525f081ec203747a436d597ce33eb3bChristian König plane_order = vl_video_buffer_plane_order(target->buffer_format); 7370121aae967d3d1366cccc8946cf89ad22818365eChristian König mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 738900168284615e61e13b6511c655b29e9ddb025b3Christian König for (i = 0, component = 0; component < VL_NUM_COMPONENTS; ++i) { 7398ea416f35de0c664ef47b71841756758f22d7faaChristian König if (!target_surfaces[i]) continue; 740d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 7418ea416f35de0c664ef47b71841756758f22d7faaChristian König nr_components = util_format_get_nr_components(target_surfaces[i]->texture->format); 7423ea7e2713c836f23d59c4034385609e371a94c8dChristian König for (j = 0; j < nr_components; ++j, ++component) { 7432eabd05b7525f081ec203747a436d597ce33eb3bChristian König unsigned plane = plane_order[component]; 7442eabd05b7525f081ec203747a436d597ce33eb3bChristian König if (!buf->num_ycbcr_blocks[plane]) continue; 7453ea7e2713c836f23d59c4034385609e371a94c8dChristian König 7462eabd05b7525f081ec203747a436d597ce33eb3bChristian König vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane); 74731096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context->set_vertex_buffers(dec->base.context, 2, vb); 7487f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 7497f04fe5338d0846ec9a6003033da5357d2785c8bChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 7502eabd05b7525f081ec203747a436d597ce33eb3bChristian König vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]); 7517f04fe5338d0846ec9a6003033da5357d2785c8bChristian König else { 7522eabd05b7525f081ec203747a436d597ce33eb3bChristian König dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[plane]); 753ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->bind_fragment_sampler_states(dec->base.context, 1, &dec->sampler_ycbcr); 7547f04fe5338d0846ec9a6003033da5357d2785c8bChristian König } 7552eabd05b7525f081ec203747a436d597ce33eb3bChristian König vl_mc_render_ycbcr(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], j, buf->num_ycbcr_blocks[plane]); 7563ea7e2713c836f23d59c4034385609e371a94c8dChristian König } 757d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König } 7588c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König ++dec->current_buffer; 7598c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König dec->current_buffer %= 4; 760d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 761d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 7621d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königstatic void 7631d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königvl_mpeg12_flush(struct pipe_video_decoder *decoder) 7641d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König{ 7651d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König assert(decoder); 7661d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 7671d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König //Noop, for shaders it is much faster to flush everything in end_frame 7681d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König} 7691d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König 770d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic bool 771d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königinit_pipe_state(struct vl_mpeg12_decoder *dec) 772d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{ 773d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König struct pipe_depth_stencil_alpha_state dsa; 7747f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct pipe_sampler_state sampler; 775d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König unsigned i; 776d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 777d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König assert(dec); 778d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 779d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König memset(&dsa, 0, sizeof dsa); 780d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.depth.enabled = 0; 781d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.depth.writemask = 0; 782d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.depth.func = PIPE_FUNC_ALWAYS; 783d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König for (i = 0; i < 2; ++i) { 784d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].enabled = 0; 785d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].func = PIPE_FUNC_ALWAYS; 786d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; 787d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; 788d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; 789d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].valuemask = 0; 790d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.stencil[i].writemask = 0; 791d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König } 792d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.alpha.enabled = 0; 793d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.alpha.func = PIPE_FUNC_ALWAYS; 794d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dsa.alpha.ref_value = 0; 795ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->dsa = dec->base.context->create_depth_stencil_alpha_state(dec->base.context, &dsa); 796ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->bind_depth_stencil_alpha_state(dec->base.context, dec->dsa); 797d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 7987f04fe5338d0846ec9a6003033da5357d2785c8bChristian König memset(&sampler, 0, sizeof(sampler)); 7997f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 8007f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 8017f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 8027f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 8037f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 8047f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 8057f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 8067f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.compare_func = PIPE_FUNC_ALWAYS; 8077f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler.normalized_coords = 1; 808ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->sampler_ycbcr = dec->base.context->create_sampler_state(dec->base.context, &sampler); 8097f04fe5338d0846ec9a6003033da5357d2785c8bChristian König if (!dec->sampler_ycbcr) 8107f04fe5338d0846ec9a6003033da5357d2785c8bChristian König return false; 8117f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 812d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return true; 813d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 814d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 815311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königstatic const struct format_config* 816311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königfind_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs) 817bad3085c7839de734f6b883088f91ae55db61a35Christian König{ 818bad3085c7839de734f6b883088f91ae55db61a35Christian König struct pipe_screen *screen; 819bad3085c7839de734f6b883088f91ae55db61a35Christian König unsigned i; 820bad3085c7839de734f6b883088f91ae55db61a35Christian König 821bad3085c7839de734f6b883088f91ae55db61a35Christian König assert(dec); 822bad3085c7839de734f6b883088f91ae55db61a35Christian König 823ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König screen = dec->base.context->screen; 824bad3085c7839de734f6b883088f91ae55db61a35Christian König 825311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König for (i = 0; i < num_configs; ++i) { 826311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D, 827311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1, PIPE_BIND_SAMPLER_VIEW)) 828311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König continue; 829311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 830311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (configs[i].idct_source_format != PIPE_FORMAT_NONE) { 831311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D, 832311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 833311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König continue; 834311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 835311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D, 836311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 837311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König continue; 838311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König } else { 839311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D, 840311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 841311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König continue; 842311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König } 843311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König return &configs[i]; 844311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König } 845bad3085c7839de734f6b883088f91ae55db61a35Christian König 846311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König return NULL; 847bad3085c7839de734f6b883088f91ae55db61a35Christian König} 848bad3085c7839de734f6b883088f91ae55db61a35Christian König 849d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic bool 850311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 851f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König{ 852f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König unsigned num_channels; 853f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 854f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König assert(dec); 855f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 856311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König dec->zscan_source_format = format_config->zscan_source_format; 857ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->zscan_linear = vl_zscan_layout(dec->base.context, vl_zscan_linear, dec->blocks_per_line); 858ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->zscan_normal = vl_zscan_layout(dec->base.context, vl_zscan_normal, dec->blocks_per_line); 859ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->zscan_alternate = vl_zscan_layout(dec->base.context, vl_zscan_alternate, dec->blocks_per_line); 860f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 861f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1; 862f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 863ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!vl_zscan_init(&dec->zscan_y, dec->base.context, dec->base.width, dec->base.height, 864a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König dec->blocks_per_line, dec->num_blocks, num_channels)) 865f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return false; 866f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 867ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!vl_zscan_init(&dec->zscan_c, dec->base.context, dec->chroma_width, dec->chroma_height, 868a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König dec->blocks_per_line, dec->num_blocks, num_channels)) 869f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return false; 870f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 871f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König return true; 872f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König} 873f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 874f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian Königstatic bool 875311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 876d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{ 877ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König unsigned nr_of_idct_render_targets, max_inst; 8780121aae967d3d1366cccc8946cf89ad22818365eChristian König enum pipe_format formats[3]; 879e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König struct pipe_video_buffer templat; 8800121aae967d3d1366cccc8946cf89ad22818365eChristian König 881311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König struct pipe_sampler_view *matrix = NULL; 882d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 883ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König nr_of_idct_render_targets = dec->base.context->screen->get_param 884ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König ( 885ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->screen, PIPE_CAP_MAX_RENDER_TARGETS 886ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König ); 887ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König 888ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König max_inst = dec->base.context->screen->get_shader_param 889ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König ( 890ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König dec->base.context->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INSTRUCTIONS 891ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König ); 892871d6d49c931739d94e646f2b0c3eb5db8a03d69Christian König 893ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König // Just assume we need 32 inst per render target, not 100% true, but should work in most cases 894ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4) 895ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König // more than 4 render targets usually doesn't makes any seens 896ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König nr_of_idct_render_targets = 4; 897ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König else 898ded2a9a628c58c2c8bfaaf6b8dd213e68de1dd20Christian König nr_of_idct_render_targets = 1; 899fcf765620d803b376582afb618b1f643242b641bChristian König 900311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König formats[0] = formats[1] = formats[2] = format_config->idct_source_format; 901e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König memset(&templat, 0, sizeof(templat)); 902e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.width = dec->base.width / 4; 903e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.height = dec->base.height; 904e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.chroma_format = dec->base.chroma_format; 9054e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König dec->idct_source = vl_video_buffer_create_ex 9064e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ( 907e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König dec->base.context, &templat, 908e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König formats, 1, PIPE_USAGE_STATIC 9094e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ); 9104e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König 9110121aae967d3d1366cccc8946cf89ad22818365eChristian König if (!dec->idct_source) 9120121aae967d3d1366cccc8946cf89ad22818365eChristian König goto error_idct_source; 9130121aae967d3d1366cccc8946cf89ad22818365eChristian König 914311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 915e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König memset(&templat, 0, sizeof(templat)); 916e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.width = dec->base.width / nr_of_idct_render_targets; 917e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.height = dec->base.height / 4; 918e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.chroma_format = dec->base.chroma_format; 9194e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König dec->mc_source = vl_video_buffer_create_ex 9204e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ( 921e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König dec->base.context, &templat, 922e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König formats, nr_of_idct_render_targets, PIPE_USAGE_STATIC 9234e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ); 9240121aae967d3d1366cccc8946cf89ad22818365eChristian König 9250121aae967d3d1366cccc8946cf89ad22818365eChristian König if (!dec->mc_source) 9260121aae967d3d1366cccc8946cf89ad22818365eChristian König goto error_mc_source; 927ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König 928ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!(matrix = vl_idct_upload_matrix(dec->base.context, format_config->idct_scale))) 929ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König goto error_matrix; 930ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König 931ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!vl_idct_init(&dec->idct_y, dec->base.context, dec->base.width, dec->base.height, 932311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König nr_of_idct_render_targets, matrix, matrix)) 933ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König goto error_y; 934d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 935ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if(!vl_idct_init(&dec->idct_c, dec->base.context, dec->chroma_width, dec->chroma_height, 936311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König nr_of_idct_render_targets, matrix, matrix)) 937ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König goto error_c; 938d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 939ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König pipe_sampler_view_reference(&matrix, NULL); 9400121aae967d3d1366cccc8946cf89ad22818365eChristian König 941d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return true; 942d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 943ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_c: 944d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König vl_idct_cleanup(&dec->idct_y); 945d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 946ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_y: 947ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König pipe_sampler_view_reference(&matrix, NULL); 948d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 949ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian Königerror_matrix: 9500121aae967d3d1366cccc8946cf89ad22818365eChristian König dec->mc_source->destroy(dec->mc_source); 9510121aae967d3d1366cccc8946cf89ad22818365eChristian König 9520121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_mc_source: 9530121aae967d3d1366cccc8946cf89ad22818365eChristian König dec->idct_source->destroy(dec->idct_source); 9540121aae967d3d1366cccc8946cf89ad22818365eChristian König 9550121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_idct_source: 956d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return false; 957d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 958d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 9590121aae967d3d1366cccc8946cf89ad22818365eChristian Königstatic bool 960311eb749a1ab7ffd417bc456345d63eba75e3fecChristian Königinit_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 9610121aae967d3d1366cccc8946cf89ad22818365eChristian König{ 9620121aae967d3d1366cccc8946cf89ad22818365eChristian König enum pipe_format formats[3]; 963e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König struct pipe_video_buffer templat; 9640121aae967d3d1366cccc8946cf89ad22818365eChristian König 965311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 966e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König memset(&templat, 0, sizeof(templat)); 967e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.width = dec->base.width; 968e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.height = dec->base.height; 969e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König templat.chroma_format = dec->base.chroma_format; 9704e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König dec->mc_source = vl_video_buffer_create_ex 9714e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ( 972e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König dec->base.context, &templat, 973e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König formats, 1, PIPE_USAGE_STATIC 9744e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König ); 9754e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König 976311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König return dec->mc_source != NULL; 9770121aae967d3d1366cccc8946cf89ad22818365eChristian König} 9780121aae967d3d1366cccc8946cf89ad22818365eChristian König 9797f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königstatic void 9807f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königmc_vert_shader_callback(void *priv, struct vl_mc *mc, 9817f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_program *shader, 9827f04fe5338d0846ec9a6003033da5357d2785c8bChristian König unsigned first_output, 9837f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_dst tex) 9847f04fe5338d0846ec9a6003033da5357d2785c8bChristian König{ 9857f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct vl_mpeg12_decoder *dec = priv; 9867f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_dst o_vtex; 9877f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 9887f04fe5338d0846ec9a6003033da5357d2785c8bChristian König assert(priv && mc); 9897f04fe5338d0846ec9a6003033da5357d2785c8bChristian König assert(shader); 9907f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 9917f04fe5338d0846ec9a6003033da5357d2785c8bChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 9927f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 9937f04fe5338d0846ec9a6003033da5357d2785c8bChristian König vl_idct_stage2_vert_shader(idct, shader, first_output, tex); 9947f04fe5338d0846ec9a6003033da5357d2785c8bChristian König } else { 9957f04fe5338d0846ec9a6003033da5357d2785c8bChristian König o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output); 9967f04fe5338d0846ec9a6003033da5357d2785c8bChristian König ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex)); 9977f04fe5338d0846ec9a6003033da5357d2785c8bChristian König } 9987f04fe5338d0846ec9a6003033da5357d2785c8bChristian König} 9997f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 10007f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königstatic void 10017f04fe5338d0846ec9a6003033da5357d2785c8bChristian Königmc_frag_shader_callback(void *priv, struct vl_mc *mc, 10027f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_program *shader, 10037f04fe5338d0846ec9a6003033da5357d2785c8bChristian König unsigned first_input, 10047f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_dst dst) 10057f04fe5338d0846ec9a6003033da5357d2785c8bChristian König{ 10067f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct vl_mpeg12_decoder *dec = priv; 10077f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct ureg_src src, sampler; 10087f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 10097f04fe5338d0846ec9a6003033da5357d2785c8bChristian König assert(priv && mc); 10107f04fe5338d0846ec9a6003033da5357d2785c8bChristian König assert(shader); 10117f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 10127f04fe5338d0846ec9a6003033da5357d2785c8bChristian König if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 10137f04fe5338d0846ec9a6003033da5357d2785c8bChristian König struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 10147f04fe5338d0846ec9a6003033da5357d2785c8bChristian König vl_idct_stage2_frag_shader(idct, shader, first_input, dst); 10157f04fe5338d0846ec9a6003033da5357d2785c8bChristian König } else { 10167f04fe5338d0846ec9a6003033da5357d2785c8bChristian König src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR); 10177f04fe5338d0846ec9a6003033da5357d2785c8bChristian König sampler = ureg_DECL_sampler(shader, 0); 10187f04fe5338d0846ec9a6003033da5357d2785c8bChristian König ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler); 10197f04fe5338d0846ec9a6003033da5357d2785c8bChristian König } 10207f04fe5338d0846ec9a6003033da5357d2785c8bChristian König} 10217f04fe5338d0846ec9a6003033da5357d2785c8bChristian König 1022d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstruct pipe_video_decoder * 1023ea78480029450c019287c2a94d7c42a6a1d12dc3Christian Königvl_create_mpeg12_decoder(struct pipe_context *context, 1024d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König enum pipe_video_profile profile, 1025fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König enum pipe_video_entrypoint entrypoint, 1026d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König enum pipe_video_chroma_format chroma_format, 10278c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König unsigned width, unsigned height, unsigned max_references, 10288c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König bool expect_chunked_decode) 1029d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{ 103070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König const unsigned block_size_pixels = VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; 1031311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König const struct format_config *format_config; 1032d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König struct vl_mpeg12_decoder *dec; 1033d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1034d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); 1035d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1036d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec = CALLOC_STRUCT(vl_mpeg12_decoder); 1037d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1038d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König if (!dec) 1039d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return NULL; 1040d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1041d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.context = context; 1042d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.profile = profile; 1043fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König dec->base.entrypoint = entrypoint; 1044d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.chroma_format = chroma_format; 1045d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.width = width; 1046d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.height = height; 104782e8bf36d8fcd46bcb76ec300875a47c7312f1a1Emeric Grange dec->base.max_references = max_references; 1048d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1049d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König dec->base.destroy = vl_mpeg12_destroy; 10501d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.begin_frame = vl_mpeg12_begin_frame; 1051d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König dec->base.decode_macroblock = vl_mpeg12_decode_macroblock; 10521d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.decode_bitstream = vl_mpeg12_decode_bitstream; 10531d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.end_frame = vl_mpeg12_end_frame; 10541d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König dec->base.flush = vl_mpeg12_flush; 1055d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1056a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4); 1057a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels; 105870a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König dec->width_in_macroblocks = align(dec->base.width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; 10598c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König dec->expect_chunked_decode = expect_chunked_decode; 1060a6c76c8a90dc8995feed3c61b02dbd8408149036Christian König 1061fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König /* TODO: Implement 422, 444 */ 1062fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 1063d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1064f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 1065f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_width = dec->base.width / 2; 1066f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_height = dec->base.height / 2; 106731096e13f858daf896c0c53077fb25e92da089a6Christian König dec->num_blocks = dec->num_blocks * 2; 1068f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 1069f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_width = dec->base.width; 1070f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_height = dec->base.height / 2; 107131096e13f858daf896c0c53077fb25e92da089a6Christian König dec->num_blocks = dec->num_blocks * 2 + dec->num_blocks; 1072f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König } else { 1073f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_width = dec->base.width; 1074f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König dec->chroma_height = dec->base.height; 107531096e13f858daf896c0c53077fb25e92da089a6Christian König dec->num_blocks = dec->num_blocks * 3; 1076f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König } 1077f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 107831096e13f858daf896c0c53077fb25e92da089a6Christian König dec->quads = vl_vb_upload_quads(dec->base.context); 107931096e13f858daf896c0c53077fb25e92da089a6Christian König dec->pos = vl_vb_upload_pos( 108031096e13f858daf896c0c53077fb25e92da089a6Christian König dec->base.context, 108170a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König dec->base.width / VL_MACROBLOCK_WIDTH, 108270a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König dec->base.height / VL_MACROBLOCK_HEIGHT 108331096e13f858daf896c0c53077fb25e92da089a6Christian König ); 108431096e13f858daf896c0c53077fb25e92da089a6Christian König 108531096e13f858daf896c0c53077fb25e92da089a6Christian König dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->base.context); 108631096e13f858daf896c0c53077fb25e92da089a6Christian König dec->ves_mv = vl_vb_get_ves_mv(dec->base.context); 108731096e13f858daf896c0c53077fb25e92da089a6Christian König 1088311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König switch (entrypoint) { 1089311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: 1090311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs); 1091311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König break; 1092311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1093311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König case PIPE_VIDEO_ENTRYPOINT_IDCT: 1094311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König format_config = find_format_config(dec, idct_format_config, num_idct_format_configs); 1095311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König break; 1096311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1097311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König case PIPE_VIDEO_ENTRYPOINT_MC: 1098311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König format_config = find_format_config(dec, mc_format_config, num_mc_format_configs); 1099311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König break; 1100311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1101311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König default: 1102311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König assert(0); 1103adb7f1351e4c231184a6355573c01c7780135342Vinson Lee FREE(dec); 1104311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König return NULL; 1105311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König } 1106311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1107adb7f1351e4c231184a6355573c01c7780135342Vinson Lee if (!format_config) { 1108adb7f1351e4c231184a6355573c01c7780135342Vinson Lee FREE(dec); 1109311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König return NULL; 1110adb7f1351e4c231184a6355573c01c7780135342Vinson Lee } 1111311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König 1112311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!init_zscan(dec, format_config)) 111324d76d2966a5c666c9627034e6751621b17024c8Christian König goto error_zscan; 1114f0819a22f3dc63d1c0dde6320babf9b7fcda15bbChristian König 1115ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 1116311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!init_idct(dec, format_config)) 11170121aae967d3d1366cccc8946cf89ad22818365eChristian König goto error_sources; 1118ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König } else { 1119311eb749a1ab7ffd417bc456345d63eba75e3fecChristian König if (!init_mc_source_widthout_idct(dec, format_config)) 11200121aae967d3d1366cccc8946cf89ad22818365eChristian König goto error_sources; 1121ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König } 1122ccc80d2c09ad35f867c0c0a85f7e1cadd73941bbChristian König 1123ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!vl_mc_init(&dec->mc_y, dec->base.context, dec->base.width, dec->base.height, 112470a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König VL_MACROBLOCK_HEIGHT, format_config->mc_scale, 11257f04fe5338d0846ec9a6003033da5357d2785c8bChristian König mc_vert_shader_callback, mc_frag_shader_callback, dec)) 1126ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König goto error_mc_y; 1127ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König 1128f1485e155a985df3100708f4bfb1a9d7c72217f4Christian König // TODO 1129ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König if (!vl_mc_init(&dec->mc_c, dec->base.context, dec->base.width, dec->base.height, 113070a7695b4d1bd3f609eb9f98dd6872f1a5b89762Christian König VL_BLOCK_HEIGHT, format_config->mc_scale, 11317f04fe5338d0846ec9a6003033da5357d2785c8bChristian König mc_vert_shader_callback, mc_frag_shader_callback, dec)) 1132ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König goto error_mc_c; 1133d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1134d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König if (!init_pipe_state(dec)) 1135d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König goto error_pipe_state; 1136d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1137d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return &dec->base; 1138d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1139d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königerror_pipe_state: 1140ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König vl_mc_cleanup(&dec->mc_c); 1141ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König 1142ff210aea7c080600bd45eb18b29a6109468ed4dfChristian Königerror_mc_c: 1143ff210aea7c080600bd45eb18b29a6109468ed4dfChristian König vl_mc_cleanup(&dec->mc_y); 1144d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 1145ff210aea7c080600bd45eb18b29a6109468ed4dfChristian Königerror_mc_y: 1146fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 1147fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König vl_idct_cleanup(&dec->idct_y); 1148fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König vl_idct_cleanup(&dec->idct_c); 11490121aae967d3d1366cccc8946cf89ad22818365eChristian König dec->idct_source->destroy(dec->idct_source); 1150fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König } 11510121aae967d3d1366cccc8946cf89ad22818365eChristian König dec->mc_source->destroy(dec->mc_source); 1152d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König 11530121aae967d3d1366cccc8946cf89ad22818365eChristian Königerror_sources: 115424d76d2966a5c666c9627034e6751621b17024c8Christian König vl_zscan_cleanup(&dec->zscan_y); 115524d76d2966a5c666c9627034e6751621b17024c8Christian König vl_zscan_cleanup(&dec->zscan_c); 115624d76d2966a5c666c9627034e6751621b17024c8Christian König 115724d76d2966a5c666c9627034e6751621b17024c8Christian Königerror_zscan: 1158d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König FREE(dec); 1159d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König return NULL; 1160d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König} 1161