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