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