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