vl_mpeg12_decoder.c revision a019b60dd37c546a29ca42209bb2f31eec3456d4
1/************************************************************************** 2 * 3 * Copyright 2009 Younes Manton. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include <math.h> 29#include <assert.h> 30 31#include <util/u_memory.h> 32#include <util/u_rect.h> 33#include <util/u_video.h> 34 35#include "vl_mpeg12_decoder.h" 36#include "vl_defines.h" 37 38#define SCALE_FACTOR_SNORM (32768.0f / 256.0f) 39#define SCALE_FACTOR_SSCALED (1.0f / 256.0f) 40 41struct format_config { 42 enum pipe_format zscan_source_format; 43 enum pipe_format idct_source_format; 44 enum pipe_format mc_source_format; 45 46 float idct_scale; 47 float mc_scale; 48}; 49 50static const struct format_config bitstream_format_config[] = { 51 { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 52 { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 53 { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 54 { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 55}; 56 57static const unsigned num_bitstream_format_configs = 58 sizeof(bitstream_format_config) / sizeof(struct format_config); 59 60static const struct format_config idct_format_config[] = { 61 { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED }, 62 { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED }, 63 { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SNORM }, 64 { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, 1.0f, SCALE_FACTOR_SNORM } 65}; 66 67static const unsigned num_idct_format_configs = 68 sizeof(idct_format_config) / sizeof(struct format_config); 69 70static const struct format_config mc_format_config[] = { 71 //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED }, 72 { PIPE_FORMAT_R16_SNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SNORM, 0.0f, SCALE_FACTOR_SNORM } 73}; 74 75static const unsigned num_mc_format_configs = 76 sizeof(mc_format_config) / sizeof(struct format_config); 77 78static bool 79init_zscan_buffer(struct vl_mpeg12_buffer *buffer) 80{ 81 enum pipe_format formats[3]; 82 83 struct pipe_sampler_view **source; 84 struct pipe_surface **destination; 85 86 struct vl_mpeg12_decoder *dec; 87 88 unsigned i; 89 90 assert(buffer); 91 92 dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 93 94 formats[0] = formats[1] = formats[2] = dec->zscan_source_format; 95 buffer->zscan_source = vl_video_buffer_init(dec->base.context, dec->pipe, 96 dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT, 97 align(dec->max_blocks, dec->blocks_per_line) / dec->blocks_per_line, 98 1, PIPE_VIDEO_CHROMA_FORMAT_444, 99 formats, PIPE_USAGE_STATIC); 100 if (!buffer->zscan_source) 101 goto error_source; 102 103 source = buffer->zscan_source->get_sampler_view_planes(buffer->zscan_source); 104 if (!source) 105 goto error_sampler; 106 107 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 108 destination = dec->idct_source->get_surfaces(dec->idct_source); 109 else 110 destination = dec->mc_source->get_surfaces(dec->mc_source); 111 112 if (!destination) 113 goto error_surface; 114 115 for (i = 0; i < VL_MAX_PLANES; ++i) 116 if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c, 117 &buffer->zscan[i], source[i], destination[i])) 118 goto error_plane; 119 120 return true; 121 122error_plane: 123 for (; i > 0; --i) 124 vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]); 125 126error_surface: 127error_sampler: 128 buffer->zscan_source->destroy(buffer->zscan_source); 129 130error_source: 131 return false; 132} 133 134static void 135cleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer) 136{ 137 unsigned i; 138 139 assert(buffer); 140 141 for (i = 0; i < VL_MAX_PLANES; ++i) 142 vl_zscan_cleanup_buffer(&buffer->zscan[i]); 143 buffer->zscan_source->destroy(buffer->zscan_source); 144} 145 146static bool 147init_idct_buffer(struct vl_mpeg12_buffer *buffer) 148{ 149 struct pipe_sampler_view **idct_source_sv, **mc_source_sv; 150 151 struct vl_mpeg12_decoder *dec; 152 153 unsigned i; 154 155 assert(buffer); 156 157 dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 158 159 idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source); 160 if (!idct_source_sv) 161 goto error_source_sv; 162 163 mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 164 if (!mc_source_sv) 165 goto error_mc_source_sv; 166 167 for (i = 0; i < 3; ++i) 168 if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, 169 &buffer->idct[i], idct_source_sv[i], 170 mc_source_sv[i])) 171 goto error_plane; 172 173 return true; 174 175error_plane: 176 for (; i > 0; --i) 177 vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]); 178 179error_mc_source_sv: 180error_source_sv: 181 return false; 182} 183 184static void 185cleanup_idct_buffer(struct vl_mpeg12_buffer *buf) 186{ 187 struct vl_mpeg12_decoder *dec; 188 assert(buf); 189 190 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 191 assert(dec); 192 193 vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]); 194 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]); 195 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]); 196} 197 198static bool 199init_mc_buffer(struct vl_mpeg12_buffer *buf) 200{ 201 struct vl_mpeg12_decoder *dec; 202 203 assert(buf); 204 205 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 206 assert(dec); 207 208 if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0])) 209 goto error_mc_y; 210 211 if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1])) 212 goto error_mc_cb; 213 214 if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2])) 215 goto error_mc_cr; 216 217 return true; 218 219error_mc_cr: 220 vl_mc_cleanup_buffer(&buf->mc[1]); 221 222error_mc_cb: 223 vl_mc_cleanup_buffer(&buf->mc[0]); 224 225error_mc_y: 226 return false; 227} 228 229static void 230cleanup_mc_buffer(struct vl_mpeg12_buffer *buf) 231{ 232 unsigned i; 233 234 assert(buf); 235 236 for (i = 0; i < VL_MAX_PLANES; ++i) 237 vl_mc_cleanup_buffer(&buf->mc[i]); 238} 239 240static void 241vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer) 242{ 243 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 244 struct vl_mpeg12_decoder *dec; 245 246 assert(buf); 247 248 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 249 assert(dec); 250 251 cleanup_zscan_buffer(buf); 252 253 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 254 cleanup_idct_buffer(buf); 255 256 cleanup_mc_buffer(buf); 257 258 vl_vb_cleanup(&buf->vertex_stream); 259 260 FREE(buf); 261} 262 263static void 264vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer) 265{ 266 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 267 struct vl_mpeg12_decoder *dec; 268 269 struct pipe_sampler_view **sampler_views; 270 unsigned i; 271 272 assert(buf); 273 274 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 275 assert(dec); 276 277 vl_vb_map(&buf->vertex_stream, dec->pipe); 278 279 sampler_views = buf->zscan_source->get_sampler_view_planes(buf->zscan_source); 280 281 assert(sampler_views); 282 283 for (i = 0; i < VL_MAX_PLANES; ++i) { 284 struct pipe_resource *tex = sampler_views[i]->texture; 285 struct pipe_box rect = 286 { 287 0, 0, 0, 288 tex->width0, 289 tex->height0, 290 1 291 }; 292 293 buf->tex_transfer[i] = dec->pipe->get_transfer 294 ( 295 dec->pipe, tex, 296 0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 297 &rect 298 ); 299 300 buf->texels[i] = dec->pipe->transfer_map(dec->pipe, buf->tex_transfer[i]); 301 } 302 303 if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) { 304 struct pipe_ycbcr_block *ycbcr_stream[VL_MAX_PLANES]; 305 struct pipe_motionvector *mv_stream[VL_MAX_REF_FRAMES]; 306 307 for (i = 0; i < VL_MAX_PLANES; ++i) 308 ycbcr_stream[i] = vl_vb_get_ycbcr_stream(&buf->vertex_stream, i); 309 310 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) 311 mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i); 312 313 vl_mpg12_bs_set_buffers(&buf->bs, ycbcr_stream, buf->texels, mv_stream); 314 } else { 315 static const uint8_t dummy_quant[64] = { 316 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 317 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 318 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 319 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 320 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 321 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 322 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 323 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 324 }; 325 326 for (i = 0; i < VL_MAX_PLANES; ++i) { 327 vl_zscan_set_layout(&buf->zscan[i], dec->zscan_linear); 328 vl_zscan_upload_quant(&buf->zscan[i], dummy_quant, dummy_quant); 329 } 330 } 331} 332 333static struct pipe_ycbcr_block * 334vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component) 335{ 336 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 337 338 assert(buf); 339 340 return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component); 341} 342 343static short * 344vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component) 345{ 346 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 347 348 assert(buf); 349 assert(component < VL_MAX_PLANES); 350 351 return buf->texels[component]; 352} 353 354static unsigned 355vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer) 356{ 357 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 358 359 assert(buf); 360 361 return vl_vb_get_mv_stream_stride(&buf->vertex_stream); 362} 363 364static struct pipe_motionvector * 365vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame) 366{ 367 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 368 369 assert(buf); 370 371 return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame); 372} 373 374static void 375vl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer *buffer, 376 unsigned num_bytes, const void *data, 377 struct pipe_mpeg12_picture_desc *picture, 378 unsigned num_ycbcr_blocks[3]) 379{ 380 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 381 uint8_t intra_quantizer_matrix[64]; 382 struct vl_mpeg12_decoder *dec; 383 unsigned i; 384 385 assert(buf); 386 387 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 388 assert(dec); 389 390 memcpy(intra_quantizer_matrix, picture->intra_quantizer_matrix, sizeof(intra_quantizer_matrix)); 391 intra_quantizer_matrix[0] = 1 << (7 - picture->intra_dc_precision); 392 393 for (i = 0; i < VL_MAX_PLANES; ++i) { 394 vl_zscan_set_layout(&buf->zscan[i], picture->alternate_scan ? dec->zscan_alternate : dec->zscan_normal); 395 vl_zscan_upload_quant(&buf->zscan[i], intra_quantizer_matrix, picture->non_intra_quantizer_matrix); 396 } 397 398 vl_mpg12_bs_decode(&buf->bs, num_bytes, data, picture, num_ycbcr_blocks); 399} 400 401static void 402vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer) 403{ 404 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 405 struct vl_mpeg12_decoder *dec; 406 unsigned i; 407 408 assert(buf); 409 410 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 411 assert(dec); 412 413 vl_vb_unmap(&buf->vertex_stream, dec->pipe); 414 415 for (i = 0; i < VL_MAX_PLANES; ++i) { 416 dec->pipe->transfer_unmap(dec->pipe, buf->tex_transfer[i]); 417 dec->pipe->transfer_destroy(dec->pipe, buf->tex_transfer[i]); 418 } 419} 420 421static void 422vl_mpeg12_destroy(struct pipe_video_decoder *decoder) 423{ 424 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 425 426 assert(decoder); 427 428 /* Asserted in softpipe_delete_fs_state() for some reason */ 429 dec->pipe->bind_vs_state(dec->pipe, NULL); 430 dec->pipe->bind_fs_state(dec->pipe, NULL); 431 432 dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa); 433 dec->pipe->delete_sampler_state(dec->pipe, dec->sampler_ycbcr); 434 435 vl_mc_cleanup(&dec->mc_y); 436 vl_mc_cleanup(&dec->mc_c); 437 dec->mc_source->destroy(dec->mc_source); 438 439 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 440 vl_idct_cleanup(&dec->idct_y); 441 vl_idct_cleanup(&dec->idct_c); 442 dec->idct_source->destroy(dec->idct_source); 443 } 444 445 vl_zscan_cleanup(&dec->zscan_y); 446 vl_zscan_cleanup(&dec->zscan_c); 447 448 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr); 449 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv); 450 451 pipe_resource_reference(&dec->quads.buffer, NULL); 452 pipe_resource_reference(&dec->pos.buffer, NULL); 453 454 pipe_sampler_view_reference(&dec->zscan_linear, NULL); 455 pipe_sampler_view_reference(&dec->zscan_normal, NULL); 456 pipe_sampler_view_reference(&dec->zscan_alternate, NULL); 457 458 FREE(dec); 459} 460 461static struct pipe_video_decode_buffer * 462vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder) 463{ 464 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 465 struct vl_mpeg12_buffer *buffer; 466 467 assert(dec); 468 469 buffer = CALLOC_STRUCT(vl_mpeg12_buffer); 470 if (buffer == NULL) 471 return NULL; 472 473 buffer->base.decoder = decoder; 474 buffer->base.destroy = vl_mpeg12_buffer_destroy; 475 buffer->base.map = vl_mpeg12_buffer_map; 476 buffer->base.get_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream; 477 buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer; 478 buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride; 479 buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream; 480 buffer->base.decode_bitstream = vl_mpeg12_buffer_decode_bitstream; 481 buffer->base.unmap = vl_mpeg12_buffer_unmap; 482 483 if (!vl_vb_init(&buffer->vertex_stream, dec->pipe, 484 dec->base.width / MACROBLOCK_WIDTH, 485 dec->base.height / MACROBLOCK_HEIGHT)) 486 goto error_vertex_buffer; 487 488 if (!init_mc_buffer(buffer)) 489 goto error_mc; 490 491 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 492 if (!init_idct_buffer(buffer)) 493 goto error_idct; 494 495 if (!init_zscan_buffer(buffer)) 496 goto error_zscan; 497 498 if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) 499 vl_mpg12_bs_init(&buffer->bs, 500 dec->base.width / MACROBLOCK_WIDTH, 501 dec->base.height / MACROBLOCK_HEIGHT); 502 503 return &buffer->base; 504 505error_zscan: 506 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 507 cleanup_idct_buffer(buffer); 508 509error_idct: 510 cleanup_mc_buffer(buffer); 511 512error_mc: 513 vl_vb_cleanup(&buffer->vertex_stream); 514 515error_vertex_buffer: 516 FREE(buffer); 517 return NULL; 518} 519 520static void 521vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, 522 unsigned num_ycbcr_blocks[3], 523 struct pipe_video_buffer *refs[2], 524 struct pipe_video_buffer *dst) 525{ 526 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; 527 struct vl_mpeg12_decoder *dec; 528 529 struct pipe_sampler_view **sv[VL_MAX_REF_FRAMES], **mc_source_sv; 530 struct pipe_surface **surfaces; 531 532 struct pipe_vertex_buffer vb[3]; 533 534 unsigned i, j, component; 535 unsigned nr_components; 536 537 assert(buf); 538 539 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 540 assert(dec); 541 542 for (i = 0; i < 2; ++i) 543 sv[i] = refs[i] ? refs[i]->get_sampler_view_planes(refs[i]) : NULL; 544 545 vb[0] = dec->quads; 546 vb[1] = dec->pos; 547 548 surfaces = dst->get_surfaces(dst); 549 550 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv); 551 for (i = 0; i < VL_MAX_PLANES; ++i) { 552 if (!surfaces[i]) continue; 553 554 vl_mc_set_surface(&buf->mc[i], surfaces[i]); 555 556 for (j = 0; j < VL_MAX_REF_FRAMES; ++j) { 557 if (!sv[j]) continue; 558 559 vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);; 560 dec->pipe->set_vertex_buffers(dec->pipe, 3, vb); 561 562 vl_mc_render_ref(&buf->mc[i], sv[j][i]); 563 } 564 } 565 566 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr); 567 for (i = 0; i < VL_MAX_PLANES; ++i) { 568 if (!num_ycbcr_blocks[i]) continue; 569 570 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); 571 dec->pipe->set_vertex_buffers(dec->pipe, 2, vb); 572 573 vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]); 574 575 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 576 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]); 577 } 578 579 mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); 580 for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) { 581 if (!surfaces[i]) continue; 582 583 nr_components = util_format_get_nr_components(surfaces[i]->texture->format); 584 for (j = 0; j < nr_components; ++j, ++component) { 585 if (!num_ycbcr_blocks[i]) continue; 586 587 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component); 588 dec->pipe->set_vertex_buffers(dec->pipe, 2, vb); 589 590 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 591 vl_idct_prepare_stage2(component == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[component]); 592 else { 593 dec->pipe->set_fragment_sampler_views(dec->pipe, 1, &mc_source_sv[component]); 594 dec->pipe->bind_fragment_sampler_states(dec->pipe, 1, &dec->sampler_ycbcr); 595 } 596 vl_mc_render_ycbcr(&buf->mc[i], j, num_ycbcr_blocks[component]); 597 } 598 } 599} 600 601static bool 602init_pipe_state(struct vl_mpeg12_decoder *dec) 603{ 604 struct pipe_depth_stencil_alpha_state dsa; 605 struct pipe_sampler_state sampler; 606 unsigned i; 607 608 assert(dec); 609 610 memset(&dsa, 0, sizeof dsa); 611 dsa.depth.enabled = 0; 612 dsa.depth.writemask = 0; 613 dsa.depth.func = PIPE_FUNC_ALWAYS; 614 for (i = 0; i < 2; ++i) { 615 dsa.stencil[i].enabled = 0; 616 dsa.stencil[i].func = PIPE_FUNC_ALWAYS; 617 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; 618 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; 619 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; 620 dsa.stencil[i].valuemask = 0; 621 dsa.stencil[i].writemask = 0; 622 } 623 dsa.alpha.enabled = 0; 624 dsa.alpha.func = PIPE_FUNC_ALWAYS; 625 dsa.alpha.ref_value = 0; 626 dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa); 627 dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa); 628 629 memset(&sampler, 0, sizeof(sampler)); 630 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 631 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 632 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 633 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 634 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 635 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 636 sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 637 sampler.compare_func = PIPE_FUNC_ALWAYS; 638 sampler.normalized_coords = 1; 639 dec->sampler_ycbcr = dec->pipe->create_sampler_state(dec->pipe, &sampler); 640 if (!dec->sampler_ycbcr) 641 return false; 642 643 return true; 644} 645 646static const struct format_config* 647find_format_config(struct vl_mpeg12_decoder *dec, const struct format_config configs[], unsigned num_configs) 648{ 649 struct pipe_screen *screen; 650 unsigned i; 651 652 assert(dec); 653 654 screen = dec->pipe->screen; 655 656 for (i = 0; i < num_configs; ++i) { 657 if (!screen->is_format_supported(screen, configs[i].zscan_source_format, PIPE_TEXTURE_2D, 658 1, PIPE_BIND_SAMPLER_VIEW)) 659 continue; 660 661 if (configs[i].idct_source_format != PIPE_FORMAT_NONE) { 662 if (!screen->is_format_supported(screen, configs[i].idct_source_format, PIPE_TEXTURE_2D, 663 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 664 continue; 665 666 if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_3D, 667 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 668 continue; 669 } else { 670 if (!screen->is_format_supported(screen, configs[i].mc_source_format, PIPE_TEXTURE_2D, 671 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 672 continue; 673 } 674 return &configs[i]; 675 } 676 677 return NULL; 678} 679 680static bool 681init_zscan(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 682{ 683 const unsigned block_size_pixels = BLOCK_WIDTH * BLOCK_HEIGHT; 684 unsigned num_channels; 685 686 assert(dec); 687 688 dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4); 689 dec->max_blocks = (dec->base.width * dec->base.height) / block_size_pixels; 690 691 dec->zscan_source_format = format_config->zscan_source_format; 692 dec->zscan_linear = vl_zscan_layout(dec->pipe, vl_zscan_linear, dec->blocks_per_line); 693 dec->zscan_normal = vl_zscan_layout(dec->pipe, vl_zscan_normal, dec->blocks_per_line); 694 dec->zscan_alternate = vl_zscan_layout(dec->pipe, vl_zscan_alternate, dec->blocks_per_line); 695 696 num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1; 697 698 if (!vl_zscan_init(&dec->zscan_y, dec->pipe, dec->base.width, dec->base.height, 699 dec->blocks_per_line, dec->max_blocks, num_channels)) 700 return false; 701 702 if (!vl_zscan_init(&dec->zscan_c, dec->pipe, dec->chroma_width, dec->chroma_height, 703 dec->blocks_per_line, dec->max_blocks, num_channels)) 704 return false; 705 706 return true; 707} 708 709static bool 710init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 711{ 712 unsigned nr_of_idct_render_targets; 713 enum pipe_format formats[3]; 714 715 struct pipe_sampler_view *matrix = NULL; 716 717 nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS); 718 719 // more than 4 render targets usually doesn't makes any seens 720 nr_of_idct_render_targets = MIN2(nr_of_idct_render_targets, 4); 721 722 formats[0] = formats[1] = formats[2] = format_config->idct_source_format; 723 dec->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe, 724 dec->base.width / 4, dec->base.height, 1, 725 dec->base.chroma_format, 726 formats, PIPE_USAGE_STATIC); 727 if (!dec->idct_source) 728 goto error_idct_source; 729 730 formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 731 dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe, 732 dec->base.width / nr_of_idct_render_targets, 733 dec->base.height / 4, nr_of_idct_render_targets, 734 dec->base.chroma_format, 735 formats, PIPE_USAGE_STATIC); 736 737 if (!dec->mc_source) 738 goto error_mc_source; 739 740 if (!(matrix = vl_idct_upload_matrix(dec->pipe, format_config->idct_scale))) 741 goto error_matrix; 742 743 if (!vl_idct_init(&dec->idct_y, dec->pipe, dec->base.width, dec->base.height, 744 nr_of_idct_render_targets, matrix, matrix)) 745 goto error_y; 746 747 if(!vl_idct_init(&dec->idct_c, dec->pipe, dec->chroma_width, dec->chroma_height, 748 nr_of_idct_render_targets, matrix, matrix)) 749 goto error_c; 750 751 pipe_sampler_view_reference(&matrix, NULL); 752 753 return true; 754 755error_c: 756 vl_idct_cleanup(&dec->idct_y); 757 758error_y: 759 pipe_sampler_view_reference(&matrix, NULL); 760 761error_matrix: 762 dec->mc_source->destroy(dec->mc_source); 763 764error_mc_source: 765 dec->idct_source->destroy(dec->idct_source); 766 767error_idct_source: 768 return false; 769} 770 771static bool 772init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_config) 773{ 774 enum pipe_format formats[3]; 775 776 formats[0] = formats[1] = formats[2] = format_config->mc_source_format; 777 dec->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe, 778 dec->base.width, dec->base.height, 1, 779 dec->base.chroma_format, 780 formats, PIPE_USAGE_STATIC); 781 782 return dec->mc_source != NULL; 783} 784 785static void 786mc_vert_shader_callback(void *priv, struct vl_mc *mc, 787 struct ureg_program *shader, 788 unsigned first_output, 789 struct ureg_dst tex) 790{ 791 struct vl_mpeg12_decoder *dec = priv; 792 struct ureg_dst o_vtex; 793 794 assert(priv && mc); 795 assert(shader); 796 797 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 798 struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 799 vl_idct_stage2_vert_shader(idct, shader, first_output, tex); 800 } else { 801 o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output); 802 ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex)); 803 } 804} 805 806static void 807mc_frag_shader_callback(void *priv, struct vl_mc *mc, 808 struct ureg_program *shader, 809 unsigned first_input, 810 struct ureg_dst dst) 811{ 812 struct vl_mpeg12_decoder *dec = priv; 813 struct ureg_src src, sampler; 814 815 assert(priv && mc); 816 assert(shader); 817 818 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 819 struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; 820 vl_idct_stage2_frag_shader(idct, shader, first_input, dst); 821 } else { 822 src = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, first_input, TGSI_INTERPOLATE_LINEAR); 823 sampler = ureg_DECL_sampler(shader, 0); 824 ureg_TEX(shader, dst, TGSI_TEXTURE_2D, src, sampler); 825 } 826} 827 828struct pipe_video_decoder * 829vl_create_mpeg12_decoder(struct pipe_video_context *context, 830 struct pipe_context *pipe, 831 enum pipe_video_profile profile, 832 enum pipe_video_entrypoint entrypoint, 833 enum pipe_video_chroma_format chroma_format, 834 unsigned width, unsigned height) 835{ 836 const struct format_config *format_config; 837 struct vl_mpeg12_decoder *dec; 838 839 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); 840 841 dec = CALLOC_STRUCT(vl_mpeg12_decoder); 842 843 if (!dec) 844 return NULL; 845 846 dec->base.context = context; 847 dec->base.profile = profile; 848 dec->base.entrypoint = entrypoint; 849 dec->base.chroma_format = chroma_format; 850 dec->base.width = width; 851 dec->base.height = height; 852 853 dec->base.destroy = vl_mpeg12_destroy; 854 dec->base.create_buffer = vl_mpeg12_create_buffer; 855 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer; 856 857 dec->pipe = pipe; 858 859 dec->quads = vl_vb_upload_quads(dec->pipe); 860 dec->pos = vl_vb_upload_pos( 861 dec->pipe, 862 dec->base.width / MACROBLOCK_WIDTH, 863 dec->base.height / MACROBLOCK_HEIGHT 864 ); 865 866 dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe); 867 dec->ves_mv = vl_vb_get_ves_mv(dec->pipe); 868 869 /* TODO: Implement 422, 444 */ 870 assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 871 872 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 873 dec->chroma_width = dec->base.width / 2; 874 dec->chroma_height = dec->base.height / 2; 875 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 876 dec->chroma_width = dec->base.width; 877 dec->chroma_height = dec->base.height / 2; 878 } else { 879 dec->chroma_width = dec->base.width; 880 dec->chroma_height = dec->base.height; 881 } 882 883 switch (entrypoint) { 884 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: 885 format_config = find_format_config(dec, bitstream_format_config, num_bitstream_format_configs); 886 break; 887 888 case PIPE_VIDEO_ENTRYPOINT_IDCT: 889 format_config = find_format_config(dec, idct_format_config, num_idct_format_configs); 890 break; 891 892 case PIPE_VIDEO_ENTRYPOINT_MC: 893 format_config = find_format_config(dec, mc_format_config, num_mc_format_configs); 894 break; 895 896 default: 897 assert(0); 898 return NULL; 899 } 900 901 if (!format_config) 902 return NULL; 903 904 if (!init_zscan(dec, format_config)) 905 goto error_zscan; 906 907 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 908 if (!init_idct(dec, format_config)) 909 goto error_sources; 910 } else { 911 if (!init_mc_source_widthout_idct(dec, format_config)) 912 goto error_sources; 913 } 914 915 if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, format_config->mc_scale, 916 mc_vert_shader_callback, mc_frag_shader_callback, dec)) 917 goto error_mc_y; 918 919 // TODO 920 if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, format_config->mc_scale, 921 mc_vert_shader_callback, mc_frag_shader_callback, dec)) 922 goto error_mc_c; 923 924 if (!init_pipe_state(dec)) 925 goto error_pipe_state; 926 927 return &dec->base; 928 929error_pipe_state: 930 vl_mc_cleanup(&dec->mc_c); 931 932error_mc_c: 933 vl_mc_cleanup(&dec->mc_y); 934 935error_mc_y: 936 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 937 vl_idct_cleanup(&dec->idct_y); 938 vl_idct_cleanup(&dec->idct_c); 939 dec->idct_source->destroy(dec->idct_source); 940 } 941 dec->mc_source->destroy(dec->mc_source); 942 943error_sources: 944 vl_zscan_cleanup(&dec->zscan_y); 945 vl_zscan_cleanup(&dec->zscan_c); 946 947error_zscan: 948 FREE(dec); 949 return NULL; 950} 951