1 #include "vl_surface.h"
4 #include <pipe/p_context.h>
5 #include <pipe/p_state.h>
6 #include <pipe/p_format.h>
7 #include <pipe/p_inlines.h>
8 #include "vl_context.h"
11 static int vlGrabBlocks
13 struct VL_CONTEXT
*context
,
14 unsigned int coded_block_pattern
,
15 enum VL_DCT_TYPE dct_type
,
16 enum VL_SAMPLE_TYPE sample_type
,
20 struct pipe_surface
*tex_surface
;
22 unsigned int b
, x
, y
, y2
;
27 tex_surface
= context
->pipe
->screen
->get_tex_surface
29 context
->pipe
->screen
,
30 context
->states
.mc
.textures
[0],
31 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
34 texels
= pipe_surface_map(tex_surface
, 0);
36 for (b
= 0; b
< 4; ++b
)
38 if ((coded_block_pattern
>> b
) & 1)
40 if (dct_type
== VL_DCT_FRAME_CODED
)
42 if (sample_type
== VL_FULL_SAMPLE
)
44 for (y
= VL_BLOCK_HEIGHT
* b
; y
< VL_BLOCK_HEIGHT
* (b
+ 1); ++y
)
47 texels
+ y
* tex_surface
->pitch
,
48 blocks
+ y
* VL_BLOCK_WIDTH
,
54 for (y
= VL_BLOCK_HEIGHT
* b
; y
< VL_BLOCK_HEIGHT
* (b
+ 1); ++y
)
55 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
56 texels
[y
* tex_surface
->pitch
+ x
] =
57 blocks
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
62 if (sample_type
== VL_FULL_SAMPLE
)
66 y
= VL_BLOCK_HEIGHT
* (b
% 2), y2
= VL_BLOCK_HEIGHT
* b
;
67 y
< VL_BLOCK_HEIGHT
* ((b
% 2) + 1);
72 texels
+ y
* tex_surface
->pitch
,
73 blocks
+ y2
* VL_BLOCK_WIDTH
,
78 y
= VL_BLOCK_HEIGHT
* ((b
% 2) + 2);
79 y
< VL_BLOCK_HEIGHT
* (((b
% 2) + 2) + 1);
84 texels
+ y
* tex_surface
->pitch
,
85 blocks
+ y2
* VL_BLOCK_WIDTH
,
93 y
= VL_BLOCK_HEIGHT
* (b
% 2), y2
= VL_BLOCK_HEIGHT
* b
;
94 y
< VL_BLOCK_HEIGHT
* ((b
% 2) + 1);
97 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
98 texels
[y
* tex_surface
->pitch
+ x
] =
99 blocks
[y2
* VL_BLOCK_WIDTH
+ x
] + 0x100;
102 y
= VL_BLOCK_HEIGHT
* ((b
% 2) + 2);
103 y
< VL_BLOCK_HEIGHT
* (((b
% 2) + 2) + 1);
106 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
107 texels
[y
* tex_surface
->pitch
+ x
] =
108 blocks
[y2
* VL_BLOCK_WIDTH
+ x
] + 0x100;
114 for (y
= VL_BLOCK_HEIGHT
* b
; y
< VL_BLOCK_HEIGHT
* (b
+ 1); ++y
)
116 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
117 texels
[y
* tex_surface
->pitch
+ x
] = 0x100;
122 pipe_surface_unmap(tex_surface
);
124 /* TODO: Implement 422, 444 */
125 for (b
= 0; b
< 2; ++b
)
127 tex_surface
= context
->pipe
->screen
->get_tex_surface
129 context
->pipe
->screen
,
130 context
->states
.mc
.textures
[b
+ 1],
131 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
134 texels
= pipe_surface_map(tex_surface
, 0);
136 if ((coded_block_pattern
>> (b
+ 4)) & 1)
138 if (sample_type
== VL_FULL_SAMPLE
)
140 for (y
= 0; y
< tex_surface
->height
; ++y
)
143 texels
+ y
* tex_surface
->pitch
,
144 blocks
+ VL_BLOCK_SIZE
* (b
+ 4) + y
* VL_BLOCK_WIDTH
,
150 for (y
= 0; y
< tex_surface
->height
; ++y
)
151 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
152 texels
[y
* tex_surface
->pitch
+ x
] =
153 blocks
[VL_BLOCK_SIZE
* (b
+ 4) + y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
158 for (y
= 0; y
< tex_surface
->height
; ++y
)
160 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
161 texels
[y
* tex_surface
->pitch
+ x
] = 0x100;
165 pipe_surface_unmap(tex_surface
);
171 int vlCreateSurface(struct VL_CONTEXT
*context
, struct VL_SURFACE
**surface
)
173 struct pipe_context
*pipe
;
174 struct pipe_texture
template;
175 struct VL_SURFACE
*sfc
;
180 pipe
= context
->pipe
;
182 sfc
= calloc(1, sizeof(struct VL_SURFACE
));
184 sfc
->context
= context
;
185 sfc
->width
= context
->video_width
;
186 sfc
->height
= context
->video_height
;
187 sfc
->format
= context
->video_format
;
189 memset(&template, 0, sizeof(struct pipe_texture
));
190 template.target
= PIPE_TEXTURE_2D
;
191 template.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
192 template.last_level
= 0;
193 template.width
[0] = sfc
->width
;
194 template.height
[0] = sfc
->height
;
195 template.depth
[0] = 1;
196 template.compressed
= 0;
199 sfc
->texture
= pipe
->screen
->texture_create(pipe
->screen
, &template);
206 int vlDestroySurface(struct VL_SURFACE
*surface
)
209 pipe_texture_release(&surface
->texture
);
215 int vlRenderIMacroBlock
217 enum VL_PICTURE picture_type
,
218 enum VL_FIELD_ORDER field_order
,
221 unsigned int coded_block_pattern
,
222 enum VL_DCT_TYPE dct_type
,
224 struct VL_SURFACE
*surface
227 struct pipe_context
*pipe
;
228 struct VL_MC_VS_CONSTS
*vscbdata
;
233 /* TODO: Implement interlaced rendering */
234 /*assert(picture_type == VL_FRAME_PICTURE);*/
235 if (picture_type
!= VL_FRAME_PICTURE
)
237 /*fprintf(stderr, "field picture (I) unimplemented, ignoring\n");*/
241 pipe
= surface
->context
->pipe
;
243 vscbdata
= pipe
->winsys
->buffer_map
246 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
247 PIPE_BUFFER_USAGE_CPU_WRITE
250 vscbdata
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
251 vscbdata
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
252 vscbdata
->scale
.z
= 1.0f
;
253 vscbdata
->scale
.w
= 1.0f
;
254 vscbdata
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
255 vscbdata
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
256 vscbdata
->mb_pos_trans
.z
= 0.0f
;
257 vscbdata
->mb_pos_trans
.w
= 0.0f
;
259 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
261 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_FULL_SAMPLE
, blocks
);
263 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
267 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
269 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
270 pipe
->set_sampler_textures(pipe
, 3, surface
->context
->states
.mc
.textures
);
271 pipe
->bind_sampler_states(pipe
, 3, (void**)surface
->context
->states
.mc
.samplers
);
272 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.i_vs
);
273 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.i_fs
);
275 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
280 int vlRenderPMacroBlock
282 enum VL_PICTURE picture_type
,
283 enum VL_FIELD_ORDER field_order
,
286 enum VL_MC_TYPE mc_type
,
287 struct VL_MOTION_VECTOR
*motion_vector
,
288 unsigned int coded_block_pattern
,
289 enum VL_DCT_TYPE dct_type
,
291 struct VL_SURFACE
*ref_surface
,
292 struct VL_SURFACE
*surface
295 struct pipe_context
*pipe
;
296 struct VL_MC_VS_CONSTS
*vscbdata
;
298 assert(motion_vectors
);
303 /* TODO: Implement interlaced rendering */
304 /*assert(picture_type == VL_FRAME_PICTURE);*/
305 if (picture_type
!= VL_FRAME_PICTURE
)
307 /*fprintf(stderr, "field picture (P) unimplemented, ignoring\n");*/
310 /* TODO: Implement field based motion compensation */
311 /*assert(mc_type == VL_FRAME_MC);*/
312 if (mc_type
!= VL_FRAME_MC
)
314 /*fprintf(stderr, "field MC (P) unimplemented, ignoring\n");*/
318 pipe
= surface
->context
->pipe
;
320 vscbdata
= pipe
->winsys
->buffer_map
323 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
324 PIPE_BUFFER_USAGE_CPU_WRITE
327 vscbdata
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
328 vscbdata
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
329 vscbdata
->scale
.z
= 1.0f
;
330 vscbdata
->scale
.w
= 1.0f
;
331 vscbdata
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
332 vscbdata
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
333 vscbdata
->mb_pos_trans
.z
= 0.0f
;
334 vscbdata
->mb_pos_trans
.w
= 0.0f
;
335 vscbdata
->mb_tc_trans
[0].x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->top_field
.x
* 0.5f
) / (float)surface
->width
;
336 vscbdata
->mb_tc_trans
[0].y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->top_field
.y
* 0.5f
) / (float)surface
->height
;
337 vscbdata
->mb_tc_trans
[0].z
= 0.0f
;
338 vscbdata
->mb_tc_trans
[0].w
= 0.0f
;
340 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
342 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
344 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
348 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
350 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
352 surface
->context
->states
.mc
.textures
[3] = ref_surface
->texture
;
353 pipe
->set_sampler_textures(pipe
, 4, surface
->context
->states
.mc
.textures
);
354 pipe
->bind_sampler_states(pipe
, 4, (void**)surface
->context
->states
.mc
.samplers
);
355 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
);
356 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
);
358 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
363 int vlRenderBMacroBlock
365 enum VL_PICTURE picture_type
,
366 enum VL_FIELD_ORDER field_order
,
369 enum VL_MC_TYPE mc_type
,
370 struct VL_MOTION_VECTOR
*motion_vector
,
371 unsigned int coded_block_pattern
,
372 enum VL_DCT_TYPE dct_type
,
374 struct VL_SURFACE
*past_surface
,
375 struct VL_SURFACE
*future_surface
,
376 struct VL_SURFACE
*surface
379 struct pipe_context
*pipe
;
380 struct VL_MC_VS_CONSTS
*vscbdata
;
382 assert(motion_vectors
);
387 /* TODO: Implement interlaced rendering */
388 /*assert(picture_type == VL_FRAME_PICTURE);*/
389 if (picture_type
!= VL_FRAME_PICTURE
)
391 /*fprintf(stderr, "field picture (B) unimplemented, ignoring\n");*/
394 /* TODO: Implement field based motion compensation */
395 /*assert(mc_type == VL_FRAME_MC);*/
396 if (mc_type
!= VL_FRAME_MC
)
398 /*fprintf(stderr, "field MC (B) unimplemented, ignoring\n");*/
402 pipe
= surface
->context
->pipe
;
404 vscbdata
= pipe
->winsys
->buffer_map
407 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
408 PIPE_BUFFER_USAGE_CPU_WRITE
411 vscbdata
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
412 vscbdata
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
413 vscbdata
->scale
.z
= 1.0f
;
414 vscbdata
->scale
.w
= 1.0f
;
415 vscbdata
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
416 vscbdata
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
417 vscbdata
->mb_pos_trans
.z
= 0.0f
;
418 vscbdata
->mb_pos_trans
.w
= 0.0f
;
419 vscbdata
->mb_tc_trans
[0].x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].top_field
.x
* 0.5f
) / (float)surface
->width
;
420 vscbdata
->mb_tc_trans
[0].y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].top_field
.y
* 0.5f
) / (float)surface
->height
;
421 vscbdata
->mb_tc_trans
[0].z
= 0.0f
;
422 vscbdata
->mb_tc_trans
[0].w
= 0.0f
;
423 vscbdata
->mb_tc_trans
[1].x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].top_field
.x
* 0.5f
) / (float)surface
->width
;
424 vscbdata
->mb_tc_trans
[1].y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].top_field
.y
* 0.5f
) / (float)surface
->height
;
425 vscbdata
->mb_tc_trans
[1].z
= 0.0f
;
426 vscbdata
->mb_tc_trans
[1].w
= 0.0f
;
428 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
430 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
432 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
436 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
438 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
440 surface
->context
->states
.mc
.textures
[3] = past_surface
->texture
;
441 surface
->context
->states
.mc
.textures
[4] = future_surface
->texture
;
442 pipe
->set_sampler_textures(pipe
, 5, surface
->context
->states
.mc
.textures
);
443 pipe
->bind_sampler_states(pipe
, 5, (void**)surface
->context
->states
.mc
.samplers
);
444 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
);
445 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
);
447 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
454 struct VL_SURFACE
*surface
,
464 enum VL_PICTURE picture_type
467 unsigned int create_fb
= 0;
468 struct pipe_context
*pipe
;
472 pipe
= surface
->context
->pipe
;
474 if (!surface
->context
->states
.csc
.framebuffer
.cbufs
[0])
478 surface
->context
->states
.csc
.framebuffer
.width
!= destw
||
479 surface
->context
->states
.csc
.framebuffer
.height
!= desth
482 pipe
->winsys
->surface_release
485 &surface
->context
->states
.csc
.framebuffer
.cbufs
[0]
493 surface
->context
->states
.csc
.viewport
.scale
[0] = destw
;
494 surface
->context
->states
.csc
.viewport
.scale
[1] = desth
;
495 surface
->context
->states
.csc
.viewport
.scale
[2] = 1;
496 surface
->context
->states
.csc
.viewport
.scale
[3] = 1;
497 surface
->context
->states
.csc
.viewport
.translate
[0] = 0;
498 surface
->context
->states
.csc
.viewport
.translate
[1] = 0;
499 surface
->context
->states
.csc
.viewport
.translate
[2] = 0;
500 surface
->context
->states
.csc
.viewport
.translate
[3] = 0;
502 surface
->context
->states
.csc
.framebuffer
.width
= destw
;
503 surface
->context
->states
.csc
.framebuffer
.height
= desth
;
504 surface
->context
->states
.csc
.framebuffer
.cbufs
[0] = pipe
->winsys
->surface_alloc(pipe
->winsys
);
505 pipe
->winsys
->surface_alloc_storage
508 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
511 PIPE_FORMAT_A8R8G8B8_UNORM
,
512 PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
,
517 vlEndRender(surface
->context
);
519 pipe
->set_sampler_textures(pipe
, 1, &surface
->texture
);
520 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLE_STRIP
, 0, 4);
521 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
522 pipe
->winsys
->flush_frontbuffer
525 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
529 vlBeginRender(surface
->context
);