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