1 /**************************************************************************
2 *
3 * Copyright 2010 Younes Manton.
4 * All Rights Reserved.
5 *
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:
13 *
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.
17 *
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 VMWARE 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.
25 *
26 **************************************************************************/
27
28 #include <assert.h>
29 #include <math.h>
30
31 #include "vdpau_private.h"
32 #include "pipe/p_screen.h"
33 #include "pipe/p_defines.h"
34 #include "util/u_debug.h"
35
36 /**
37 * Retrieve the VDPAU version implemented by the backend.
38 */
39 VdpStatus
vlVdpGetApiVersion(uint32_t * api_version)40 vlVdpGetApiVersion(uint32_t *api_version)
41 {
42 if (!api_version)
43 return VDP_STATUS_INVALID_POINTER;
44
45 *api_version = 1;
46 return VDP_STATUS_OK;
47 }
48
49 /**
50 * Retrieve an implementation-specific string description of the implementation.
51 * This typically includes detailed version information.
52 */
53 VdpStatus
vlVdpGetInformationString(char const ** information_string)54 vlVdpGetInformationString(char const **information_string)
55 {
56 if (!information_string)
57 return VDP_STATUS_INVALID_POINTER;
58
59 *information_string = INFORMATION_STRING;
60 return VDP_STATUS_OK;
61 }
62
63 /**
64 * Query the implementation's VdpVideoSurface capabilities.
65 */
66 VdpStatus
vlVdpVideoSurfaceQueryCapabilities(VdpDevice device,VdpChromaType surface_chroma_type,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)67 vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
68 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
69 {
70 vlVdpDevice *dev;
71 struct pipe_screen *pscreen;
72 uint32_t max_2d_texture_level;
73
74 if (!(is_supported && max_width && max_height))
75 return VDP_STATUS_INVALID_POINTER;
76
77 dev = vlGetDataHTAB(device);
78 if (!dev)
79 return VDP_STATUS_INVALID_HANDLE;
80
81 pscreen = dev->vscreen->pscreen;
82 if (!pscreen)
83 return VDP_STATUS_RESOURCES;
84
85 mtx_lock(&dev->mutex);
86
87 /* XXX: Current limits */
88 *is_supported = true;
89 max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
90 mtx_unlock(&dev->mutex);
91 if (!max_2d_texture_level)
92 return VDP_STATUS_RESOURCES;
93
94 /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
95 *max_width = *max_height = pow(2,max_2d_texture_level-1);
96
97 return VDP_STATUS_OK;
98 }
99
100 /**
101 * Query the implementation's VdpVideoSurface GetBits/PutBits capabilities.
102 */
103 VdpStatus
vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device,VdpChromaType surface_chroma_type,VdpYCbCrFormat bits_ycbcr_format,VdpBool * is_supported)104 vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
105 VdpYCbCrFormat bits_ycbcr_format,
106 VdpBool *is_supported)
107 {
108 vlVdpDevice *dev;
109 struct pipe_screen *pscreen;
110
111 if (!is_supported)
112 return VDP_STATUS_INVALID_POINTER;
113
114 dev = vlGetDataHTAB(device);
115 if (!dev)
116 return VDP_STATUS_INVALID_HANDLE;
117
118 pscreen = dev->vscreen->pscreen;
119 if (!pscreen)
120 return VDP_STATUS_RESOURCES;
121
122 mtx_lock(&dev->mutex);
123
124 switch(bits_ycbcr_format) {
125 case VDP_YCBCR_FORMAT_NV12:
126 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_420;
127 break;
128
129 case VDP_YCBCR_FORMAT_YV12:
130 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_420;
131
132 /* We can convert YV12 to NV12 on the fly! */
133 if (*is_supported &&
134 pscreen->is_video_format_supported(pscreen,
135 PIPE_FORMAT_NV12,
136 PIPE_VIDEO_PROFILE_UNKNOWN,
137 PIPE_VIDEO_ENTRYPOINT_BITSTREAM)) {
138 mtx_unlock(&dev->mutex);
139 return VDP_STATUS_OK;
140 }
141 break;
142
143 case VDP_YCBCR_FORMAT_UYVY:
144 case VDP_YCBCR_FORMAT_YUYV:
145 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_422;
146 break;
147
148 case VDP_YCBCR_FORMAT_Y8U8V8A8:
149 case VDP_YCBCR_FORMAT_V8U8Y8A8:
150 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_444;
151 break;
152
153 default:
154 *is_supported = false;
155 break;
156 }
157
158 *is_supported &= pscreen->is_video_format_supported
159 (
160 pscreen,
161 FormatYCBCRToPipe(bits_ycbcr_format),
162 PIPE_VIDEO_PROFILE_UNKNOWN,
163 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
164 );
165 mtx_unlock(&dev->mutex);
166
167 return VDP_STATUS_OK;
168 }
169
170 /**
171 * Query the implementation's VdpDecoder capabilities.
172 */
173 VdpStatus
vlVdpDecoderQueryCapabilities(VdpDevice device,VdpDecoderProfile profile,VdpBool * is_supported,uint32_t * max_level,uint32_t * max_macroblocks,uint32_t * max_width,uint32_t * max_height)174 vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
175 VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
176 uint32_t *max_width, uint32_t *max_height)
177 {
178 vlVdpDevice *dev;
179 struct pipe_screen *pscreen;
180 enum pipe_video_profile p_profile;
181
182 if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
183 return VDP_STATUS_INVALID_POINTER;
184
185 dev = vlGetDataHTAB(device);
186 if (!dev)
187 return VDP_STATUS_INVALID_HANDLE;
188
189 pscreen = dev->vscreen->pscreen;
190 if (!pscreen)
191 return VDP_STATUS_RESOURCES;
192
193 p_profile = ProfileToPipe(profile);
194 if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN) {
195 *is_supported = false;
196 return VDP_STATUS_OK;
197 }
198
199 mtx_lock(&dev->mutex);
200 *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
201 PIPE_VIDEO_CAP_SUPPORTED);
202 if (*is_supported) {
203 *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
204 PIPE_VIDEO_CAP_MAX_WIDTH);
205 *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
206 PIPE_VIDEO_CAP_MAX_HEIGHT);
207 *max_level = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
208 PIPE_VIDEO_CAP_MAX_LEVEL);
209 *max_macroblocks = (*max_width/16)*(*max_height/16);
210 } else {
211 *max_width = 0;
212 *max_height = 0;
213 *max_level = 0;
214 *max_macroblocks = 0;
215 }
216 mtx_unlock(&dev->mutex);
217
218 return VDP_STATUS_OK;
219 }
220
221 /**
222 * Query the implementation's VdpOutputSurface capabilities.
223 */
224 VdpStatus
vlVdpOutputSurfaceQueryCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)225 vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
226 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
227 {
228 vlVdpDevice *dev;
229 struct pipe_screen *pscreen;
230 enum pipe_format format;
231
232 dev = vlGetDataHTAB(device);
233 if (!dev)
234 return VDP_STATUS_INVALID_HANDLE;
235
236 pscreen = dev->vscreen->pscreen;
237 if (!pscreen)
238 return VDP_STATUS_RESOURCES;
239
240 format = VdpFormatRGBAToPipe(surface_rgba_format);
241 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
242 return VDP_STATUS_INVALID_RGBA_FORMAT;
243
244 if (!(is_supported && max_width && max_height))
245 return VDP_STATUS_INVALID_POINTER;
246
247 mtx_lock(&dev->mutex);
248 *is_supported = pscreen->is_format_supported
249 (
250 pscreen, format, PIPE_TEXTURE_3D, 1,
251 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
252 );
253 if (*is_supported) {
254 uint32_t max_2d_texture_level = pscreen->get_param(
255 pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
256
257 if (!max_2d_texture_level) {
258 mtx_unlock(&dev->mutex);
259 return VDP_STATUS_ERROR;
260 }
261
262 *max_width = *max_height = pow(2, max_2d_texture_level - 1);
263 } else {
264 *max_width = 0;
265 *max_height = 0;
266 }
267 mtx_unlock(&dev->mutex);
268
269 return VDP_STATUS_OK;
270 }
271
272 /**
273 * Query the implementation's capability to perform a PutBits operation using
274 * application data matching the surface's format.
275 */
276 VdpStatus
vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported)277 vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
278 VdpBool *is_supported)
279 {
280 vlVdpDevice *dev;
281 struct pipe_screen *pscreen;
282 enum pipe_format format;
283
284 dev = vlGetDataHTAB(device);
285 if (!dev)
286 return VDP_STATUS_INVALID_HANDLE;
287
288 pscreen = dev->vscreen->pscreen;
289 if (!pscreen)
290 return VDP_STATUS_ERROR;
291
292 format = VdpFormatRGBAToPipe(surface_rgba_format);
293 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
294 return VDP_STATUS_INVALID_RGBA_FORMAT;
295
296 if (!is_supported)
297 return VDP_STATUS_INVALID_POINTER;
298
299 mtx_lock(&dev->mutex);
300 *is_supported = pscreen->is_format_supported
301 (
302 pscreen, format, PIPE_TEXTURE_2D, 1,
303 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
304 );
305 mtx_unlock(&dev->mutex);
306
307 return VDP_STATUS_OK;
308 }
309
310 /**
311 * Query the implementation's capability to perform a PutBits operation using
312 * application data in a specific indexed format.
313 */
314 VdpStatus
vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpIndexedFormat bits_indexed_format,VdpColorTableFormat color_table_format,VdpBool * is_supported)315 vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
316 VdpRGBAFormat surface_rgba_format,
317 VdpIndexedFormat bits_indexed_format,
318 VdpColorTableFormat color_table_format,
319 VdpBool *is_supported)
320 {
321 vlVdpDevice *dev;
322 struct pipe_screen *pscreen;
323 enum pipe_format rgba_format, index_format, colortbl_format;
324
325 dev = vlGetDataHTAB(device);
326 if (!dev)
327 return VDP_STATUS_INVALID_HANDLE;
328
329 pscreen = dev->vscreen->pscreen;
330 if (!pscreen)
331 return VDP_STATUS_ERROR;
332
333 rgba_format = VdpFormatRGBAToPipe(surface_rgba_format);
334 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
335 return VDP_STATUS_INVALID_RGBA_FORMAT;
336
337 index_format = FormatIndexedToPipe(bits_indexed_format);
338 if (index_format == PIPE_FORMAT_NONE)
339 return VDP_STATUS_INVALID_INDEXED_FORMAT;
340
341 colortbl_format = FormatColorTableToPipe(color_table_format);
342 if (colortbl_format == PIPE_FORMAT_NONE)
343 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
344
345 if (!is_supported)
346 return VDP_STATUS_INVALID_POINTER;
347
348 mtx_lock(&dev->mutex);
349 *is_supported = pscreen->is_format_supported
350 (
351 pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
352 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
353 );
354
355 *is_supported &= pscreen->is_format_supported
356 (
357 pscreen, index_format, PIPE_TEXTURE_2D, 1,
358 PIPE_BIND_SAMPLER_VIEW
359 );
360
361 *is_supported &= pscreen->is_format_supported
362 (
363 pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
364 PIPE_BIND_SAMPLER_VIEW
365 );
366 mtx_unlock(&dev->mutex);
367
368 return VDP_STATUS_OK;
369 }
370
371 /**
372 * Query the implementation's capability to perform a PutBits operation using
373 * application data in a specific YCbCr/YUB format.
374 */
375 VdpStatus
vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpYCbCrFormat bits_ycbcr_format,VdpBool * is_supported)376 vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
377 VdpYCbCrFormat bits_ycbcr_format,
378 VdpBool *is_supported)
379 {
380 vlVdpDevice *dev;
381 struct pipe_screen *pscreen;
382 enum pipe_format rgba_format, ycbcr_format;
383
384 dev = vlGetDataHTAB(device);
385 if (!dev)
386 return VDP_STATUS_INVALID_HANDLE;
387
388 pscreen = dev->vscreen->pscreen;
389 if (!pscreen)
390 return VDP_STATUS_ERROR;
391
392 rgba_format = VdpFormatRGBAToPipe(surface_rgba_format);
393 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
394 return VDP_STATUS_INVALID_RGBA_FORMAT;
395
396 ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format);
397 if (ycbcr_format == PIPE_FORMAT_NONE)
398 return VDP_STATUS_INVALID_INDEXED_FORMAT;
399
400 if (!is_supported)
401 return VDP_STATUS_INVALID_POINTER;
402
403 mtx_lock(&dev->mutex);
404 *is_supported = pscreen->is_format_supported
405 (
406 pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
407 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
408 );
409
410 *is_supported &= pscreen->is_video_format_supported
411 (
412 pscreen, ycbcr_format,
413 PIPE_VIDEO_PROFILE_UNKNOWN,
414 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
415 );
416 mtx_unlock(&dev->mutex);
417
418 return VDP_STATUS_OK;
419 }
420
421 /**
422 * Query the implementation's VdpBitmapSurface capabilities.
423 */
424 VdpStatus
vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)425 vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
426 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
427 {
428 vlVdpDevice *dev;
429 struct pipe_screen *pscreen;
430 enum pipe_format format;
431
432 dev = vlGetDataHTAB(device);
433 if (!dev)
434 return VDP_STATUS_INVALID_HANDLE;
435
436 pscreen = dev->vscreen->pscreen;
437 if (!pscreen)
438 return VDP_STATUS_RESOURCES;
439
440 format = VdpFormatRGBAToPipe(surface_rgba_format);
441 if (format == PIPE_FORMAT_NONE)
442 return VDP_STATUS_INVALID_RGBA_FORMAT;
443
444 if (!(is_supported && max_width && max_height))
445 return VDP_STATUS_INVALID_POINTER;
446
447 mtx_lock(&dev->mutex);
448 *is_supported = pscreen->is_format_supported
449 (
450 pscreen, format, PIPE_TEXTURE_3D, 1,
451 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
452 );
453 if (*is_supported) {
454 uint32_t max_2d_texture_level = pscreen->get_param(
455 pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
456
457 if (!max_2d_texture_level) {
458 mtx_unlock(&dev->mutex);
459 return VDP_STATUS_ERROR;
460 }
461
462 *max_width = *max_height = pow(2, max_2d_texture_level - 1);
463 } else {
464 *max_width = 0;
465 *max_height = 0;
466 }
467 mtx_unlock(&dev->mutex);
468
469 return VDP_STATUS_OK;
470 }
471
472 /**
473 * Query the implementation's support for a specific feature.
474 */
475 VdpStatus
vlVdpVideoMixerQueryFeatureSupport(VdpDevice device,VdpVideoMixerFeature feature,VdpBool * is_supported)476 vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
477 VdpBool *is_supported)
478 {
479 if (!is_supported)
480 return VDP_STATUS_INVALID_POINTER;
481
482 switch (feature) {
483 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
484 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
485 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL:
486 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
487 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
488 *is_supported = VDP_TRUE;
489 break;
490 default:
491 *is_supported = VDP_FALSE;
492 break;
493 }
494 return VDP_STATUS_OK;
495 }
496
497 /**
498 * Query the implementation's support for a specific parameter.
499 */
500 VdpStatus
vlVdpVideoMixerQueryParameterSupport(VdpDevice device,VdpVideoMixerParameter parameter,VdpBool * is_supported)501 vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
502 VdpBool *is_supported)
503 {
504 if (!is_supported)
505 return VDP_STATUS_INVALID_POINTER;
506
507 switch (parameter) {
508 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
509 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
510 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
511 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
512 *is_supported = VDP_TRUE;
513 break;
514 default:
515 *is_supported = VDP_FALSE;
516 break;
517 }
518 return VDP_STATUS_OK;
519 }
520
521 /**
522 * Query the implementation's supported for a specific parameter.
523 */
524 VdpStatus
vlVdpVideoMixerQueryParameterValueRange(VdpDevice device,VdpVideoMixerParameter parameter,void * min_value,void * max_value)525 vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
526 void *min_value, void *max_value)
527 {
528 vlVdpDevice *dev = vlGetDataHTAB(device);
529 struct pipe_screen *screen;
530
531 if (!dev)
532 return VDP_STATUS_INVALID_HANDLE;
533 if (!(min_value && max_value))
534 return VDP_STATUS_INVALID_POINTER;
535
536 mtx_lock(&dev->mutex);
537 screen = dev->vscreen->pscreen;
538 switch (parameter) {
539 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
540 *(uint32_t*)min_value = 48;
541 *(uint32_t*)max_value = screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN,
542 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
543 PIPE_VIDEO_CAP_MAX_WIDTH);
544 break;
545 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
546 *(uint32_t*)min_value = 48;
547 *(uint32_t*)max_value = screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN,
548 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
549 PIPE_VIDEO_CAP_MAX_HEIGHT);
550 break;
551
552 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
553 *(uint32_t*)min_value = 0;
554 *(uint32_t*)max_value = 4;
555 break;
556
557 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
558 default:
559 mtx_unlock(&dev->mutex);
560 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
561 }
562 mtx_unlock(&dev->mutex);
563 return VDP_STATUS_OK;
564 }
565
566 /**
567 * Query the implementation's support for a specific attribute.
568 */
569 VdpStatus
vlVdpVideoMixerQueryAttributeSupport(VdpDevice device,VdpVideoMixerAttribute attribute,VdpBool * is_supported)570 vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
571 VdpBool *is_supported)
572 {
573 if (!is_supported)
574 return VDP_STATUS_INVALID_POINTER;
575
576 switch (attribute) {
577 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
578 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
579 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
580 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
581 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
582 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
583 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
584 *is_supported = VDP_TRUE;
585 break;
586 default:
587 *is_supported = VDP_FALSE;
588 }
589 return VDP_STATUS_OK;
590 }
591
592 /**
593 * Query the implementation's supported for a specific attribute.
594 */
595 VdpStatus
vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device,VdpVideoMixerAttribute attribute,void * min_value,void * max_value)596 vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
597 void *min_value, void *max_value)
598 {
599 if (!(min_value && max_value))
600 return VDP_STATUS_INVALID_POINTER;
601
602 switch (attribute) {
603 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
604 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
605 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
606 *(float*)min_value = 0.0f;
607 *(float*)max_value = 1.0f;
608 break;
609 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
610 *(float*)min_value = -1.0f;
611 *(float*)max_value = 1.0f;
612 break;
613 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
614 *(uint8_t*)min_value = 0;
615 *(uint8_t*)max_value = 1;
616 break;
617 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
618 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
619 default:
620 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
621 }
622 return VDP_STATUS_OK;
623 }
624