1 /**************************************************************************
3 * Copyright 2009 Younes Manton.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 #include <util/u_memory.h>
32 #include <util/u_rect.h>
33 #include <util/u_video.h>
35 #include "vl_mpeg12_decoder.h"
36 #include "vl_defines.h"
38 #define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
39 #define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
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 } }
47 static const enum pipe_format const_idct_source_formats
[] = {
48 PIPE_FORMAT_R16G16B16A16_SNORM
,
49 PIPE_FORMAT_R16G16B16A16_SSCALED
52 static const unsigned num_idct_source_formats
=
53 sizeof(const_idct_source_formats
) / sizeof(enum pipe_format
);
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
62 static const unsigned num_idct_intermediate_formats
=
63 sizeof(const_idct_intermediate_formats
) / sizeof(enum pipe_format
);
65 static const enum pipe_format const_mc_source_formats
[] = {
66 PIPE_FORMAT_R16_SNORM
,
67 PIPE_FORMAT_R16_SSCALED
70 static const unsigned num_mc_source_formats
=
71 sizeof(const_mc_source_formats
) / sizeof(enum pipe_format
);
74 map_buffers(struct vl_mpeg12_decoder
*ctx
, struct vl_mpeg12_buffer
*buffer
)
76 struct pipe_sampler_view
**sampler_views
;
77 struct pipe_resource
*tex
;
80 assert(ctx
&& buffer
);
82 if (ctx
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
83 sampler_views
= buffer
->idct_source
->get_sampler_views(buffer
->idct_source
);
85 sampler_views
= buffer
->mc_source
->get_sampler_views(buffer
->mc_source
);
86 assert(sampler_views
);
88 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
89 tex
= sampler_views
[i
]->texture
;
91 struct pipe_box rect
=
99 buffer
->tex_transfer
[i
] = ctx
->pipe
->get_transfer
102 0, PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
106 buffer
->texels
[i
] = ctx
->pipe
->transfer_map(ctx
->pipe
, buffer
->tex_transfer
[i
]);
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
)
123 vl_vb_add_ycbcr(&buffer
->vertex_stream
, plane
, x
, y
, intra
, type
);
125 tex_pitch
= buffer
->tex_transfer
[plane
]->stride
/ sizeof(short);
126 texels
= buffer
->texels
[plane
] + y
* tex_pitch
* BLOCK_HEIGHT
+ x
* BLOCK_WIDTH
;
128 for (i
= 0; i
< BLOCK_HEIGHT
; ++i
)
129 memcpy(texels
+ i
* tex_pitch
, block
+ i
* BLOCK_WIDTH
, BLOCK_WIDTH
* sizeof(short));
133 upload_buffer(struct vl_mpeg12_decoder
*ctx
,
134 struct vl_mpeg12_buffer
*buffer
,
135 struct pipe_mpeg12_macroblock
*mb
)
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
;
156 /* TODO: Implement 422, 444 */
157 assert(ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
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
;
169 unmap_buffers(struct vl_mpeg12_decoder
*ctx
, struct vl_mpeg12_buffer
*buffer
)
173 assert(ctx
&& buffer
);
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
]);
182 cleanup_idct_buffer(struct vl_mpeg12_buffer
*buf
)
184 struct vl_mpeg12_decoder
*dec
;
187 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
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]);
198 vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer
*buffer
)
200 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
201 struct vl_mpeg12_decoder
*dec
;
206 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
209 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
210 cleanup_idct_buffer(buf
);
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
]);
221 vl_mpeg12_buffer_map(struct pipe_video_decode_buffer
*buffer
)
223 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
224 struct vl_mpeg12_decoder
*dec
;
227 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
230 vl_vb_map(&buf
->vertex_stream
, dec
->pipe
);
231 map_buffers(dec
, buf
);
235 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_decode_buffer
*buffer
,
236 unsigned num_macroblocks
,
237 struct pipe_macroblock
*macroblocks
)
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
;
246 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
249 assert(num_macroblocks
);
251 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
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
]);
260 vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer
*buffer
)
262 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
263 struct vl_mpeg12_decoder
*dec
;
266 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
269 vl_vb_unmap(&buf
->vertex_stream
, dec
->pipe
);
270 unmap_buffers(dec
, buf
);
274 vl_mpeg12_destroy(struct pipe_video_decoder
*decoder
)
276 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
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
);
284 dec
->pipe
->delete_depth_stencil_alpha_state(dec
->pipe
, dec
->dsa
);
286 vl_mc_cleanup(&dec
->mc_y
);
287 vl_mc_cleanup(&dec
->mc_c
);
289 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
290 vl_idct_cleanup(&dec
->idct_y
);
291 vl_idct_cleanup(&dec
->idct_c
);
294 dec
->pipe
->delete_vertex_elements_state(dec
->pipe
, dec
->ves_ycbcr
);
295 dec
->pipe
->delete_vertex_elements_state(dec
->pipe
, dec
->ves_mv
);
297 pipe_resource_reference(&dec
->quads
.buffer
, NULL
);
298 pipe_resource_reference(&dec
->pos
.buffer
, NULL
);
304 init_idct_buffer(struct vl_mpeg12_buffer
*buffer
)
306 enum pipe_format formats
[3];
308 struct pipe_sampler_view
**idct_source_sv
, **idct_intermediate_sv
;
309 struct pipe_surface
**idct_surfaces
;
311 struct vl_mpeg12_decoder
*dec
;
317 dec
= (struct vl_mpeg12_decoder
*)buffer
->base
.decoder
;
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
)
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
);
334 if (!buffer
->idct_intermediate
)
335 goto error_intermediate
;
337 idct_source_sv
= buffer
->idct_source
->get_sampler_views(buffer
->idct_source
);
339 goto error_source_sv
;
341 idct_intermediate_sv
= buffer
->idct_intermediate
->get_sampler_views(buffer
->idct_intermediate
);
342 if (!idct_intermediate_sv
)
343 goto error_intermediate_sv
;
345 idct_surfaces
= buffer
->mc_source
->get_surfaces(buffer
->mc_source
);
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
]))
359 vl_idct_cleanup_buffer(i
== 1 ? &dec
->idct_c
: &dec
->idct_y
, &buffer
->idct
[i
- 1]);
362 error_intermediate_sv
:
364 buffer
->idct_intermediate
->destroy(buffer
->idct_intermediate
);
367 buffer
->idct_source
->destroy(buffer
->idct_source
);
373 static struct pipe_video_decode_buffer
*
374 vl_mpeg12_create_buffer(struct pipe_video_decoder
*decoder
)
376 enum pipe_format formats
[3];
378 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
379 struct vl_mpeg12_buffer
*buffer
;
381 struct pipe_sampler_view
**mc_source_sv
;
385 buffer
= CALLOC_STRUCT(vl_mpeg12_buffer
);
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
;
395 vl_vb_init(&buffer
->vertex_stream
, dec
->pipe
,
396 dec
->base
.width
/ MACROBLOCK_WIDTH
,
397 dec
->base
.height
/ MACROBLOCK_HEIGHT
);
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
);
405 if (!buffer
->mc_source
)
406 goto error_mc_source
;
408 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
409 if (!init_idct_buffer(buffer
))
412 mc_source_sv
= buffer
->mc_source
->get_sampler_views(buffer
->mc_source
);
414 goto error_mc_source_sv
;
416 if(!vl_mc_init_buffer(&dec
->mc_y
, &buffer
->mc
[0], mc_source_sv
[0]))
419 if(!vl_mc_init_buffer(&dec
->mc_c
, &buffer
->mc
[1], mc_source_sv
[1]))
422 if(!vl_mc_init_buffer(&dec
->mc_c
, &buffer
->mc
[2], mc_source_sv
[2]))
425 return &buffer
->base
;
428 vl_mc_cleanup_buffer(&buffer
->mc
[1]);
431 vl_mc_cleanup_buffer(&buffer
->mc
[0]);
435 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
436 cleanup_idct_buffer(buffer
);
439 buffer
->mc_source
->destroy(buffer
->mc_source
);
442 vl_vb_cleanup(&buffer
->vertex_stream
);
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
)
455 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
456 struct vl_mpeg12_decoder
*dec
;
458 struct pipe_sampler_view
**sv
[2];
459 struct pipe_surface
**surfaces
;
461 struct pipe_vertex_buffer vb
[3];
467 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
470 for (i
= 0; i
< 2; ++i
)
471 sv
[i
] = refs
[i
] ? refs
[i
]->get_sampler_views(refs
[i
]) : NULL
;
473 surfaces
= dst
->get_surfaces(dst
);
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
]);
482 for (j
= 0; j
< 2; ++j
) {
483 if (sv
[j
] == NULL
) continue;
485 vb
[2] = vl_vb_get_mv(&buf
->vertex_stream
, j
);;
486 dec
->pipe
->set_vertex_buffers(dec
->pipe
, 3, vb
);
488 vl_mc_render_ref(&buf
->mc
[i
], sv
[j
][i
]);
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
);
496 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, i
);
497 dec
->pipe
->set_vertex_buffers(dec
->pipe
, 2, vb
);
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
);
502 vl_mc_render_ycbcr(&buf
->mc
[i
], num_instances
);
505 dec
->pipe
->flush(dec
->pipe
, fence
);
509 vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer
*buffer
)
511 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
516 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
517 vl_vb_restart(&buf
->vertex_stream
, i
);
521 init_pipe_state(struct vl_mpeg12_decoder
*dec
)
523 struct pipe_depth_stencil_alpha_state dsa
;
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;
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
);
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
)
556 struct pipe_screen
*screen
;
561 screen
= dec
->pipe
->screen
;
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
))
568 return PIPE_FORMAT_NONE
;
572 init_idct(struct vl_mpeg12_decoder
*dec
, unsigned buffer_width
, unsigned buffer_height
)
574 unsigned chroma_width
, chroma_height
;
575 struct pipe_sampler_view
*matrix
, *transpose
;
576 float matrix_scale
, transpose_scale
;
578 dec
->nr_of_idct_render_targets
= dec
->pipe
->screen
->get_param(dec
->pipe
->screen
, PIPE_CAP_MAX_RENDER_TARGETS
);
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);
583 dec
->idct_source_format
= find_first_supported_format(dec
, const_idct_source_formats
,
584 num_idct_source_formats
, PIPE_TEXTURE_2D
);
586 if (dec
->idct_source_format
== PIPE_FORMAT_NONE
)
589 dec
->idct_intermediate_format
= find_first_supported_format(dec
, const_idct_intermediate_formats
,
590 num_idct_intermediate_formats
, PIPE_TEXTURE_3D
);
592 if (dec
->idct_intermediate_format
== PIPE_FORMAT_NONE
)
595 switch (dec
->idct_source_format
) {
596 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
597 matrix_scale
= SCALE_FACTOR_SSCALED
;
600 case PIPE_FORMAT_R16G16B16A16_SNORM
:
601 matrix_scale
= SCALE_FACTOR_SNORM
;
609 if (dec
->idct_intermediate_format
== PIPE_FORMAT_R16G16B16A16_FLOAT
||
610 dec
->idct_intermediate_format
== PIPE_FORMAT_R32G32B32A32_FLOAT
)
611 transpose_scale
= 1.0f
;
613 transpose_scale
= matrix_scale
= sqrt(matrix_scale
);
615 if (dec
->mc_source_format
== PIPE_FORMAT_R16_SSCALED
)
616 transpose_scale
/= SCALE_FACTOR_SSCALED
;
618 if (!(matrix
= vl_idct_upload_matrix(dec
->pipe
, matrix_scale
)))
621 if (matrix_scale
!= transpose_scale
) {
622 if (!(transpose
= vl_idct_upload_matrix(dec
->pipe
, transpose_scale
)))
623 goto error_transpose
;
625 pipe_sampler_view_reference(&transpose
, matrix
);
627 if (!vl_idct_init(&dec
->idct_y
, dec
->pipe
, buffer_width
, buffer_height
,
628 dec
->nr_of_idct_render_targets
, matrix
, transpose
))
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;
638 chroma_width
= buffer_width
;
639 chroma_height
= buffer_height
;
642 if(!vl_idct_init(&dec
->idct_c
, dec
->pipe
, chroma_width
, chroma_height
,
643 dec
->nr_of_idct_render_targets
, matrix
, transpose
))
646 pipe_sampler_view_reference(&matrix
, NULL
);
647 pipe_sampler_view_reference(&transpose
, NULL
);
651 vl_idct_cleanup(&dec
->idct_y
);
654 pipe_sampler_view_reference(&transpose
, NULL
);
657 pipe_sampler_view_reference(&matrix
, NULL
);
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
)
671 struct vl_mpeg12_decoder
*dec
;
674 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
676 dec
= CALLOC_STRUCT(vl_mpeg12_decoder
);
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
;
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
;
693 dec
->base
.width
= align(width
, MACROBLOCK_WIDTH
);
694 dec
->base
.height
= align(height
, MACROBLOCK_HEIGHT
);
698 dec
->quads
= vl_vb_upload_quads(dec
->pipe
);
699 dec
->pos
= vl_vb_upload_pos(
701 dec
->base
.width
/ MACROBLOCK_WIDTH
,
702 dec
->base
.height
/ MACROBLOCK_HEIGHT
705 dec
->ves_ycbcr
= vl_vb_get_ves_ycbcr(dec
->pipe
);
706 dec
->ves_mv
= vl_vb_get_ves_mv(dec
->pipe
);
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
;
712 dec
->mc_source_format
= find_first_supported_format(dec
, const_mc_source_formats
,
713 num_mc_source_formats
, PIPE_TEXTURE_3D
);
715 if (dec
->mc_source_format
== PIPE_FORMAT_NONE
)
718 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
719 if (!init_idct(dec
, dec
->base
.width
, dec
->base
.height
))
721 if (dec
->mc_source_format
== PIPE_FORMAT_R16_SSCALED
)
722 mc_scale
= SCALE_FACTOR_SSCALED
;
726 switch (dec
->mc_source_format
) {
727 case PIPE_FORMAT_R16_SNORM
:
728 mc_scale
= SCALE_FACTOR_SNORM
;
731 case PIPE_FORMAT_R16_SSCALED
:
732 mc_scale
= SCALE_FACTOR_SSCALED
;
741 if (!vl_mc_init(&dec
->mc_y
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
, MACROBLOCK_HEIGHT
, mc_scale
))
745 if (!vl_mc_init(&dec
->mc_c
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
, BLOCK_HEIGHT
, mc_scale
))
748 if (!init_pipe_state(dec
))
749 goto error_pipe_state
;
754 vl_mc_cleanup(&dec
->mc_c
);
757 vl_mc_cleanup(&dec
->mc_y
);
760 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
761 vl_idct_cleanup(&dec
->idct_y
);
762 vl_idct_cleanup(&dec
->idct_c
);