[g3dvl] also use video buffer for idct intermediate
[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_16_TO_9 (32768.0f / 256.0f)
39
40 static 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
46 static void
47 map_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
83 static void
84 upload_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
101 static void
102 upload_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
135 static void
136 unmap_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
148 static void
149 vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
150 {
151 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
152 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
153 assert(buf && dec);
154
155 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
156 buf->idct_source->destroy(buf->idct_source);
157 buf->idct_intermediate->destroy(buf->idct_intermediate);
158 vl_idct_cleanup_buffer(&dec->idct_y, &buf->idct[0]);
159 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[1]);
160 vl_idct_cleanup_buffer(&dec->idct_c, &buf->idct[2]);
161 }
162 buf->mc_source->destroy(buf->mc_source);
163 vl_vb_cleanup(&buf->vertex_stream);
164 vl_mpeg12_mc_cleanup_buffer(&buf->mc[0]);
165 vl_mpeg12_mc_cleanup_buffer(&buf->mc[1]);
166 vl_mpeg12_mc_cleanup_buffer(&buf->mc[2]);
167
168 FREE(buf);
169 }
170
171 static void
172 vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer)
173 {
174 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
175 struct vl_mpeg12_decoder *dec;
176 assert(buf);
177
178 dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
179 assert(dec);
180
181 vl_vb_map(&buf->vertex_stream, dec->pipe);
182 map_buffers(dec, buf);
183 }
184
185 static void
186 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer *buffer,
187 unsigned num_macroblocks,
188 struct pipe_macroblock *macroblocks)
189 {
190 struct pipe_mpeg12_macroblock *mb = (struct pipe_mpeg12_macroblock*)macroblocks;
191 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
192 struct vl_mpeg12_decoder *dec;
193 unsigned i;
194
195 assert(buf);
196
197 dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
198 assert(dec);
199
200 assert(num_macroblocks);
201 assert(macroblocks);
202 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
203
204 for ( i = 0; i < num_macroblocks; ++i ) {
205 vl_vb_add_block(&buf->vertex_stream, &mb[i], dec->empty_block_mask);
206 upload_buffer(dec, buf, &mb[i]);
207 }
208 }
209
210 static void
211 vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer *buffer)
212 {
213 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
214 struct vl_mpeg12_decoder *dec;
215 assert(buf);
216
217 dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
218 assert(dec);
219
220 vl_vb_unmap(&buf->vertex_stream, dec->pipe);
221 unmap_buffers(dec, buf);
222 }
223
224 static void
225 vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
226 {
227 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
228
229 assert(decoder);
230
231 /* Asserted in softpipe_delete_fs_state() for some reason */
232 dec->pipe->bind_vs_state(dec->pipe, NULL);
233 dec->pipe->bind_fs_state(dec->pipe, NULL);
234
235 dec->pipe->delete_blend_state(dec->pipe, dec->blend);
236 dec->pipe->delete_rasterizer_state(dec->pipe, dec->rast);
237 dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
238
239 vl_mpeg12_mc_renderer_cleanup(&dec->mc);
240 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
241 vl_idct_cleanup(&dec->idct_y);
242 vl_idct_cleanup(&dec->idct_c);
243 }
244 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[0]);
245 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[1]);
246 dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[2]);
247 pipe_resource_reference(&dec->quads.buffer, NULL);
248
249 FREE(dec);
250 }
251
252 static struct pipe_video_decode_buffer *
253 vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
254 {
255 const enum pipe_format idct_source_formats[3] = {
256 PIPE_FORMAT_R16G16B16A16_SNORM,
257 PIPE_FORMAT_R16G16B16A16_SNORM,
258 PIPE_FORMAT_R16G16B16A16_SNORM
259 };
260
261 const enum pipe_format mc_source_formats[3] = {
262 PIPE_FORMAT_R16_SNORM,
263 PIPE_FORMAT_R16_SNORM,
264 PIPE_FORMAT_R16_SNORM
265 };
266
267 struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
268 struct vl_mpeg12_buffer *buffer;
269
270 struct pipe_sampler_view **idct_source_sv, **idct_intermediate_sv, **mc_source_sv;
271 struct pipe_surface **idct_surfaces;
272
273 assert(dec);
274
275 buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
276 if (buffer == NULL)
277 return NULL;
278
279 buffer->base.decoder = decoder;
280 buffer->base.destroy = vl_mpeg12_buffer_destroy;
281 buffer->base.map = vl_mpeg12_buffer_map;
282 buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
283 buffer->base.unmap = vl_mpeg12_buffer_unmap;
284
285 buffer->vertex_bufs.individual.quad.stride = dec->quads.stride;
286 buffer->vertex_bufs.individual.quad.buffer_offset = dec->quads.buffer_offset;
287 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, dec->quads.buffer);
288
289 buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, dec->pipe,
290 dec->base.width / MACROBLOCK_WIDTH *
291 dec->base.height / MACROBLOCK_HEIGHT);
292 if (!buffer->vertex_bufs.individual.stream.buffer)
293 goto error_vertex_stream;
294
295 buffer->mc_source = vl_video_buffer_init(dec->base.context, dec->pipe,
296 dec->base.width, dec->base.height, 1,
297 dec->base.chroma_format, 3,
298 mc_source_formats,
299 PIPE_USAGE_STATIC);
300
301 if (!buffer->mc_source)
302 goto error_mc_source;
303
304 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
305 buffer->idct_source = vl_video_buffer_init(dec->base.context, dec->pipe,
306 dec->base.width / 4, dec->base.height, 1,
307 dec->base.chroma_format, 3,
308 idct_source_formats,
309 PIPE_USAGE_STREAM);
310 if (!buffer->idct_source)
311 goto error_idct_source;
312
313 buffer->idct_intermediate = vl_video_buffer_init(dec->base.context, dec->pipe,
314 dec->base.width / 4, dec->base.height / 4, 4,
315 dec->base.chroma_format, 3,
316 idct_source_formats,
317 PIPE_USAGE_STATIC);
318
319 if (!buffer->idct_intermediate)
320 goto error_idct_intermediate;
321
322 idct_source_sv = buffer->idct_source->get_sampler_views(buffer->idct_source);
323 if (!idct_source_sv)
324 goto error_idct_source_sv;
325
326 idct_intermediate_sv = buffer->idct_intermediate->get_sampler_views(buffer->idct_intermediate);
327 if (!idct_intermediate_sv)
328 goto error_idct_intermediate_sv;
329
330 idct_surfaces = buffer->mc_source->get_surfaces(buffer->mc_source);
331 if (!idct_surfaces)
332 goto error_idct_surfaces;
333
334 if (!vl_idct_init_buffer(&dec->idct_y, &buffer->idct[0],
335 idct_source_sv[0],
336 idct_intermediate_sv[0],
337 idct_surfaces[0]))
338 goto error_idct_y;
339
340 if (!vl_idct_init_buffer(&dec->idct_c, &buffer->idct[1],
341 idct_source_sv[1],
342 idct_intermediate_sv[1],
343 idct_surfaces[1]))
344 goto error_idct_cb;
345
346 if (!vl_idct_init_buffer(&dec->idct_c, &buffer->idct[2],
347 idct_source_sv[2],
348 idct_intermediate_sv[2],
349 idct_surfaces[2]))
350 goto error_idct_cr;
351 }
352
353 mc_source_sv = buffer->mc_source->get_sampler_views(buffer->mc_source);
354 if (!mc_source_sv)
355 goto error_mc_source_sv;
356
357 if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[0], mc_source_sv[0]))
358 goto error_mc_y;
359
360 if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[1], mc_source_sv[1]))
361 goto error_mc_cb;
362
363 if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[2], mc_source_sv[2]))
364 goto error_mc_cr;
365
366 return &buffer->base;
367
368 error_mc_cr:
369 vl_mpeg12_mc_cleanup_buffer(&buffer->mc[1]);
370
371 error_mc_cb:
372 vl_mpeg12_mc_cleanup_buffer(&buffer->mc[0]);
373
374 error_mc_y:
375 error_mc_source_sv:
376 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
377 vl_idct_cleanup_buffer(&dec->idct_c, &buffer->idct[2]);
378
379 error_idct_cr:
380 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
381 vl_idct_cleanup_buffer(&dec->idct_c, &buffer->idct[1]);
382
383 error_idct_cb:
384 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
385 vl_idct_cleanup_buffer(&dec->idct_y, &buffer->idct[0]);
386
387 error_idct_y:
388 error_idct_surfaces:
389 error_idct_intermediate_sv:
390 error_idct_source_sv:
391 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
392 buffer->idct_intermediate->destroy(buffer->idct_intermediate);
393
394 error_idct_intermediate:
395 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
396 buffer->idct_source->destroy(buffer->idct_source);
397
398 error_idct_source:
399 buffer->mc_source->destroy(buffer->mc_source);
400
401 error_mc_source:
402 vl_vb_cleanup(&buffer->vertex_stream);
403
404 error_vertex_stream:
405 FREE(buffer);
406 return NULL;
407 }
408
409 static void
410 vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
411 struct pipe_video_buffer *refs[2],
412 struct pipe_video_buffer *dst,
413 struct pipe_fence_handle **fence)
414 {
415 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
416 struct vl_mpeg12_decoder *dec;
417
418 struct pipe_sampler_view **sv_past;
419 struct pipe_sampler_view **sv_future;
420 struct pipe_surface **surfaces;
421
422 struct pipe_sampler_view *sv_refs[2];
423 unsigned ne_start, ne_num, e_start, e_num;
424 unsigned i;
425
426 assert(buf);
427
428 dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
429 assert(dec);
430
431 sv_past = refs[0] ? refs[0]->get_sampler_views(refs[0]) : NULL;
432 sv_future = refs[1] ? refs[1]->get_sampler_views(refs[1]) : NULL;
433
434 surfaces = dst->get_surfaces(dst);
435
436 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
437
438 dec->pipe->set_vertex_buffers(dec->pipe, 2, buf->vertex_bufs.all);
439 dec->pipe->bind_blend_state(dec->pipe, dec->blend);
440
441 for (i = 0; i < VL_MAX_PLANES; ++i) {
442 dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves[i]);
443
444 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
445 vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], ne_num);
446
447 sv_refs[0] = sv_past ? sv_past[i] : NULL;
448 sv_refs[1] = sv_future ? sv_future[i] : NULL;
449
450 vl_mpeg12_mc_renderer_flush(&dec->mc, &buf->mc[i], surfaces[i], sv_refs,
451 ne_start, ne_num, e_start, e_num, fence);
452 }
453 }
454
455 static void
456 vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer *buffer)
457 {
458 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
459 unsigned ne_start, ne_num, e_start, e_num;
460
461 assert(buf);
462
463 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
464 }
465
466 static bool
467 init_pipe_state(struct vl_mpeg12_decoder *dec)
468 {
469 struct pipe_rasterizer_state rast;
470 struct pipe_blend_state blend;
471 struct pipe_depth_stencil_alpha_state dsa;
472 unsigned i;
473
474 assert(dec);
475
476 memset(&rast, 0, sizeof rast);
477 rast.flatshade = 1;
478 rast.flatshade_first = 0;
479 rast.light_twoside = 0;
480 rast.front_ccw = 1;
481 rast.cull_face = PIPE_FACE_NONE;
482 rast.fill_back = PIPE_POLYGON_MODE_FILL;
483 rast.fill_front = PIPE_POLYGON_MODE_FILL;
484 rast.offset_point = 0;
485 rast.offset_line = 0;
486 rast.scissor = 0;
487 rast.poly_smooth = 0;
488 rast.poly_stipple_enable = 0;
489 rast.sprite_coord_enable = 0;
490 rast.point_size_per_vertex = 0;
491 rast.multisample = 0;
492 rast.line_smooth = 0;
493 rast.line_stipple_enable = 0;
494 rast.line_stipple_factor = 0;
495 rast.line_stipple_pattern = 0;
496 rast.line_last_pixel = 0;
497 rast.line_width = 1;
498 rast.point_smooth = 0;
499 rast.point_quad_rasterization = 0;
500 rast.point_size_per_vertex = 1;
501 rast.offset_units = 1;
502 rast.offset_scale = 1;
503 rast.gl_rasterization_rules = 1;
504
505 dec->rast = dec->pipe->create_rasterizer_state(dec->pipe, &rast);
506 dec->pipe->bind_rasterizer_state(dec->pipe, dec->rast);
507
508 memset(&blend, 0, sizeof blend);
509
510 blend.independent_blend_enable = 0;
511 blend.rt[0].blend_enable = 0;
512 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
513 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
514 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
515 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
516 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
517 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
518 blend.logicop_enable = 0;
519 blend.logicop_func = PIPE_LOGICOP_CLEAR;
520 /* Needed to allow color writes to FB, even if blending disabled */
521 blend.rt[0].colormask = PIPE_MASK_RGBA;
522 blend.dither = 0;
523 dec->blend = dec->pipe->create_blend_state(dec->pipe, &blend);
524
525 memset(&dsa, 0, sizeof dsa);
526 dsa.depth.enabled = 0;
527 dsa.depth.writemask = 0;
528 dsa.depth.func = PIPE_FUNC_ALWAYS;
529 for (i = 0; i < 2; ++i) {
530 dsa.stencil[i].enabled = 0;
531 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
532 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
533 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
534 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
535 dsa.stencil[i].valuemask = 0;
536 dsa.stencil[i].writemask = 0;
537 }
538 dsa.alpha.enabled = 0;
539 dsa.alpha.func = PIPE_FUNC_ALWAYS;
540 dsa.alpha.ref_value = 0;
541 dec->dsa = dec->pipe->create_depth_stencil_alpha_state(dec->pipe, &dsa);
542 dec->pipe->bind_depth_stencil_alpha_state(dec->pipe, dec->dsa);
543
544 return true;
545 }
546
547 static bool
548 init_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_height)
549 {
550 unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
551 struct pipe_sampler_view *idct_matrix;
552
553 if (!(idct_matrix = vl_idct_upload_matrix(dec->pipe, sqrt(SCALE_FACTOR_16_TO_9))))
554 goto error_idct_matrix;
555
556 if (!vl_idct_init(&dec->idct_y, dec->pipe, buffer_width, buffer_height,
557 2, 2, idct_matrix))
558 goto error_idct_y;
559
560 if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
561 chroma_width = buffer_width / 2;
562 chroma_height = buffer_height / 2;
563 chroma_blocks_x = 1;
564 chroma_blocks_y = 1;
565 } else if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
566 chroma_width = buffer_width;
567 chroma_height = buffer_height / 2;
568 chroma_blocks_x = 2;
569 chroma_blocks_y = 1;
570 } else {
571 chroma_width = buffer_width;
572 chroma_height = buffer_height;
573 chroma_blocks_x = 2;
574 chroma_blocks_y = 2;
575 }
576
577 if(!vl_idct_init(&dec->idct_c, dec->pipe, chroma_width, chroma_height,
578 chroma_blocks_x, chroma_blocks_y, idct_matrix))
579 goto error_idct_c;
580
581 pipe_sampler_view_reference(&idct_matrix, NULL);
582 return true;
583
584 error_idct_c:
585 vl_idct_cleanup(&dec->idct_y);
586
587 error_idct_y:
588 pipe_sampler_view_reference(&idct_matrix, NULL);
589
590 error_idct_matrix:
591 return false;
592 }
593
594 struct pipe_video_decoder *
595 vl_create_mpeg12_decoder(struct pipe_video_context *context,
596 struct pipe_context *pipe,
597 enum pipe_video_profile profile,
598 enum pipe_video_entrypoint entrypoint,
599 enum pipe_video_chroma_format chroma_format,
600 unsigned width, unsigned height)
601 {
602 struct vl_mpeg12_decoder *dec;
603 unsigned i;
604
605 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
606
607 dec = CALLOC_STRUCT(vl_mpeg12_decoder);
608
609 if (!dec)
610 return NULL;
611
612 dec->base.context = context;
613 dec->base.profile = profile;
614 dec->base.entrypoint = entrypoint;
615 dec->base.chroma_format = chroma_format;
616 dec->base.width = width;
617 dec->base.height = height;
618
619 dec->base.destroy = vl_mpeg12_destroy;
620 dec->base.create_buffer = vl_mpeg12_create_buffer;
621 dec->base.flush_buffer = vl_mpeg12_decoder_flush_buffer;
622 dec->base.clear_buffer = vl_mpeg12_decoder_clear_buffer;
623
624 dec->pipe = pipe;
625
626 dec->quads = vl_vb_upload_quads(dec->pipe, 2, 2);
627 for (i = 0; i < VL_MAX_PLANES; ++i)
628 dec->ves[i] = vl_vb_get_elems_state(dec->pipe, i);
629
630 dec->base.width = align(width, MACROBLOCK_WIDTH);
631 dec->base.height = align(height, MACROBLOCK_HEIGHT);
632
633 /* TODO: Implement 422, 444 */
634 assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
635 dec->empty_block_mask = &const_empty_block_mask_420;
636
637 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
638 if (!init_idct(dec, dec->base.width, dec->base.height))
639 goto error_idct;
640
641 if (!vl_mpeg12_mc_renderer_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height,
642 entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 1.0f : SCALE_FACTOR_16_TO_9))
643 goto error_mc;
644
645 if (!init_pipe_state(dec))
646 goto error_pipe_state;
647
648 return &dec->base;
649
650 error_pipe_state:
651 vl_mpeg12_mc_renderer_cleanup(&dec->mc);
652
653 error_mc:
654 if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
655 vl_idct_cleanup(&dec->idct_y);
656 vl_idct_cleanup(&dec->idct_c);
657 }
658
659 error_idct:
660 FREE(dec);
661 return NULL;
662 }