vl_mpeg12_decoder.c revision ff210aea7c080600bd45eb18b29a6109468ed4df
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, unsigned x, unsigned y, short *block) 112{ 113 unsigned tex_pitch; 114 short *texels; 115 116 unsigned i; 117 118 assert(buffer); 119 assert(block); 120 121 tex_pitch = buffer->tex_transfer[plane]->stride / sizeof(short); 122 texels = buffer->texels[plane] + y * tex_pitch * BLOCK_HEIGHT + x * BLOCK_WIDTH; 123 124 for (i = 0; i < BLOCK_HEIGHT; ++i) 125 memcpy(texels + i * tex_pitch, block + i * BLOCK_WIDTH, BLOCK_WIDTH * sizeof(short)); 126} 127 128static void 129upload_buffer(struct vl_mpeg12_decoder *ctx, 130 struct vl_mpeg12_buffer *buffer, 131 struct pipe_mpeg12_macroblock *mb) 132{ 133 short *blocks; 134 unsigned tb, x, y; 135 136 assert(ctx); 137 assert(buffer); 138 assert(mb); 139 140 blocks = mb->blocks; 141 142 for (y = 0; y < 2; ++y) { 143 for (x = 0; x < 2; ++x, ++tb) { 144 if (mb->cbp & (*ctx->empty_block_mask)[0][y][x]) { 145 upload_block(buffer, 0, mb->mbx * 2 + x, mb->mby * 2 + y, blocks); 146 blocks += BLOCK_WIDTH * BLOCK_HEIGHT; 147 } 148 } 149 } 150 151 /* TODO: Implement 422, 444 */ 152 assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); 153 154 for (tb = 1; tb < 3; ++tb) { 155 if (mb->cbp & (*ctx->empty_block_mask)[tb][0][0]) { 156 upload_block(buffer, tb, mb->mbx, mb->mby, blocks); 157 blocks += BLOCK_WIDTH * BLOCK_HEIGHT; 158 } 159 } 160} 161 162static void 163unmap_buffers(struct vl_mpeg12_decoder *ctx, struct vl_mpeg12_buffer *buffer) 164{ 165 unsigned i; 166 167 assert(ctx && buffer); 168 169 for (i = 0; i < VL_MAX_PLANES; ++i) { 170 ctx->pipe->transfer_unmap(ctx->pipe, buffer->tex_transfer[i]); 171 ctx->pipe->transfer_destroy(ctx->pipe, buffer->tex_transfer[i]); 172 } 173} 174 175static void 176cleanup_idct_buffer(struct vl_mpeg12_buffer *buf) 177{ 178 struct vl_mpeg12_decoder *dec; 179 assert(buf); 180 181 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 182 assert(dec); 183 184 buf->idct_source->destroy(buf->idct_source); 185 buf->idct_intermediate->destroy(buf->idct_intermediate); 186 vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]); 187 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]); 188 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]); 189} 190 191static void 192vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer) 193{ 194 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 195 struct vl_mpeg12_decoder *dec; 196 unsigned i; 197 198 assert(buf); 199 200 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 201 assert(dec); 202 203 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 204 cleanup_idct_buffer(buf); 205 206 buf->mc_source->destroy(buf->mc_source); 207 vl_vb_cleanup(&buf->vertex_stream); 208 for (i = 0; i < VL_MAX_PLANES; ++i) 209 vl_mc_cleanup_buffer(&buf->mc[i]); 210 211 FREE(buf); 212} 213 214static void 215vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer) 216{ 217 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 218 struct vl_mpeg12_decoder *dec; 219 assert(buf); 220 221 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 222 assert(dec); 223 224 vl_vb_map(&buf->vertex_stream, dec->pipe); 225 map_buffers(dec, buf); 226} 227 228static void 229vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer, 230 unsigned num_macroblocks, 231 struct pipe_macroblock *macroblocks) 232{ 233 struct pipe_mpeg12_macroblock *mb = (struct pipe_mpeg12_macroblock*)macroblocks; 234 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 235 struct vl_mpeg12_decoder *dec; 236 unsigned i; 237 238 assert(buf); 239 240 dec = (struct vl_mpeg12_decoder*)buf->base.decoder; 241 assert(dec); 242 243 assert(num_macroblocks); 244 assert(macroblocks); 245 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); 246 247 for ( i = 0; i < num_macroblocks; ++i ) { 248 vl_vb_add_block(&buf->vertex_stream, &mb[i], dec->empty_block_mask); 249 upload_buffer(dec, buf, &mb[i]); 250 } 251} 252 253static void 254vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer) 255{ 256 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer; 257 struct vl_mpeg12_decoder *dec; 258 assert(buf); 259 260 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 261 assert(dec); 262 263 vl_vb_unmap(&buf->vertex_stream, dec->pipe); 264 unmap_buffers(dec, buf); 265} 266 267static void 268vl_mpeg12_destroy(struct pipe_video_decoder *decoder) 269{ 270 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 271 unsigned i; 272 273 assert(decoder); 274 275 /* Asserted in softpipe_delete_fs_state() for some reason */ 276 dec->pipe->bind_vs_state(dec->pipe, NULL); 277 dec->pipe->bind_fs_state(dec->pipe, NULL); 278 279 dec->pipe->delete_blend_state(dec->pipe, dec->blend); 280 dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa); 281 282 vl_mc_cleanup(&dec->mc_y); 283 vl_mc_cleanup(&dec->mc_c); 284 285 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 286 vl_idct_cleanup(&dec->idct_y); 287 vl_idct_cleanup(&dec->idct_c); 288 } 289 290 for (i = 0; i < VL_MAX_PLANES; ++i) 291 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_eb[i]); 292 293 for (i = 0; i < 2; ++i) 294 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv[i]); 295 296 pipe_resource_reference(&dec->quads.buffer, NULL); 297 298 FREE(dec); 299} 300 301static bool 302init_idct_buffer(struct vl_mpeg12_buffer *buffer) 303{ 304 enum pipe_format formats[3]; 305 306 struct pipe_sampler_view **idct_source_sv, **idct_intermediate_sv; 307 struct pipe_surface **idct_surfaces; 308 309 struct vl_mpeg12_decoder *dec; 310 311 unsigned i; 312 313 assert(buffer); 314 315 dec = (struct vl_mpeg12_decoder*)buffer->base.decoder; 316 317 formats[0] = formats[1] = formats[2] = dec->idct_source_format; 318 buffer->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe, 319 dec->base.width / 4, dec->base.height, 1, 320 dec->base.chroma_format, 321 formats, PIPE_USAGE_STREAM); 322 if (!buffer->idct_source) 323 goto error_source; 324 325 formats[0] = formats[1] = formats[2] = dec->idct_intermediate_format; 326 buffer->idct_intermediate = vl_video_buffer_init(dec->base.context, dec->pipe, 327 dec->base.width / dec->nr_of_idct_render_targets, 328 dec->base.height / 4, dec->nr_of_idct_render_targets, 329 dec->base.chroma_format, 330 formats, PIPE_USAGE_STATIC); 331 332 if (!buffer->idct_intermediate) 333 goto error_intermediate; 334 335 idct_source_sv = buffer->idct_source->get_sampler_views(buffer->idct_source); 336 if (!idct_source_sv) 337 goto error_source_sv; 338 339 idct_intermediate_sv = buffer->idct_intermediate->get_sampler_views(buffer->idct_intermediate); 340 if (!idct_intermediate_sv) 341 goto error_intermediate_sv; 342 343 idct_surfaces = buffer->mc_source->get_surfaces(buffer->mc_source); 344 if (!idct_surfaces) 345 goto error_surfaces; 346 347 for (i = 0; i < 3; ++i) 348 if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c, 349 &buffer->idct[i], idct_source_sv[i], 350 idct_intermediate_sv[i], idct_surfaces[i])) 351 goto error_plane; 352 353 return true; 354 355error_plane: 356 for (; i > 0; --i) 357 vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]); 358 359error_surfaces: 360error_intermediate_sv: 361error_source_sv: 362 buffer->idct_intermediate->destroy(buffer->idct_intermediate); 363 364error_intermediate: 365 buffer->idct_source->destroy(buffer->idct_source); 366 367error_source: 368 return false; 369} 370 371static struct pipe_video_decode_buffer * 372vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder) 373{ 374 enum pipe_format formats[3]; 375 376 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder; 377 struct vl_mpeg12_buffer *buffer; 378 379 struct pipe_sampler_view **mc_source_sv; 380 381 assert(dec); 382 383 buffer = CALLOC_STRUCT(vl_mpeg12_buffer); 384 if (buffer == NULL) 385 return NULL; 386 387 buffer->base.decoder = decoder; 388 buffer->base.destroy = vl_mpeg12_buffer_destroy; 389 buffer->base.map = vl_mpeg12_buffer_map; 390 buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks; 391 buffer->base.unmap = vl_mpeg12_buffer_unmap; 392 393 buffer->vertex_bufs.individual.quad.stride = dec->quads.stride; 394 buffer->vertex_bufs.individual.quad.buffer_offset = dec->quads.buffer_offset; 395 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, dec->quads.buffer); 396 397 buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, dec->pipe, 398 dec->base.width / MACROBLOCK_WIDTH * 399 dec->base.height / MACROBLOCK_HEIGHT); 400 if (!buffer->vertex_bufs.individual.stream.buffer) 401 goto error_vertex_stream; 402 403 formats[0] = formats[1] = formats[2] =dec->mc_source_format; 404 buffer->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe, 405 dec->base.width, dec->base.height, 1, 406 dec->base.chroma_format, 407 formats, PIPE_USAGE_STATIC); 408 409 if (!buffer->mc_source) 410 goto error_mc_source; 411 412 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 413 if (!init_idct_buffer(buffer)) 414 goto error_idct; 415 416 mc_source_sv = buffer->mc_source->get_sampler_views(buffer->mc_source); 417 if (!mc_source_sv) 418 goto error_mc_source_sv; 419 420 if(!vl_mc_init_buffer(&dec->mc_y, &buffer->mc[0], mc_source_sv[0])) 421 goto error_mc_y; 422 423 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[1], mc_source_sv[1])) 424 goto error_mc_cb; 425 426 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[2], mc_source_sv[2])) 427 goto error_mc_cr; 428 429 return &buffer->base; 430 431error_mc_cr: 432 vl_mc_cleanup_buffer(&buffer->mc[1]); 433 434error_mc_cb: 435 vl_mc_cleanup_buffer(&buffer->mc[0]); 436 437error_mc_y: 438error_mc_source_sv: 439 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 440 cleanup_idct_buffer(buffer); 441 442error_idct: 443 buffer->mc_source->destroy(buffer->mc_source); 444 445error_mc_source: 446 vl_vb_cleanup(&buffer->vertex_stream); 447 448error_vertex_stream: 449 FREE(buffer); 450 return NULL; 451} 452 453static void 454vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, 455 struct pipe_video_buffer *refs[2], 456 struct pipe_video_buffer *dst, 457 struct pipe_fence_handle **fence) 458{ 459 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; 460 struct vl_mpeg12_decoder *dec; 461 462 struct pipe_sampler_view **sv[2]; 463 struct pipe_surface **surfaces; 464 465 unsigned ne_start, ne_num, e_start, e_num; 466 unsigned i, j; 467 468 assert(buf); 469 470 dec = (struct vl_mpeg12_decoder *)buf->base.decoder; 471 assert(dec); 472 473 for (i = 0; i < 2; ++i) 474 sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL; 475 476 surfaces = dst->get_surfaces(dst); 477 478 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num); 479 480 dec->pipe->set_vertex_buffers(dec->pipe, 2, buf->vertex_bufs.all); 481 482 for (i = 0; i < VL_MAX_PLANES; ++i) { 483 bool first = true; 484 485 vl_mc_set_surface(i == 0 ? &dec->mc_y : &dec->mc_c, surfaces[i]); 486 487 for (j = 0; j < 2; ++j) { 488 if (sv[j] == NULL) continue; 489 490 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv[j]); 491 vl_mc_render_ref(&buf->mc[i], sv[j][i], first, ne_start, ne_num, e_start, e_num); 492 first = false; 493 } 494 495 dec->pipe->bind_blend_state(dec->pipe, dec->blend); 496 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_eb[i]); 497 498 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) 499 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], ne_num); 500 501 vl_mc_render_ycbcr(&buf->mc[i], first, ne_start, ne_num); 502 503 } 504 dec->pipe->flush(dec->pipe, fence); 505} 506 507static void 508vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer *buffer) 509{ 510 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; 511 unsigned ne_start, ne_num, e_start, e_num; 512 513 assert(buf); 514 515 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num); 516} 517 518static bool 519init_pipe_state(struct vl_mpeg12_decoder *dec) 520{ 521 struct pipe_blend_state blend; 522 struct pipe_depth_stencil_alpha_state dsa; 523 unsigned i; 524 525 assert(dec); 526 527 memset(&blend, 0, sizeof blend); 528 529 blend.independent_blend_enable = 0; 530 blend.rt[0].blend_enable = 0; 531 blend.rt[0].rgb_func = PIPE_BLEND_ADD; 532 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 533 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 534 blend.rt[0].alpha_func = PIPE_BLEND_ADD; 535 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 536 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 537 blend.logicop_enable = 0; 538 blend.logicop_func = PIPE_LOGICOP_CLEAR; 539 /* Needed to allow color writes to FB, even if blending disabled */ 540 blend.rt[0].colormask = PIPE_MASK_RGBA; 541 blend.dither = 0; 542 dec->blend = dec->pipe->create_blend_state(dec->pipe, &blend); 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_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_height) 589{ 590 unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y; 591 struct pipe_sampler_view *matrix, *transpose; 592 float matrix_scale, transpose_scale; 593 594 dec->nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS); 595 596 // more than 4 render targets usually doesn't makes any seens 597 dec->nr_of_idct_render_targets = MIN2(dec->nr_of_idct_render_targets, 4); 598 599 dec->idct_source_format = find_first_supported_format(dec, const_idct_source_formats, 600 num_idct_source_formats, PIPE_TEXTURE_2D); 601 602 if (dec->idct_source_format == PIPE_FORMAT_NONE) 603 return false; 604 605 dec->idct_intermediate_format = find_first_supported_format(dec, const_idct_intermediate_formats, 606 num_idct_intermediate_formats, PIPE_TEXTURE_3D); 607 608 if (dec->idct_intermediate_format == PIPE_FORMAT_NONE) 609 return false; 610 611 switch (dec->idct_source_format) { 612 case PIPE_FORMAT_R16G16B16A16_SSCALED: 613 matrix_scale = SCALE_FACTOR_SSCALED; 614 break; 615 616 case PIPE_FORMAT_R16G16B16A16_SNORM: 617 matrix_scale = SCALE_FACTOR_SNORM; 618 break; 619 620 default: 621 assert(0); 622 return false; 623 } 624 625 if (dec->idct_intermediate_format == PIPE_FORMAT_R16G16B16A16_FLOAT || 626 dec->idct_intermediate_format == PIPE_FORMAT_R32G32B32A32_FLOAT) 627 transpose_scale = 1.0f; 628 else 629 transpose_scale = matrix_scale = sqrt(matrix_scale); 630 631 if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED) 632 transpose_scale /= SCALE_FACTOR_SSCALED; 633 634 if (!(matrix = vl_idct_upload_matrix(dec->pipe, matrix_scale))) 635 goto error_matrix; 636 637 if (matrix_scale != transpose_scale) { 638 if (!(transpose = vl_idct_upload_matrix(dec->pipe, transpose_scale))) 639 goto error_transpose; 640 } else 641 pipe_sampler_view_reference(&transpose, matrix); 642 643 if (!vl_idct_init(&dec->idct_y, dec->pipe, buffer_width, buffer_height, 644 2, 2, dec->nr_of_idct_render_targets, matrix, transpose)) 645 goto error_y; 646 647 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 648 chroma_width = buffer_width / 2; 649 chroma_height = buffer_height / 2; 650 chroma_blocks_x = 1; 651 chroma_blocks_y = 1; 652 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 653 chroma_width = buffer_width; 654 chroma_height = buffer_height / 2; 655 chroma_blocks_x = 2; 656 chroma_blocks_y = 1; 657 } else { 658 chroma_width = buffer_width; 659 chroma_height = buffer_height; 660 chroma_blocks_x = 2; 661 chroma_blocks_y = 2; 662 } 663 664 if(!vl_idct_init(&dec->idct_c, dec->pipe, chroma_width, chroma_height, 665 chroma_blocks_x, chroma_blocks_y, 666 dec->nr_of_idct_render_targets, matrix, transpose)) 667 goto error_c; 668 669 pipe_sampler_view_reference(&matrix, NULL); 670 pipe_sampler_view_reference(&transpose, NULL); 671 return true; 672 673error_c: 674 vl_idct_cleanup(&dec->idct_y); 675 676error_y: 677 pipe_sampler_view_reference(&transpose, NULL); 678 679error_transpose: 680 pipe_sampler_view_reference(&matrix, NULL); 681 682error_matrix: 683 return false; 684} 685 686struct pipe_video_decoder * 687vl_create_mpeg12_decoder(struct pipe_video_context *context, 688 struct pipe_context *pipe, 689 enum pipe_video_profile profile, 690 enum pipe_video_entrypoint entrypoint, 691 enum pipe_video_chroma_format chroma_format, 692 unsigned width, unsigned height) 693{ 694 struct vl_mpeg12_decoder *dec; 695 float mc_scale; 696 unsigned i; 697 698 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); 699 700 dec = CALLOC_STRUCT(vl_mpeg12_decoder); 701 702 if (!dec) 703 return NULL; 704 705 dec->base.context = context; 706 dec->base.profile = profile; 707 dec->base.entrypoint = entrypoint; 708 dec->base.chroma_format = chroma_format; 709 dec->base.width = width; 710 dec->base.height = height; 711 712 dec->base.destroy = vl_mpeg12_destroy; 713 dec->base.create_buffer = vl_mpeg12_create_buffer; 714 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer; 715 dec->base.clear_buffer = vl_mpeg12_decoder_clear_buffer; 716 717 dec->pipe = pipe; 718 719 dec->quads = vl_vb_upload_quads(dec->pipe, 2, 2); 720 for (i = 0; i < VL_MAX_PLANES; ++i) 721 dec->ves_eb[i] = vl_vb_get_ves_eb(dec->pipe, i); 722 723 for (i = 0; i < 2; ++i) 724 dec->ves_mv[i] = vl_vb_get_ves_mv(dec->pipe, i); 725 726 dec->base.width = align(width, MACROBLOCK_WIDTH); 727 dec->base.height = align(height, MACROBLOCK_HEIGHT); 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, mc_scale)) 763 goto error_mc_y; 764 765 if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, mc_scale)) 766 goto error_mc_c; 767 768 if (!init_pipe_state(dec)) 769 goto error_pipe_state; 770 771 return &dec->base; 772 773error_pipe_state: 774 vl_mc_cleanup(&dec->mc_c); 775 776error_mc_c: 777 vl_mc_cleanup(&dec->mc_y); 778 779error_mc_y: 780 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { 781 vl_idct_cleanup(&dec->idct_y); 782 vl_idct_cleanup(&dec->idct_c); 783 } 784 785error_idct: 786 FREE(dec); 787 return NULL; 788} 789