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_create_ex
98 dec
->blocks_per_line
* BLOCK_WIDTH
* BLOCK_HEIGHT
,
99 align(dec
->num_blocks
, dec
->blocks_per_line
) / dec
->blocks_per_line
,
100 1, PIPE_VIDEO_CHROMA_FORMAT_444
, formats
, PIPE_USAGE_STATIC
103 if (!buffer
->zscan_source
)
106 source
= buffer
->zscan_source
->get_sampler_view_planes(buffer
->zscan_source
);
110 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
111 destination
= dec
->idct_source
->get_surfaces(dec
->idct_source
);
113 destination
= dec
->mc_source
->get_surfaces(dec
->mc_source
);
118 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
119 if (!vl_zscan_init_buffer(i
== 0 ? &dec
->zscan_y
: &dec
->zscan_c
,
120 &buffer
->zscan
[i
], source
[i
], destination
[i
]))
127 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
- 1]);
131 buffer
->zscan_source
->destroy(buffer
->zscan_source
);
138 cleanup_zscan_buffer(struct vl_mpeg12_buffer
*buffer
)
144 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
145 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
]);
146 buffer
->zscan_source
->destroy(buffer
->zscan_source
);
150 init_idct_buffer(struct vl_mpeg12_buffer
*buffer
)
152 struct pipe_sampler_view
**idct_source_sv
, **mc_source_sv
;
154 struct vl_mpeg12_decoder
*dec
;
160 dec
= (struct vl_mpeg12_decoder
*)buffer
->base
.decoder
;
162 idct_source_sv
= dec
->idct_source
->get_sampler_view_planes(dec
->idct_source
);
164 goto error_source_sv
;
166 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
168 goto error_mc_source_sv
;
170 for (i
= 0; i
< 3; ++i
)
171 if (!vl_idct_init_buffer(i
== 0 ? &dec
->idct_y
: &dec
->idct_c
,
172 &buffer
->idct
[i
], idct_source_sv
[i
],
180 vl_idct_cleanup_buffer(i
== 1 ? &dec
->idct_c
: &dec
->idct_y
, &buffer
->idct
[i
- 1]);
188 cleanup_idct_buffer(struct vl_mpeg12_buffer
*buf
)
190 struct vl_mpeg12_decoder
*dec
;
193 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
196 vl_idct_cleanup_buffer(&dec
->idct_y
, &buf
->idct
[0]);
197 vl_idct_cleanup_buffer(&dec
->idct_c
, &buf
->idct
[1]);
198 vl_idct_cleanup_buffer(&dec
->idct_c
, &buf
->idct
[2]);
202 init_mc_buffer(struct vl_mpeg12_buffer
*buf
)
204 struct vl_mpeg12_decoder
*dec
;
208 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
211 if(!vl_mc_init_buffer(&dec
->mc_y
, &buf
->mc
[0]))
214 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[1]))
217 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[2]))
223 vl_mc_cleanup_buffer(&buf
->mc
[1]);
226 vl_mc_cleanup_buffer(&buf
->mc
[0]);
233 cleanup_mc_buffer(struct vl_mpeg12_buffer
*buf
)
239 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
240 vl_mc_cleanup_buffer(&buf
->mc
[i
]);
244 vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer
*buffer
)
246 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
247 struct vl_mpeg12_decoder
*dec
;
251 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
254 cleanup_zscan_buffer(buf
);
256 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
257 cleanup_idct_buffer(buf
);
259 cleanup_mc_buffer(buf
);
261 vl_vb_cleanup(&buf
->vertex_stream
);
267 vl_mpeg12_buffer_begin_frame(struct pipe_video_decode_buffer
*buffer
)
269 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
270 struct vl_mpeg12_decoder
*dec
;
272 struct pipe_sampler_view
**sampler_views
;
277 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
280 vl_vb_map(&buf
->vertex_stream
, dec
->base
.context
);
282 sampler_views
= buf
->zscan_source
->get_sampler_view_planes(buf
->zscan_source
);
284 assert(sampler_views
);
286 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
287 struct pipe_resource
*tex
= sampler_views
[i
]->texture
;
288 struct pipe_box rect
=
296 buf
->tex_transfer
[i
] = dec
->base
.context
->get_transfer
298 dec
->base
.context
, tex
,
299 0, PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
303 buf
->texels
[i
] = dec
->base
.context
->transfer_map(dec
->base
.context
, buf
->tex_transfer
[i
]);
306 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
307 struct pipe_ycbcr_block
*ycbcr_stream
[VL_MAX_PLANES
];
308 struct pipe_motionvector
*mv_stream
[VL_MAX_REF_FRAMES
];
310 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
311 ycbcr_stream
[i
] = vl_vb_get_ycbcr_stream(&buf
->vertex_stream
, i
);
313 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
)
314 mv_stream
[i
] = vl_vb_get_mv_stream(&buf
->vertex_stream
, i
);
316 vl_mpg12_bs_set_buffers(&buf
->bs
, ycbcr_stream
, buf
->texels
, mv_stream
);
319 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
320 vl_zscan_set_layout(&buf
->zscan
[i
], dec
->zscan_linear
);
325 vl_mpeg12_buffer_set_quant_matrix(struct pipe_video_decode_buffer
*buffer
,
326 const uint8_t intra_matrix
[64],
327 const uint8_t non_intra_matrix
[64])
329 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
332 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
333 vl_zscan_upload_quant(&buf
->zscan
[i
], intra_matrix
, non_intra_matrix
);
336 static struct pipe_ycbcr_block
*
337 vl_mpeg12_buffer_get_ycbcr_stream(struct pipe_video_decode_buffer
*buffer
, int component
)
339 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
343 return vl_vb_get_ycbcr_stream(&buf
->vertex_stream
, component
);
347 vl_mpeg12_buffer_get_ycbcr_buffer(struct pipe_video_decode_buffer
*buffer
, int component
)
349 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
352 assert(component
< VL_MAX_PLANES
);
354 return buf
->texels
[component
];
358 vl_mpeg12_buffer_get_mv_stream_stride(struct pipe_video_decode_buffer
*buffer
)
360 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
364 return vl_vb_get_mv_stream_stride(&buf
->vertex_stream
);
367 static struct pipe_motionvector
*
368 vl_mpeg12_buffer_get_mv_stream(struct pipe_video_decode_buffer
*buffer
, int ref_frame
)
370 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
374 return vl_vb_get_mv_stream(&buf
->vertex_stream
, ref_frame
);
378 vl_mpeg12_buffer_decode_bitstream(struct pipe_video_decode_buffer
*buffer
,
379 unsigned num_bytes
, const void *data
,
380 struct pipe_mpeg12_picture_desc
*picture
,
381 unsigned num_ycbcr_blocks
[3])
383 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
384 struct vl_mpeg12_decoder
*dec
;
389 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
392 for (i
= 0; i
< VL_MAX_PLANES
; ++i
)
393 vl_zscan_set_layout(&buf
->zscan
[i
], picture
->alternate_scan
? dec
->zscan_alternate
: dec
->zscan_normal
);
395 vl_mpg12_bs_decode(&buf
->bs
, num_bytes
, data
, picture
, num_ycbcr_blocks
);
399 vl_mpeg12_buffer_end_frame(struct pipe_video_decode_buffer
*buffer
)
401 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
402 struct vl_mpeg12_decoder
*dec
;
407 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
410 vl_vb_unmap(&buf
->vertex_stream
, dec
->base
.context
);
412 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
413 dec
->base
.context
->transfer_unmap(dec
->base
.context
, buf
->tex_transfer
[i
]);
414 dec
->base
.context
->transfer_destroy(dec
->base
.context
, buf
->tex_transfer
[i
]);
419 vl_mpeg12_destroy(struct pipe_video_decoder
*decoder
)
421 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
425 /* Asserted in softpipe_delete_fs_state() for some reason */
426 dec
->base
.context
->bind_vs_state(dec
->base
.context
, NULL
);
427 dec
->base
.context
->bind_fs_state(dec
->base
.context
, NULL
);
429 dec
->base
.context
->delete_depth_stencil_alpha_state(dec
->base
.context
, dec
->dsa
);
430 dec
->base
.context
->delete_sampler_state(dec
->base
.context
, dec
->sampler_ycbcr
);
432 vl_mc_cleanup(&dec
->mc_y
);
433 vl_mc_cleanup(&dec
->mc_c
);
434 dec
->mc_source
->destroy(dec
->mc_source
);
436 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
437 vl_idct_cleanup(&dec
->idct_y
);
438 vl_idct_cleanup(&dec
->idct_c
);
439 dec
->idct_source
->destroy(dec
->idct_source
);
442 vl_zscan_cleanup(&dec
->zscan_y
);
443 vl_zscan_cleanup(&dec
->zscan_c
);
445 dec
->base
.context
->delete_vertex_elements_state(dec
->base
.context
, dec
->ves_ycbcr
);
446 dec
->base
.context
->delete_vertex_elements_state(dec
->base
.context
, dec
->ves_mv
);
448 pipe_resource_reference(&dec
->quads
.buffer
, NULL
);
449 pipe_resource_reference(&dec
->pos
.buffer
, NULL
);
451 pipe_sampler_view_reference(&dec
->zscan_linear
, NULL
);
452 pipe_sampler_view_reference(&dec
->zscan_normal
, NULL
);
453 pipe_sampler_view_reference(&dec
->zscan_alternate
, NULL
);
458 static struct pipe_video_decode_buffer
*
459 vl_mpeg12_create_buffer(struct pipe_video_decoder
*decoder
)
461 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
462 struct vl_mpeg12_buffer
*buffer
;
466 buffer
= CALLOC_STRUCT(vl_mpeg12_buffer
);
470 buffer
->base
.decoder
= decoder
;
471 buffer
->base
.destroy
= vl_mpeg12_buffer_destroy
;
472 buffer
->base
.begin_frame
= vl_mpeg12_buffer_begin_frame
;
473 buffer
->base
.set_quant_matrix
= vl_mpeg12_buffer_set_quant_matrix
;
474 buffer
->base
.get_ycbcr_stream
= vl_mpeg12_buffer_get_ycbcr_stream
;
475 buffer
->base
.get_ycbcr_buffer
= vl_mpeg12_buffer_get_ycbcr_buffer
;
476 buffer
->base
.get_mv_stream_stride
= vl_mpeg12_buffer_get_mv_stream_stride
;
477 buffer
->base
.get_mv_stream
= vl_mpeg12_buffer_get_mv_stream
;
478 buffer
->base
.decode_bitstream
= vl_mpeg12_buffer_decode_bitstream
;
479 buffer
->base
.end_frame
= vl_mpeg12_buffer_end_frame
;
481 if (!vl_vb_init(&buffer
->vertex_stream
, dec
->base
.context
,
482 dec
->base
.width
/ MACROBLOCK_WIDTH
,
483 dec
->base
.height
/ MACROBLOCK_HEIGHT
))
484 goto error_vertex_buffer
;
486 if (!init_mc_buffer(buffer
))
489 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
490 if (!init_idct_buffer(buffer
))
493 if (!init_zscan_buffer(buffer
))
496 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
)
497 vl_mpg12_bs_init(&buffer
->bs
,
498 dec
->base
.width
/ MACROBLOCK_WIDTH
,
499 dec
->base
.height
/ MACROBLOCK_HEIGHT
);
501 return &buffer
->base
;
504 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
505 cleanup_idct_buffer(buffer
);
508 cleanup_mc_buffer(buffer
);
511 vl_vb_cleanup(&buffer
->vertex_stream
);
519 vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer
*buffer
,
520 unsigned num_ycbcr_blocks
[3],
521 struct pipe_video_buffer
*refs
[2],
522 struct pipe_video_buffer
*dst
)
524 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)buffer
;
525 struct vl_mpeg12_decoder
*dec
;
527 struct pipe_sampler_view
**sv
[VL_MAX_REF_FRAMES
], **mc_source_sv
;
528 struct pipe_surface
**surfaces
;
530 struct pipe_vertex_buffer vb
[3];
532 unsigned i
, j
, component
;
533 unsigned nr_components
;
537 dec
= (struct vl_mpeg12_decoder
*)buf
->base
.decoder
;
540 for (i
= 0; i
< 2; ++i
)
541 sv
[i
] = refs
[i
] ? refs
[i
]->get_sampler_view_planes(refs
[i
]) : NULL
;
546 surfaces
= dst
->get_surfaces(dst
);
548 dec
->base
.context
->bind_vertex_elements_state(dec
->base
.context
, dec
->ves_mv
);
549 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
550 if (!surfaces
[i
]) continue;
552 vl_mc_set_surface(&buf
->mc
[i
], surfaces
[i
]);
554 for (j
= 0; j
< VL_MAX_REF_FRAMES
; ++j
) {
555 if (!sv
[j
]) continue;
557 vb
[2] = vl_vb_get_mv(&buf
->vertex_stream
, j
);;
558 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 3, vb
);
560 vl_mc_render_ref(&buf
->mc
[i
], sv
[j
][i
]);
564 vb
[2] = dec
->block_num
;
566 dec
->base
.context
->bind_vertex_elements_state(dec
->base
.context
, dec
->ves_ycbcr
);
567 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
568 if (!num_ycbcr_blocks
[i
]) continue;
570 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, i
);
571 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 3, vb
);
573 vl_zscan_render(&buf
->zscan
[i
] , num_ycbcr_blocks
[i
]);
575 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
576 vl_idct_flush(i
== 0 ? &dec
->idct_y
: &dec
->idct_c
, &buf
->idct
[i
], num_ycbcr_blocks
[i
]);
579 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
580 for (i
= 0, component
= 0; i
< VL_MAX_PLANES
; ++i
) {
581 if (!surfaces
[i
]) continue;
583 nr_components
= util_format_get_nr_components(surfaces
[i
]->texture
->format
);
584 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
585 if (!num_ycbcr_blocks
[i
]) continue;
587 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, component
);
588 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 3, vb
);
590 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
591 vl_idct_prepare_stage2(component
== 0 ? &dec
->idct_y
: &dec
->idct_c
, &buf
->idct
[component
]);
593 dec
->base
.context
->set_fragment_sampler_views(dec
->base
.context
, 1, &mc_source_sv
[component
]);
594 dec
->base
.context
->bind_fragment_sampler_states(dec
->base
.context
, 1, &dec
->sampler_ycbcr
);
596 vl_mc_render_ycbcr(&buf
->mc
[i
], j
, num_ycbcr_blocks
[component
]);
602 init_pipe_state(struct vl_mpeg12_decoder
*dec
)
604 struct pipe_depth_stencil_alpha_state dsa
;
605 struct pipe_sampler_state sampler
;
610 memset(&dsa
, 0, sizeof dsa
);
611 dsa
.depth
.enabled
= 0;
612 dsa
.depth
.writemask
= 0;
613 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
614 for (i
= 0; i
< 2; ++i
) {
615 dsa
.stencil
[i
].enabled
= 0;
616 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
617 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
618 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
619 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
620 dsa
.stencil
[i
].valuemask
= 0;
621 dsa
.stencil
[i
].writemask
= 0;
623 dsa
.alpha
.enabled
= 0;
624 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
625 dsa
.alpha
.ref_value
= 0;
626 dec
->dsa
= dec
->base
.context
->create_depth_stencil_alpha_state(dec
->base
.context
, &dsa
);
627 dec
->base
.context
->bind_depth_stencil_alpha_state(dec
->base
.context
, dec
->dsa
);
629 memset(&sampler
, 0, sizeof(sampler
));
630 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
631 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
632 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
633 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
634 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
635 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
636 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
637 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
638 sampler
.normalized_coords
= 1;
639 dec
->sampler_ycbcr
= dec
->base
.context
->create_sampler_state(dec
->base
.context
, &sampler
);
640 if (!dec
->sampler_ycbcr
)
646 static const struct format_config
*
647 find_format_config(struct vl_mpeg12_decoder
*dec
, const struct format_config configs
[], unsigned num_configs
)
649 struct pipe_screen
*screen
;
654 screen
= dec
->base
.context
->screen
;
656 for (i
= 0; i
< num_configs
; ++i
) {
657 if (!screen
->is_format_supported(screen
, configs
[i
].zscan_source_format
, PIPE_TEXTURE_2D
,
658 1, PIPE_BIND_SAMPLER_VIEW
))
661 if (configs
[i
].idct_source_format
!= PIPE_FORMAT_NONE
) {
662 if (!screen
->is_format_supported(screen
, configs
[i
].idct_source_format
, PIPE_TEXTURE_2D
,
663 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
666 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_3D
,
667 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
670 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_2D
,
671 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
681 init_zscan(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
683 unsigned num_channels
;
687 dec
->zscan_source_format
= format_config
->zscan_source_format
;
688 dec
->zscan_linear
= vl_zscan_layout(dec
->base
.context
, vl_zscan_linear
, dec
->blocks_per_line
);
689 dec
->zscan_normal
= vl_zscan_layout(dec
->base
.context
, vl_zscan_normal
, dec
->blocks_per_line
);
690 dec
->zscan_alternate
= vl_zscan_layout(dec
->base
.context
, vl_zscan_alternate
, dec
->blocks_per_line
);
692 num_channels
= dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
? 4 : 1;
694 if (!vl_zscan_init(&dec
->zscan_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
695 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
698 if (!vl_zscan_init(&dec
->zscan_c
, dec
->base
.context
, dec
->chroma_width
, dec
->chroma_height
,
699 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
706 init_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
708 unsigned nr_of_idct_render_targets
, max_inst
;
709 enum pipe_format formats
[3];
711 struct pipe_sampler_view
*matrix
= NULL
;
713 nr_of_idct_render_targets
= dec
->base
.context
->screen
->get_param
715 dec
->base
.context
->screen
, PIPE_CAP_MAX_RENDER_TARGETS
718 max_inst
= dec
->base
.context
->screen
->get_shader_param
720 dec
->base
.context
->screen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
723 // Just assume we need 32 inst per render target, not 100% true, but should work in most cases
724 if (nr_of_idct_render_targets
>= 4 && max_inst
>= 32*4)
725 // more than 4 render targets usually doesn't makes any seens
726 nr_of_idct_render_targets
= 4;
728 nr_of_idct_render_targets
= 1;
730 formats
[0] = formats
[1] = formats
[2] = format_config
->idct_source_format
;
731 dec
->idct_source
= vl_video_buffer_create_ex
733 dec
->base
.context
, dec
->base
.width
/ 4, dec
->base
.height
, 1,
734 dec
->base
.chroma_format
, formats
, PIPE_USAGE_STATIC
737 if (!dec
->idct_source
)
738 goto error_idct_source
;
740 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
741 dec
->mc_source
= vl_video_buffer_create_ex
743 dec
->base
.context
, dec
->base
.width
/ nr_of_idct_render_targets
,
744 dec
->base
.height
/ 4, nr_of_idct_render_targets
,
745 dec
->base
.chroma_format
, formats
, PIPE_USAGE_STATIC
749 goto error_mc_source
;
751 if (!(matrix
= vl_idct_upload_matrix(dec
->base
.context
, format_config
->idct_scale
)))
754 if (!vl_idct_init(&dec
->idct_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
755 nr_of_idct_render_targets
, matrix
, matrix
))
758 if(!vl_idct_init(&dec
->idct_c
, dec
->base
.context
, dec
->chroma_width
, dec
->chroma_height
,
759 nr_of_idct_render_targets
, matrix
, matrix
))
762 pipe_sampler_view_reference(&matrix
, NULL
);
767 vl_idct_cleanup(&dec
->idct_y
);
770 pipe_sampler_view_reference(&matrix
, NULL
);
773 dec
->mc_source
->destroy(dec
->mc_source
);
776 dec
->idct_source
->destroy(dec
->idct_source
);
783 init_mc_source_widthout_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
785 enum pipe_format formats
[3];
787 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
788 dec
->mc_source
= vl_video_buffer_create_ex
790 dec
->base
.context
, dec
->base
.width
, dec
->base
.height
, 1,
791 dec
->base
.chroma_format
, formats
, PIPE_USAGE_STATIC
794 return dec
->mc_source
!= NULL
;
798 mc_vert_shader_callback(void *priv
, struct vl_mc
*mc
,
799 struct ureg_program
*shader
,
800 unsigned first_output
,
803 struct vl_mpeg12_decoder
*dec
= priv
;
804 struct ureg_dst o_vtex
;
809 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
810 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
811 vl_idct_stage2_vert_shader(idct
, shader
, first_output
, tex
);
813 o_vtex
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, first_output
);
814 ureg_MOV(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_XY
), ureg_src(tex
));
819 mc_frag_shader_callback(void *priv
, struct vl_mc
*mc
,
820 struct ureg_program
*shader
,
821 unsigned first_input
,
824 struct vl_mpeg12_decoder
*dec
= priv
;
825 struct ureg_src src
, sampler
;
830 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
831 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
832 vl_idct_stage2_frag_shader(idct
, shader
, first_input
, dst
);
834 src
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, first_input
, TGSI_INTERPOLATE_LINEAR
);
835 sampler
= ureg_DECL_sampler(shader
, 0);
836 ureg_TEX(shader
, dst
, TGSI_TEXTURE_2D
, src
, sampler
);
840 struct pipe_video_decoder
*
841 vl_create_mpeg12_decoder(struct pipe_context
*context
,
842 enum pipe_video_profile profile
,
843 enum pipe_video_entrypoint entrypoint
,
844 enum pipe_video_chroma_format chroma_format
,
845 unsigned width
, unsigned height
)
847 const unsigned block_size_pixels
= BLOCK_WIDTH
* BLOCK_HEIGHT
;
848 const struct format_config
*format_config
;
849 struct vl_mpeg12_decoder
*dec
;
851 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
853 dec
= CALLOC_STRUCT(vl_mpeg12_decoder
);
858 dec
->base
.context
= context
;
859 dec
->base
.profile
= profile
;
860 dec
->base
.entrypoint
= entrypoint
;
861 dec
->base
.chroma_format
= chroma_format
;
862 dec
->base
.width
= width
;
863 dec
->base
.height
= height
;
865 dec
->base
.destroy
= vl_mpeg12_destroy
;
866 dec
->base
.create_buffer
= vl_mpeg12_create_buffer
;
867 dec
->base
.flush_buffer
= vl_mpeg12_decoder_flush_buffer
;
869 dec
->blocks_per_line
= MAX2(util_next_power_of_two(dec
->base
.width
) / block_size_pixels
, 4);
870 dec
->num_blocks
= (dec
->base
.width
* dec
->base
.height
) / block_size_pixels
;
872 dec
->quads
= vl_vb_upload_quads(dec
->base
.context
);
873 dec
->pos
= vl_vb_upload_pos(
875 dec
->base
.width
/ MACROBLOCK_WIDTH
,
876 dec
->base
.height
/ MACROBLOCK_HEIGHT
878 dec
->block_num
= vl_vb_upload_block_num(dec
->base
.context
, dec
->num_blocks
);
880 dec
->ves_ycbcr
= vl_vb_get_ves_ycbcr(dec
->base
.context
);
881 dec
->ves_mv
= vl_vb_get_ves_mv(dec
->base
.context
);
883 /* TODO: Implement 422, 444 */
884 assert(dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
886 if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
) {
887 dec
->chroma_width
= dec
->base
.width
/ 2;
888 dec
->chroma_height
= dec
->base
.height
/ 2;
889 } else if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_422
) {
890 dec
->chroma_width
= dec
->base
.width
;
891 dec
->chroma_height
= dec
->base
.height
/ 2;
893 dec
->chroma_width
= dec
->base
.width
;
894 dec
->chroma_height
= dec
->base
.height
;
897 switch (entrypoint
) {
898 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
:
899 format_config
= find_format_config(dec
, bitstream_format_config
, num_bitstream_format_configs
);
902 case PIPE_VIDEO_ENTRYPOINT_IDCT
:
903 format_config
= find_format_config(dec
, idct_format_config
, num_idct_format_configs
);
906 case PIPE_VIDEO_ENTRYPOINT_MC
:
907 format_config
= find_format_config(dec
, mc_format_config
, num_mc_format_configs
);
918 if (!init_zscan(dec
, format_config
))
921 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
922 if (!init_idct(dec
, format_config
))
925 if (!init_mc_source_widthout_idct(dec
, format_config
))
929 if (!vl_mc_init(&dec
->mc_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
930 MACROBLOCK_HEIGHT
, format_config
->mc_scale
,
931 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
935 if (!vl_mc_init(&dec
->mc_c
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
936 BLOCK_HEIGHT
, format_config
->mc_scale
,
937 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
940 if (!init_pipe_state(dec
))
941 goto error_pipe_state
;
946 vl_mc_cleanup(&dec
->mc_c
);
949 vl_mc_cleanup(&dec
->mc_y
);
952 if (entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
953 vl_idct_cleanup(&dec
->idct_y
);
954 vl_idct_cleanup(&dec
->idct_c
);
955 dec
->idct_source
->destroy(dec
->idct_source
);
957 dec
->mc_source
->destroy(dec
->mc_source
);
960 vl_zscan_cleanup(&dec
->zscan_y
);
961 vl_zscan_cleanup(&dec
->zscan_c
);