g3dvl: Add support for field sampler view planes in pipe_video_buffer
[mesa/nouveau-pmpeg.git] / src / gallium / state_trackers / vdpau / mixer.c
blobca7266ce8ac97ab77f8cde3f821d85add1e01029
1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen.
4 * All Rights Reserved.
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
16 * of the Software.
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 <vdpau/vdpau.h>
30 #include "util/u_memory.h"
31 #include "util/u_debug.h"
33 #include "vl/vl_csc.h"
35 #include "vdpau_private.h"
37 /**
38 * Create a VdpVideoMixer.
40 VdpStatus
41 vlVdpVideoMixerCreate(VdpDevice device,
42 uint32_t feature_count,
43 VdpVideoMixerFeature const *features,
44 uint32_t parameter_count,
45 VdpVideoMixerParameter const *parameters,
46 void const *const *parameter_values,
47 VdpVideoMixer *mixer)
49 vlVdpVideoMixer *vmixer = NULL;
50 VdpStatus ret;
51 struct pipe_screen *screen;
52 unsigned max_width, max_height, i;
53 enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
55 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating VideoMixer\n");
57 vlVdpDevice *dev = vlGetDataHTAB(device);
58 if (!dev)
59 return VDP_STATUS_INVALID_HANDLE;
60 screen = dev->vscreen->pscreen;
62 vmixer = CALLOC(1, sizeof(vlVdpVideoMixer));
63 if (!vmixer)
64 return VDP_STATUS_RESOURCES;
66 vmixer->device = dev;
69 * TODO: Handle features
72 *mixer = vlAddDataHTAB(vmixer);
73 if (*mixer == 0) {
74 ret = VDP_STATUS_ERROR;
75 goto no_handle;
77 vmixer->chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
78 ret = VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
79 for (i = 0; i < parameter_count; ++i) {
80 switch (parameters[i]) {
81 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
82 vmixer->video_width = *(uint32_t*)parameter_values[i];
83 break;
84 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
85 vmixer->video_height = *(uint32_t*)parameter_values[i];
86 break;
87 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
88 vmixer->chroma_format = ChromaToPipe(*(VdpChromaType*)parameter_values[i]);
89 break;
90 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
91 vmixer->max_layers = *(uint32_t*)parameter_values[i];
92 break;
93 default: goto no_params;
96 ret = VDP_STATUS_INVALID_VALUE;
97 if (vmixer->max_layers > 4) {
98 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Max layers > 4 not supported\n", vmixer->max_layers);
99 goto no_params;
101 max_width = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
102 max_height = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
103 if (vmixer->video_width < 48 ||
104 vmixer->video_width > max_width) {
105 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for width\n", vmixer->video_width, max_width);
106 goto no_params;
108 if (vmixer->video_height < 48 ||
109 vmixer->video_height > max_height) {
110 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for height\n", vmixer->video_height, max_height);
111 goto no_params;
113 vmixer->luma_key_min = 0.f;
114 vmixer->luma_key_max = 1.f;
115 vmixer->noise_reduction_level = 0.f;
116 vmixer->sharpness = 0.f;
118 ret = VDP_STATUS_RESOURCES;
119 if (!vl_compositor_init_video(&vmixer->compositor, dev->context->pipe, vmixer->chroma_format, vmixer->video_width, vmixer->video_height))
120 goto no_resources;
122 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, vmixer->csc);
123 if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
124 vl_compositor_set_csc_matrix(&vmixer->compositor, vmixer->csc);
126 return VDP_STATUS_OK;
128 no_resources:
129 no_params:
130 vlRemoveDataHTAB(*mixer);
131 no_handle:
132 FREE(vmixer);
133 return ret;
137 * Destroy a VdpVideoMixer.
139 VdpStatus
140 vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
142 vlVdpVideoMixer *vmixer;
144 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Destroying VideoMixer\n");
146 vmixer = vlGetDataHTAB(mixer);
147 if (!vmixer)
148 return VDP_STATUS_INVALID_HANDLE;
149 vlRemoveDataHTAB(mixer);
151 vl_compositor_cleanup(&vmixer->compositor);
153 FREE(vmixer);
155 return VDP_STATUS_OK;
159 * Enable or disable features.
161 VdpStatus
162 vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
163 uint32_t feature_count,
164 VdpVideoMixerFeature const *features,
165 VdpBool const *feature_enables)
167 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Setting VideoMixer features\n");
169 if (!(features && feature_enables))
170 return VDP_STATUS_INVALID_POINTER;
172 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
173 if (!vmixer)
174 return VDP_STATUS_INVALID_HANDLE;
177 * TODO: Set features
180 return VDP_STATUS_OK;
183 static VdpStatus
184 vl_check_video_surface(vlVdpVideoMixer *mixer, vlVdpSurface *surf)
186 if (surf->device != mixer->device)
187 return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
188 if (mixer->video_width != surf->video_buffer->width ||
189 mixer->video_height != surf->video_buffer->height ||
190 mixer->chroma_format != surf->video_buffer->chroma_format)
191 return VDP_STATUS_INVALID_SIZE;
192 return VDP_STATUS_OK;
196 * Perform a video post-processing and compositing operation.
198 VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
199 VdpOutputSurface background_surface,
200 VdpRect const *background_source_rect,
201 VdpVideoMixerPictureStructure current_picture_structure,
202 uint32_t video_surface_past_count,
203 VdpVideoSurface const *video_surface_past,
204 VdpVideoSurface video_surface_current,
205 uint32_t video_surface_future_count,
206 VdpVideoSurface const *video_surface_future,
207 VdpRect const *video_source_rect,
208 VdpOutputSurface destination_surface,
209 VdpRect const *destination_rect,
210 VdpRect const *destination_video_rect,
211 uint32_t layer_count,
212 VdpLayer const *layers)
214 struct pipe_video_rect src_rect, dst_rect;
215 VdpStatus ret;
217 vlVdpVideoMixer *vmixer;
218 vlVdpSurface *surf;
219 vlVdpOutputSurface *dst, *bg;
220 unsigned layer = 0;
222 vmixer = vlGetDataHTAB(mixer);
223 if (!vmixer)
224 return VDP_STATUS_INVALID_HANDLE;
226 surf = vlGetDataHTAB(video_surface_current);
227 if (!surf)
228 return VDP_STATUS_INVALID_HANDLE;
229 ret = vl_check_video_surface(vmixer, surf);
230 if (ret)
231 return ret;
232 if (layer_count > vmixer->max_layers)
233 return VDP_STATUS_INVALID_VALUE;
235 dst = vlGetDataHTAB(destination_surface);
236 if (!dst)
237 return VDP_STATUS_INVALID_HANDLE;
239 vl_compositor_clear_layers(&vmixer->compositor);
240 vl_compositor_reset_dirty_area(&vmixer->compositor);
241 if (background_surface != VDP_INVALID_HANDLE) {
242 bg = vlGetDataHTAB(background_surface);
243 if (!bg)
244 return VDP_STATUS_INVALID_HANDLE;
245 vl_compositor_set_rgba_layer(&vmixer->compositor, layer++, bg->sampler_view,
246 RectToPipe(background_source_rect, &src_rect), NULL);
248 vl_compositor_set_buffer_layer(&vmixer->compositor, layer, surf->video_buffer,
249 RectToPipe(video_source_rect, &src_rect),
250 RectToPipe(destination_video_rect, &dst_rect));
251 vl_compositor_render(&vmixer->compositor, dst->surface, NULL,
252 RectToPipe(destination_rect, &dst_rect), !layer);
254 assert(!layer_count);
255 return VDP_STATUS_OK;
259 * Set attribute values.
261 VdpStatus
262 vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
263 uint32_t attribute_count,
264 VdpVideoMixerAttribute const *attributes,
265 void const *const *attribute_values)
267 const VdpColor *background_color;
268 union pipe_color_union color;
269 const float *vdp_csc;
270 float val;
271 unsigned i;
273 if (!(attributes && attribute_values))
274 return VDP_STATUS_INVALID_POINTER;
276 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
277 if (!vmixer)
278 return VDP_STATUS_INVALID_HANDLE;
280 for (i = 0; i < attribute_count; ++i) {
281 switch (attributes[i]) {
282 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
283 background_color = attribute_values[i];
284 color.f[0] = background_color->red;
285 color.f[1] = background_color->green;
286 color.f[2] = background_color->blue;
287 color.f[3] = background_color->alpha;
288 vl_compositor_set_clear_color(&vmixer->compositor, &color);
289 break;
290 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
291 vdp_csc = attribute_values[i];
292 vmixer->custom_csc = !!vdp_csc;
293 if (!vdp_csc)
294 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, vmixer->csc);
295 else
296 memcpy(vmixer->csc, vdp_csc, sizeof(float)*12);
297 if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
298 vl_compositor_set_csc_matrix(&vmixer->compositor, vmixer->csc);
299 break;
300 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
301 val = *(float*)attribute_values[i];
302 if (val < 0.f || val > 1.f)
303 return VDP_STATUS_INVALID_VALUE;
304 vmixer->noise_reduction_level = val;
305 break;
306 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
307 val = *(float*)attribute_values[i];
308 if (val < 0.f || val > 1.f)
309 return VDP_STATUS_INVALID_VALUE;
310 vmixer->luma_key_min = val;
311 break;
312 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
313 val = *(float*)attribute_values[i];
314 if (val < 0.f || val > 1.f)
315 return VDP_STATUS_INVALID_VALUE;
316 vmixer->luma_key_max = val;
317 break;
318 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
319 val = *(float*)attribute_values[i];
320 if (val < -1.f || val > 1.f)
321 return VDP_STATUS_INVALID_VALUE;
322 vmixer->sharpness = val;
323 break;
324 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
325 if (*(uint8_t*)attribute_values[i] > 1)
326 return VDP_STATUS_INVALID_VALUE;
327 vmixer->skip_chroma_deint = *(uint8_t*)attribute_values[i];
328 break;
329 default:
330 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
334 return VDP_STATUS_OK;
338 * Retrieve whether features were requested at creation time.
340 VdpStatus
341 vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer,
342 uint32_t feature_count,
343 VdpVideoMixerFeature const *features,
344 VdpBool *feature_supports)
346 return VDP_STATUS_NO_IMPLEMENTATION;
350 * Retrieve whether features are enabled.
352 VdpStatus
353 vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer,
354 uint32_t feature_count,
355 VdpVideoMixerFeature const *features,
356 VdpBool *feature_enables)
358 return VDP_STATUS_NO_IMPLEMENTATION;
362 * Retrieve parameter values given at creation time.
364 VdpStatus
365 vlVdpVideoMixerGetParameterValues(VdpVideoMixer mixer,
366 uint32_t parameter_count,
367 VdpVideoMixerParameter const *parameters,
368 void *const *parameter_values)
370 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
371 unsigned i;
372 if (!vmixer)
373 return VDP_STATUS_INVALID_HANDLE;
375 if (!parameter_count)
376 return VDP_STATUS_OK;
377 if (!(parameters && parameter_values))
378 return VDP_STATUS_INVALID_POINTER;
379 for (i = 0; i < parameter_count; ++i) {
380 switch (parameters[i]) {
381 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
382 *(uint32_t*)parameter_values[i] = vmixer->video_width;
383 break;
384 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
385 *(uint32_t*)parameter_values[i] = vmixer->video_height;
386 break;
387 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
388 *(VdpChromaType*)parameter_values[i] = PipeToChroma(vmixer->chroma_format);
389 break;
390 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
391 *(uint32_t*)parameter_values[i] = vmixer->max_layers;
392 break;
393 default:
394 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
397 return VDP_STATUS_OK;
401 * Retrieve current attribute values.
403 VdpStatus
404 vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer,
405 uint32_t attribute_count,
406 VdpVideoMixerAttribute const *attributes,
407 void *const *attribute_values)
409 unsigned i;
410 VdpCSCMatrix **vdp_csc;
412 if (!(attributes && attribute_values))
413 return VDP_STATUS_INVALID_POINTER;
415 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
416 if (!vmixer)
417 return VDP_STATUS_INVALID_HANDLE;
419 for (i = 0; i < attribute_count; ++i) {
420 switch (attributes[i]) {
421 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
422 vl_compositor_get_clear_color(&vmixer->compositor, attribute_values[i]);
423 break;
424 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
425 vdp_csc = attribute_values[i];
426 if (!vmixer->custom_csc) {
427 *vdp_csc = NULL;
428 break;
430 memcpy(*vdp_csc, vmixer->csc, sizeof(float)*12);
431 break;
432 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
433 *(float*)attribute_values[i] = vmixer->noise_reduction_level;
434 break;
435 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
436 *(float*)attribute_values[i] = vmixer->luma_key_min;
437 break;
438 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
439 *(float*)attribute_values[i] = vmixer->luma_key_max;
440 break;
441 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
442 *(float*)attribute_values[i] = vmixer->sharpness;
443 break;
444 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
445 *(uint8_t*)attribute_values[i] = vmixer->skip_chroma_deint;
446 break;
447 default:
448 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
451 return VDP_STATUS_OK;
455 * Generate a color space conversion matrix.
457 VdpStatus
458 vlVdpGenerateCSCMatrix(VdpProcamp *procamp,
459 VdpColorStandard standard,
460 VdpCSCMatrix *csc_matrix)
462 float matrix[16];
463 enum VL_CSC_COLOR_STANDARD vl_std;
464 struct vl_procamp camp;
466 if (!(csc_matrix && procamp))
467 return VDP_STATUS_INVALID_POINTER;
469 if (procamp->struct_version > VDP_PROCAMP_VERSION)
470 return VDP_STATUS_INVALID_STRUCT_VERSION;
472 switch (standard) {
473 case VDP_COLOR_STANDARD_ITUR_BT_601: vl_std = VL_CSC_COLOR_STANDARD_BT_601; break;
474 case VDP_COLOR_STANDARD_ITUR_BT_709: vl_std = VL_CSC_COLOR_STANDARD_BT_709; break;
475 case VDP_COLOR_STANDARD_SMPTE_240M: vl_std = VL_CSC_COLOR_STANDARD_SMPTE_240M; break;
476 default: return VDP_STATUS_INVALID_COLOR_STANDARD;
478 camp.brightness = procamp->brightness;
479 camp.contrast = procamp->contrast;
480 camp.saturation = procamp->saturation;
481 camp.hue = procamp->hue;
482 vl_csc_get_matrix(vl_std, &camp, 1, matrix);
483 memcpy(csc_matrix, matrix, sizeof(float)*12);
484 return VDP_STATUS_OK;