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_sampler.h"
34 #include "util/u_video.h"
36 #include "vl_mpeg12_decoder.h"
37 #include "vl_defines.h"
39 #define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
40 #define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
42 struct format_config
{
43 enum pipe_format zscan_source_format
;
44 enum pipe_format idct_source_format
;
45 enum pipe_format mc_source_format
;
51 static const struct format_config bitstream_format_config
[] = {
52 // { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
53 // { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
54 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SNORM
},
55 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, 1.0f
, SCALE_FACTOR_SNORM
}
58 static const unsigned num_bitstream_format_configs
=
59 sizeof(bitstream_format_config
) / sizeof(struct format_config
);
61 static const struct format_config idct_format_config
[] = {
62 // { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_FLOAT, 1.0f, SCALE_FACTOR_SSCALED },
63 // { PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, PIPE_FORMAT_R16G16B16A16_SSCALED, 1.0f, SCALE_FACTOR_SSCALED },
64 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_FLOAT
, 1.0f
, SCALE_FACTOR_SNORM
},
65 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, PIPE_FORMAT_R16G16B16A16_SNORM
, 1.0f
, SCALE_FACTOR_SNORM
}
68 static const unsigned num_idct_format_configs
=
69 sizeof(idct_format_config
) / sizeof(struct format_config
);
71 static const struct format_config mc_format_config
[] = {
72 //{ PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_NONE, PIPE_FORMAT_R16_SSCALED, 0.0f, SCALE_FACTOR_SSCALED },
73 { PIPE_FORMAT_R16_SNORM
, PIPE_FORMAT_NONE
, PIPE_FORMAT_R16_SNORM
, 0.0f
, SCALE_FACTOR_SNORM
}
76 static const unsigned num_mc_format_configs
=
77 sizeof(mc_format_config
) / sizeof(struct format_config
);
79 static const unsigned const_empty_block_mask_420
[3][2][2] = {
80 { { 0x20, 0x10 }, { 0x08, 0x04 } },
81 { { 0x02, 0x02 }, { 0x02, 0x02 } },
82 { { 0x01, 0x01 }, { 0x01, 0x01 } }
86 init_zscan_buffer(struct vl_mpeg12_decoder
*dec
, struct vl_mpeg12_buffer
*buffer
)
88 struct pipe_resource
*res
, res_tmpl
;
89 struct pipe_sampler_view sv_tmpl
;
90 struct pipe_surface
**destination
;
94 assert(dec
&& buffer
);
96 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
97 res_tmpl
.target
= PIPE_TEXTURE_2D
;
98 res_tmpl
.format
= dec
->zscan_source_format
;
99 res_tmpl
.width0
= dec
->blocks_per_line
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
100 res_tmpl
.height0
= align(dec
->num_blocks
, dec
->blocks_per_line
) / dec
->blocks_per_line
;
102 res_tmpl
.array_size
= 1;
103 res_tmpl
.usage
= PIPE_USAGE_STREAM
;
104 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
106 res
= dec
->base
.context
->screen
->resource_create(dec
->base
.context
->screen
, &res_tmpl
);
111 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
112 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
113 sv_tmpl
.swizzle_r
= sv_tmpl
.swizzle_g
= sv_tmpl
.swizzle_b
= sv_tmpl
.swizzle_a
= PIPE_SWIZZLE_RED
;
114 buffer
->zscan_source
= dec
->base
.context
->create_sampler_view(dec
->base
.context
, res
, &sv_tmpl
);
115 pipe_resource_reference(&res
, NULL
);
116 if (!buffer
->zscan_source
)
119 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
120 destination
= dec
->idct_source
->get_surfaces(dec
->idct_source
);
122 destination
= dec
->mc_source
->get_surfaces(dec
->mc_source
);
127 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
)
128 if (!vl_zscan_init_buffer(i
== 0 ? &dec
->zscan_y
: &dec
->zscan_c
,
129 &buffer
->zscan
[i
], buffer
->zscan_source
, destination
[i
]))
136 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
- 1]);
140 pipe_sampler_view_reference(&buffer
->zscan_source
, NULL
);
147 cleanup_zscan_buffer(struct vl_mpeg12_buffer
*buffer
)
153 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
)
154 vl_zscan_cleanup_buffer(&buffer
->zscan
[i
]);
156 pipe_sampler_view_reference(&buffer
->zscan_source
, NULL
);
160 init_idct_buffer(struct vl_mpeg12_decoder
*dec
, struct vl_mpeg12_buffer
*buffer
)
162 struct pipe_sampler_view
**idct_source_sv
, **mc_source_sv
;
166 assert(dec
&& buffer
);
168 idct_source_sv
= dec
->idct_source
->get_sampler_view_planes(dec
->idct_source
);
170 goto error_source_sv
;
172 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
174 goto error_mc_source_sv
;
176 for (i
= 0; i
< 3; ++i
)
177 if (!vl_idct_init_buffer(i
== 0 ? &dec
->idct_y
: &dec
->idct_c
,
178 &buffer
->idct
[i
], idct_source_sv
[i
],
186 vl_idct_cleanup_buffer(&buffer
->idct
[i
- 1]);
194 cleanup_idct_buffer(struct vl_mpeg12_buffer
*buf
)
200 for (i
= 0; i
< 3; ++i
)
201 vl_idct_cleanup_buffer(&buf
->idct
[i
]);
205 init_mc_buffer(struct vl_mpeg12_decoder
*dec
, struct vl_mpeg12_buffer
*buf
)
209 if(!vl_mc_init_buffer(&dec
->mc_y
, &buf
->mc
[0]))
212 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[1]))
215 if(!vl_mc_init_buffer(&dec
->mc_c
, &buf
->mc
[2]))
221 vl_mc_cleanup_buffer(&buf
->mc
[1]);
224 vl_mc_cleanup_buffer(&buf
->mc
[0]);
231 cleanup_mc_buffer(struct vl_mpeg12_buffer
*buf
)
237 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
)
238 vl_mc_cleanup_buffer(&buf
->mc
[i
]);
242 MacroBlockTypeToPipeWeights(const struct pipe_mpeg12_macroblock
*mb
, unsigned weights
[2])
246 switch (mb
->macroblock_type
& (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
| PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
)) {
247 case PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
:
248 weights
[0] = PIPE_VIDEO_MV_WEIGHT_MAX
;
249 weights
[1] = PIPE_VIDEO_MV_WEIGHT_MIN
;
252 case (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
| PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
):
253 weights
[0] = PIPE_VIDEO_MV_WEIGHT_HALF
;
254 weights
[1] = PIPE_VIDEO_MV_WEIGHT_HALF
;
257 case PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
:
258 weights
[0] = PIPE_VIDEO_MV_WEIGHT_MIN
;
259 weights
[1] = PIPE_VIDEO_MV_WEIGHT_MAX
;
263 if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
264 weights
[0] = PIPE_VIDEO_MV_WEIGHT_MIN
;
265 weights
[1] = PIPE_VIDEO_MV_WEIGHT_MIN
;
267 /* no motion vector, but also not intra mb ->
268 just copy the old frame content */
269 weights
[0] = PIPE_VIDEO_MV_WEIGHT_MAX
;
270 weights
[1] = PIPE_VIDEO_MV_WEIGHT_MIN
;
276 static INLINE
struct vl_motionvector
277 MotionVectorToPipe(const struct pipe_mpeg12_macroblock
*mb
, unsigned vector
,
278 unsigned field_select_mask
, unsigned weight
)
280 struct vl_motionvector mv
;
284 if (mb
->macroblock_type
& (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
| PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
)) {
285 switch (mb
->macroblock_modes
.bits
.frame_motion_type
) {
286 case PIPE_MPEG12_MO_TYPE_FRAME
:
287 mv
.top
.x
= mb
->PMV
[0][vector
][0];
288 mv
.top
.y
= mb
->PMV
[0][vector
][1];
289 mv
.top
.field_select
= PIPE_VIDEO_FRAME
;
290 mv
.top
.weight
= weight
;
292 mv
.bottom
.x
= mb
->PMV
[0][vector
][0];
293 mv
.bottom
.y
= mb
->PMV
[0][vector
][1];
294 mv
.bottom
.weight
= weight
;
295 mv
.bottom
.field_select
= PIPE_VIDEO_FRAME
;
298 case PIPE_MPEG12_MO_TYPE_FIELD
:
299 mv
.top
.x
= mb
->PMV
[0][vector
][0];
300 mv
.top
.y
= mb
->PMV
[0][vector
][1];
301 mv
.top
.field_select
= (mb
->motion_vertical_field_select
& field_select_mask
) ?
302 PIPE_VIDEO_BOTTOM_FIELD
: PIPE_VIDEO_TOP_FIELD
;
303 mv
.top
.weight
= weight
;
305 mv
.bottom
.x
= mb
->PMV
[1][vector
][0];
306 mv
.bottom
.y
= mb
->PMV
[1][vector
][1];
307 mv
.bottom
.field_select
= (mb
->motion_vertical_field_select
& (field_select_mask
<< 2)) ?
308 PIPE_VIDEO_BOTTOM_FIELD
: PIPE_VIDEO_TOP_FIELD
;
309 mv
.bottom
.weight
= weight
;
312 default: // TODO: Support DUALPRIME and 16x8
316 mv
.top
.x
= mv
.top
.y
= 0;
317 mv
.top
.field_select
= PIPE_VIDEO_FRAME
;
318 mv
.top
.weight
= weight
;
320 mv
.bottom
.x
= mv
.bottom
.y
= 0;
321 mv
.bottom
.field_select
= PIPE_VIDEO_FRAME
;
322 mv
.bottom
.weight
= weight
;
328 UploadYcbcrBlocks(struct vl_mpeg12_decoder
*dec
,
329 struct vl_mpeg12_buffer
*buf
,
330 const struct pipe_mpeg12_macroblock
*mb
)
333 unsigned tb
, x
, y
, num_blocks
= 0;
338 if (!mb
->coded_block_pattern
)
341 intra
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
? 1 : 0;
343 for (y
= 0; y
< 2; ++y
) {
344 for (x
= 0; x
< 2; ++x
) {
345 if (mb
->coded_block_pattern
& const_empty_block_mask_420
[0][y
][x
]) {
347 struct vl_ycbcr_block
*stream
= buf
->ycbcr_stream
[0];
348 stream
->x
= mb
->x
* 2 + x
;
349 stream
->y
= mb
->y
* 2 + y
;
350 stream
->intra
= intra
;
351 stream
->coding
= mb
->macroblock_modes
.bits
.dct_type
;
352 stream
->block_num
= buf
->block_num
++;
354 buf
->num_ycbcr_blocks
[0]++;
355 buf
->ycbcr_stream
[0]++;
362 /* TODO: Implement 422, 444 */
363 //assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
365 for (tb
= 1; tb
< 3; ++tb
) {
366 if (mb
->coded_block_pattern
& const_empty_block_mask_420
[tb
][0][0]) {
368 struct vl_ycbcr_block
*stream
= buf
->ycbcr_stream
[tb
];
371 stream
->intra
= intra
;
373 stream
->block_num
= buf
->block_num
++;
375 buf
->num_ycbcr_blocks
[tb
]++;
376 buf
->ycbcr_stream
[tb
]++;
382 memcpy(buf
->texels
, mb
->blocks
, 64 * sizeof(short) * num_blocks
);
383 buf
->texels
+= 64 * num_blocks
;
387 vl_mpeg12_destroy_buffer(void *buffer
)
389 struct vl_mpeg12_buffer
*buf
= buffer
;
393 cleanup_zscan_buffer(buf
);
394 cleanup_idct_buffer(buf
);
395 cleanup_mc_buffer(buf
);
396 vl_vb_cleanup(&buf
->vertex_stream
);
402 vl_mpeg12_destroy(struct pipe_video_codec
*decoder
)
404 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
409 /* Asserted in softpipe_delete_fs_state() for some reason */
410 dec
->base
.context
->bind_vs_state(dec
->base
.context
, NULL
);
411 dec
->base
.context
->bind_fs_state(dec
->base
.context
, NULL
);
413 dec
->base
.context
->delete_depth_stencil_alpha_state(dec
->base
.context
, dec
->dsa
);
414 dec
->base
.context
->delete_sampler_state(dec
->base
.context
, dec
->sampler_ycbcr
);
416 vl_mc_cleanup(&dec
->mc_y
);
417 vl_mc_cleanup(&dec
->mc_c
);
418 dec
->mc_source
->destroy(dec
->mc_source
);
420 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
421 vl_idct_cleanup(&dec
->idct_y
);
422 vl_idct_cleanup(&dec
->idct_c
);
423 dec
->idct_source
->destroy(dec
->idct_source
);
426 vl_zscan_cleanup(&dec
->zscan_y
);
427 vl_zscan_cleanup(&dec
->zscan_c
);
429 dec
->base
.context
->delete_vertex_elements_state(dec
->base
.context
, dec
->ves_ycbcr
);
430 dec
->base
.context
->delete_vertex_elements_state(dec
->base
.context
, dec
->ves_mv
);
432 pipe_resource_reference(&dec
->quads
.buffer
, NULL
);
433 pipe_resource_reference(&dec
->pos
.buffer
, NULL
);
435 pipe_sampler_view_reference(&dec
->zscan_linear
, NULL
);
436 pipe_sampler_view_reference(&dec
->zscan_normal
, NULL
);
437 pipe_sampler_view_reference(&dec
->zscan_alternate
, NULL
);
439 for (i
= 0; i
< 4; ++i
)
440 if (dec
->dec_buffers
[i
])
441 vl_mpeg12_destroy_buffer(dec
->dec_buffers
[i
]);
446 static struct vl_mpeg12_buffer
*
447 vl_mpeg12_get_decode_buffer(struct vl_mpeg12_decoder
*dec
, struct pipe_video_buffer
*target
)
449 struct vl_mpeg12_buffer
*buffer
;
453 buffer
= vl_video_buffer_get_associated_data(target
, &dec
->base
);
457 buffer
= dec
->dec_buffers
[dec
->current_buffer
];
461 buffer
= CALLOC_STRUCT(vl_mpeg12_buffer
);
465 if (!vl_vb_init(&buffer
->vertex_stream
, dec
->base
.context
,
466 dec
->base
.width
/ VL_MACROBLOCK_WIDTH
,
467 dec
->base
.height
/ VL_MACROBLOCK_HEIGHT
))
468 goto error_vertex_buffer
;
470 if (!init_mc_buffer(dec
, buffer
))
473 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
474 if (!init_idct_buffer(dec
, buffer
))
477 if (!init_zscan_buffer(dec
, buffer
))
480 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
)
481 vl_mpg12_bs_init(&buffer
->bs
, &dec
->base
);
483 if (dec
->base
.expect_chunked_decode
)
484 vl_video_buffer_set_associated_data(target
, &dec
->base
,
485 buffer
, vl_mpeg12_destroy_buffer
);
487 dec
->dec_buffers
[dec
->current_buffer
] = buffer
;
492 cleanup_idct_buffer(buffer
);
495 cleanup_mc_buffer(buffer
);
498 vl_vb_cleanup(&buffer
->vertex_stream
);
506 vl_mpeg12_begin_frame(struct pipe_video_codec
*decoder
,
507 struct pipe_video_buffer
*target
,
508 struct pipe_picture_desc
*picture
)
510 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
511 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
512 struct vl_mpeg12_buffer
*buf
;
514 struct pipe_resource
*tex
;
515 struct pipe_box rect
= { 0, 0, 0, 1, 1, 1 };
517 uint8_t intra_matrix
[64];
518 uint8_t non_intra_matrix
[64];
522 assert(dec
&& target
&& picture
);
524 buf
= vl_mpeg12_get_decode_buffer(dec
, target
);
527 if (dec
->base
.entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
528 memcpy(intra_matrix
, desc
->intra_matrix
, sizeof(intra_matrix
));
529 memcpy(non_intra_matrix
, desc
->non_intra_matrix
, sizeof(non_intra_matrix
));
530 intra_matrix
[0] = 1 << (7 - desc
->intra_dc_precision
);
532 memset(intra_matrix
, 0x10, sizeof(intra_matrix
));
533 memset(non_intra_matrix
, 0x10, sizeof(non_intra_matrix
));
536 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
537 struct vl_zscan
*zscan
= i
== 0 ? &dec
->zscan_y
: &dec
->zscan_c
;
538 vl_zscan_upload_quant(zscan
, &buf
->zscan
[i
], intra_matrix
, true);
539 vl_zscan_upload_quant(zscan
, &buf
->zscan
[i
], non_intra_matrix
, false);
542 vl_vb_map(&buf
->vertex_stream
, dec
->base
.context
);
544 tex
= buf
->zscan_source
->texture
;
545 rect
.width
= tex
->width0
;
546 rect
.height
= tex
->height0
;
549 dec
->base
.context
->transfer_map(dec
->base
.context
, tex
, 0,
550 PIPE_TRANSFER_WRITE
|
551 PIPE_TRANSFER_DISCARD_RANGE
,
552 &rect
, &buf
->tex_transfer
);
556 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
557 buf
->ycbcr_stream
[i
] = vl_vb_get_ycbcr_stream(&buf
->vertex_stream
, i
);
558 buf
->num_ycbcr_blocks
[i
] = 0;
561 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
)
562 buf
->mv_stream
[i
] = vl_vb_get_mv_stream(&buf
->vertex_stream
, i
);
564 if (dec
->base
.entrypoint
>= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
565 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
)
566 vl_zscan_set_layout(&buf
->zscan
[i
], dec
->zscan_linear
);
571 vl_mpeg12_decode_macroblock(struct pipe_video_codec
*decoder
,
572 struct pipe_video_buffer
*target
,
573 struct pipe_picture_desc
*picture
,
574 const struct pipe_macroblock
*macroblocks
,
575 unsigned num_macroblocks
)
577 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
578 const struct pipe_mpeg12_macroblock
*mb
= (const struct pipe_mpeg12_macroblock
*)macroblocks
;
579 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
580 struct vl_mpeg12_buffer
*buf
;
582 unsigned i
, j
, mv_weights
[2];
584 assert(dec
&& target
&& picture
);
585 assert(macroblocks
&& macroblocks
->codec
== PIPE_VIDEO_FORMAT_MPEG12
);
587 buf
= vl_mpeg12_get_decode_buffer(dec
, target
);
590 for (; num_macroblocks
> 0; --num_macroblocks
) {
591 unsigned mb_addr
= mb
->y
* dec
->width_in_macroblocks
+ mb
->x
;
593 if (mb
->macroblock_type
& (PIPE_MPEG12_MB_TYPE_PATTERN
| PIPE_MPEG12_MB_TYPE_INTRA
))
594 UploadYcbcrBlocks(dec
, buf
, mb
);
596 MacroBlockTypeToPipeWeights(mb
, mv_weights
);
598 for (i
= 0; i
< 2; ++i
) {
599 if (!desc
->ref
[i
]) continue;
601 buf
->mv_stream
[i
][mb_addr
] = MotionVectorToPipe
604 i
? PIPE_MPEG12_FS_FIRST_BACKWARD
: PIPE_MPEG12_FS_FIRST_FORWARD
,
609 /* see section 7.6.6 of the spec */
610 if (mb
->num_skipped_macroblocks
> 0) {
611 struct vl_motionvector skipped_mv
[2];
613 if (desc
->ref
[0] && !desc
->ref
[1]) {
614 skipped_mv
[0].top
.x
= skipped_mv
[0].top
.y
= 0;
615 skipped_mv
[0].top
.weight
= PIPE_VIDEO_MV_WEIGHT_MAX
;
617 skipped_mv
[0] = buf
->mv_stream
[0][mb_addr
];
618 skipped_mv
[1] = buf
->mv_stream
[1][mb_addr
];
620 skipped_mv
[0].top
.field_select
= PIPE_VIDEO_FRAME
;
621 skipped_mv
[1].top
.field_select
= PIPE_VIDEO_FRAME
;
623 skipped_mv
[0].bottom
= skipped_mv
[0].top
;
624 skipped_mv
[1].bottom
= skipped_mv
[1].top
;
627 for (i
= 0; i
< mb
->num_skipped_macroblocks
; ++i
, ++mb_addr
) {
628 for (j
= 0; j
< 2; ++j
) {
629 if (!desc
->ref
[j
]) continue;
630 buf
->mv_stream
[j
][mb_addr
] = skipped_mv
[j
];
641 vl_mpeg12_decode_bitstream(struct pipe_video_codec
*decoder
,
642 struct pipe_video_buffer
*target
,
643 struct pipe_picture_desc
*picture
,
644 unsigned num_buffers
,
645 const void * const *buffers
,
646 const unsigned *sizes
)
648 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
649 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
650 struct vl_mpeg12_buffer
*buf
;
654 assert(dec
&& target
&& picture
);
656 buf
= vl_mpeg12_get_decode_buffer(dec
, target
);
659 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
)
660 vl_zscan_set_layout(&buf
->zscan
[i
], desc
->alternate_scan
?
661 dec
->zscan_alternate
: dec
->zscan_normal
);
663 vl_mpg12_bs_decode(&buf
->bs
, target
, desc
, num_buffers
, buffers
, sizes
);
667 vl_mpeg12_end_frame(struct pipe_video_codec
*decoder
,
668 struct pipe_video_buffer
*target
,
669 struct pipe_picture_desc
*picture
)
671 struct vl_mpeg12_decoder
*dec
= (struct vl_mpeg12_decoder
*)decoder
;
672 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
673 struct pipe_sampler_view
**ref_frames
[2];
674 struct pipe_sampler_view
**mc_source_sv
;
675 struct pipe_surface
**target_surfaces
;
676 struct pipe_vertex_buffer vb
[3];
677 struct vl_mpeg12_buffer
*buf
;
679 const unsigned *plane_order
;
680 unsigned i
, j
, component
;
681 unsigned nr_components
;
683 assert(dec
&& target
&& picture
);
684 assert(!target
->interlaced
);
686 buf
= vl_mpeg12_get_decode_buffer(dec
, target
);
688 vl_vb_unmap(&buf
->vertex_stream
, dec
->base
.context
);
690 dec
->base
.context
->transfer_unmap(dec
->base
.context
, buf
->tex_transfer
);
695 target_surfaces
= target
->get_surfaces(target
);
697 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
699 ref_frames
[i
] = desc
->ref
[i
]->get_sampler_view_planes(desc
->ref
[i
]);
701 ref_frames
[i
] = NULL
;
704 dec
->base
.context
->bind_vertex_elements_state(dec
->base
.context
, dec
->ves_mv
);
705 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
706 if (!target_surfaces
[i
]) continue;
708 vl_mc_set_surface(&buf
->mc
[i
], target_surfaces
[i
]);
710 for (j
= 0; j
< VL_MAX_REF_FRAMES
; ++j
) {
711 if (!ref_frames
[j
] || !ref_frames
[j
][i
]) continue;
713 vb
[2] = vl_vb_get_mv(&buf
->vertex_stream
, j
);;
714 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 0, 3, vb
);
716 vl_mc_render_ref(i
? &dec
->mc_c
: &dec
->mc_y
, &buf
->mc
[i
], ref_frames
[j
][i
]);
720 dec
->base
.context
->bind_vertex_elements_state(dec
->base
.context
, dec
->ves_ycbcr
);
721 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
722 if (!buf
->num_ycbcr_blocks
[i
]) continue;
724 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, i
);
725 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 0, 2, vb
);
727 vl_zscan_render(i
? &dec
->zscan_c
: & dec
->zscan_y
, &buf
->zscan
[i
] , buf
->num_ycbcr_blocks
[i
]);
729 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
730 vl_idct_flush(i
? &dec
->idct_c
: &dec
->idct_y
, &buf
->idct
[i
], buf
->num_ycbcr_blocks
[i
]);
733 plane_order
= vl_video_buffer_plane_order(target
->buffer_format
);
734 mc_source_sv
= dec
->mc_source
->get_sampler_view_planes(dec
->mc_source
);
735 for (i
= 0, component
= 0; component
< VL_NUM_COMPONENTS
; ++i
) {
736 if (!target_surfaces
[i
]) continue;
738 nr_components
= util_format_get_nr_components(target_surfaces
[i
]->texture
->format
);
739 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
740 unsigned plane
= plane_order
[component
];
741 if (!buf
->num_ycbcr_blocks
[plane
]) continue;
743 vb
[1] = vl_vb_get_ycbcr(&buf
->vertex_stream
, plane
);
744 dec
->base
.context
->set_vertex_buffers(dec
->base
.context
, 0, 2, vb
);
746 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
747 vl_idct_prepare_stage2(i
? &dec
->idct_c
: &dec
->idct_y
, &buf
->idct
[plane
]);
749 dec
->base
.context
->set_fragment_sampler_views(dec
->base
.context
, 1, &mc_source_sv
[plane
]);
750 dec
->base
.context
->bind_fragment_sampler_states(dec
->base
.context
, 1, &dec
->sampler_ycbcr
);
752 vl_mc_render_ycbcr(i
? &dec
->mc_c
: &dec
->mc_y
, &buf
->mc
[i
], j
, buf
->num_ycbcr_blocks
[plane
]);
755 ++dec
->current_buffer
;
756 dec
->current_buffer
%= 4;
760 vl_mpeg12_flush(struct pipe_video_codec
*decoder
)
764 //Noop, for shaders it is much faster to flush everything in end_frame
768 init_pipe_state(struct vl_mpeg12_decoder
*dec
)
770 struct pipe_depth_stencil_alpha_state dsa
;
771 struct pipe_sampler_state sampler
;
776 memset(&dsa
, 0, sizeof dsa
);
777 dsa
.depth
.enabled
= 0;
778 dsa
.depth
.writemask
= 0;
779 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
780 for (i
= 0; i
< 2; ++i
) {
781 dsa
.stencil
[i
].enabled
= 0;
782 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
783 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
784 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
785 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
786 dsa
.stencil
[i
].valuemask
= 0;
787 dsa
.stencil
[i
].writemask
= 0;
789 dsa
.alpha
.enabled
= 0;
790 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
791 dsa
.alpha
.ref_value
= 0;
792 dec
->dsa
= dec
->base
.context
->create_depth_stencil_alpha_state(dec
->base
.context
, &dsa
);
793 dec
->base
.context
->bind_depth_stencil_alpha_state(dec
->base
.context
, dec
->dsa
);
795 memset(&sampler
, 0, sizeof(sampler
));
796 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
797 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
798 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
799 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
800 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
801 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
802 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
803 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
804 sampler
.normalized_coords
= 1;
805 dec
->sampler_ycbcr
= dec
->base
.context
->create_sampler_state(dec
->base
.context
, &sampler
);
806 if (!dec
->sampler_ycbcr
)
812 static const struct format_config
*
813 find_format_config(struct vl_mpeg12_decoder
*dec
, const struct format_config configs
[], unsigned num_configs
)
815 struct pipe_screen
*screen
;
820 screen
= dec
->base
.context
->screen
;
822 for (i
= 0; i
< num_configs
; ++i
) {
823 if (!screen
->is_format_supported(screen
, configs
[i
].zscan_source_format
, PIPE_TEXTURE_2D
,
824 1, PIPE_BIND_SAMPLER_VIEW
))
827 if (configs
[i
].idct_source_format
!= PIPE_FORMAT_NONE
) {
828 if (!screen
->is_format_supported(screen
, configs
[i
].idct_source_format
, PIPE_TEXTURE_2D
,
829 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
832 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_3D
,
833 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
836 if (!screen
->is_format_supported(screen
, configs
[i
].mc_source_format
, PIPE_TEXTURE_2D
,
837 1, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
847 init_zscan(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
849 unsigned num_channels
;
853 dec
->zscan_source_format
= format_config
->zscan_source_format
;
854 dec
->zscan_linear
= vl_zscan_layout(dec
->base
.context
, vl_zscan_linear
, dec
->blocks_per_line
);
855 dec
->zscan_normal
= vl_zscan_layout(dec
->base
.context
, vl_zscan_normal
, dec
->blocks_per_line
);
856 dec
->zscan_alternate
= vl_zscan_layout(dec
->base
.context
, vl_zscan_alternate
, dec
->blocks_per_line
);
858 num_channels
= dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
? 4 : 1;
860 if (!vl_zscan_init(&dec
->zscan_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
861 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
864 if (!vl_zscan_init(&dec
->zscan_c
, dec
->base
.context
, dec
->chroma_width
, dec
->chroma_height
,
865 dec
->blocks_per_line
, dec
->num_blocks
, num_channels
))
872 init_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
874 unsigned nr_of_idct_render_targets
, max_inst
;
875 enum pipe_format formats
[3];
876 struct pipe_video_buffer templat
;
878 struct pipe_sampler_view
*matrix
= NULL
;
880 nr_of_idct_render_targets
= dec
->base
.context
->screen
->get_param
882 dec
->base
.context
->screen
, PIPE_CAP_MAX_RENDER_TARGETS
885 max_inst
= dec
->base
.context
->screen
->get_shader_param
887 dec
->base
.context
->screen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
890 // Just assume we need 32 inst per render target, not 100% true, but should work in most cases
891 if (nr_of_idct_render_targets
>= 4 && max_inst
>= 32*4)
892 // more than 4 render targets usually doesn't makes any seens
893 nr_of_idct_render_targets
= 4;
895 nr_of_idct_render_targets
= 1;
897 formats
[0] = formats
[1] = formats
[2] = format_config
->idct_source_format
;
898 memset(&templat
, 0, sizeof(templat
));
899 templat
.width
= dec
->base
.width
/ 4;
900 templat
.height
= dec
->base
.height
;
901 templat
.chroma_format
= dec
->base
.chroma_format
;
902 dec
->idct_source
= vl_video_buffer_create_ex
904 dec
->base
.context
, &templat
,
905 formats
, 1, 1, PIPE_USAGE_STATIC
908 if (!dec
->idct_source
)
909 goto error_idct_source
;
911 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
912 memset(&templat
, 0, sizeof(templat
));
913 templat
.width
= dec
->base
.width
/ nr_of_idct_render_targets
;
914 templat
.height
= dec
->base
.height
/ 4;
915 templat
.chroma_format
= dec
->base
.chroma_format
;
916 dec
->mc_source
= vl_video_buffer_create_ex
918 dec
->base
.context
, &templat
,
919 formats
, nr_of_idct_render_targets
, 1, PIPE_USAGE_STATIC
923 goto error_mc_source
;
925 if (!(matrix
= vl_idct_upload_matrix(dec
->base
.context
, format_config
->idct_scale
)))
928 if (!vl_idct_init(&dec
->idct_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
929 nr_of_idct_render_targets
, matrix
, matrix
))
932 if(!vl_idct_init(&dec
->idct_c
, dec
->base
.context
, dec
->chroma_width
, dec
->chroma_height
,
933 nr_of_idct_render_targets
, matrix
, matrix
))
936 pipe_sampler_view_reference(&matrix
, NULL
);
941 vl_idct_cleanup(&dec
->idct_y
);
944 pipe_sampler_view_reference(&matrix
, NULL
);
947 dec
->mc_source
->destroy(dec
->mc_source
);
950 dec
->idct_source
->destroy(dec
->idct_source
);
957 init_mc_source_widthout_idct(struct vl_mpeg12_decoder
*dec
, const struct format_config
* format_config
)
959 enum pipe_format formats
[3];
960 struct pipe_video_buffer templat
;
962 formats
[0] = formats
[1] = formats
[2] = format_config
->mc_source_format
;
963 memset(&templat
, 0, sizeof(templat
));
964 templat
.width
= dec
->base
.width
;
965 templat
.height
= dec
->base
.height
;
966 templat
.chroma_format
= dec
->base
.chroma_format
;
967 dec
->mc_source
= vl_video_buffer_create_ex
969 dec
->base
.context
, &templat
,
970 formats
, 1, 1, PIPE_USAGE_STATIC
973 return dec
->mc_source
!= NULL
;
977 mc_vert_shader_callback(void *priv
, struct vl_mc
*mc
,
978 struct ureg_program
*shader
,
979 unsigned first_output
,
982 struct vl_mpeg12_decoder
*dec
= priv
;
983 struct ureg_dst o_vtex
;
988 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
989 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
990 vl_idct_stage2_vert_shader(idct
, shader
, first_output
, tex
);
992 o_vtex
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, first_output
);
993 ureg_MOV(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_XY
), ureg_src(tex
));
998 mc_frag_shader_callback(void *priv
, struct vl_mc
*mc
,
999 struct ureg_program
*shader
,
1000 unsigned first_input
,
1001 struct ureg_dst dst
)
1003 struct vl_mpeg12_decoder
*dec
= priv
;
1004 struct ureg_src src
, sampler
;
1009 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
1010 struct vl_idct
*idct
= mc
== &dec
->mc_y
? &dec
->idct_y
: &dec
->idct_c
;
1011 vl_idct_stage2_frag_shader(idct
, shader
, first_input
, dst
);
1013 src
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, first_input
, TGSI_INTERPOLATE_LINEAR
);
1014 sampler
= ureg_DECL_sampler(shader
, 0);
1015 ureg_TEX(shader
, dst
, TGSI_TEXTURE_2D
, src
, sampler
);
1019 struct pipe_video_codec
*
1020 vl_create_mpeg12_decoder(struct pipe_context
*context
,
1021 const struct pipe_video_codec
*templat
)
1023 const unsigned block_size_pixels
= VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
1024 const struct format_config
*format_config
;
1025 struct vl_mpeg12_decoder
*dec
;
1027 assert(u_reduce_video_profile(templat
->profile
) == PIPE_VIDEO_FORMAT_MPEG12
);
1029 dec
= CALLOC_STRUCT(vl_mpeg12_decoder
);
1034 dec
->base
= *templat
;
1035 dec
->base
.context
= context
;
1037 dec
->base
.destroy
= vl_mpeg12_destroy
;
1038 dec
->base
.begin_frame
= vl_mpeg12_begin_frame
;
1039 dec
->base
.decode_macroblock
= vl_mpeg12_decode_macroblock
;
1040 dec
->base
.decode_bitstream
= vl_mpeg12_decode_bitstream
;
1041 dec
->base
.end_frame
= vl_mpeg12_end_frame
;
1042 dec
->base
.flush
= vl_mpeg12_flush
;
1044 dec
->blocks_per_line
= MAX2(util_next_power_of_two(dec
->base
.width
) / block_size_pixels
, 4);
1045 dec
->num_blocks
= (dec
->base
.width
* dec
->base
.height
) / block_size_pixels
;
1046 dec
->width_in_macroblocks
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
) / VL_MACROBLOCK_WIDTH
;
1048 /* TODO: Implement 422, 444 */
1049 assert(dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
1051 if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
) {
1052 dec
->chroma_width
= dec
->base
.width
/ 2;
1053 dec
->chroma_height
= dec
->base
.height
/ 2;
1054 dec
->num_blocks
= dec
->num_blocks
* 2;
1055 } else if (dec
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_422
) {
1056 dec
->chroma_width
= dec
->base
.width
/ 2;
1057 dec
->chroma_height
= dec
->base
.height
;
1058 dec
->num_blocks
= dec
->num_blocks
* 2 + dec
->num_blocks
;
1060 dec
->chroma_width
= dec
->base
.width
;
1061 dec
->chroma_height
= dec
->base
.height
;
1062 dec
->num_blocks
= dec
->num_blocks
* 3;
1065 dec
->quads
= vl_vb_upload_quads(dec
->base
.context
);
1066 dec
->pos
= vl_vb_upload_pos(
1068 dec
->base
.width
/ VL_MACROBLOCK_WIDTH
,
1069 dec
->base
.height
/ VL_MACROBLOCK_HEIGHT
1072 dec
->ves_ycbcr
= vl_vb_get_ves_ycbcr(dec
->base
.context
);
1073 dec
->ves_mv
= vl_vb_get_ves_mv(dec
->base
.context
);
1075 switch (templat
->entrypoint
) {
1076 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
:
1077 format_config
= find_format_config(dec
, bitstream_format_config
, num_bitstream_format_configs
);
1080 case PIPE_VIDEO_ENTRYPOINT_IDCT
:
1081 format_config
= find_format_config(dec
, idct_format_config
, num_idct_format_configs
);
1084 case PIPE_VIDEO_ENTRYPOINT_MC
:
1085 format_config
= find_format_config(dec
, mc_format_config
, num_mc_format_configs
);
1094 if (!format_config
) {
1099 if (!init_zscan(dec
, format_config
))
1102 if (templat
->entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
1103 if (!init_idct(dec
, format_config
))
1106 if (!init_mc_source_widthout_idct(dec
, format_config
))
1110 if (!vl_mc_init(&dec
->mc_y
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
1111 VL_MACROBLOCK_HEIGHT
, format_config
->mc_scale
,
1112 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
1116 if (!vl_mc_init(&dec
->mc_c
, dec
->base
.context
, dec
->base
.width
, dec
->base
.height
,
1117 VL_BLOCK_HEIGHT
, format_config
->mc_scale
,
1118 mc_vert_shader_callback
, mc_frag_shader_callback
, dec
))
1121 if (!init_pipe_state(dec
))
1122 goto error_pipe_state
;
1127 vl_mc_cleanup(&dec
->mc_c
);
1130 vl_mc_cleanup(&dec
->mc_y
);
1133 if (templat
->entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
) {
1134 vl_idct_cleanup(&dec
->idct_y
);
1135 vl_idct_cleanup(&dec
->idct_c
);
1136 dec
->idct_source
->destroy(dec
->idct_source
);
1138 dec
->mc_source
->destroy(dec
->mc_source
);
1141 vl_zscan_cleanup(&dec
->zscan_y
);
1142 vl_zscan_cleanup(&dec
->zscan_c
);