1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen.
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 <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"
38 * Create a VdpVideoMixer.
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
,
49 vlVdpVideoMixer
*vmixer
= NULL
;
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
);
59 return VDP_STATUS_INVALID_HANDLE
;
60 screen
= dev
->vscreen
->pscreen
;
62 vmixer
= CALLOC(1, sizeof(vlVdpVideoMixer
));
64 return VDP_STATUS_RESOURCES
;
67 vl_compositor_init(&vmixer
->compositor
, dev
->context
->pipe
);
69 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, true, vmixer
->csc
);
70 if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE
))
71 vl_compositor_set_csc_matrix(&vmixer
->compositor
, vmixer
->csc
);
73 *mixer
= vlAddDataHTAB(vmixer
);
75 ret
= VDP_STATUS_ERROR
;
79 ret
= VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE
;
80 for (i
= 0; i
< feature_count
; ++i
) {
81 switch (features
[i
]) {
82 /* they are valid, but we doesn't support them */
83 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL
:
84 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL
:
85 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1
:
86 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2
:
87 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3
:
88 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4
:
89 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5
:
90 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6
:
91 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7
:
92 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8
:
93 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9
:
94 case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE
:
95 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY
:
96 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS
:
99 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION
:
100 vmixer
->noise_reduction
.supported
= true;
103 default: goto no_params
;
107 vmixer
->chroma_format
= PIPE_VIDEO_CHROMA_FORMAT_420
;
108 ret
= VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER
;
109 for (i
= 0; i
< parameter_count
; ++i
) {
110 switch (parameters
[i
]) {
111 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH
:
112 vmixer
->video_width
= *(uint32_t*)parameter_values
[i
];
114 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT
:
115 vmixer
->video_height
= *(uint32_t*)parameter_values
[i
];
117 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE
:
118 vmixer
->chroma_format
= ChromaToPipe(*(VdpChromaType
*)parameter_values
[i
]);
120 case VDP_VIDEO_MIXER_PARAMETER_LAYERS
:
121 vmixer
->max_layers
= *(uint32_t*)parameter_values
[i
];
123 default: goto no_params
;
126 ret
= VDP_STATUS_INVALID_VALUE
;
127 if (vmixer
->max_layers
> 4) {
128 VDPAU_MSG(VDPAU_TRACE
, "[VDPAU] Max layers > 4 not supported\n", vmixer
->max_layers
);
131 max_width
= screen
->get_video_param(screen
, prof
, PIPE_VIDEO_CAP_MAX_WIDTH
);
132 max_height
= screen
->get_video_param(screen
, prof
, PIPE_VIDEO_CAP_MAX_HEIGHT
);
133 if (vmixer
->video_width
< 48 ||
134 vmixer
->video_width
> max_width
) {
135 VDPAU_MSG(VDPAU_TRACE
, "[VDPAU] 48 < %u < %u not valid for width\n", vmixer
->video_width
, max_width
);
138 if (vmixer
->video_height
< 48 ||
139 vmixer
->video_height
> max_height
) {
140 VDPAU_MSG(VDPAU_TRACE
, "[VDPAU] 48 < %u < %u not valid for height\n", vmixer
->video_height
, max_height
);
143 vmixer
->luma_key_min
= 0.f
;
144 vmixer
->luma_key_max
= 1.f
;
145 vmixer
->sharpness
= 0.f
;
147 return VDP_STATUS_OK
;
150 vlRemoveDataHTAB(*mixer
);
152 vl_compositor_cleanup(&vmixer
->compositor
);
158 * Destroy a VdpVideoMixer.
161 vlVdpVideoMixerDestroy(VdpVideoMixer mixer
)
163 vlVdpVideoMixer
*vmixer
;
165 VDPAU_MSG(VDPAU_TRACE
, "[VDPAU] Destroying VideoMixer\n");
167 vmixer
= vlGetDataHTAB(mixer
);
169 return VDP_STATUS_INVALID_HANDLE
;
170 vlRemoveDataHTAB(mixer
);
172 vl_compositor_cleanup(&vmixer
->compositor
);
174 if (vmixer
->noise_reduction
.filter
) {
175 vl_median_filter_cleanup(vmixer
->noise_reduction
.filter
);
176 FREE(vmixer
->noise_reduction
.filter
);
181 return VDP_STATUS_OK
;
185 * Perform a video post-processing and compositing operation.
187 VdpStatus
vlVdpVideoMixerRender(VdpVideoMixer mixer
,
188 VdpOutputSurface background_surface
,
189 VdpRect
const *background_source_rect
,
190 VdpVideoMixerPictureStructure current_picture_structure
,
191 uint32_t video_surface_past_count
,
192 VdpVideoSurface
const *video_surface_past
,
193 VdpVideoSurface video_surface_current
,
194 uint32_t video_surface_future_count
,
195 VdpVideoSurface
const *video_surface_future
,
196 VdpRect
const *video_source_rect
,
197 VdpOutputSurface destination_surface
,
198 VdpRect
const *destination_rect
,
199 VdpRect
const *destination_video_rect
,
200 uint32_t layer_count
,
201 VdpLayer
const *layers
)
203 struct pipe_video_rect src_rect
, dst_rect
, dst_clip
;
206 vlVdpVideoMixer
*vmixer
;
208 vlVdpOutputSurface
*dst
;
210 vmixer
= vlGetDataHTAB(mixer
);
212 return VDP_STATUS_INVALID_HANDLE
;
214 surf
= vlGetDataHTAB(video_surface_current
);
216 return VDP_STATUS_INVALID_HANDLE
;
218 if (surf
->device
!= vmixer
->device
)
219 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
221 if (vmixer
->video_width
> surf
->video_buffer
->width
||
222 vmixer
->video_height
> surf
->video_buffer
->height
||
223 vmixer
->chroma_format
!= surf
->video_buffer
->chroma_format
)
224 return VDP_STATUS_INVALID_SIZE
;
226 if (layer_count
> vmixer
->max_layers
)
227 return VDP_STATUS_INVALID_VALUE
;
229 dst
= vlGetDataHTAB(destination_surface
);
231 return VDP_STATUS_INVALID_HANDLE
;
233 if (background_surface
!= VDP_INVALID_HANDLE
) {
234 vlVdpOutputSurface
*bg
= vlGetDataHTAB(background_surface
);
236 return VDP_STATUS_INVALID_HANDLE
;
237 vl_compositor_set_rgba_layer(&vmixer
->compositor
, layer
++, bg
->sampler_view
,
238 RectToPipe(background_source_rect
, &src_rect
), NULL
);
241 vl_compositor_clear_layers(&vmixer
->compositor
);
242 vl_compositor_set_buffer_layer(&vmixer
->compositor
, layer
++, surf
->video_buffer
,
243 RectToPipe(video_source_rect
, &src_rect
), NULL
);
244 vl_compositor_render(&vmixer
->compositor
, dst
->surface
,
245 RectToPipe(destination_video_rect
, &dst_rect
),
246 RectToPipe(destination_rect
, &dst_clip
),
249 /* applying the noise reduction after scaling is actually not very
250 clever, but currently we should avoid to copy around the image
252 if (vmixer
->noise_reduction
.filter
)
253 vl_median_filter_render(vmixer
->noise_reduction
.filter
,
254 dst
->sampler_view
, dst
->surface
);
256 return VDP_STATUS_OK
;
260 * Update the noise reduction setting
263 vlVdpVideoMixerUpdateNoiseReductionFilter(vlVdpVideoMixer
*vmixer
)
267 /* if present remove the old filter first */
268 if (vmixer
->noise_reduction
.filter
) {
269 vl_median_filter_cleanup(vmixer
->noise_reduction
.filter
);
270 FREE(vmixer
->noise_reduction
.filter
);
271 vmixer
->noise_reduction
.filter
= NULL
;
274 /* and create a new filter as needed */
275 if (vmixer
->noise_reduction
. enabled
&& vmixer
->noise_reduction
.level
> 0.0f
) {
276 vmixer
->noise_reduction
.filter
= MALLOC(sizeof(struct vl_median_filter
));
277 vl_median_filter_init(vmixer
->noise_reduction
.filter
,
278 vmixer
->device
->context
->pipe
,
279 vmixer
->video_width
, vmixer
->video_height
,
280 9 * vmixer
->noise_reduction
.level
,
281 VL_MEDIAN_FILTER_CROSS
);
286 * Retrieve whether features were requested at creation time.
289 vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer
,
290 uint32_t feature_count
,
291 VdpVideoMixerFeature
const *features
,
292 VdpBool
*feature_supports
)
294 vlVdpVideoMixer
*vmixer
;
297 if (!(features
&& feature_supports
))
298 return VDP_STATUS_INVALID_POINTER
;
300 vmixer
= vlGetDataHTAB(mixer
);
302 return VDP_STATUS_INVALID_HANDLE
;
304 for (i
= 0; i
< feature_count
; ++i
) {
305 switch (features
[i
]) {
306 /* they are valid, but we doesn't support them */
307 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL
:
308 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL
:
309 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1
:
310 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2
:
311 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3
:
312 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4
:
313 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5
:
314 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6
:
315 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7
:
316 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8
:
317 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9
:
318 case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE
:
319 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY
:
320 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS
:
321 feature_supports
[i
] = false;
324 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION
:
325 feature_supports
[i
] = vmixer
->noise_reduction
.supported
;
329 return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE
;
333 return VDP_STATUS_OK
;
337 * Enable or disable features.
340 vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer
,
341 uint32_t feature_count
,
342 VdpVideoMixerFeature
const *features
,
343 VdpBool
const *feature_enables
)
345 vlVdpVideoMixer
*vmixer
;
348 if (!(features
&& feature_enables
))
349 return VDP_STATUS_INVALID_POINTER
;
351 vmixer
= vlGetDataHTAB(mixer
);
353 return VDP_STATUS_INVALID_HANDLE
;
355 for (i
= 0; i
< feature_count
; ++i
) {
356 switch (features
[i
]) {
357 /* they are valid, but we doesn't support them */
358 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL
:
359 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL
:
360 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1
:
361 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2
:
362 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3
:
363 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4
:
364 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5
:
365 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6
:
366 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7
:
367 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8
:
368 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9
:
369 case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE
:
370 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY
:
371 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS
:
374 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION
:
375 vmixer
->noise_reduction
.enabled
= feature_enables
[i
];
376 vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer
);
380 return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE
;
384 return VDP_STATUS_OK
;
388 * Retrieve whether features are enabled.
391 vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer
,
392 uint32_t feature_count
,
393 VdpVideoMixerFeature
const *features
,
394 VdpBool
*feature_enables
)
396 vlVdpVideoMixer
*vmixer
;
399 if (!(features
&& feature_enables
))
400 return VDP_STATUS_INVALID_POINTER
;
402 vmixer
= vlGetDataHTAB(mixer
);
404 return VDP_STATUS_INVALID_HANDLE
;
406 for (i
= 0; i
< feature_count
; ++i
) {
407 switch (features
[i
]) {
408 /* they are valid, but we doesn't support them */
409 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL
:
410 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL
:
411 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1
:
412 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2
:
413 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3
:
414 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4
:
415 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5
:
416 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6
:
417 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7
:
418 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8
:
419 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9
:
420 case VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE
:
421 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY
:
422 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS
:
425 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION
:
426 vmixer
->noise_reduction
.enabled
= feature_enables
[i
];
427 vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer
);
431 return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE
;
435 return VDP_STATUS_OK
;
439 * Set attribute values.
442 vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer
,
443 uint32_t attribute_count
,
444 VdpVideoMixerAttribute
const *attributes
,
445 void const *const *attribute_values
)
447 const VdpColor
*background_color
;
448 union pipe_color_union color
;
449 const float *vdp_csc
;
453 if (!(attributes
&& attribute_values
))
454 return VDP_STATUS_INVALID_POINTER
;
456 vlVdpVideoMixer
*vmixer
= vlGetDataHTAB(mixer
);
458 return VDP_STATUS_INVALID_HANDLE
;
460 for (i
= 0; i
< attribute_count
; ++i
) {
461 switch (attributes
[i
]) {
462 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR
:
463 background_color
= attribute_values
[i
];
464 color
.f
[0] = background_color
->red
;
465 color
.f
[1] = background_color
->green
;
466 color
.f
[2] = background_color
->blue
;
467 color
.f
[3] = background_color
->alpha
;
468 vl_compositor_set_clear_color(&vmixer
->compositor
, &color
);
470 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX
:
471 vdp_csc
= attribute_values
[i
];
472 vmixer
->custom_csc
= !!vdp_csc
;
474 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, vmixer
->csc
);
476 memcpy(vmixer
->csc
, vdp_csc
, sizeof(float)*12);
477 if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE
))
478 vl_compositor_set_csc_matrix(&vmixer
->compositor
, vmixer
->csc
);
481 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL
:
483 val
= *(float*)attribute_values
[i
];
484 if (val
< 0.f
|| val
> 1.f
)
485 return VDP_STATUS_INVALID_VALUE
;
487 vmixer
->noise_reduction
.level
= val
;
488 vlVdpVideoMixerUpdateNoiseReductionFilter(vmixer
);
491 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA
:
492 val
= *(float*)attribute_values
[i
];
493 if (val
< 0.f
|| val
> 1.f
)
494 return VDP_STATUS_INVALID_VALUE
;
495 vmixer
->luma_key_min
= val
;
497 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA
:
498 val
= *(float*)attribute_values
[i
];
499 if (val
< 0.f
|| val
> 1.f
)
500 return VDP_STATUS_INVALID_VALUE
;
501 vmixer
->luma_key_max
= val
;
503 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL
:
504 val
= *(float*)attribute_values
[i
];
505 if (val
< -1.f
|| val
> 1.f
)
506 return VDP_STATUS_INVALID_VALUE
;
507 vmixer
->sharpness
= val
;
509 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE
:
510 if (*(uint8_t*)attribute_values
[i
] > 1)
511 return VDP_STATUS_INVALID_VALUE
;
512 vmixer
->skip_chroma_deint
= *(uint8_t*)attribute_values
[i
];
515 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE
;
519 return VDP_STATUS_OK
;
523 * Retrieve parameter values given at creation time.
526 vlVdpVideoMixerGetParameterValues(VdpVideoMixer mixer
,
527 uint32_t parameter_count
,
528 VdpVideoMixerParameter
const *parameters
,
529 void *const *parameter_values
)
531 vlVdpVideoMixer
*vmixer
= vlGetDataHTAB(mixer
);
534 return VDP_STATUS_INVALID_HANDLE
;
536 if (!parameter_count
)
537 return VDP_STATUS_OK
;
538 if (!(parameters
&& parameter_values
))
539 return VDP_STATUS_INVALID_POINTER
;
540 for (i
= 0; i
< parameter_count
; ++i
) {
541 switch (parameters
[i
]) {
542 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH
:
543 *(uint32_t*)parameter_values
[i
] = vmixer
->video_width
;
545 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT
:
546 *(uint32_t*)parameter_values
[i
] = vmixer
->video_height
;
548 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE
:
549 *(VdpChromaType
*)parameter_values
[i
] = PipeToChroma(vmixer
->chroma_format
);
551 case VDP_VIDEO_MIXER_PARAMETER_LAYERS
:
552 *(uint32_t*)parameter_values
[i
] = vmixer
->max_layers
;
555 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER
;
558 return VDP_STATUS_OK
;
562 * Retrieve current attribute values.
565 vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer
,
566 uint32_t attribute_count
,
567 VdpVideoMixerAttribute
const *attributes
,
568 void *const *attribute_values
)
571 VdpCSCMatrix
**vdp_csc
;
573 if (!(attributes
&& attribute_values
))
574 return VDP_STATUS_INVALID_POINTER
;
576 vlVdpVideoMixer
*vmixer
= vlGetDataHTAB(mixer
);
578 return VDP_STATUS_INVALID_HANDLE
;
580 for (i
= 0; i
< attribute_count
; ++i
) {
581 switch (attributes
[i
]) {
582 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR
:
583 vl_compositor_get_clear_color(&vmixer
->compositor
, attribute_values
[i
]);
585 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX
:
586 vdp_csc
= attribute_values
[i
];
587 if (!vmixer
->custom_csc
) {
591 memcpy(*vdp_csc
, vmixer
->csc
, sizeof(float)*12);
594 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL
:
595 *(float*)attribute_values
[i
] = vmixer
->noise_reduction
.level
;
598 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA
:
599 *(float*)attribute_values
[i
] = vmixer
->luma_key_min
;
601 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA
:
602 *(float*)attribute_values
[i
] = vmixer
->luma_key_max
;
604 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL
:
605 *(float*)attribute_values
[i
] = vmixer
->sharpness
;
607 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE
:
608 *(uint8_t*)attribute_values
[i
] = vmixer
->skip_chroma_deint
;
611 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE
;
614 return VDP_STATUS_OK
;
618 * Generate a color space conversion matrix.
621 vlVdpGenerateCSCMatrix(VdpProcamp
*procamp
,
622 VdpColorStandard standard
,
623 VdpCSCMatrix
*csc_matrix
)
626 enum VL_CSC_COLOR_STANDARD vl_std
;
627 struct vl_procamp camp
;
629 if (!(csc_matrix
&& procamp
))
630 return VDP_STATUS_INVALID_POINTER
;
632 if (procamp
->struct_version
> VDP_PROCAMP_VERSION
)
633 return VDP_STATUS_INVALID_STRUCT_VERSION
;
636 case VDP_COLOR_STANDARD_ITUR_BT_601
: vl_std
= VL_CSC_COLOR_STANDARD_BT_601
; break;
637 case VDP_COLOR_STANDARD_ITUR_BT_709
: vl_std
= VL_CSC_COLOR_STANDARD_BT_709
; break;
638 case VDP_COLOR_STANDARD_SMPTE_240M
: vl_std
= VL_CSC_COLOR_STANDARD_SMPTE_240M
; break;
639 default: return VDP_STATUS_INVALID_COLOR_STANDARD
;
641 camp
.brightness
= procamp
->brightness
;
642 camp
.contrast
= procamp
->contrast
;
643 camp
.saturation
= procamp
->saturation
;
644 camp
.hue
= procamp
->hue
;
645 vl_csc_get_matrix(vl_std
, &camp
, 1, matrix
);
646 memcpy(csc_matrix
, matrix
, sizeof(float)*12);
647 return VDP_STATUS_OK
;