vl_mpeg12_decoder.c revision df5e0b9435c869f88234a69db9bfe97342b027d4
103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/************************************************************************** 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009 Younes Manton. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved. 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * 69ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch * Permission is hereby granted, free of charge, to any person obtaining a 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * copy of this software and associated documentation files (the 86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish, 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * the following conditions: 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * The above copyright notice and this permission notice (including the 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * of the Software. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) **************************************************************************/ 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <math.h> 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <assert.h> 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <util/u_memory.h> 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <util/u_rect.h> 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <util/u_video.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "vl_mpeg12_decoder.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "vl_defines.h" 37c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 38c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#define SCALE_FACTOR_SNORM (32768.0f / 256.0f) 39c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#define SCALE_FACTOR_SSCALED (1.0f / 256.0f) 40c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 41c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochstruct format_config { 42c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch enum pipe_format zscan_source_format; 43c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch enum pipe_format idct_source_format; 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enum pipe_format mc_source_format; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch float idct_scale; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float mc_scale; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct format_config bitstream_format_config[] = { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 56c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const unsigned num_bitstream_format_configs = 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(bitstream_format_config) / sizeof(struct format_config); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct format_config idct_format_config[] = { 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const unsigned num_idct_format_configs = 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sizeof(idct_format_config) / sizeof(struct format_config); 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)static const struct format_config mc_format_config[] = { 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED }, 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM } 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const unsigned num_mc_format_configs = 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sizeof(mc_format_config) / sizeof(struct format_config); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochinit_zscan_buffer(struct vl_mpeg12_buffer *buffer) 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum pipe_format formats[3]; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_sampler_view **source; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_surface **destination; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct vl_mpeg12_decoder *dec; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned i; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) assert(buffer); 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formats[0] = formats[1] = formats[2] = dec->zscan_source_format; 95c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch buffer->zscan_source = vl_video_buffer_create_ex 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ( 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dec->base.context, 986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT, 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) align(dec->num_blocks, dec->blocks_per_line) / dec->blocks_per_line, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, PIPE_VIDEO_CHROMA_FORMAT_444, formats, PIPE_USAGE_STATIC 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!buffer->zscan_source) 104c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_source; 105c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 106c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch source = buffer->zscan_source->get_sampler_view_planes(buffer->zscan_source); 107c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!source) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error_sampler; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination = dec->idct_source->get_surfaces(dec->idct_source); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination = dec->mc_source->get_surfaces(dec->mc_source); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!destination) 116c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_surface; 117c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 118c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch for (i = 0; i < VL_MAX_PLANES; ++i) 119c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &buffer->zscan[i], source[i], destination[i])) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error_plane; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return true; 124c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 125c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdocherror_plane: 126c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch for (; i > 0; --i) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)error_surface: 130c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdocherror_sampler: 131c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch buffer->zscan_source->destroy(buffer->zscan_source); 132c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 133c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdocherror_source: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochstatic void 138c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochcleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer) 139c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch{ 140c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch unsigned i; 141c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 142c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(buffer); 143c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 144c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch for (i = 0; i < VL_MAX_PLANES; ++i) 145c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_zscan_cleanup_buffer(&buffer->zscan[i]); 146c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch buffer->zscan_source->destroy(buffer->zscan_source); 147c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 148c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)init_idct_buffer(struct vl_mpeg12_buffer *buffer) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 152c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch struct pipe_sampler_view **idct_source_sv, **mc_source_sv; 153c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 154c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch struct vl_mpeg12_decoder *dec; 155c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned i; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(buffer); 159c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 160c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 161c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 162c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source); 163c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!idct_source_sv) 164c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_source_sv; 165c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 166c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 167c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!mc_source_sv) 168c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_mc_source_sv; 169c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 170c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch for (i = 0; i < 3; ++i) 171c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, 172c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch &buffer->idct[i], idct_source_sv[i], 173c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch mc_source_sv[i])) 174c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_plane; 175c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 176c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return true; 177c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 178c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdocherror_plane: 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (; i > 0; --i) 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]); 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)error_mc_source_sv: 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)error_source_sv: 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)cleanup_idct_buffer(struct vl_mpeg12_buffer *buf) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct vl_mpeg12_decoder *dec; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(buf); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 194c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(dec); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]); 197c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]); 198c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]); 199c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)init_mc_buffer(struct vl_mpeg12_buffer *buf) 203c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch{ 204c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch struct vl_mpeg12_decoder *dec; 205c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 206c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(buf); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 209c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(dec); 210c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 211c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0])) 212c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_mc_y; 213c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 214c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1])) 215c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_mc_cb; 216c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 217c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2])) 218c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch goto error_mc_cr; 219c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 220c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return true; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error_mc_cr: 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vl_mc_cleanup_buffer(&buf->mc[1]); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error_mc_cb: 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vl_mc_cleanup_buffer(&buf->mc[0]); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)error_mc_y: 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 231c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 232c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochstatic void 233c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochcleanup_mc_buffer(struct vl_mpeg12_buffer *buf) 234c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch{ 235c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch unsigned i; 236c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(buf); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 239c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch for (i = 0; i < VL_MAX_PLANES; ++i) 240c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_mc_cleanup_buffer(&buf->mc[i]); 241c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 242c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct vl_mpeg12_decoder *dec; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(buf); 250c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 251c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 252c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(dec); 253c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 254c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch cleanup_zscan_buffer(buf); 255c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 256c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 257c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch cleanup_idct_buffer(buf); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cleanup_mc_buffer(buf); 260c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 261c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch vl_vb_cleanup(&buf->vertex_stream); 262c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 263c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch FREE(buf); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void 267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvl_mpeg12_buffer_begin_frame(struct pipe_video_decode_buffer *buffer) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct vl_mpeg12_decoder *dec; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_sampler_view **sampler_views; 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned i; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(buf); 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(dec); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vl_vb_map(&buf->vertex_stream, dec->base.context); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sampler_views = buf->zscan_source->get_sampler_view_planes(buf->zscan_source); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(sampler_views); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < VL_MAX_PLANES; ++i) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_resource *tex = sampler_views[i]->texture; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_box rect = 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 0, 0, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tex->width0, 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tex->height0, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf->tex_transfer[i] = dec->base.context->get_transfer 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ( 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dec->base.context, tex, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &rect 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf->texels[i] = dec->base.context->transfer_map(dec->base.context, buf->tex_transfer[i]); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) { 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct pipe_ycbcr_block *ycbcr_stream[VL_MAX_PLANES]; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct pipe_motionvector *mv_stream[VL_MAX_REF_FRAMES]; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (i = 0; i < VL_MAX_PLANES; ++i) 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (i = 0; i < VL_MAX_REF_FRAMES; ++i) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vl_mpg12_bs_set_buffers(&buf->bs, ycbcr_stream, buf->texels, mv_stream); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (i = 0; i < VL_MAX_PLANES; ++i) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear); 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void 3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)vl_mpeg12_buffer_set_quant_matrix(struct pipe_video_decode_buffer *buffer, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint8_t intra_matrix[64], 3270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const uint8_t non_intra_matrix[64]) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned i; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (i = 0; i < VL_MAX_PLANES; ++i) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vl_zscan_upload_quant(&buf->zscan[i], intra_matrix, non_intra_matrix); 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static struct pipe_ycbcr_block * 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component) 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch{ 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) assert(buf); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static short * 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(buf); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(component < VL_MAX_PLANES); 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return buf->texels[component]; 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic unsigned 358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer) 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 360c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 361c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 362c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch assert(buf); 363c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 364c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return vl_vb_get_mv_stream_stride(&buf->vertex_stream); 365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic struct pipe_motionvector * 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame) 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 370 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 371 372 assert(buf); 373 374 return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame); 375} 376 377static void 378vl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer *buffer, 379 unsigned num_bytes, const void *data, 380 struct pipe_mpeg12_picture_desc *picture, 381 unsigned num_ycbcr_blocks[3]) 382{ 383 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 384 struct vl_mpeg12_decoder *dec; 385 unsigned i; 386 387 assert(buf); 388 389 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 390 assert(dec); 391 392 for (i = 0; i < VL_MAX_PLANES; ++i) 393 vl_zscan_set_layout(&buf->zscan[i], picture->alternate_scan ? dec->zscan_alternate : dec->zscan_normal); 394 395 vl_mpg12_bs_decode(&buf->bs, num_bytes, data, picture, num_ycbcr_blocks); 396} 397 398static void 399vl_mpeg12_buffer_end_frame(struct pipe_video_decode_buffer *buffer) 400{ 401 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 402 struct vl_mpeg12_decoder *dec; 403 unsigned i; 404 405 assert(buf); 406 407 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 408 assert(dec); 409 410 vl_vb_unmap(&buf->vertex_stream, dec->base.context); 411 412 for (i = 0; i < VL_MAX_PLANES; ++i) { 413 dec->base.context->transfer_unmap(dec->base.context, buf->tex_transfer[i]); 414 dec->base.context->transfer_destroy(dec->base.context, buf->tex_transfer[i]); 415 } 416} 417 418static void 419vl_mpeg12_destroy(struct pipe_video_decoder *decoder) 420{ 421 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 422 423 assert(decoder); 424 425 /* Asserted in softpipe_delete_fs_state() for some reason */ 426 dec->base.context->bind_vs_state(dec->base.context, NULL); 427 dec->base.context->bind_fs_state(dec->base.context, NULL); 428 429 dec->base.context->delete_depth_stencil_alpha_state(dec->base.context, dec->dsa); 430 dec->base.context->delete_sampler_state(dec->base.context, dec->sampler_ycbcr); 431 432 vl_mc_cleanup(&dec->mc_y); 433 vl_mc_cleanup(&dec->mc_c); 434 dec->mc_source->destroy(dec->mc_source); 435 436 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 437 vl_idct_cleanup(&dec->idct_y); 438 vl_idct_cleanup(&dec->idct_c); 439 dec->idct_source->destroy(dec->idct_source); 440 } 441 442 vl_zscan_cleanup(&dec->zscan_y); 443 vl_zscan_cleanup(&dec->zscan_c); 444 445 dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_ycbcr); 446 dec->base.context->delete_vertex_elements_state(dec->base.context, dec->ves_mv); 447 448 pipe_resource_reference(&dec->quads.buffer, NULL); 449 pipe_resource_reference(&dec->pos.buffer, NULL); 450 pipe_resource_reference(&dec->block_num.buffer, NULL); 451 452 pipe_sampler_view_reference(&dec->zscan_linear, NULL); 453 pipe_sampler_view_reference(&dec->zscan_normal, NULL); 454 pipe_sampler_view_reference(&dec->zscan_alternate, NULL); 455 456 FREE(dec); 457} 458 459static struct pipe_video_decode_buffer * 460vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder) 461{ 462 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 463 struct vl_mpeg12_buffer *buffer; 464 465 assert(dec); 466 467 buffer = CALLOC_STRUCT(vl_mpeg12_buffer); 468 if (buffer == NULL) 469 return NULL; 470 471 buffer->base.decoder = decoder; 472 buffer->base.destroy = vl_mpeg12_buffer_destroy; 473 buffer->base.begin_frame = vl_mpeg12_buffer_begin_frame; 474 buffer->base.set_quant_matrix = vl_mpeg12_buffer_set_quant_matrix; 475 buffer->base.get_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream; 476 buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer; 477 buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride; 478 buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream; 479 buffer->base.decode_bitstream = vl_mpeg12_buffer_decode_bitstream; 480 buffer->base.end_frame = vl_mpeg12_buffer_end_frame; 481 482 if (!vl_vb_init(&buffer->vertex_stream, dec->base.context, 483 dec->base.width / MACROBLOCK_WIDTH, 484 dec->base.height / MACROBLOCK_HEIGHT)) 485 goto error_vertex_buffer; 486 487 if (!init_mc_buffer(buffer)) 488 goto error_mc; 489 490 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 491 if (!init_idct_buffer(buffer)) 492 goto error_idct; 493 494 if (!init_zscan_buffer(buffer)) 495 goto error_zscan; 496 497 if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) 498 vl_mpg12_bs_init(&buffer->bs, 499 dec->base.width / MACROBLOCK_WIDTH, 500 dec->base.height / MACROBLOCK_HEIGHT); 501 502 return &buffer->base; 503 504error_zscan: 505 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 506 cleanup_idct_buffer(buffer); 507 508error_idct: 509 cleanup_mc_buffer(buffer); 510 511error_mc: 512 vl_vb_cleanup(&buffer->vertex_stream); 513 514error_vertex_buffer: 515 FREE(buffer); 516 return NULL; 517} 518 519static void 520vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, 521 unsigned num_ycbcr_blocks[3], 522 struct pipe_video_buffer *refs[2], 523 struct pipe_video_buffer *dst) 524{ 525 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; 526 struct vl_mpeg12_decoder *dec; 527 528 struct pipe_sampler_view **sv[VL_MAX_REF_FRAMES], **mc_source_sv; 529 struct pipe_surface **surfaces; 530 531 struct pipe_vertex_buffer vb[3]; 532 533 unsigned i, j, component; 534 unsigned nr_components; 535 536 assert(buf); 537 538 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 539 assert(dec); 540 541 for (i = 0; i < 2; ++i) 542 sv[i] = refs[i] ? refs[i]->get_sampler_view_planes(refs[i]) : NULL; 543 544 vb[0] = dec->quads; 545 vb[1] = dec->pos; 546 547 surfaces = dst->get_surfaces(dst); 548 549 dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_mv); 550 for (i = 0; i < VL_MAX_PLANES; ++i) { 551 if (!surfaces[i]) continue; 552 553 vl_mc_set_surface(&buf->mc[i], surfaces[i]); 554 555 for (j = 0; j < VL_MAX_REF_FRAMES; ++j) { 556 if (!sv[j]) continue; 557 558 vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);; 559 dec->base.context->set_vertex_buffers(dec->base.context, 3, vb); 560 561 vl_mc_render_ref(&buf->mc[i], sv[j][i]); 562 } 563 } 564 565 vb[2] = dec->block_num; 566 567 dec->base.context->bind_vertex_elements_state(dec->base.context, dec->ves_ycbcr); 568 for (i = 0; i < VL_MAX_PLANES; ++i) { 569 if (!num_ycbcr_blocks[i]) continue; 570 571 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); 572 dec->base.context->set_vertex_buffers(dec->base.context, 3, vb); 573 574 vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]); 575 576 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 577 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]); 578 } 579 580 mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 581 for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) { 582 if (!surfaces[i]) continue; 583 584 nr_components = util_format_get_nr_components(surfaces[i]->texture->format); 585 for (j = 0; j < nr_components; ++j, ++component) { 586 if (!num_ycbcr_blocks[i]) continue; 587 588 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component); 589 dec->base.context->set_vertex_buffers(dec->base.context, 3, vb); 590 591 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 592 vl_idct_prepare_stage2(component == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[component]); 593 else { 594 dec->base.context->set_fragment_sampler_views(dec->base.context, 1, &mc_source_sv[component]); 595 dec->base.context->bind_fragment_sampler_states(dec->base.context, 1, &dec->sampler_ycbcr); 596 } 597 vl_mc_render_ycbcr(&buf->mc[i], j, num_ycbcr_blocks[component]); 598 } 599 } 600} 601 602static bool 603init_pipe_state(struct vl_mpeg12_decoder *dec) 604{ 605 struct pipe_depth_stencil_alpha_state dsa; 606 struct pipe_sampler_state sampler; 607 unsigned i; 608 609 assert(dec); 610 611 memset(&dsa, 0, sizeof dsa); 612 dsa.depth.enabled = 0; 613 dsa.depth.writemask = 0; 614 dsa.depth.func = PIPE_FUNC_ALWAYS; 615 for (i = 0; i < 2; ++i) { 616 dsa.stencil[i].enabled = 0; 617 dsa.stencil[i].func = PIPE_FUNC_ALWAYS; 618 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; 619 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; 620 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; 621 dsa.stencil[i].valuemask = 0; 622 dsa.stencil[i].writemask = 0; 623 } 624 dsa.alpha.enabled = 0; 625 dsa.alpha.func = PIPE_FUNC_ALWAYS; 626 dsa.alpha.ref_value = 0; 627 dec->dsa = dec->base.context->create_depth_stencil_alpha_state(dec->base.context, &dsa); 628 dec->base.context->bind_depth_stencil_alpha_state(dec->base.context, dec->dsa); 629 630 memset(&sampler, 0, sizeof(sampler)); 631 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 632 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 633 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 634 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 635 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 636 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 637 sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 638 sampler.compare_func = PIPE_FUNC_ALWAYS; 639 sampler.normalized_coords = 1; 640 dec->sampler_ycbcr = dec->base.context->create_sampler_state(dec->base.context, &sampler); 641 if (!dec->sampler_ycbcr) 642 return false; 643 644 return true; 645} 646 647static const struct format_config* 648find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs) 649{ 650 struct pipe_screen *screen; 651 unsigned i; 652 653 assert(dec); 654 655 screen = dec->base.context->screen; 656 657 for (i = 0; i < num_configs; ++i) { 658 if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D, 659 1, PIPE_BIND_SAMPLER_VIEW)) 660 continue; 661 662 if (configs[i].idct_source_format != PIPE_FORMAT_NONE) { 663 if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D, 664 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 665 continue; 666 667 if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D, 668 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 669 continue; 670 } else { 671 if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D, 672 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 673 continue; 674 } 675 return &configs[i]; 676 } 677 678 return NULL; 679} 680 681static bool 682init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 683{ 684 unsigned num_channels; 685 686 assert(dec); 687 688 dec->zscan_source_format = format_config->zscan_source_format; 689 dec->zscan_linear = vl_zscan_layout(dec->base.context, vl_zscan_linear, dec->blocks_per_line); 690 dec->zscan_normal = vl_zscan_layout(dec->base.context, vl_zscan_normal, dec->blocks_per_line); 691 dec->zscan_alternate = vl_zscan_layout(dec->base.context, vl_zscan_alternate, dec->blocks_per_line); 692 693 num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1; 694 695 if (!vl_zscan_init(&dec->zscan_y, dec->base.context, dec->base.width, dec->base.height, 696 dec->blocks_per_line, dec->num_blocks, num_channels)) 697 return false; 698 699 if (!vl_zscan_init(&dec->zscan_c, dec->base.context, dec->chroma_width, dec->chroma_height, 700 dec->blocks_per_line, dec->num_blocks, num_channels)) 701 return false; 702 703 return true; 704} 705 706static bool 707init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 708{ 709 unsigned nr_of_idct_render_targets, max_inst; 710 enum pipe_format formats[3]; 711 712 struct pipe_sampler_view *matrix = NULL; 713 714 nr_of_idct_render_targets = dec->base.context->screen->get_param 715 ( 716 dec->base.context->screen, PIPE_CAP_MAX_RENDER_TARGETS 717 ); 718 719 max_inst = dec->base.context->screen->get_shader_param 720 ( 721 dec->base.context->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INSTRUCTIONS 722 ); 723 724 // Just assume we need 32 inst per render target, not 100% true, but should work in most cases 725 if (nr_of_idct_render_targets >= 4 && max_inst >= 32*4) 726 // more than 4 render targets usually doesn't makes any seens 727 nr_of_idct_render_targets = 4; 728 else 729 nr_of_idct_render_targets = 1; 730 731 formats[0] = formats[1] = formats[2] = format_config->idct_source_format; 732 dec->idct_source = vl_video_buffer_create_ex 733 ( 734 dec->base.context, dec->base.width / 4, dec->base.height, 1, 735 dec->base.chroma_format, formats, PIPE_USAGE_STATIC 736 ); 737 738 if (!dec->idct_source) 739 goto error_idct_source; 740 741 formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 742 dec->mc_source = vl_video_buffer_create_ex 743 ( 744 dec->base.context, dec->base.width / nr_of_idct_render_targets, 745 dec->base.height / 4, nr_of_idct_render_targets, 746 dec->base.chroma_format, formats, PIPE_USAGE_STATIC 747 ); 748 749 if (!dec->mc_source) 750 goto error_mc_source; 751 752 if (!(matrix = vl_idct_upload_matrix(dec->base.context, format_config->idct_scale))) 753 goto error_matrix; 754 755 if (!vl_idct_init(&dec->idct_y, dec->base.context, dec->base.width, dec->base.height, 756 nr_of_idct_render_targets, matrix, matrix)) 757 goto error_y; 758 759 if(!vl_idct_init(&dec->idct_c, dec->base.context, dec->chroma_width, dec->chroma_height, 760 nr_of_idct_render_targets, matrix, matrix)) 761 goto error_c; 762 763 pipe_sampler_view_reference(&matrix, NULL); 764 765 return true; 766 767error_c: 768 vl_idct_cleanup(&dec->idct_y); 769 770error_y: 771 pipe_sampler_view_reference(&matrix, NULL); 772 773error_matrix: 774 dec->mc_source->destroy(dec->mc_source); 775 776error_mc_source: 777 dec->idct_source->destroy(dec->idct_source); 778 779error_idct_source: 780 return false; 781} 782 783static bool 784init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 785{ 786 enum pipe_format formats[3]; 787 788 formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 789 dec->mc_source = vl_video_buffer_create_ex 790 ( 791 dec->base.context, dec->base.width, dec->base.height, 1, 792 dec->base.chroma_format, formats, PIPE_USAGE_STATIC 793 ); 794 795 return dec->mc_source != NULL; 796} 797 798static void 799mc_vert_shader_callback(void *priv, struct vl_mc *mc, 800 struct ureg_program *shader, 801 unsigned first_output, 802 struct ureg_dst tex) 803{ 804 struct vl_mpeg12_decoder *dec = priv; 805 struct ureg_dst o_vtex; 806 807 assert(priv && mc); 808 assert(shader); 809 810 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 811 struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 812 vl_idct_stage2_vert_shader(idct, shader, first_output, tex); 813 } else { 814 o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output); 815 ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex)); 816 } 817} 818 819static void 820mc_frag_shader_callback(void *priv, struct vl_mc *mc, 821 struct ureg_program *shader, 822 unsigned first_input, 823 struct ureg_dst dst) 824{ 825 struct vl_mpeg12_decoder *dec = priv; 826 struct ureg_src src, sampler; 827 828 assert(priv && mc); 829 assert(shader); 830 831 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 832 struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 833 vl_idct_stage2_frag_shader(idct, shader, first_input, dst); 834 } else { 835 src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR); 836 sampler = ureg_DECL_sampler(shader, 0); 837 ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler); 838 } 839} 840 841struct pipe_video_decoder * 842vl_create_mpeg12_decoder(struct pipe_context *context, 843 enum pipe_video_profile profile, 844 enum pipe_video_entrypoint entrypoint, 845 enum pipe_video_chroma_format chroma_format, 846 unsigned width, unsigned height) 847{ 848 const unsigned block_size_pixels = BLOCK_WIDTH * BLOCK_HEIGHT; 849 const struct format_config *format_config; 850 struct vl_mpeg12_decoder *dec; 851 852 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); 853 854 dec = CALLOC_STRUCT(vl_mpeg12_decoder); 855 856 if (!dec) 857 return NULL; 858 859 dec->base.context = context; 860 dec->base.profile = profile; 861 dec->base.entrypoint = entrypoint; 862 dec->base.chroma_format = chroma_format; 863 dec->base.width = width; 864 dec->base.height = height; 865 866 dec->base.destroy = vl_mpeg12_destroy; 867 dec->base.create_buffer = vl_mpeg12_create_buffer; 868 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer; 869 870 dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4); 871 dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels; 872 873 dec->quads = vl_vb_upload_quads(dec->base.context); 874 dec->pos = vl_vb_upload_pos( 875 dec->base.context, 876 dec->base.width / MACROBLOCK_WIDTH, 877 dec->base.height / MACROBLOCK_HEIGHT 878 ); 879 dec->block_num = vl_vb_upload_block_num(dec->base.context, dec->num_blocks); 880 881 dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->base.context); 882 dec->ves_mv = vl_vb_get_ves_mv(dec->base.context); 883 884 /* TODO: Implement 422, 444 */ 885 assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 886 887 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 888 dec->chroma_width = dec->base.width / 2; 889 dec->chroma_height = dec->base.height / 2; 890 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 891 dec->chroma_width = dec->base.width; 892 dec->chroma_height = dec->base.height / 2; 893 } else { 894 dec->chroma_width = dec->base.width; 895 dec->chroma_height = dec->base.height; 896 } 897 898 switch (entrypoint) { 899 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: 900 format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs); 901 break; 902 903 case PIPE_VIDEO_ENTRYPOINT_IDCT: 904 format_config = find_format_config(dec, idct_format_config, num_idct_format_configs); 905 break; 906 907 case PIPE_VIDEO_ENTRYPOINT_MC: 908 format_config = find_format_config(dec, mc_format_config, num_mc_format_configs); 909 break; 910 911 default: 912 assert(0); 913 return NULL; 914 } 915 916 if (!format_config) 917 return NULL; 918 919 if (!init_zscan(dec, format_config)) 920 goto error_zscan; 921 922 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 923 if (!init_idct(dec, format_config)) 924 goto error_sources; 925 } else { 926 if (!init_mc_source_widthout_idct(dec, format_config)) 927 goto error_sources; 928 } 929 930 if (!vl_mc_init(&dec->mc_y, dec->base.context, dec->base.width, dec->base.height, 931 MACROBLOCK_HEIGHT, format_config->mc_scale, 932 mc_vert_shader_callback, mc_frag_shader_callback, dec)) 933 goto error_mc_y; 934 935 // TODO 936 if (!vl_mc_init(&dec->mc_c, dec->base.context, dec->base.width, dec->base.height, 937 BLOCK_HEIGHT, format_config->mc_scale, 938 mc_vert_shader_callback, mc_frag_shader_callback, dec)) 939 goto error_mc_c; 940 941 if (!init_pipe_state(dec)) 942 goto error_pipe_state; 943 944 return &dec->base; 945 946error_pipe_state: 947 vl_mc_cleanup(&dec->mc_c); 948 949error_mc_c: 950 vl_mc_cleanup(&dec->mc_y); 951 952error_mc_y: 953 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 954 vl_idct_cleanup(&dec->idct_y); 955 vl_idct_cleanup(&dec->idct_c); 956 dec->idct_source->destroy(dec->idct_source); 957 } 958 dec->mc_source->destroy(dec->mc_source); 959 960error_sources: 961 vl_zscan_cleanup(&dec->zscan_y); 962 vl_zscan_cleanup(&dec->zscan_c); 963 964error_zscan: 965 FREE(dec); 966 return NULL; 967} 968