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 struct format_config
{
42 enum pipe_format zscan_source_format
;
43 enum pipe_format idct_source_format
;
44 enum pipe_format mc_source_format
;
50 static const struct format_config bitstream_format_config
[] = {
51 { PIPE_FORMAT_R16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SSCALED
},
52 { PIPE_FORMAT_R16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, 1.0f
, SCALE_FACTOR_SSCALED
},
53 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SNORM
},
54 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, 1.0f
, SCALE_FACTOR_SNORM
}
57 static const unsigned num_bitstream_format_configs
=
58 sizeof(bitstream_format_config
) / sizeof(struct format_config
);
60 static const struct format_config idct_format_config
[] = {
61 { PIPE_FORMAT_R16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SSCALED
},
62 { PIPE_FORMAT_R16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, PIPE_FORMAT_R16G16B16A16_SSCALED
, 1.0f
, SCALE_FACTOR_SSCALED
},
63 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SNORM
},
64 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, 1.0f
, SCALE_FACTOR_SNORM
}
67 static const unsigned num_idct_format_configs
=
68 sizeof(idct_format_config
) / sizeof(struct format_config
);
70 static const struct format_config mc_format_config
[] = {
71 //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
72 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_NONE
, PIPE_FORMAT_R16_SNORM
, 0.0f
, SCALE_FACTOR_SNORM
}
75 static const unsigned num_mc_format_configs
=
76 sizeof(mc_format_config
) / sizeof(struct format_config
);
79 init_zscan_buffer(struct vl_mpeg12_buffer
*buffer
)
81 enum pipe_format formats
[3];
83 struct pipe_sampler_view
**source
;
84 struct pipe_surface
**destination
;
86 struct vl_mpeg12_decoder
*dec
;
92 dec
= (struct vl_mpeg12_decoder
*)buffer
->base
.decoder
;
94 formats
[0] = formats
[1] = formats
[2] = dec
->zscan_source_format
;
95 buffer
->zscan_source
= vl_video_buffer_init(dec
->base
.context
, dec
->pipe
,
96 dec
->blocks_per_line
* BLOCK_WIDTH
* BLOCK_HEIGHT
,
97 align(dec
->num_blocks
, dec
->blocks_per_line
) / dec
->blocks_per_line
,
98 1, PIPE_VIDEO_CHROMA_FORMAT_444
,
99 formats
, PIPE_USAGE_STATIC
);
100 if (!buffer
->zscan_source
)
103 source
= buffer
->zscan_source
->get_sampler_view_planes(buffer
->zscan_source
);
107 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
108 destination
= dec
->idct_source
->get_surfaces(dec
->idct_source
);
110 destination
= dec
->mc_source
->get_surfaces(dec
->mc_source
);
115 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
116 if (!vl_zscan_init_buffer(i
== 0 ? &dec
->zscan_y
: &dec
->zscan_c
,
117 &buffer
->zscan
[i
], source
[i
], destination
[i
]))
124 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
- 1]);
128 buffer
->zscan_source
->destroy(buffer
->zscan_source
);
135 cleanup_zscan_buffer(struct vl_mpeg12_buffer
*buffer
)
141 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
142 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
]);
143 buffer
->zscan_source
->destroy(buffer
->zscan_source
);
147 init_idct_buffer(struct vl_mpeg12_buffer
*buffer
)
149 struct pipe_sampler_view
**idct_source_sv
, **mc_source_sv
;
151 struct vl_mpeg12_decoder
*dec
;
157 dec
= (struct vl_mpeg12_decoder
*)buffer
->base
.decoder
;
159 idct_source_sv
= dec
->idct_source
->get_sampler_view_planes(dec
->idct_source
);
161 goto error_source_sv
;
163 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
165 goto error_mc_source_sv
;
167 for (i
= 0; i
< 3; ++i
)
168 if (!vl_idct_init_buffer(i
== 0 ? &dec
->idct_y
: &dec
->idct_c
,
169 &buffer
->idct
[i
], idct_source_sv
[i
],
177 vl_idct_cleanup_buffer(i
== 1 ? &dec
->idct_c
: &dec
->idct_y
, &buffer
->idct
[i
- 1]);
185 cleanup_idct_buffer(struct vl_mpeg12_buffer
*buf
)
187 struct vl_mpeg12_decoder
*dec
;
190 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
193 vl_idct_cleanup_buffer(&dec
->idct_y
, &buf
->idct
[0]);
194 vl_idct_cleanup_buffer(&dec
->idct_c
, &buf
->idct
[1]);
195 vl_idct_cleanup_buffer(&dec
->idct_c
, &buf
->idct
[2]);
199 init_mc_buffer(struct vl_mpeg12_buffer
*buf
)
201 struct vl_mpeg12_decoder
*dec
;
205 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
208 if(!vl_mc_init_buffer(&dec
->mc_y
, &buf
->mc
[0]))
211 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[1]))
214 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[2]))
220 vl_mc_cleanup_buffer(&buf
->mc
[1]);
223 vl_mc_cleanup_buffer(&buf
->mc
[0]);
230 cleanup_mc_buffer(struct vl_mpeg12_buffer
*buf
)
236 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
237 vl_mc_cleanup_buffer(&buf
->mc
[i
]);
241 vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer
*buffer
)
243 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
244 struct vl_mpeg12_decoder
*dec
;
248 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
251 cleanup_zscan_buffer(buf
);
253 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
254 cleanup_idct_buffer(buf
);
256 cleanup_mc_buffer(buf
);
258 vl_vb_cleanup(&buf
->vertex_stream
);
264 vl_mpeg12_buffer_map(struct pipe_video_decode_buffer
*buffer
)
266 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
267 struct vl_mpeg12_decoder
*dec
;
269 struct pipe_sampler_view
**sampler_views
;
274 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
277 vl_vb_map(&buf
->vertex_stream
, dec
->pipe
);
279 sampler_views
= buf
->zscan_source
->get_sampler_view_planes(buf
->zscan_source
);
281 assert(sampler_views
);
283 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
284 struct pipe_resource
*tex
= sampler_views
[i
]->texture
;
285 struct pipe_box rect
=
293 buf
->tex_transfer
[i
] = dec
->pipe
->get_transfer
296 0, PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
300 buf
->texels
[i
] = dec
->pipe
->transfer_map(dec
->pipe
, buf
->tex_transfer
[i
]);
303 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
304 struct pipe_ycbcr_block
*ycbcr_stream
[VL_MAX_PLANES
];
305 struct pipe_motionvector
*mv_stream
[VL_MAX_REF_FRAMES
];
307 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
308 ycbcr_stream
[i
] = vl_vb_get_ycbcr_stream(&buf
->vertex_stream
, i
);
310 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
)
311 mv_stream
[i
] = vl_vb_get_mv_stream(&buf
->vertex_stream
, i
);
313 vl_mpg12_bs_set_buffers(&buf
->bs
, ycbcr_stream
, buf
->texels
, mv_stream
);
315 static const uint8_t dummy_quant
[64] = {
316 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
317 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
318 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
319 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
320 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
321 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
322 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
323 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
326 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
327 vl_zscan_set_layout(&buf
->zscan
[i
], dec
->zscan_linear
);
328 vl_zscan_upload_quant(&buf
->zscan
[i
], dummy_quant
, dummy_quant
);
333 static struct pipe_ycbcr_block
*
334 vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer
*buffer
, int component
)
336 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
340 return vl_vb_get_ycbcr_stream(&buf
->vertex_stream
, component
);
344 vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer
*buffer
, int component
)
346 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
349 assert(component
< VL_MAX_PLANES
);
351 return buf
->texels
[component
];
355 vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer
*buffer
)
357 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
361 return vl_vb_get_mv_stream_stride(&buf
->vertex_stream
);
364 static struct pipe_motionvector
*
365 vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer
*buffer
, int ref_frame
)
367 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
371 return vl_vb_get_mv_stream(&buf
->vertex_stream
, ref_frame
);
375 vl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer
*buffer
,
376 unsigned num_bytes
, const void *data
,
377 struct pipe_mpeg12_picture_desc
*picture
,
378 unsigned num_ycbcr_blocks
[3])
380 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
381 uint8_t intra_quantizer_matrix
[64];
382 struct vl_mpeg12_decoder
*dec
;
387 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
390 memcpy(intra_quantizer_matrix
, picture
->intra_quantizer_matrix
, sizeof(intra_quantizer_matrix
));
391 intra_quantizer_matrix
[0] = 1 << (7 - picture
->intra_dc_precision
);
393 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
394 vl_zscan_set_layout(&buf
->zscan
[i
], picture
->alternate_scan
? dec
->zscan_alternate
: dec
->zscan_normal
);
395 vl_zscan_upload_quant(&buf
->zscan
[i
], intra_quantizer_matrix
, picture
->non_intra_quantizer_matrix
);
398 vl_mpg12_bs_decode(&buf
->bs
, num_bytes
, data
, picture
, num_ycbcr_blocks
);
402 vl_mpeg12_buffer_unmap(struct pipe_video_decode_buffer
*buffer
)
404 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
405 struct vl_mpeg12_decoder
*dec
;
410 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
413 vl_vb_unmap(&buf
->vertex_stream
, dec
->pipe
);
415 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
416 dec
->pipe
->transfer_unmap(dec
->pipe
, buf
->tex_transfer
[i
]);
417 dec
->pipe
->transfer_destroy(dec
->pipe
, buf
->tex_transfer
[i
]);
422 vl_mpeg12_destroy(struct pipe_video_decoder
*decoder
)
424 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
428 /* Asserted in softpipe_delete_fs_state() for some reason */
429 dec
->pipe
->bind_vs_state(dec
->pipe
, NULL
);
430 dec
->pipe
->bind_fs_state(dec
->pipe
, NULL
);
432 dec
->pipe
->delete_depth_stencil_alpha_state(dec
->pipe
, dec
->dsa
);
433 dec
->pipe
->delete_sampler_state(dec
->pipe
, dec
->sampler_ycbcr
);
435 vl_mc_cleanup(&dec
->mc_y
);
436 vl_mc_cleanup(&dec
->mc_c
);
437 dec
->mc_source
->destroy(dec
->mc_source
);
439 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
440 vl_idct_cleanup(&dec
->idct_y
);
441 vl_idct_cleanup(&dec
->idct_c
);
442 dec
->idct_source
->destroy(dec
->idct_source
);
445 vl_zscan_cleanup(&dec
->zscan_y
);
446 vl_zscan_cleanup(&dec
->zscan_c
);
448 dec
->pipe
->delete_vertex_elements_state(dec
->pipe
, dec
->ves_ycbcr
);
449 dec
->pipe
->delete_vertex_elements_state(dec
->pipe
, dec
->ves_mv
);
451 pipe_resource_reference(&dec
->quads
.buffer
, NULL
);
452 pipe_resource_reference(&dec
->pos
.buffer
, NULL
);
454 pipe_sampler_view_reference(&dec
->zscan_linear
, NULL
);
455 pipe_sampler_view_reference(&dec
->zscan_normal
, NULL
);
456 pipe_sampler_view_reference(&dec
->zscan_alternate
, NULL
);
461 static struct pipe_video_decode_buffer
*
462 vl_mpeg12_create_buffer(struct pipe_video_decoder
*decoder
)
464 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
465 struct vl_mpeg12_buffer
*buffer
;
469 buffer
= CALLOC_STRUCT(vl_mpeg12_buffer
);
473 buffer
->base
.decoder
= decoder
;
474 buffer
->base
.destroy
= vl_mpeg12_buffer_destroy
;
475 buffer
->base
.map
= vl_mpeg12_buffer_map
;
476 buffer
->base
.get_ycbcr_stream
= vl_mpeg12_buffer_get_ycbcr_stream
;
477 buffer
->base
.get_ycbcr_buffer
= vl_mpeg12_buffer_get_ycbcr_buffer
;
478 buffer
->base
.get_mv_stream_stride
= vl_mpeg12_buffer_get_mv_stream_stride
;
479 buffer
->base
.get_mv_stream
= vl_mpeg12_buffer_get_mv_stream
;
480 buffer
->base
.decode_bitstream
= vl_mpeg12_buffer_decode_bitstream
;
481 buffer
->base
.unmap
= vl_mpeg12_buffer_unmap
;
483 if (!vl_vb_init(&buffer
->vertex_stream
, dec
->pipe
,
484 dec
->base
.width
/ MACROBLOCK_WIDTH
,
485 dec
->base
.height
/ MACROBLOCK_HEIGHT
))
486 goto error_vertex_buffer
;
488 if (!init_mc_buffer(buffer
))
491 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
492 if (!init_idct_buffer(buffer
))
495 if (!init_zscan_buffer(buffer
))
498 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
)
499 vl_mpg12_bs_init(&buffer
->bs
,
500 dec
->base
.width
/ MACROBLOCK_WIDTH
,
501 dec
->base
.height
/ MACROBLOCK_HEIGHT
);
503 return &buffer
->base
;
506 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
507 cleanup_idct_buffer(buffer
);
510 cleanup_mc_buffer(buffer
);
513 vl_vb_cleanup(&buffer
->vertex_stream
);
521 vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer
*buffer
,
522 unsigned num_ycbcr_blocks
[3],
523 struct pipe_video_buffer
*refs
[2],
524 struct pipe_video_buffer
*dst
)
526 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
527 struct vl_mpeg12_decoder
*dec
;
529 struct pipe_sampler_view
**sv
[VL_MAX_REF_FRAMES
], **mc_source_sv
;
530 struct pipe_surface
**surfaces
;
532 struct pipe_vertex_buffer vb
[3];
534 unsigned i
, j
, component
;
535 unsigned nr_components
;
539 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
542 for (i
= 0; i
< 2; ++i
)
543 sv
[i
] = refs
[i
] ? refs
[i
]->get_sampler_view_planes(refs
[i
]) : NULL
;
548 surfaces
= dst
->get_surfaces(dst
);
550 dec
->pipe
->bind_vertex_elements_state(dec
->pipe
, dec
->ves_mv
);
551 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
552 if (!surfaces
[i
]) continue;
554 vl_mc_set_surface(&buf
->mc
[i
], surfaces
[i
]);
556 for (j
= 0; j
< VL_MAX_REF_FRAMES
; ++j
) {
557 if (!sv
[j
]) continue;
559 vb
[2] = vl_vb_get_mv(&buf
->vertex_stream
, j
);;
560 dec
->pipe
->set_vertex_buffers(dec
->pipe
, 3, vb
);
562 vl_mc_render_ref(&buf
->mc
[i
], sv
[j
][i
]);
566 vb
[2] = dec
->block_num
;
568 dec
->pipe
->bind_vertex_elements_state(dec
->pipe
, dec
->ves_ycbcr
);
569 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
570 if (!num_ycbcr_blocks
[i
]) continue;
572 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, i
);
573 dec
->pipe
->set_vertex_buffers(dec
->pipe
, 3, vb
);
575 vl_zscan_render(&buf
->zscan
[i
] , num_ycbcr_blocks
[i
]);
577 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
578 vl_idct_flush(i
== 0 ? &dec
->idct_y
: &dec
->idct_c
, &buf
->idct
[i
], num_ycbcr_blocks
[i
]);
581 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
582 for (i
= 0, component
= 0; i
< VL_MAX_PLANES
; ++i
) {
583 if (!surfaces
[i
]) continue;
585 nr_components
= util_format_get_nr_components(surfaces
[i
]->texture
->format
);
586 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
587 if (!num_ycbcr_blocks
[i
]) continue;
589 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, component
);
590 dec
->pipe
->set_vertex_buffers(dec
->pipe
, 3, vb
);
592 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
593 vl_idct_prepare_stage2(component
== 0 ? &dec
->idct_y
: &dec
->idct_c
, &buf
->idct
[component
]);
595 dec
->pipe
->set_fragment_sampler_views(dec
->pipe
, 1, &mc_source_sv
[component
]);
596 dec
->pipe
->bind_fragment_sampler_states(dec
->pipe
, 1, &dec
->sampler_ycbcr
);
598 vl_mc_render_ycbcr(&buf
->mc
[i
], j
, num_ycbcr_blocks
[component
]);
604 init_pipe_state(struct vl_mpeg12_decoder
*dec
)
606 struct pipe_depth_stencil_alpha_state dsa
;
607 struct pipe_sampler_state sampler
;
612 memset(&dsa
, 0, sizeof dsa
);
613 dsa
.depth
.enabled
= 0;
614 dsa
.depth
.writemask
= 0;
615 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
616 for (i
= 0; i
< 2; ++i
) {
617 dsa
.stencil
[i
].enabled
= 0;
618 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
619 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
620 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
621 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
622 dsa
.stencil
[i
].valuemask
= 0;
623 dsa
.stencil
[i
].writemask
= 0;
625 dsa
.alpha
.enabled
= 0;
626 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
627 dsa
.alpha
.ref_value
= 0;
628 dec
->dsa
= dec
->pipe
->create_depth_stencil_alpha_state(dec
->pipe
, &dsa
);
629 dec
->pipe
->bind_depth_stencil_alpha_state(dec
->pipe
, dec
->dsa
);
631 memset(&sampler
, 0, sizeof(sampler
));
632 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
633 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
634 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
635 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
636 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
637 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
638 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
639 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
640 sampler
.normalized_coords
= 1;
641 dec
->sampler_ycbcr
= dec
->pipe
->create_sampler_state(dec
->pipe
, &sampler
);
642 if (!dec
->sampler_ycbcr
)
648 static const struct format_config
*
649 find_format_config(struct vl_mpeg12_decoder
*dec
, const struct format_config configs
[], unsigned num_configs
)
651 struct pipe_screen
*screen
;
656 screen
= dec
->pipe
->screen
;
658 for (i
= 0; i
< num_configs
; ++i
) {
659 if (!screen
->is_format_supported(screen
, configs
[i
].zscan_source_format
, PIPE_TEXTURE_2D
,
660 1, PIPE_BIND_SAMPLER_VIEW
))
663 if (configs
[i
].idct_source_format
!= PIPE_FORMAT_NONE
) {
664 if (!screen
->is_format_supported(screen
, configs
[i
].idct_source_format
, PIPE_TEXTURE_2D
,
665 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
668 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_3D
,
669 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
672 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_2D
,
673 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
683 init_zscan(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
685 unsigned num_channels
;
689 dec
->zscan_source_format
= format_config
->zscan_source_format
;
690 dec
->zscan_linear
= vl_zscan_layout(dec
->pipe
, vl_zscan_linear
, dec
->blocks_per_line
);
691 dec
->zscan_normal
= vl_zscan_layout(dec
->pipe
, vl_zscan_normal
, dec
->blocks_per_line
);
692 dec
->zscan_alternate
= vl_zscan_layout(dec
->pipe
, vl_zscan_alternate
, dec
->blocks_per_line
);
694 num_channels
= dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
? 4 : 1;
696 if (!vl_zscan_init(&dec
->zscan_y
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
,
697 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
700 if (!vl_zscan_init(&dec
->zscan_c
, dec
->pipe
, dec
->chroma_width
, dec
->chroma_height
,
701 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
708 init_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
710 unsigned nr_of_idct_render_targets
, max_inst
;
711 enum pipe_format formats
[3];
713 struct pipe_sampler_view
*matrix
= NULL
;
715 nr_of_idct_render_targets
= dec
->pipe
->screen
->get_param(dec
->pipe
->screen
, PIPE_CAP_MAX_RENDER_TARGETS
);
716 max_inst
= dec
->pipe
->screen
->get_shader_param(dec
->pipe
->screen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
);
718 // Just assume we need 32 inst per render target, not 100% true, but should work in most cases
719 if (nr_of_idct_render_targets
>= 4 && max_inst
>= 32*4)
720 // more than 4 render targets usually doesn't makes any seens
721 nr_of_idct_render_targets
= 4;
723 nr_of_idct_render_targets
= 1;
725 formats
[0] = formats
[1] = formats
[2] = format_config
->idct_source_format
;
726 dec
->idct_source
= vl_video_buffer_init(dec
->base
.context
, dec
->pipe
,
727 dec
->base
.width
/ 4, dec
->base
.height
, 1,
728 dec
->base
.chroma_format
,
729 formats
, PIPE_USAGE_STATIC
);
730 if (!dec
->idct_source
)
731 goto error_idct_source
;
733 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
734 dec
->mc_source
= vl_video_buffer_init(dec
->base
.context
, dec
->pipe
,
735 dec
->base
.width
/ nr_of_idct_render_targets
,
736 dec
->base
.height
/ 4, nr_of_idct_render_targets
,
737 dec
->base
.chroma_format
,
738 formats
, PIPE_USAGE_STATIC
);
741 goto error_mc_source
;
743 if (!(matrix
= vl_idct_upload_matrix(dec
->pipe
, format_config
->idct_scale
)))
746 if (!vl_idct_init(&dec
->idct_y
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
,
747 nr_of_idct_render_targets
, matrix
, matrix
))
750 if(!vl_idct_init(&dec
->idct_c
, dec
->pipe
, dec
->chroma_width
, dec
->chroma_height
,
751 nr_of_idct_render_targets
, matrix
, matrix
))
754 pipe_sampler_view_reference(&matrix
, NULL
);
759 vl_idct_cleanup(&dec
->idct_y
);
762 pipe_sampler_view_reference(&matrix
, NULL
);
765 dec
->mc_source
->destroy(dec
->mc_source
);
768 dec
->idct_source
->destroy(dec
->idct_source
);
775 init_mc_source_widthout_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
777 enum pipe_format formats
[3];
779 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
780 dec
->mc_source
= vl_video_buffer_init(dec
->base
.context
, dec
->pipe
,
781 dec
->base
.width
, dec
->base
.height
, 1,
782 dec
->base
.chroma_format
,
783 formats
, PIPE_USAGE_STATIC
);
785 return dec
->mc_source
!= NULL
;
789 mc_vert_shader_callback(void *priv
, struct vl_mc
*mc
,
790 struct ureg_program
*shader
,
791 unsigned first_output
,
794 struct vl_mpeg12_decoder
*dec
= priv
;
795 struct ureg_dst o_vtex
;
800 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
801 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
802 vl_idct_stage2_vert_shader(idct
, shader
, first_output
, tex
);
804 o_vtex
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, first_output
);
805 ureg_MOV(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_XY
), ureg_src(tex
));
810 mc_frag_shader_callback(void *priv
, struct vl_mc
*mc
,
811 struct ureg_program
*shader
,
812 unsigned first_input
,
815 struct vl_mpeg12_decoder
*dec
= priv
;
816 struct ureg_src src
, sampler
;
821 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
822 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
823 vl_idct_stage2_frag_shader(idct
, shader
, first_input
, dst
);
825 src
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, first_input
, TGSI_INTERPOLATE_LINEAR
);
826 sampler
= ureg_DECL_sampler(shader
, 0);
827 ureg_TEX(shader
, dst
, TGSI_TEXTURE_2D
, src
, sampler
);
831 struct pipe_video_decoder
*
832 vl_create_mpeg12_decoder(struct pipe_video_context
*context
,
833 struct pipe_context
*pipe
,
834 enum pipe_video_profile profile
,
835 enum pipe_video_entrypoint entrypoint
,
836 enum pipe_video_chroma_format chroma_format
,
837 unsigned width
, unsigned height
)
839 const unsigned block_size_pixels
= BLOCK_WIDTH
* BLOCK_HEIGHT
;
840 const struct format_config
*format_config
;
841 struct vl_mpeg12_decoder
*dec
;
843 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
845 dec
= CALLOC_STRUCT(vl_mpeg12_decoder
);
850 dec
->base
.context
= context
;
851 dec
->base
.profile
= profile
;
852 dec
->base
.entrypoint
= entrypoint
;
853 dec
->base
.chroma_format
= chroma_format
;
854 dec
->base
.width
= width
;
855 dec
->base
.height
= height
;
857 dec
->base
.destroy
= vl_mpeg12_destroy
;
858 dec
->base
.create_buffer
= vl_mpeg12_create_buffer
;
859 dec
->base
.flush_buffer
= vl_mpeg12_decoder_flush_buffer
;
863 dec
->blocks_per_line
= MAX2(util_next_power_of_two(dec
->base
.width
) / block_size_pixels
, 4);
864 dec
->num_blocks
= (dec
->base
.width
* dec
->base
.height
) / block_size_pixels
;
866 dec
->quads
= vl_vb_upload_quads(dec
->pipe
);
867 dec
->pos
= vl_vb_upload_pos(
869 dec
->base
.width
/ MACROBLOCK_WIDTH
,
870 dec
->base
.height
/ MACROBLOCK_HEIGHT
872 dec
->block_num
= vl_vb_upload_block_num(dec
->pipe
, dec
->num_blocks
);
874 dec
->ves_ycbcr
= vl_vb_get_ves_ycbcr(dec
->pipe
);
875 dec
->ves_mv
= vl_vb_get_ves_mv(dec
->pipe
);
877 /* TODO: Implement 422, 444 */
878 assert(dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
880 if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
) {
881 dec
->chroma_width
= dec
->base
.width
/ 2;
882 dec
->chroma_height
= dec
->base
.height
/ 2;
883 } else if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_422
) {
884 dec
->chroma_width
= dec
->base
.width
;
885 dec
->chroma_height
= dec
->base
.height
/ 2;
887 dec
->chroma_width
= dec
->base
.width
;
888 dec
->chroma_height
= dec
->base
.height
;
891 switch (entrypoint
) {
892 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
:
893 format_config
= find_format_config(dec
, bitstream_format_config
, num_bitstream_format_configs
);
896 case PIPE_VIDEO_ENTRYPOINT_IDCT
:
897 format_config
= find_format_config(dec
, idct_format_config
, num_idct_format_configs
);
900 case PIPE_VIDEO_ENTRYPOINT_MC
:
901 format_config
= find_format_config(dec
, mc_format_config
, num_mc_format_configs
);
912 if (!init_zscan(dec
, format_config
))
915 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
916 if (!init_idct(dec
, format_config
))
919 if (!init_mc_source_widthout_idct(dec
, format_config
))
923 if (!vl_mc_init(&dec
->mc_y
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
, MACROBLOCK_HEIGHT
, format_config
->mc_scale
,
924 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
928 if (!vl_mc_init(&dec
->mc_c
, dec
->pipe
, dec
->base
.width
, dec
->base
.height
, BLOCK_HEIGHT
, format_config
->mc_scale
,
929 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
932 if (!init_pipe_state(dec
))
933 goto error_pipe_state
;
938 vl_mc_cleanup(&dec
->mc_c
);
941 vl_mc_cleanup(&dec
->mc_y
);
944 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
945 vl_idct_cleanup(&dec
->idct_y
);
946 vl_idct_cleanup(&dec
->idct_c
);
947 dec
->idct_source
->destroy(dec
->idct_source
);
949 dec
->mc_source
->destroy(dec
->mc_source
);
952 vl_zscan_cleanup(&dec
->zscan_y
);
953 vl_zscan_cleanup(&dec
->zscan_c
);