vl_mpeg12_decoder.c revision 2e6274fc3b123e7de695038054b5cbd20b11559a
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 41static const enum pipe_format const_zscan_source_formats[] = { 42 PIPE_FORMAT_R16_SNORM, 43 PIPE_FORMAT_R16_SSCALED 44}; 45 46static const unsigned num_zscan_source_formats = 47 sizeof(const_zscan_source_formats) / sizeof(enum pipe_format); 48 49static const enum pipe_format const_idct_source_formats[] = { 50 PIPE_FORMAT_R16G16B16A16_SNORM, 51 PIPE_FORMAT_R16G16B16A16_SSCALED 52}; 53 54static const unsigned num_idct_source_formats = 55 sizeof(const_idct_source_formats) / sizeof(enum pipe_format); 56 57static const enum pipe_format const_idct_intermediate_formats[] = { 58 PIPE_FORMAT_R16G16B16A16_FLOAT, 59 PIPE_FORMAT_R16G16B16A16_SNORM, 60 PIPE_FORMAT_R16G16B16A16_SSCALED, 61 PIPE_FORMAT_R32G32B32A32_FLOAT 62}; 63 64static const unsigned num_idct_intermediate_formats = 65 sizeof(const_idct_intermediate_formats) / sizeof(enum pipe_format); 66 67static const enum pipe_format const_mc_source_formats[] = { 68 PIPE_FORMAT_R16_SNORM, 69 PIPE_FORMAT_R16_SSCALED 70}; 71 72static const unsigned num_mc_source_formats = 73 sizeof(const_mc_source_formats) / sizeof(enum pipe_format); 74 75static bool 76init_zscan_buffer(struct vl_mpeg12_buffer *buffer) 77{ 78 enum pipe_format formats[3]; 79 80 struct pipe_sampler_view **source; 81 struct pipe_surface **destination; 82 83 struct vl_mpeg12_decoder *dec; 84 85 unsigned i; 86 87 assert(buffer); 88 89 dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 90 91 formats[0] = formats[1] = formats[2] = dec->zscan_source_format; 92 buffer->zscan_source = vl_video_buffer_init(dec->base.context, dec->pipe, 93 dec->blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT, 94 dec->max_blocks / dec->blocks_per_line, 95 1, PIPE_VIDEO_CHROMA_FORMAT_444, 96 formats, PIPE_USAGE_STATIC); 97 if (!buffer->zscan_source) 98 goto error_source; 99 100 source = buffer->zscan_source->get_sampler_views(buffer->zscan_source); 101 if (!source) 102 goto error_sampler; 103 104 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 105 destination = buffer->idct_source->get_surfaces(buffer->idct_source); 106 else 107 destination = buffer->mc_source->get_surfaces(buffer->mc_source); 108 109 if (!destination) 110 goto error_surface; 111 112 for (i = 0; i < VL_MAX_PLANES; ++i) 113 if (!vl_zscan_init_buffer(i == 0 ? &dec->zscan_y : &dec->zscan_c, 114 &buffer->zscan[i], source[i], destination[i])) 115 goto error_plane; 116 117 return true; 118 119error_plane: 120 for (; i > 0; --i) 121 vl_zscan_cleanup_buffer(&buffer->zscan[i - 1]); 122 123error_surface: 124error_sampler: 125 buffer->zscan_source->destroy(buffer->zscan_source); 126 127error_source: 128 return false; 129} 130 131static void 132cleanup_zscan_buffer(struct vl_mpeg12_buffer *buffer) 133{ 134 unsigned i; 135 136 assert(buffer); 137 138 for (i = 0; i < VL_MAX_PLANES; ++i) 139 vl_zscan_cleanup_buffer(&buffer->zscan[i]); 140 buffer->zscan_source->destroy(buffer->zscan_source); 141} 142 143static bool 144init_idct_buffer(struct vl_mpeg12_buffer *buffer) 145{ 146 enum pipe_format formats[3]; 147 148 struct pipe_sampler_view **idct_source_sv, **idct_intermediate_sv; 149 struct pipe_surface **idct_surfaces; 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 formats[0] = formats[1] = formats[2] = dec->idct_source_format; 160 buffer->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe, 161 dec->base.width / 4, dec->base.height, 1, 162 dec->base.chroma_format, 163 formats, PIPE_USAGE_STATIC); 164 if (!buffer->idct_source) 165 goto error_source; 166 167 formats[0] = formats[1] = formats[2] = dec->idct_intermediate_format; 168 buffer->idct_intermediate = vl_video_buffer_init(dec->base.context, dec->pipe, 169 dec->base.width / dec->nr_of_idct_render_targets, 170 dec->base.height / 4, dec->nr_of_idct_render_targets, 171 dec->base.chroma_format, 172 formats, PIPE_USAGE_STATIC); 173 174 if (!buffer->idct_intermediate) 175 goto error_intermediate; 176 177 idct_source_sv = buffer->idct_source->get_sampler_views(buffer->idct_source); 178 if (!idct_source_sv) 179 goto error_source_sv; 180 181 idct_intermediate_sv = buffer->idct_intermediate->get_sampler_views(buffer->idct_intermediate); 182 if (!idct_intermediate_sv) 183 goto error_intermediate_sv; 184 185 idct_surfaces = buffer->mc_source->get_surfaces(buffer->mc_source); 186 if (!idct_surfaces) 187 goto error_surfaces; 188 189 for (i = 0; i < 3; ++i) 190 if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, 191 &buffer->idct[i], idct_source_sv[i], 192 idct_intermediate_sv[i], idct_surfaces[i])) 193 goto error_plane; 194 195 return true; 196 197error_plane: 198 for (; i > 0; --i) 199 vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]); 200 201error_surfaces: 202error_intermediate_sv: 203error_source_sv: 204 buffer->idct_intermediate->destroy(buffer->idct_intermediate); 205 206error_intermediate: 207 buffer->idct_source->destroy(buffer->idct_source); 208 209error_source: 210 return false; 211} 212 213static void 214cleanup_idct_buffer(struct vl_mpeg12_buffer *buf) 215{ 216 struct vl_mpeg12_decoder *dec; 217 assert(buf); 218 219 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 220 assert(dec); 221 222 vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]); 223 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]); 224 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]); 225 buf->idct_source->destroy(buf->idct_source); 226 buf->idct_intermediate->destroy(buf->idct_intermediate); 227} 228 229static void 230vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer) 231{ 232 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 233 struct vl_mpeg12_decoder *dec; 234 unsigned i; 235 236 assert(buf); 237 238 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 239 assert(dec); 240 241 cleanup_zscan_buffer(buf); 242 243 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 244 cleanup_idct_buffer(buf); 245 246 buf->mc_source->destroy(buf->mc_source); 247 vl_vb_cleanup(&buf->vertex_stream); 248 for (i = 0; i < VL_MAX_PLANES; ++i) 249 vl_mc_cleanup_buffer(&buf->mc[i]); 250 251 FREE(buf); 252} 253 254static void 255vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer) 256{ 257 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 258 struct vl_mpeg12_decoder *dec; 259 260 struct pipe_sampler_view **sampler_views; 261 unsigned i; 262 263 assert(buf); 264 265 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 266 assert(dec); 267 268 vl_vb_map(&buf->vertex_stream, dec->pipe); 269 270 sampler_views = buf->zscan_source->get_sampler_views(buf->zscan_source); 271 272 assert(sampler_views); 273 274 for (i = 0; i < VL_MAX_PLANES; ++i) { 275 struct pipe_resource *tex = sampler_views[i]->texture; 276 struct pipe_box rect = 277 { 278 0, 0, 0, 279 tex->width0, 280 tex->height0, 281 1 282 }; 283 284 buf->tex_transfer[i] = dec->pipe->get_transfer 285 ( 286 dec->pipe, tex, 287 0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 288 &rect 289 ); 290 291 buf->texels[i] = dec->pipe->transfer_map(dec->pipe, buf->tex_transfer[i]); 292 } 293} 294 295static struct pipe_ycbcr_block * 296vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer *buffer, int component) 297{ 298 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 299 300 assert(buf); 301 302 return vl_vb_get_ycbcr_stream(&buf->vertex_stream, component); 303} 304 305static short * 306vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer *buffer, int component) 307{ 308 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 309 310 assert(buf); 311 assert(component < VL_MAX_PLANES); 312 313 return buf->texels[component]; 314} 315 316static unsigned 317vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer *buffer) 318{ 319 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 320 321 assert(buf); 322 323 return vl_vb_get_mv_stream_stride(&buf->vertex_stream); 324} 325 326static struct pipe_motionvector * 327vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer *buffer, int ref_frame) 328{ 329 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 330 331 assert(buf); 332 333 return vl_vb_get_mv_stream(&buf->vertex_stream, ref_frame); 334} 335 336static void 337vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer) 338{ 339 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 340 struct vl_mpeg12_decoder *dec; 341 unsigned i; 342 343 assert(buf); 344 345 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 346 assert(dec); 347 348 vl_vb_unmap(&buf->vertex_stream, dec->pipe); 349 350 for (i = 0; i < VL_MAX_PLANES; ++i) { 351 dec->pipe->transfer_unmap(dec->pipe, buf->tex_transfer[i]); 352 dec->pipe->transfer_destroy(dec->pipe, buf->tex_transfer[i]); 353 } 354} 355 356static void 357vl_mpeg12_destroy(struct pipe_video_decoder *decoder) 358{ 359 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 360 361 assert(decoder); 362 363 /* Asserted in softpipe_delete_fs_state() for some reason */ 364 dec->pipe->bind_vs_state(dec->pipe, NULL); 365 dec->pipe->bind_fs_state(dec->pipe, NULL); 366 367 dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa); 368 369 vl_mc_cleanup(&dec->mc_y); 370 vl_mc_cleanup(&dec->mc_c); 371 372 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 373 vl_idct_cleanup(&dec->idct_y); 374 vl_idct_cleanup(&dec->idct_c); 375 } 376 377 vl_zscan_cleanup(&dec->zscan_y); 378 vl_zscan_cleanup(&dec->zscan_c); 379 380 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr); 381 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv); 382 383 pipe_resource_reference(&dec->quads.buffer, NULL); 384 pipe_resource_reference(&dec->pos.buffer, NULL); 385 386 FREE(dec); 387} 388 389static struct pipe_video_decode_buffer * 390vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder) 391{ 392 enum pipe_format formats[3]; 393 394 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 395 struct vl_mpeg12_buffer *buffer; 396 397 struct pipe_sampler_view **mc_source_sv; 398 399 assert(dec); 400 401 buffer = CALLOC_STRUCT(vl_mpeg12_buffer); 402 if (buffer == NULL) 403 return NULL; 404 405 buffer->base.decoder = decoder; 406 buffer->base.destroy = vl_mpeg12_buffer_destroy; 407 buffer->base.map = vl_mpeg12_buffer_map; 408 buffer->base.get_ycbcr_stream = vl_mpeg12_buffer_get_ycbcr_stream; 409 buffer->base.get_ycbcr_buffer = vl_mpeg12_buffer_get_ycbcr_buffer; 410 buffer->base.get_mv_stream_stride = vl_mpeg12_buffer_get_mv_stream_stride; 411 buffer->base.get_mv_stream = vl_mpeg12_buffer_get_mv_stream; 412 buffer->base.unmap = vl_mpeg12_buffer_unmap; 413 414 vl_vb_init(&buffer->vertex_stream, dec->pipe, 415 dec->base.width / MACROBLOCK_WIDTH, 416 dec->base.height / MACROBLOCK_HEIGHT); 417 418 formats[0] = formats[1] = formats[2] =dec->mc_source_format; 419 buffer->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe, 420 dec->base.width, dec->base.height, 1, 421 dec->base.chroma_format, 422 formats, PIPE_USAGE_STATIC); 423 424 if (!buffer->mc_source) 425 goto error_mc_source; 426 427 mc_source_sv = buffer->mc_source->get_sampler_views(buffer->mc_source); 428 if (!mc_source_sv) 429 goto error_mc_source_sv; 430 431 if(!vl_mc_init_buffer(&dec->mc_y, &buffer->mc[0], mc_source_sv[0])) 432 goto error_mc_y; 433 434 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[1], mc_source_sv[1])) 435 goto error_mc_cb; 436 437 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[2], mc_source_sv[2])) 438 goto error_mc_cr; 439 440 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 441 if (!init_idct_buffer(buffer)) 442 goto error_idct; 443 444 if (!init_zscan_buffer(buffer)) 445 goto error_zscan; 446 447 return &buffer->base; 448 449error_zscan: 450 // TODO Cleanup error handling 451 452error_mc_cr: 453 vl_mc_cleanup_buffer(&buffer->mc[1]); 454 455error_mc_cb: 456 vl_mc_cleanup_buffer(&buffer->mc[0]); 457 458error_mc_y: 459error_mc_source_sv: 460 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 461 cleanup_idct_buffer(buffer); 462 463error_idct: 464 buffer->mc_source->destroy(buffer->mc_source); 465 466error_mc_source: 467 vl_vb_cleanup(&buffer->vertex_stream); 468 469error_vertex_stream: 470 FREE(buffer); 471 return NULL; 472} 473 474static void 475vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, 476 unsigned num_ycbcr_blocks[3], 477 struct pipe_video_buffer *refs[2], 478 struct pipe_video_buffer *dst, 479 struct pipe_fence_handle **fence) 480{ 481 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; 482 struct vl_mpeg12_decoder *dec; 483 484 struct pipe_sampler_view **sv[2]; 485 struct pipe_surface **surfaces; 486 487 struct pipe_vertex_buffer vb[3]; 488 489 unsigned i, j; 490 491 assert(buf); 492 493 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 494 assert(dec); 495 496 for (i = 0; i < 2; ++i) 497 sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL; 498 499 surfaces = dst->get_surfaces(dst); 500 501 vb[0] = dec->quads; 502 vb[1] = dec->pos; 503 504 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv); 505 for (i = 0; i < VL_MAX_PLANES; ++i) { 506 vl_mc_set_surface(&buf->mc[i], surfaces[i]); 507 508 for (j = 0; j < 2; ++j) { 509 if (sv[j] == NULL) continue; 510 511 vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);; 512 dec->pipe->set_vertex_buffers(dec->pipe, 3, vb); 513 514 vl_mc_render_ref(&buf->mc[i], sv[j][i]); 515 } 516 } 517 518 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr); 519 for (i = 0; i < VL_MAX_PLANES; ++i) { 520 if (num_ycbcr_blocks[i] == 0) continue; 521 522 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); 523 dec->pipe->set_vertex_buffers(dec->pipe, 2, vb); 524 525 vl_zscan_render(&buf->zscan[i] , num_ycbcr_blocks[i]); 526 527 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 528 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]); 529 530 vl_mc_render_ycbcr(&buf->mc[i], num_ycbcr_blocks[i]); 531 } 532 533 dec->pipe->flush(dec->pipe, fence); 534} 535 536static bool 537init_pipe_state(struct vl_mpeg12_decoder *dec) 538{ 539 struct pipe_depth_stencil_alpha_state dsa; 540 unsigned i; 541 542 assert(dec); 543 544 memset(&dsa, 0, sizeof dsa); 545 dsa.depth.enabled = 0; 546 dsa.depth.writemask = 0; 547 dsa.depth.func = PIPE_FUNC_ALWAYS; 548 for (i = 0; i < 2; ++i) { 549 dsa.stencil[i].enabled = 0; 550 dsa.stencil[i].func = PIPE_FUNC_ALWAYS; 551 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; 552 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; 553 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; 554 dsa.stencil[i].valuemask = 0; 555 dsa.stencil[i].writemask = 0; 556 } 557 dsa.alpha.enabled = 0; 558 dsa.alpha.func = PIPE_FUNC_ALWAYS; 559 dsa.alpha.ref_value = 0; 560 dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa); 561 dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa); 562 563 return true; 564} 565 566static enum pipe_format 567find_first_supported_format(struct vl_mpeg12_decoder *dec, 568 const enum pipe_format formats[], 569 unsigned num_formats, 570 enum pipe_texture_target target) 571{ 572 struct pipe_screen *screen; 573 unsigned i; 574 575 assert(dec); 576 577 screen = dec->pipe->screen; 578 579 for (i = 0; i < num_formats; ++i) 580 if (screen->is_format_supported(dec->pipe->screen, formats[i], target, 1, 581 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) 582 return formats[i]; 583 584 return PIPE_FORMAT_NONE; 585} 586 587static bool 588init_zscan(struct vl_mpeg12_decoder *dec) 589{ 590 struct pipe_sampler_view *layout; 591 592 unsigned num_channels; 593 594 assert(dec); 595 596 dec->blocks_per_line = 4; 597 dec->max_blocks = 598 (dec->base.width * dec->base.height) / 599 (BLOCK_WIDTH * BLOCK_HEIGHT); 600 601 dec->zscan_source_format = find_first_supported_format(dec, const_zscan_source_formats, 602 num_zscan_source_formats, PIPE_TEXTURE_2D); 603 604 if (dec->zscan_source_format == PIPE_FORMAT_NONE) 605 return false; 606 607 layout = vl_zscan_linear(dec->pipe, dec->blocks_per_line); 608 609 num_channels = dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 4 : 1; 610 611 if (!vl_zscan_init(&dec->zscan_y, dec->pipe, dec->base.width, dec->base.height, 612 dec->blocks_per_line, dec->max_blocks, num_channels)) 613 return false; 614 615 vl_zscan_set_layout(&dec->zscan_y, layout); 616 617 if (!vl_zscan_init(&dec->zscan_c, dec->pipe, dec->chroma_width, dec->chroma_height, 618 dec->blocks_per_line, dec->max_blocks, num_channels)) 619 return false; 620 621 vl_zscan_set_layout(&dec->zscan_c, layout); 622 623 return true; 624} 625 626static bool 627init_idct(struct vl_mpeg12_decoder *dec) 628{ 629 struct pipe_sampler_view *matrix, *transpose; 630 float matrix_scale, transpose_scale; 631 632 dec->nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS); 633 634 // more than 4 render targets usually doesn't makes any seens 635 dec->nr_of_idct_render_targets = MIN2(dec->nr_of_idct_render_targets, 4); 636 637 dec->idct_source_format = find_first_supported_format(dec, const_idct_source_formats, 638 num_idct_source_formats, PIPE_TEXTURE_2D); 639 640 if (dec->idct_source_format == PIPE_FORMAT_NONE) 641 return false; 642 643 dec->idct_intermediate_format = find_first_supported_format(dec, const_idct_intermediate_formats, 644 num_idct_intermediate_formats, PIPE_TEXTURE_3D); 645 646 if (dec->idct_intermediate_format == PIPE_FORMAT_NONE) 647 return false; 648 649 switch (dec->idct_source_format) { 650 case PIPE_FORMAT_R16G16B16A16_SSCALED: 651 matrix_scale = SCALE_FACTOR_SSCALED; 652 break; 653 654 case PIPE_FORMAT_R16G16B16A16_SNORM: 655 matrix_scale = SCALE_FACTOR_SNORM; 656 break; 657 658 default: 659 assert(0); 660 return false; 661 } 662 663 if (dec->idct_intermediate_format == PIPE_FORMAT_R16G16B16A16_FLOAT || 664 dec->idct_intermediate_format == PIPE_FORMAT_R32G32B32A32_FLOAT) 665 transpose_scale = 1.0f; 666 else 667 transpose_scale = matrix_scale = sqrt(matrix_scale); 668 669 if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED) 670 transpose_scale /= SCALE_FACTOR_SSCALED; 671 672 if (!(matrix = vl_idct_upload_matrix(dec->pipe, matrix_scale))) 673 goto error_matrix; 674 675 if (matrix_scale != transpose_scale) { 676 if (!(transpose = vl_idct_upload_matrix(dec->pipe, transpose_scale))) 677 goto error_transpose; 678 } else 679 pipe_sampler_view_reference(&transpose, matrix); 680 681 if (!vl_idct_init(&dec->idct_y, dec->pipe, dec->base.width, dec->base.height, 682 dec->nr_of_idct_render_targets, matrix, transpose)) 683 goto error_y; 684 685 if(!vl_idct_init(&dec->idct_c, dec->pipe, dec->chroma_width, dec->chroma_height, 686 dec->nr_of_idct_render_targets, matrix, transpose)) 687 goto error_c; 688 689 pipe_sampler_view_reference(&matrix, NULL); 690 pipe_sampler_view_reference(&transpose, NULL); 691 return true; 692 693error_c: 694 vl_idct_cleanup(&dec->idct_y); 695 696error_y: 697 pipe_sampler_view_reference(&transpose, NULL); 698 699error_transpose: 700 pipe_sampler_view_reference(&matrix, NULL); 701 702error_matrix: 703 return false; 704} 705 706struct pipe_video_decoder * 707vl_create_mpeg12_decoder(struct pipe_video_context *context, 708 struct pipe_context *pipe, 709 enum pipe_video_profile profile, 710 enum pipe_video_entrypoint entrypoint, 711 enum pipe_video_chroma_format chroma_format, 712 unsigned width, unsigned height) 713{ 714 struct vl_mpeg12_decoder *dec; 715 float mc_scale; 716 717 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); 718 719 dec = CALLOC_STRUCT(vl_mpeg12_decoder); 720 721 if (!dec) 722 return NULL; 723 724 dec->base.context = context; 725 dec->base.profile = profile; 726 dec->base.entrypoint = entrypoint; 727 dec->base.chroma_format = chroma_format; 728 dec->base.width = width; 729 dec->base.height = height; 730 731 dec->base.destroy = vl_mpeg12_destroy; 732 dec->base.create_buffer = vl_mpeg12_create_buffer; 733 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer; 734 735 dec->base.width = align(width, MACROBLOCK_WIDTH); 736 dec->base.height = align(height, MACROBLOCK_HEIGHT); 737 738 dec->pipe = pipe; 739 740 dec->quads = vl_vb_upload_quads(dec->pipe); 741 dec->pos = vl_vb_upload_pos( 742 dec->pipe, 743 dec->base.width / MACROBLOCK_WIDTH, 744 dec->base.height / MACROBLOCK_HEIGHT 745 ); 746 747 dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe); 748 dec->ves_mv = vl_vb_get_ves_mv(dec->pipe); 749 750 /* TODO: Implement 422, 444 */ 751 assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 752 753 dec->mc_source_format = find_first_supported_format(dec, const_mc_source_formats, 754 num_mc_source_formats, PIPE_TEXTURE_3D); 755 756 if (dec->mc_source_format == PIPE_FORMAT_NONE) 757 return NULL; 758 759 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 760 dec->chroma_width = dec->base.width / 2; 761 dec->chroma_height = dec->base.height / 2; 762 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 763 dec->chroma_width = dec->base.width; 764 dec->chroma_height = dec->base.height / 2; 765 } else { 766 dec->chroma_width = dec->base.width; 767 dec->chroma_height = dec->base.height; 768 } 769 770 if (!init_zscan(dec)) 771 return NULL; // TODO error handling 772 773 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 774 if (!init_idct(dec)) 775 goto error_idct; 776 if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED) 777 mc_scale = SCALE_FACTOR_SSCALED; 778 else 779 mc_scale = 1.0f; 780 } else { 781 switch (dec->mc_source_format) { 782 case PIPE_FORMAT_R16_SNORM: 783 mc_scale = SCALE_FACTOR_SNORM; 784 break; 785 786 case PIPE_FORMAT_R16_SSCALED: 787 mc_scale = SCALE_FACTOR_SSCALED; 788 break; 789 790 default: 791 assert(0); 792 return NULL; 793 } 794 } 795 796 if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, mc_scale)) 797 goto error_mc_y; 798 799 // TODO 800 if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, mc_scale)) 801 goto error_mc_c; 802 803 if (!init_pipe_state(dec)) 804 goto error_pipe_state; 805 806 return &dec->base; 807 808error_pipe_state: 809 vl_mc_cleanup(&dec->mc_c); 810 811error_mc_c: 812 vl_mc_cleanup(&dec->mc_y); 813 814error_mc_y: 815 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 816 vl_idct_cleanup(&dec->idct_y); 817 vl_idct_cleanup(&dec->idct_c); 818 } 819 820error_idct: 821 FREE(dec); 822 return NULL; 823} 824