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 **************************************************************************/
28 #include "util/u_inlines.h"
29 #include "util/u_memory.h"
31 #include "vl_mpeg12_context.h"
32 #include "vl_defines.h"
33 #include <pipe/p_shader_tokens.h>
34 #include <util/u_inlines.h>
35 #include <util/u_memory.h>
36 #include <util/u_keymap.h>
37 #include <util/u_rect.h>
38 #include <util/u_video.h>
39 #include <util/u_surface.h>
43 static const unsigned const_empty_block_mask_420
[3][2][2] = {
44 { { 0x20, 0x10 }, { 0x08, 0x04 } },
45 { { 0x02, 0x02 }, { 0x02, 0x02 } },
46 { { 0x01, 0x01 }, { 0x01, 0x01 } }
50 flush_buffer(struct vl_mpeg12_context
*ctx
)
52 unsigned ne_start
, ne_num
, e_start
, e_num
;
55 if(ctx
->cur_buffer
!= NULL
) {
57 vl_vb_unmap(&ctx
->cur_buffer
->vertex_stream
, ctx
->pipe
);
58 vl_idct_unmap_buffers(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
);
59 vl_idct_unmap_buffers(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
);
60 vl_idct_unmap_buffers(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
);
61 vl_vb_restart(&ctx
->cur_buffer
->vertex_stream
,
62 &ne_start
, &ne_num
, &e_start
, &e_num
);
64 ctx
->pipe
->set_vertex_buffers(ctx
->pipe
, 2, ctx
->cur_buffer
->vertex_bufs
.all
);
65 ctx
->pipe
->bind_vertex_elements_state(ctx
->pipe
, ctx
->vertex_elems_state
);
66 vl_idct_flush(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
, ne_num
);
67 vl_idct_flush(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
, ne_num
);
68 vl_idct_flush(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
, ne_num
);
69 vl_mpeg12_mc_renderer_flush(&ctx
->mc_renderer
, &ctx
->cur_buffer
->mc
,
70 ne_start
, ne_num
, e_start
, e_num
);
72 ctx
->cur_buffer
= NULL
;
77 rotate_buffer(struct vl_mpeg12_context
*ctx
)
79 struct pipe_resource
*y
, *cr
, *cb
;
80 static unsigned key
= 0;
81 struct vl_mpeg12_buffer
*buffer
;
87 buffer
= (struct vl_mpeg12_buffer
*)util_keymap_lookup(ctx
->buffer_map
, &key
);
91 buffer
= CALLOC_STRUCT(vl_mpeg12_buffer
);
95 buffer
->vertex_bufs
.individual
.quad
.stride
= ctx
->quads
.stride
;
96 buffer
->vertex_bufs
.individual
.quad
.buffer_offset
= ctx
->quads
.buffer_offset
;
97 pipe_resource_reference(&buffer
->vertex_bufs
.individual
.quad
.buffer
, ctx
->quads
.buffer
);
99 buffer
->vertex_bufs
.individual
.stream
= vl_vb_init(&buffer
->vertex_stream
, ctx
->pipe
,
100 ctx
->vertex_buffer_size
);
101 if (!(y
= vl_idct_init_buffer(&ctx
->idct_y
, &buffer
->idct_y
))) {
106 if (!(cr
= vl_idct_init_buffer(&ctx
->idct_cr
, &buffer
->idct_cr
))) {
111 if (!(cb
= vl_idct_init_buffer(&ctx
->idct_cb
, &buffer
->idct_cb
))) {
116 if(!vl_mpeg12_mc_init_buffer(&ctx
->mc_renderer
, &buffer
->mc
, y
, cr
, cb
)) {
121 added_to_map
= util_keymap_insert(ctx
->buffer_map
, &key
, buffer
, ctx
);
122 assert(added_to_map
);
126 ctx
->cur_buffer
= buffer
;
128 vl_vb_map(&ctx
->cur_buffer
->vertex_stream
, ctx
->pipe
);
129 vl_idct_map_buffers(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
);
130 vl_idct_map_buffers(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
);
131 vl_idct_map_buffers(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
);
135 delete_buffer(const struct keymap
*map
,
136 const void *key
, void *data
,
139 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)user
;
140 struct vl_mpeg12_buffer
*buf
= (struct vl_mpeg12_buffer
*)data
;
147 vl_vb_cleanup(&buf
->vertex_stream
);
148 vl_idct_cleanup_buffer(&ctx
->idct_y
, &buf
->idct_y
);
149 vl_idct_cleanup_buffer(&ctx
->idct_cb
, &buf
->idct_cb
);
150 vl_idct_cleanup_buffer(&ctx
->idct_cr
, &buf
->idct_cr
);
151 vl_mpeg12_mc_cleanup_buffer(&ctx
->mc_renderer
, &buf
->mc
);
155 upload_buffer(struct vl_mpeg12_context
*ctx
,
156 struct vl_mpeg12_buffer
*buffer
,
157 struct pipe_mpeg12_macroblock
*mb
)
168 for (y
= 0; y
< 2; ++y
) {
169 for (x
= 0; x
< 2; ++x
, ++tb
) {
170 if (mb
->cbp
& (*ctx
->empty_block_mask
)[0][y
][x
]) {
171 vl_idct_add_block(&buffer
->idct_y
, mb
->mbx
* 2 + x
, mb
->mby
* 2 + y
, blocks
);
172 blocks
+= BLOCK_WIDTH
* BLOCK_HEIGHT
;
177 /* TODO: Implement 422, 444 */
178 assert(ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
180 for (tb
= 1; tb
< 3; ++tb
) {
181 if (mb
->cbp
& (*ctx
->empty_block_mask
)[tb
][0][0]) {
183 vl_idct_add_block(&buffer
->idct_cb
, mb
->mbx
, mb
->mby
, blocks
);
185 vl_idct_add_block(&buffer
->idct_cr
, mb
->mbx
, mb
->mby
, blocks
);
186 blocks
+= BLOCK_WIDTH
* BLOCK_HEIGHT
;
192 vl_mpeg12_destroy(struct pipe_video_context
*vpipe
)
194 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
200 /* Asserted in softpipe_delete_fs_state() for some reason */
201 ctx
->pipe
->bind_vs_state(ctx
->pipe
, NULL
);
202 ctx
->pipe
->bind_fs_state(ctx
->pipe
, NULL
);
204 ctx
->pipe
->delete_blend_state(ctx
->pipe
, ctx
->blend
);
205 ctx
->pipe
->delete_rasterizer_state(ctx
->pipe
, ctx
->rast
);
206 ctx
->pipe
->delete_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
208 pipe_surface_reference(&ctx
->decode_target
, NULL
);
209 vl_compositor_cleanup(&ctx
->compositor
);
210 util_delete_keymap(ctx
->buffer_map
, ctx
);
211 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
212 vl_idct_cleanup(&ctx
->idct_y
);
213 vl_idct_cleanup(&ctx
->idct_cr
);
214 vl_idct_cleanup(&ctx
->idct_cb
);
215 ctx
->pipe
->delete_vertex_elements_state(ctx
->pipe
, ctx
->vertex_elems_state
);
216 pipe_resource_reference(&ctx
->quads
.buffer
, NULL
);
217 ctx
->pipe
->destroy(ctx
->pipe
);
223 vl_mpeg12_get_param(struct pipe_video_context
*vpipe
, int param
)
225 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
230 case PIPE_CAP_NPOT_TEXTURES
:
231 /* XXX: Temporary; not all paths are NPOT-tested */
233 return ctx
->pipe
->screen
->get_param(ctx
->pipe
->screen
, param
);
236 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT
:
237 return ctx
->decode_format
;
240 debug_printf("vl_mpeg12_context: Unknown PIPE_CAP %d\n", param
);
246 static struct pipe_surface
*
247 vl_mpeg12_create_surface(struct pipe_video_context
*vpipe
,
248 struct pipe_resource
*resource
,
249 const struct pipe_surface
*templat
)
251 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
255 return ctx
->pipe
->create_surface(ctx
->pipe
, resource
, templat
);
259 vl_mpeg12_is_format_supported(struct pipe_video_context
*vpipe
,
260 enum pipe_format format
,
263 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
267 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, format
,
273 vl_mpeg12_decode_macroblocks(struct pipe_video_context
*vpipe
,
274 struct pipe_surface
*past
,
275 struct pipe_surface
*future
,
276 unsigned num_macroblocks
,
277 struct pipe_macroblock
*macroblocks
,
278 struct pipe_fence_handle
**fence
)
280 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
281 struct pipe_mpeg12_macroblock
*mpeg12_macroblocks
= (struct pipe_mpeg12_macroblock
*)macroblocks
;
285 assert(num_macroblocks
);
287 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
288 assert(ctx
->decode_target
);
289 assert(ctx
->cur_buffer
);
291 for ( i
= 0; i
< num_macroblocks
; ++i
) {
292 vl_vb_add_block(&ctx
->cur_buffer
->vertex_stream
, &mpeg12_macroblocks
[i
],
293 ctx
->empty_block_mask
);
294 upload_buffer(ctx
, ctx
->cur_buffer
, &mpeg12_macroblocks
[i
]);
297 vl_mpeg12_mc_set_surfaces(&ctx
->mc_renderer
, &ctx
->cur_buffer
->mc
,
298 ctx
->decode_target
, past
, future
, fence
);
302 vl_mpeg12_clear_render_target(struct pipe_video_context
*vpipe
,
303 struct pipe_surface
*dst
,
304 unsigned dstx
, unsigned dsty
,
306 unsigned width
, unsigned height
)
308 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
313 if (ctx
->pipe
->clear_render_target
)
314 ctx
->pipe
->clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
316 util_clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
320 vl_mpeg12_resource_copy_region(struct pipe_video_context
*vpipe
,
321 struct pipe_resource
*dst
,
322 unsigned dstx
, unsigned dsty
, unsigned dstz
,
323 struct pipe_resource
*src
,
324 unsigned srcx
, unsigned srcy
, unsigned srcz
,
325 unsigned width
, unsigned height
)
327 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
339 if (ctx
->pipe
->resource_copy_region
)
340 ctx
->pipe
->resource_copy_region(ctx
->pipe
, dst
, 0,
344 util_resource_copy_region(ctx
->pipe
, dst
, 0,
349 static struct pipe_transfer
*
350 vl_mpeg12_get_transfer(struct pipe_video_context
*vpipe
,
351 struct pipe_resource
*resource
,
353 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
354 const struct pipe_box
*box
)
356 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
362 return ctx
->pipe
->get_transfer(ctx
->pipe
, resource
, level
, usage
, box
);
366 vl_mpeg12_transfer_destroy(struct pipe_video_context
*vpipe
,
367 struct pipe_transfer
*transfer
)
369 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
374 ctx
->pipe
->transfer_destroy(ctx
->pipe
, transfer
);
378 vl_mpeg12_transfer_map(struct pipe_video_context
*vpipe
,
379 struct pipe_transfer
*transfer
)
381 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
386 return ctx
->pipe
->transfer_map(ctx
->pipe
, transfer
);
390 vl_mpeg12_transfer_flush_region(struct pipe_video_context
*vpipe
,
391 struct pipe_transfer
*transfer
,
392 const struct pipe_box
*box
)
394 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
400 ctx
->pipe
->transfer_flush_region(ctx
->pipe
, transfer
, box
);
404 vl_mpeg12_transfer_unmap(struct pipe_video_context
*vpipe
,
405 struct pipe_transfer
*transfer
)
407 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
412 ctx
->pipe
->transfer_unmap(ctx
->pipe
, transfer
);
416 vl_mpeg12_transfer_inline_write(struct pipe_video_context
*vpipe
,
417 struct pipe_resource
*resource
,
419 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
420 const struct pipe_box
*box
,
423 unsigned slice_stride
)
425 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
431 assert(ctx
->pipe
->transfer_inline_write
);
433 ctx
->pipe
->transfer_inline_write(ctx
->pipe
, resource
, level
, usage
,
434 box
, data
, stride
, slice_stride
);
438 vl_mpeg12_render_picture(struct pipe_video_context
*vpipe
,
439 struct pipe_surface
*src_surface
,
440 enum pipe_mpeg12_picture_type picture_type
,
441 /*unsigned num_past_surfaces,
442 struct pipe_surface *past_surfaces,
443 unsigned num_future_surfaces,
444 struct pipe_surface *future_surfaces,*/
445 struct pipe_video_rect
*src_area
,
446 struct pipe_surface
*dst_surface
,
447 struct pipe_video_rect
*dst_area
,
448 struct pipe_fence_handle
**fence
)
450 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
460 vl_compositor_render(&ctx
->compositor
, src_surface
,
461 picture_type
, src_area
, dst_surface
, dst_area
, fence
);
465 vl_mpeg12_set_picture_background(struct pipe_video_context
*vpipe
,
466 struct pipe_surface
*bg
,
467 struct pipe_video_rect
*bg_src_rect
)
469 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
475 vl_compositor_set_background(&ctx
->compositor
, bg
, bg_src_rect
);
479 vl_mpeg12_set_picture_layers(struct pipe_video_context
*vpipe
,
480 struct pipe_surface
*layers
[],
481 struct pipe_video_rect
*src_rects
[],
482 struct pipe_video_rect
*dst_rects
[],
485 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
488 assert((layers
&& src_rects
&& dst_rects
) ||
489 (!layers
&& !src_rects
&& !dst_rects
));
491 vl_compositor_set_layers(&ctx
->compositor
, layers
, src_rects
, dst_rects
, num_layers
);
495 vl_mpeg12_set_decode_target(struct pipe_video_context
*vpipe
,
496 struct pipe_surface
*dt
)
498 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
503 if (ctx
->decode_target
!= dt
|| ctx
->cur_buffer
== NULL
) {
506 pipe_surface_reference(&ctx
->decode_target
, dt
);
511 vl_mpeg12_set_csc_matrix(struct pipe_video_context
*vpipe
, const float *mat
)
513 struct vl_mpeg12_context
*ctx
= (struct vl_mpeg12_context
*)vpipe
;
517 vl_compositor_set_csc_matrix(&ctx
->compositor
, mat
);
521 init_pipe_state(struct vl_mpeg12_context
*ctx
)
523 struct pipe_rasterizer_state rast
;
524 struct pipe_blend_state blend
;
525 struct pipe_depth_stencil_alpha_state dsa
;
530 memset(&rast
, 0, sizeof rast
);
532 rast
.flatshade_first
= 0;
533 rast
.light_twoside
= 0;
535 rast
.cull_face
= PIPE_FACE_NONE
;
536 rast
.fill_back
= PIPE_POLYGON_MODE_FILL
;
537 rast
.fill_front
= PIPE_POLYGON_MODE_FILL
;
538 rast
.offset_point
= 0;
539 rast
.offset_line
= 0;
541 rast
.poly_smooth
= 0;
542 rast
.poly_stipple_enable
= 0;
543 rast
.sprite_coord_enable
= 0;
544 rast
.point_size_per_vertex
= 0;
545 rast
.multisample
= 0;
546 rast
.line_smooth
= 0;
547 rast
.line_stipple_enable
= 0;
548 rast
.line_stipple_factor
= 0;
549 rast
.line_stipple_pattern
= 0;
550 rast
.line_last_pixel
= 0;
552 rast
.point_smooth
= 0;
553 rast
.point_quad_rasterization
= 0;
554 rast
.point_size_per_vertex
= 1;
555 rast
.offset_units
= 1;
556 rast
.offset_scale
= 1;
557 rast
.gl_rasterization_rules
= 1;
559 ctx
->rast
= ctx
->pipe
->create_rasterizer_state(ctx
->pipe
, &rast
);
560 ctx
->pipe
->bind_rasterizer_state(ctx
->pipe
, ctx
->rast
);
562 memset(&blend
, 0, sizeof blend
);
564 blend
.independent_blend_enable
= 0;
565 blend
.rt
[0].blend_enable
= 0;
566 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
567 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
568 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
569 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
570 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
571 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
572 blend
.logicop_enable
= 0;
573 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
574 /* Needed to allow color writes to FB, even if blending disabled */
575 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
577 ctx
->blend
= ctx
->pipe
->create_blend_state(ctx
->pipe
, &blend
);
578 ctx
->pipe
->bind_blend_state(ctx
->pipe
, ctx
->blend
);
580 memset(&dsa
, 0, sizeof dsa
);
581 dsa
.depth
.enabled
= 0;
582 dsa
.depth
.writemask
= 0;
583 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
584 for (i
= 0; i
< 2; ++i
) {
585 dsa
.stencil
[i
].enabled
= 0;
586 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
587 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
588 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
589 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
590 dsa
.stencil
[i
].valuemask
= 0;
591 dsa
.stencil
[i
].writemask
= 0;
593 dsa
.alpha
.enabled
= 0;
594 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
595 dsa
.alpha
.ref_value
= 0;
596 ctx
->dsa
= ctx
->pipe
->create_depth_stencil_alpha_state(ctx
->pipe
, &dsa
);
597 ctx
->pipe
->bind_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
603 init_idct(struct vl_mpeg12_context
*ctx
, unsigned buffer_width
, unsigned buffer_height
)
605 unsigned chroma_width
, chroma_height
, chroma_blocks_x
, chroma_blocks_y
;
606 struct pipe_resource
*idct_matrix
;
608 /* TODO: Implement 422, 444 */
609 assert(ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
610 ctx
->empty_block_mask
= &const_empty_block_mask_420
;
612 if (!(idct_matrix
= vl_idct_upload_matrix(ctx
->pipe
)))
615 if (!vl_idct_init(&ctx
->idct_y
, ctx
->pipe
, buffer_width
, buffer_height
,
616 2, 2, TGSI_SWIZZLE_X
, idct_matrix
))
619 if (ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
) {
620 chroma_width
= buffer_width
/ 2;
621 chroma_height
= buffer_height
/ 2;
624 } else if (ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_422
) {
625 chroma_width
= buffer_width
;
626 chroma_height
= buffer_height
/ 2;
630 chroma_width
= buffer_width
;
631 chroma_height
= buffer_height
;
636 if(!vl_idct_init(&ctx
->idct_cr
, ctx
->pipe
, chroma_width
, chroma_height
,
637 chroma_blocks_x
, chroma_blocks_y
, TGSI_SWIZZLE_Z
, idct_matrix
))
640 if(!vl_idct_init(&ctx
->idct_cb
, ctx
->pipe
, chroma_width
, chroma_height
,
641 chroma_blocks_x
, chroma_blocks_y
, TGSI_SWIZZLE_Y
, idct_matrix
))
647 struct pipe_video_context
*
648 vl_create_mpeg12_context(struct pipe_context
*pipe
,
649 enum pipe_video_profile profile
,
650 enum pipe_video_chroma_format chroma_format
,
651 unsigned width
, unsigned height
,
653 enum pipe_format decode_format
)
655 struct vl_mpeg12_context
*ctx
;
656 unsigned buffer_width
, buffer_height
;
658 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
660 ctx
= CALLOC_STRUCT(vl_mpeg12_context
);
665 ctx
->base
.profile
= profile
;
666 ctx
->base
.chroma_format
= chroma_format
;
667 ctx
->base
.width
= width
;
668 ctx
->base
.height
= height
;
670 ctx
->base
.screen
= pipe
->screen
;
672 ctx
->base
.destroy
= vl_mpeg12_destroy
;
673 ctx
->base
.get_param
= vl_mpeg12_get_param
;
674 ctx
->base
.is_format_supported
= vl_mpeg12_is_format_supported
;
675 ctx
->base
.create_surface
= vl_mpeg12_create_surface
;
676 ctx
->base
.decode_macroblocks
= vl_mpeg12_decode_macroblocks
;
677 ctx
->base
.render_picture
= vl_mpeg12_render_picture
;
678 ctx
->base
.clear_render_target
= vl_mpeg12_clear_render_target
;
679 ctx
->base
.resource_copy_region
= vl_mpeg12_resource_copy_region
;
680 ctx
->base
.get_transfer
= vl_mpeg12_get_transfer
;
681 ctx
->base
.transfer_destroy
= vl_mpeg12_transfer_destroy
;
682 ctx
->base
.transfer_map
= vl_mpeg12_transfer_map
;
683 ctx
->base
.transfer_flush_region
= vl_mpeg12_transfer_flush_region
;
684 ctx
->base
.transfer_unmap
= vl_mpeg12_transfer_unmap
;
685 if (pipe
->transfer_inline_write
)
686 ctx
->base
.transfer_inline_write
= vl_mpeg12_transfer_inline_write
;
687 ctx
->base
.set_picture_background
= vl_mpeg12_set_picture_background
;
688 ctx
->base
.set_picture_layers
= vl_mpeg12_set_picture_layers
;
689 ctx
->base
.set_decode_target
= vl_mpeg12_set_decode_target
;
690 ctx
->base
.set_csc_matrix
= vl_mpeg12_set_csc_matrix
;
693 ctx
->decode_format
= decode_format
;
695 ctx
->quads
= vl_vb_upload_quads(ctx
->pipe
, 2, 2);
696 ctx
->vertex_buffer_size
= width
/ MACROBLOCK_WIDTH
* height
/ MACROBLOCK_HEIGHT
;
697 ctx
->vertex_elems_state
= vl_vb_get_elems_state(ctx
->pipe
, true);
699 if (ctx
->vertex_elems_state
== NULL
) {
700 ctx
->pipe
->destroy(ctx
->pipe
);
705 /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
707 buffer_width
= pot_buffers
? util_next_power_of_two(width
) : width
;
708 buffer_height
= pot_buffers
? util_next_power_of_two(height
) : height
;
710 if (!init_idct(ctx
, buffer_width
, buffer_height
)) {
711 ctx
->pipe
->destroy(ctx
->pipe
);
716 if (!vl_mpeg12_mc_renderer_init(&ctx
->mc_renderer
, ctx
->pipe
,
717 buffer_width
, buffer_height
, chroma_format
)) {
718 vl_idct_cleanup(&ctx
->idct_y
);
719 vl_idct_cleanup(&ctx
->idct_cr
);
720 vl_idct_cleanup(&ctx
->idct_cb
);
721 ctx
->pipe
->destroy(ctx
->pipe
);
726 ctx
->buffer_map
= util_new_keymap(sizeof(unsigned), -1, delete_buffer
);
727 if (!ctx
->buffer_map
) {
728 vl_idct_cleanup(&ctx
->idct_y
);
729 vl_idct_cleanup(&ctx
->idct_cr
);
730 vl_idct_cleanup(&ctx
->idct_cb
);
731 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
732 ctx
->pipe
->destroy(ctx
->pipe
);
737 if (!vl_compositor_init(&ctx
->compositor
, ctx
->pipe
)) {
738 vl_idct_cleanup(&ctx
->idct_y
);
739 vl_idct_cleanup(&ctx
->idct_cr
);
740 vl_idct_cleanup(&ctx
->idct_cb
);
741 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
742 util_delete_keymap(ctx
->buffer_map
, ctx
);
743 ctx
->pipe
->destroy(ctx
->pipe
);
748 if (!init_pipe_state(ctx
)) {
749 vl_idct_cleanup(&ctx
->idct_y
);
750 vl_idct_cleanup(&ctx
->idct_cr
);
751 vl_idct_cleanup(&ctx
->idct_cb
);
752 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
753 util_delete_keymap(ctx
->buffer_map
, ctx
);
754 vl_compositor_cleanup(&ctx
->compositor
);
755 ctx
->pipe
->destroy(ctx
->pipe
);