[g3dvl] revert commit 310eea52ca1e997295c84163066cc5d0fd4f8cf6
[mesa.git] / src / gallium / auxiliary / vl / vl_mpeg12_decoder.c
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
41 static 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
47 static const enum pipe_format const_idct_source_formats[] = {
48 PIPE_FORMAT_R16G16B16A16_SNORM,
49 PIPE_FORMAT_R16G16B16A16_SSCALED
50 };
51
52 static const unsigned num_idct_source_formats =
53 sizeof(const_idct_source_formats) / sizeof(enum pipe_format);
54
55 static 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
62 static const unsigned num_idct_intermediate_formats =
63 sizeof(const_idct_intermediate_formats) / sizeof(enum pipe_format);
64
65 static const enum pipe_format const_mc_source_formats[] = {
66 PIPE_FORMAT_R16_SNORM,
67 PIPE_FORMAT_R16_SSCALED
68 };
69
70 static const unsigned num_mc_source_formats =
71 sizeof(const_mc_source_formats) / sizeof(enum pipe_format);
72
73 static void
74 map_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
110 static void
111 upload_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
132 static void
133 upload_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
168 static void
169 unmap_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
181 static void
182 cleanup_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
197 static void
198 vl_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
220 static void
221 vl_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
234 static void
235 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
236 unsigned num_macroblocks,
237 struct pipe_macroblock *macroblocks)
238 {
239 struct pipe_mpeg12_macroblock *mb = (struct pipe_mpeg12_macroblock*)macroblocks;
240 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
241 struct vl_mpeg12_decoder *dec;
242 unsigned i;
243
244 assert(buf);
245
246 dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
247 assert(dec);
248
249 assert(num_macroblocks);
250 assert(macroblocks);
251 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
252
253 for ( i = 0; i < num_macroblocks; ++i ) {
254 vl_vb_add_block(&buf->vertex_stream, &mb[i]);
255 upload_buffer(dec, buf, &mb[i]);
256 }
257 }
258
259 static void
260 vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer)
261 {
262 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
263 struct vl_mpeg12_decoder *dec;
264 assert(buf);
265
266 dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
267 assert(dec);
268
269 vl_vb_unmap(&buf->vertex_stream, dec->pipe);
270 unmap_buffers(dec, buf);
271 }
272
273 static void
274 vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
275 {
276 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
277
278 assert(decoder);
279
280 /* Asserted in softpipe_delete_fs_state() for some reason */
281 dec->pipe->bind_vs_state(dec->pipe, NULL);
282 dec->pipe->bind_fs_state(dec->pipe, NULL);
283
284 dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
285
286 vl_mc_cleanup(&dec->mc_y);
287 vl_mc_cleanup(&dec->mc_c);
288
289 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
290 vl_idct_cleanup(&dec->idct_y);
291 vl_idct_cleanup(&dec->idct_c);
292 }
293
294 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
295 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv);
296
297 pipe_resource_reference(&dec->quads.buffer, NULL);
298 pipe_resource_reference(&dec->pos.buffer, NULL);
299
300 FREE(dec);
301 }
302
303 static bool
304 init_idct_buffer(struct vl_mpeg12_buffer *buffer)
305 {
306 enum pipe_format formats[3];
307
308 struct pipe_sampler_view **idct_source_sv, **idct_intermediate_sv;
309 struct pipe_surface **idct_surfaces;
310
311 struct vl_mpeg12_decoder *dec;
312
313 unsigned i;
314
315 assert(buffer);
316
317 dec = (struct vl_mpeg12_decoder*)buffer->base.decoder;
318
319 formats[0] = formats[1] = formats[2] = dec->idct_source_format;
320 buffer->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe,
321 dec->base.width / 4, dec->base.height, 1,
322 dec->base.chroma_format,
323 formats, PIPE_USAGE_STREAM);
324 if (!buffer->idct_source)
325 goto error_source;
326
327 formats[0] = formats[1] = formats[2] = dec->idct_intermediate_format;
328 buffer->idct_intermediate = vl_video_buffer_init(dec->base.context, dec->pipe,
329 dec->base.width / dec->nr_of_idct_render_targets,
330 dec->base.height / 4, dec->nr_of_idct_render_targets,
331 dec->base.chroma_format,
332 formats, PIPE_USAGE_STATIC);
333
334 if (!buffer->idct_intermediate)
335 goto error_intermediate;
336
337 idct_source_sv = buffer->idct_source->get_sampler_views(buffer->idct_source);
338 if (!idct_source_sv)
339 goto error_source_sv;
340
341 idct_intermediate_sv = buffer->idct_intermediate->get_sampler_views(buffer->idct_intermediate);
342 if (!idct_intermediate_sv)
343 goto error_intermediate_sv;
344
345 idct_surfaces = buffer->mc_source->get_surfaces(buffer->mc_source);
346 if (!idct_surfaces)
347 goto error_surfaces;
348
349 for (i = 0; i < 3; ++i)
350 if (!vl_idct_init_buffer(i == 0 ? &dec->idct_y : &dec->idct_c,
351 &buffer->idct[i], idct_source_sv[i],
352 idct_intermediate_sv[i], idct_surfaces[i]))
353 goto error_plane;
354
355 return true;
356
357 error_plane:
358 for (; i > 0; --i)
359 vl_idct_cleanup_buffer(i == 1 ? &dec->idct_c : &dec->idct_y, &buffer->idct[i - 1]);
360
361 error_surfaces:
362 error_intermediate_sv:
363 error_source_sv:
364 buffer->idct_intermediate->destroy(buffer->idct_intermediate);
365
366 error_intermediate:
367 buffer->idct_source->destroy(buffer->idct_source);
368
369 error_source:
370 return false;
371 }
372
373 static struct pipe_video_decode_buffer *
374 vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
375 {
376 enum pipe_format formats[3];
377
378 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
379 struct vl_mpeg12_buffer *buffer;
380
381 struct pipe_sampler_view **mc_source_sv;
382
383 assert(dec);
384
385 buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
386 if (buffer == NULL)
387 return NULL;
388
389 buffer->base.decoder = decoder;
390 buffer->base.destroy = vl_mpeg12_buffer_destroy;
391 buffer->base.map = vl_mpeg12_buffer_map;
392 buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
393 buffer->base.unmap = vl_mpeg12_buffer_unmap;
394
395 vl_vb_init(&buffer->vertex_stream, dec->pipe,
396 dec->base.width / MACROBLOCK_WIDTH,
397 dec->base.height / MACROBLOCK_HEIGHT);
398
399 formats[0] = formats[1] = formats[2] =dec->mc_source_format;
400 buffer->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
401 dec->base.width, dec->base.height, 1,
402 dec->base.chroma_format,
403 formats, PIPE_USAGE_STATIC);
404
405 if (!buffer->mc_source)
406 goto error_mc_source;
407
408 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
409 if (!init_idct_buffer(buffer))
410 goto error_idct;
411
412 mc_source_sv = buffer->mc_source->get_sampler_views(buffer->mc_source);
413 if (!mc_source_sv)
414 goto error_mc_source_sv;
415
416 if(!vl_mc_init_buffer(&dec->mc_y, &buffer->mc[0], mc_source_sv[0]))
417 goto error_mc_y;
418
419 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[1], mc_source_sv[1]))
420 goto error_mc_cb;
421
422 if(!vl_mc_init_buffer(&dec->mc_c, &buffer->mc[2], mc_source_sv[2]))
423 goto error_mc_cr;
424
425 return &buffer->base;
426
427 error_mc_cr:
428 vl_mc_cleanup_buffer(&buffer->mc[1]);
429
430 error_mc_cb:
431 vl_mc_cleanup_buffer(&buffer->mc[0]);
432
433 error_mc_y:
434 error_mc_source_sv:
435 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
436 cleanup_idct_buffer(buffer);
437
438 error_idct:
439 buffer->mc_source->destroy(buffer->mc_source);
440
441 error_mc_source:
442 vl_vb_cleanup(&buffer->vertex_stream);
443
444 error_vertex_stream:
445 FREE(buffer);
446 return NULL;
447 }
448
449 static void
450 vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
451 struct pipe_video_buffer *refs[2],
452 struct pipe_video_buffer *dst,
453 struct pipe_fence_handle **fence)
454 {
455 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
456 struct vl_mpeg12_decoder *dec;
457
458 struct pipe_sampler_view **sv[2];
459 struct pipe_surface **surfaces;
460
461 struct pipe_vertex_buffer vb[3];
462
463 unsigned i, j;
464
465 assert(buf);
466
467 dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
468 assert(dec);
469
470 for (i = 0; i < 2; ++i)
471 sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL;
472
473 surfaces = dst->get_surfaces(dst);
474
475 vb[0] = dec->quads;
476 vb[1] = dec->pos;
477
478 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv);
479 for (i = 0; i < VL_MAX_PLANES; ++i) {
480 vl_mc_set_surface(&buf->mc[i], surfaces[i]);
481
482 for (j = 0; j < 2; ++j) {
483 if (sv[j] == NULL) continue;
484
485 vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
486 dec->pipe->set_vertex_buffers(dec->pipe, 3, vb);
487
488 vl_mc_render_ref(&buf->mc[i], sv[j][i]);
489 }
490 }
491
492 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
493 for (i = 0; i < VL_MAX_PLANES; ++i) {
494 unsigned num_instances = vl_vb_restart(&buf->vertex_stream, i);
495
496 vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
497 dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
498
499 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
500 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_instances);
501
502 vl_mc_render_ycbcr(&buf->mc[i], num_instances);
503 }
504
505 dec->pipe->flush(dec->pipe, fence);
506 }
507
508 static void
509 vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer *buffer)
510 {
511 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
512 unsigned i;
513
514 assert(buf);
515
516 for (i = 0; i < VL_MAX_PLANES; ++i)
517 vl_vb_restart(&buf->vertex_stream, i);
518 }
519
520 static bool
521 init_pipe_state(struct vl_mpeg12_decoder *dec)
522 {
523 struct pipe_depth_stencil_alpha_state dsa;
524 unsigned i;
525
526 assert(dec);
527
528 memset(&dsa, 0, sizeof dsa);
529 dsa.depth.enabled = 0;
530 dsa.depth.writemask = 0;
531 dsa.depth.func = PIPE_FUNC_ALWAYS;
532 for (i = 0; i < 2; ++i) {
533 dsa.stencil[i].enabled = 0;
534 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
535 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
536 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
537 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
538 dsa.stencil[i].valuemask = 0;
539 dsa.stencil[i].writemask = 0;
540 }
541 dsa.alpha.enabled = 0;
542 dsa.alpha.func = PIPE_FUNC_ALWAYS;
543 dsa.alpha.ref_value = 0;
544 dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa);
545 dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa);
546
547 return true;
548 }
549
550 static enum pipe_format
551 find_first_supported_format(struct vl_mpeg12_decoder *dec,
552 const enum pipe_format formats[],
553 unsigned num_formats,
554 enum pipe_texture_target target)
555 {
556 struct pipe_screen *screen;
557 unsigned i;
558
559 assert(dec);
560
561 screen = dec->pipe->screen;
562
563 for (i = 0; i < num_formats; ++i)
564 if (screen->is_format_supported(dec->pipe->screen, formats[i], target, 1,
565 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
566 return formats[i];
567
568 return PIPE_FORMAT_NONE;
569 }
570
571 static bool
572 init_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_height)
573 {
574 unsigned chroma_width, chroma_height;
575 struct pipe_sampler_view *matrix, *transpose;
576 float matrix_scale, transpose_scale;
577
578 dec->nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS);
579
580 // more than 4 render targets usually doesn't makes any seens
581 dec->nr_of_idct_render_targets = MIN2(dec->nr_of_idct_render_targets, 4);
582
583 dec->idct_source_format = find_first_supported_format(dec, const_idct_source_formats,
584 num_idct_source_formats, PIPE_TEXTURE_2D);
585
586 if (dec->idct_source_format == PIPE_FORMAT_NONE)
587 return false;
588
589 dec->idct_intermediate_format = find_first_supported_format(dec, const_idct_intermediate_formats,
590 num_idct_intermediate_formats, PIPE_TEXTURE_3D);
591
592 if (dec->idct_intermediate_format == PIPE_FORMAT_NONE)
593 return false;
594
595 switch (dec->idct_source_format) {
596 case PIPE_FORMAT_R16G16B16A16_SSCALED:
597 matrix_scale = SCALE_FACTOR_SSCALED;
598 break;
599
600 case PIPE_FORMAT_R16G16B16A16_SNORM:
601 matrix_scale = SCALE_FACTOR_SNORM;
602 break;
603
604 default:
605 assert(0);
606 return false;
607 }
608
609 if (dec->idct_intermediate_format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
610 dec->idct_intermediate_format == PIPE_FORMAT_R32G32B32A32_FLOAT)
611 transpose_scale = 1.0f;
612 else
613 transpose_scale = matrix_scale = sqrt(matrix_scale);
614
615 if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED)
616 transpose_scale /= SCALE_FACTOR_SSCALED;
617
618 if (!(matrix = vl_idct_upload_matrix(dec->pipe, matrix_scale)))
619 goto error_matrix;
620
621 if (matrix_scale != transpose_scale) {
622 if (!(transpose = vl_idct_upload_matrix(dec->pipe, transpose_scale)))
623 goto error_transpose;
624 } else
625 pipe_sampler_view_reference(&transpose, matrix);
626
627 if (!vl_idct_init(&dec->idct_y, dec->pipe, buffer_width, buffer_height,
628 dec->nr_of_idct_render_targets, matrix, transpose))
629 goto error_y;
630
631 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
632 chroma_width = buffer_width / 2;
633 chroma_height = buffer_height / 2;
634 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
635 chroma_width = buffer_width;
636 chroma_height = buffer_height / 2;
637 } else {
638 chroma_width = buffer_width;
639 chroma_height = buffer_height;
640 }
641
642 if(!vl_idct_init(&dec->idct_c, dec->pipe, chroma_width, chroma_height,
643 dec->nr_of_idct_render_targets, matrix, transpose))
644 goto error_c;
645
646 pipe_sampler_view_reference(&matrix, NULL);
647 pipe_sampler_view_reference(&transpose, NULL);
648 return true;
649
650 error_c:
651 vl_idct_cleanup(&dec->idct_y);
652
653 error_y:
654 pipe_sampler_view_reference(&transpose, NULL);
655
656 error_transpose:
657 pipe_sampler_view_reference(&matrix, NULL);
658
659 error_matrix:
660 return false;
661 }
662
663 struct pipe_video_decoder *
664 vl_create_mpeg12_decoder(struct pipe_video_context *context,
665 struct pipe_context *pipe,
666 enum pipe_video_profile profile,
667 enum pipe_video_entrypoint entrypoint,
668 enum pipe_video_chroma_format chroma_format,
669 unsigned width, unsigned height)
670 {
671 struct vl_mpeg12_decoder *dec;
672 float mc_scale;
673
674 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
675
676 dec = CALLOC_STRUCT(vl_mpeg12_decoder);
677
678 if (!dec)
679 return NULL;
680
681 dec->base.context = context;
682 dec->base.profile = profile;
683 dec->base.entrypoint = entrypoint;
684 dec->base.chroma_format = chroma_format;
685 dec->base.width = width;
686 dec->base.height = height;
687
688 dec->base.destroy = vl_mpeg12_destroy;
689 dec->base.create_buffer = vl_mpeg12_create_buffer;
690 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer;
691 dec->base.clear_buffer = vl_mpeg12_decoder_clear_buffer;
692
693 dec->base.width = align(width, MACROBLOCK_WIDTH);
694 dec->base.height = align(height, MACROBLOCK_HEIGHT);
695
696 dec->pipe = pipe;
697
698 dec->quads = vl_vb_upload_quads(dec->pipe);
699 dec->pos = vl_vb_upload_pos(
700 dec->pipe,
701 dec->base.width / MACROBLOCK_WIDTH,
702 dec->base.height / MACROBLOCK_HEIGHT
703 );
704
705 dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe);
706 dec->ves_mv = vl_vb_get_ves_mv(dec->pipe);
707
708 /* TODO: Implement 422, 444 */
709 assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
710 dec->empty_block_mask = &const_empty_block_mask_420;
711
712 dec->mc_source_format = find_first_supported_format(dec, const_mc_source_formats,
713 num_mc_source_formats, PIPE_TEXTURE_3D);
714
715 if (dec->mc_source_format == PIPE_FORMAT_NONE)
716 return NULL;
717
718 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
719 if (!init_idct(dec, dec->base.width, dec->base.height))
720 goto error_idct;
721 if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED)
722 mc_scale = SCALE_FACTOR_SSCALED;
723 else
724 mc_scale = 1.0f;
725 } else {
726 switch (dec->mc_source_format) {
727 case PIPE_FORMAT_R16_SNORM:
728 mc_scale = SCALE_FACTOR_SNORM;
729 break;
730
731 case PIPE_FORMAT_R16_SSCALED:
732 mc_scale = SCALE_FACTOR_SSCALED;
733 break;
734
735 default:
736 assert(0);
737 return NULL;
738 }
739 }
740
741 if (!vl_mc_init(&dec->mc_y, dec->pipe, dec->base.width, dec->base.height, MACROBLOCK_HEIGHT, mc_scale))
742 goto error_mc_y;
743
744 // TODO
745 if (!vl_mc_init(&dec->mc_c, dec->pipe, dec->base.width, dec->base.height, BLOCK_HEIGHT, mc_scale))
746 goto error_mc_c;
747
748 if (!init_pipe_state(dec))
749 goto error_pipe_state;
750
751 return &dec->base;
752
753 error_pipe_state:
754 vl_mc_cleanup(&dec->mc_c);
755
756 error_mc_c:
757 vl_mc_cleanup(&dec->mc_y);
758
759 error_mc_y:
760 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
761 vl_idct_cleanup(&dec->idct_y);
762 vl_idct_cleanup(&dec->idct_c);
763 }
764
765 error_idct:
766 FREE(dec);
767 return NULL;
768 }