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 <pipe/p_video_context.h>
30 #include <util/u_memory.h>
31 #include <util/u_rect.h>
32 #include <util/u_video.h>
34 #include "vl_context.h"
35 #include "vl_compositor.h"
36 #include "vl_mpeg12_decoder.h"
38 const enum pipe_format const_resource_formats_YV12
[3] = {
44 const enum pipe_format const_resource_formats_NV12
[3] = {
46 PIPE_FORMAT_R8G8_UNORM
,
51 vl_context_destroy(struct pipe_video_context
*context
)
53 struct vl_context
*ctx
= (struct vl_context
*)context
;
57 ctx
->pipe
->destroy(ctx
->pipe
);
63 vl_context_get_param(struct pipe_video_context
*context
, int param
)
65 struct vl_context
*ctx
= (struct vl_context
*)context
;
69 if (param
== PIPE_CAP_NPOT_TEXTURES
)
70 return !ctx
->pot_buffers
;
72 debug_printf("vl_context: Unknown PIPE_CAP %d\n", param
);
77 vl_context_is_format_supported(struct pipe_video_context
*context
,
78 enum pipe_format format
,
81 struct vl_context
*ctx
= (struct vl_context
*)context
;
85 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, format
,
90 static struct pipe_surface
*
91 vl_context_create_surface(struct pipe_video_context
*context
,
92 struct pipe_resource
*resource
,
93 const struct pipe_surface
*templ
)
95 struct vl_context
*ctx
= (struct vl_context
*)context
;
99 return ctx
->pipe
->create_surface(ctx
->pipe
, resource
, templ
);
102 static struct pipe_sampler_view
*
103 vl_context_create_sampler_view(struct pipe_video_context
*context
,
104 struct pipe_resource
*resource
,
105 const struct pipe_sampler_view
*templ
)
107 struct vl_context
*ctx
= (struct vl_context
*)context
;
111 return ctx
->pipe
->create_sampler_view(ctx
->pipe
, resource
, templ
);
115 vl_context_upload_sampler(struct pipe_video_context
*context
,
116 struct pipe_sampler_view
*dst
,
117 const struct pipe_box
*dst_box
,
118 const void *src
, unsigned src_stride
,
119 unsigned src_x
, unsigned src_y
)
121 struct vl_context
*ctx
= (struct vl_context
*)context
;
122 struct pipe_transfer
*transfer
;
130 transfer
= ctx
->pipe
->get_transfer(ctx
->pipe
, dst
->texture
, 0, PIPE_TRANSFER_WRITE
, dst_box
);
134 map
= ctx
->pipe
->transfer_map(ctx
->pipe
, transfer
);
138 util_copy_rect(map
, dst
->texture
->format
, transfer
->stride
, 0, 0,
139 dst_box
->width
, dst_box
->height
,
140 src
, src_stride
, src_x
, src_y
);
142 ctx
->pipe
->transfer_unmap(ctx
->pipe
, transfer
);
145 ctx
->pipe
->transfer_destroy(ctx
->pipe
, transfer
);
149 vl_context_clear_sampler(struct pipe_video_context
*context
,
150 struct pipe_sampler_view
*dst
,
151 const struct pipe_box
*dst_box
,
154 struct vl_context
*ctx
= (struct vl_context
*)context
;
155 struct pipe_transfer
*transfer
;
165 transfer
= ctx
->pipe
->get_transfer(ctx
->pipe
, dst
->texture
, 0, PIPE_TRANSFER_WRITE
, dst_box
);
169 map
= ctx
->pipe
->transfer_map(ctx
->pipe
, transfer
);
173 for ( i
= 0; i
< 4; ++i
)
176 util_fill_rect(map
, dst
->texture
->format
, transfer
->stride
, 0, 0,
177 dst_box
->width
, dst_box
->height
, &uc
);
179 ctx
->pipe
->transfer_unmap(ctx
->pipe
, transfer
);
182 ctx
->pipe
->transfer_destroy(ctx
->pipe
, transfer
);
185 static struct pipe_video_decoder
*
186 vl_context_create_decoder(struct pipe_video_context
*context
,
187 enum pipe_video_profile profile
,
188 enum pipe_video_entrypoint entrypoint
,
189 enum pipe_video_chroma_format chroma_format
,
190 unsigned width
, unsigned height
)
192 struct vl_context
*ctx
= (struct vl_context
*)context
;
193 unsigned buffer_width
, buffer_height
;
196 assert(width
> 0 && height
> 0);
198 buffer_width
= ctx
->pot_buffers
? util_next_power_of_two(width
) : align(width
, MACROBLOCK_WIDTH
);
199 buffer_height
= ctx
->pot_buffers
? util_next_power_of_two(height
) : align(height
, MACROBLOCK_HEIGHT
);
201 switch (u_reduce_video_profile(profile
)) {
202 case PIPE_VIDEO_CODEC_MPEG12
:
203 return vl_create_mpeg12_decoder(context
, ctx
->pipe
, profile
, entrypoint
,
204 chroma_format
, buffer_width
, buffer_height
);
211 static struct pipe_video_buffer
*
212 vl_context_create_buffer(struct pipe_video_context
*context
,
213 enum pipe_format buffer_format
,
214 enum pipe_video_chroma_format chroma_format
,
215 unsigned width
, unsigned height
)
217 struct vl_context
*ctx
= (struct vl_context
*)context
;
218 struct pipe_video_buffer
*result
;
219 unsigned buffer_width
, buffer_height
;
221 const enum pipe_format
*resource_formats
;
224 assert(width
> 0 && height
> 0);
226 switch(buffer_format
) {
227 case PIPE_FORMAT_YV12
:
228 resource_formats
= const_resource_formats_YV12
;
231 case PIPE_FORMAT_NV12
:
232 resource_formats
= const_resource_formats_NV12
;
240 buffer_width
= ctx
->pot_buffers
? util_next_power_of_two(width
) : align(width
, MACROBLOCK_WIDTH
);
241 buffer_height
= ctx
->pot_buffers
? util_next_power_of_two(height
) : align(height
, MACROBLOCK_HEIGHT
);
243 result
= vl_video_buffer_init(context
, ctx
->pipe
,
244 buffer_width
, buffer_height
, 1,
248 if (result
) // TODO move format handling into vl_video_buffer
249 result
->buffer_format
= buffer_format
;
254 static struct pipe_video_compositor
*
255 vl_context_create_compositor(struct pipe_video_context
*context
)
257 struct vl_context
*ctx
= (struct vl_context
*)context
;
261 return vl_compositor_init(context
, ctx
->pipe
);
264 struct pipe_video_context
*
265 vl_create_context(struct pipe_context
*pipe
, bool pot_buffers
)
267 struct vl_context
*ctx
;
269 ctx
= CALLOC_STRUCT(vl_context
);
274 ctx
->base
.screen
= pipe
->screen
;
276 ctx
->base
.destroy
= vl_context_destroy
;
277 ctx
->base
.get_param
= vl_context_get_param
;
278 ctx
->base
.is_format_supported
= vl_context_is_format_supported
;
279 ctx
->base
.create_surface
= vl_context_create_surface
;
280 ctx
->base
.create_sampler_view
= vl_context_create_sampler_view
;
281 ctx
->base
.clear_sampler
= vl_context_clear_sampler
;
282 ctx
->base
.upload_sampler
= vl_context_upload_sampler
;
283 ctx
->base
.create_decoder
= vl_context_create_decoder
;
284 ctx
->base
.create_buffer
= vl_context_create_buffer
;
285 ctx
->base
.create_compositor
= vl_context_create_compositor
;
288 ctx
->pot_buffers
= pot_buffers
;