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 = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
209 PIPE_VIDEO_CAP_MAX_MACROBLOCKS);
210 if (*max_macroblocks == 0) {
211 *max_macroblocks = (*max_width/16)*(*max_height/16);
212 }
213 } else {
214 *max_width = 0;
215 *max_height = 0;
216 *max_level = 0;
217 *max_macroblocks = 0;
218 }
219 mtx_unlock(&dev->mutex);
220
221 return VDP_STATUS_OK;
222 }
223
224 /**
225 * Query the implementation's VdpOutputSurface capabilities.
226 */
227 VdpStatus
vlVdpOutputSurfaceQueryCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)228 vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
229 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
230 {
231 vlVdpDevice *dev;
232 struct pipe_screen *pscreen;
233 enum pipe_format format;
234
235 dev = vlGetDataHTAB(device);
236 if (!dev)
237 return VDP_STATUS_INVALID_HANDLE;
238
239 pscreen = dev->vscreen->pscreen;
240 if (!pscreen)
241 return VDP_STATUS_RESOURCES;
242
243 format = VdpFormatRGBAToPipe(surface_rgba_format);
244 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
245 return VDP_STATUS_INVALID_RGBA_FORMAT;
246
247 if (!(is_supported && max_width && max_height))
248 return VDP_STATUS_INVALID_POINTER;
249
250 mtx_lock(&dev->mutex);
251 *is_supported = pscreen->is_format_supported
252 (
253 pscreen, format, PIPE_TEXTURE_2D, 1, 1,
254 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
255 );
256 if (*is_supported) {
257 uint32_t max_2d_texture_size = pscreen->get_param(
258 pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
259
260 if (!max_2d_texture_size) {
261 mtx_unlock(&dev->mutex);
262 return VDP_STATUS_ERROR;
263 }
264
265 *max_width = *max_height = max_2d_texture_size;
266 } else {
267 *max_width = 0;
268 *max_height = 0;
269 }
270 mtx_unlock(&dev->mutex);
271
272 return VDP_STATUS_OK;
273 }
274
275 /**
276 * Query the implementation's capability to perform a PutBits operation using
277 * application data matching the surface's format.
278 */
279 VdpStatus
vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported)280 vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
281 VdpBool *is_supported)
282 {
283 vlVdpDevice *dev;
284 struct pipe_screen *pscreen;
285 enum pipe_format format;
286
287 dev = vlGetDataHTAB(device);
288 if (!dev)
289 return VDP_STATUS_INVALID_HANDLE;
290
291 pscreen = dev->vscreen->pscreen;
292 if (!pscreen)
293 return VDP_STATUS_ERROR;
294
295 format = VdpFormatRGBAToPipe(surface_rgba_format);
296 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
297 return VDP_STATUS_INVALID_RGBA_FORMAT;
298
299 if (!is_supported)
300 return VDP_STATUS_INVALID_POINTER;
301
302 mtx_lock(&dev->mutex);
303 *is_supported = pscreen->is_format_supported
304 (
305 pscreen, format, PIPE_TEXTURE_2D, 1, 1,
306 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
307 );
308 mtx_unlock(&dev->mutex);
309
310 return VDP_STATUS_OK;
311 }
312
313 /**
314 * Query the implementation's capability to perform a PutBits operation using
315 * application data in a specific indexed format.
316 */
317 VdpStatus
vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpIndexedFormat bits_indexed_format,VdpColorTableFormat color_table_format,VdpBool * is_supported)318 vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
319 VdpRGBAFormat surface_rgba_format,
320 VdpIndexedFormat bits_indexed_format,
321 VdpColorTableFormat color_table_format,
322 VdpBool *is_supported)
323 {
324 vlVdpDevice *dev;
325 struct pipe_screen *pscreen;
326 enum pipe_format rgba_format, index_format, colortbl_format;
327
328 dev = vlGetDataHTAB(device);
329 if (!dev)
330 return VDP_STATUS_INVALID_HANDLE;
331
332 pscreen = dev->vscreen->pscreen;
333 if (!pscreen)
334 return VDP_STATUS_ERROR;
335
336 rgba_format = VdpFormatRGBAToPipe(surface_rgba_format);
337 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
338 return VDP_STATUS_INVALID_RGBA_FORMAT;
339
340 index_format = FormatIndexedToPipe(bits_indexed_format);
341 if (index_format == PIPE_FORMAT_NONE)
342 return VDP_STATUS_INVALID_INDEXED_FORMAT;
343
344 colortbl_format = FormatColorTableToPipe(color_table_format);
345 if (colortbl_format == PIPE_FORMAT_NONE)
346 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
347
348 if (!is_supported)
349 return VDP_STATUS_INVALID_POINTER;
350
351 mtx_lock(&dev->mutex);
352 *is_supported = pscreen->is_format_supported
353 (
354 pscreen, rgba_format, PIPE_TEXTURE_2D, 1, 1,
355 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
356 );
357
358 *is_supported &= pscreen->is_format_supported
359 (
360 pscreen, index_format, PIPE_TEXTURE_2D, 1, 1,
361 PIPE_BIND_SAMPLER_VIEW
362 );
363
364 *is_supported &= pscreen->is_format_supported
365 (
366 pscreen, colortbl_format, PIPE_TEXTURE_1D, 1, 1,
367 PIPE_BIND_SAMPLER_VIEW
368 );
369 mtx_unlock(&dev->mutex);
370
371 return VDP_STATUS_OK;
372 }
373
374 /**
375 * Query the implementation's capability to perform a PutBits operation using
376 * application data in a specific YCbCr/YUB format.
377 */
378 VdpStatus
vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpYCbCrFormat bits_ycbcr_format,VdpBool * is_supported)379 vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
380 VdpYCbCrFormat bits_ycbcr_format,
381 VdpBool *is_supported)
382 {
383 vlVdpDevice *dev;
384 struct pipe_screen *pscreen;
385 enum pipe_format rgba_format, ycbcr_format;
386
387 dev = vlGetDataHTAB(device);
388 if (!dev)
389 return VDP_STATUS_INVALID_HANDLE;
390
391 pscreen = dev->vscreen->pscreen;
392 if (!pscreen)
393 return VDP_STATUS_ERROR;
394
395 rgba_format = VdpFormatRGBAToPipe(surface_rgba_format);
396 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
397 return VDP_STATUS_INVALID_RGBA_FORMAT;
398
399 ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format);
400 if (ycbcr_format == PIPE_FORMAT_NONE)
401 return VDP_STATUS_INVALID_INDEXED_FORMAT;
402
403 if (!is_supported)
404 return VDP_STATUS_INVALID_POINTER;
405
406 mtx_lock(&dev->mutex);
407 *is_supported = pscreen->is_format_supported
408 (
409 pscreen, rgba_format, PIPE_TEXTURE_2D, 1, 1,
410 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
411 );
412
413 *is_supported &= pscreen->is_video_format_supported
414 (
415 pscreen, ycbcr_format,
416 PIPE_VIDEO_PROFILE_UNKNOWN,
417 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
418 );
419 mtx_unlock(&dev->mutex);
420
421 return VDP_STATUS_OK;
422 }
423
424 /**
425 * Query the implementation's VdpBitmapSurface capabilities.
426 */
427 VdpStatus
vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)428 vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
429 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
430 {
431 vlVdpDevice *dev;
432 struct pipe_screen *pscreen;
433 enum pipe_format format;
434
435 dev = vlGetDataHTAB(device);
436 if (!dev)
437 return VDP_STATUS_INVALID_HANDLE;
438
439 pscreen = dev->vscreen->pscreen;
440 if (!pscreen)
441 return VDP_STATUS_RESOURCES;
442
443 format = VdpFormatRGBAToPipe(surface_rgba_format);
444 if (format == PIPE_FORMAT_NONE)
445 return VDP_STATUS_INVALID_RGBA_FORMAT;
446
447 if (!(is_supported && max_width && max_height))
448 return VDP_STATUS_INVALID_POINTER;
449
450 mtx_lock(&dev->mutex);
451 *is_supported = pscreen->is_format_supported
452 (
453 pscreen, format, PIPE_TEXTURE_2D, 1, 1,
454 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
455 );
456 if (*is_supported) {
457 uint32_t max_2d_texture_size = pscreen->get_param(
458 pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
459
460 if (!max_2d_texture_size) {
461 mtx_unlock(&dev->mutex);
462 return VDP_STATUS_ERROR;
463 }
464
465 *max_width = *max_height = max_2d_texture_size;
466 } else {
467 *max_width = 0;
468 *max_height = 0;
469 }
470 mtx_unlock(&dev->mutex);
471
472 return VDP_STATUS_OK;
473 }
474
475 /**
476 * Query the implementation's support for a specific feature.
477 */
478 VdpStatus
vlVdpVideoMixerQueryFeatureSupport(VdpDevice device,VdpVideoMixerFeature feature,VdpBool * is_supported)479 vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
480 VdpBool *is_supported)
481 {
482 if (!is_supported)
483 return VDP_STATUS_INVALID_POINTER;
484
485 switch (feature) {
486 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
487 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
488 case VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL:
489 case VDP_VIDEO_MIXER_FEATURE_LUMA_KEY:
490 case VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1:
491 *is_supported = VDP_TRUE;
492 break;
493 default:
494 *is_supported = VDP_FALSE;
495 break;
496 }
497 return VDP_STATUS_OK;
498 }
499
500 /**
501 * Query the implementation's support for a specific parameter.
502 */
503 VdpStatus
vlVdpVideoMixerQueryParameterSupport(VdpDevice device,VdpVideoMixerParameter parameter,VdpBool * is_supported)504 vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
505 VdpBool *is_supported)
506 {
507 if (!is_supported)
508 return VDP_STATUS_INVALID_POINTER;
509
510 switch (parameter) {
511 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
512 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
513 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
514 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
515 *is_supported = VDP_TRUE;
516 break;
517 default:
518 *is_supported = VDP_FALSE;
519 break;
520 }
521 return VDP_STATUS_OK;
522 }
523
524 /**
525 * Query the implementation's supported for a specific parameter.
526 */
527 VdpStatus
vlVdpVideoMixerQueryParameterValueRange(VdpDevice device,VdpVideoMixerParameter parameter,void * min_value,void * max_value)528 vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
529 void *min_value, void *max_value)
530 {
531 vlVdpDevice *dev = vlGetDataHTAB(device);
532 struct pipe_screen *screen;
533
534 if (!dev)
535 return VDP_STATUS_INVALID_HANDLE;
536 if (!(min_value && max_value))
537 return VDP_STATUS_INVALID_POINTER;
538
539 mtx_lock(&dev->mutex);
540 screen = dev->vscreen->pscreen;
541 switch (parameter) {
542 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
543 *(uint32_t*)min_value = 48;
544 *(uint32_t*)max_value = screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN,
545 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
546 PIPE_VIDEO_CAP_MAX_WIDTH);
547 break;
548 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
549 *(uint32_t*)min_value = 48;
550 *(uint32_t*)max_value = screen->get_video_param(screen, PIPE_VIDEO_PROFILE_UNKNOWN,
551 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
552 PIPE_VIDEO_CAP_MAX_HEIGHT);
553 break;
554
555 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
556 *(uint32_t*)min_value = 0;
557 *(uint32_t*)max_value = 4;
558 break;
559
560 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
561 default:
562 mtx_unlock(&dev->mutex);
563 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
564 }
565 mtx_unlock(&dev->mutex);
566 return VDP_STATUS_OK;
567 }
568
569 /**
570 * Query the implementation's support for a specific attribute.
571 */
572 VdpStatus
vlVdpVideoMixerQueryAttributeSupport(VdpDevice device,VdpVideoMixerAttribute attribute,VdpBool * is_supported)573 vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
574 VdpBool *is_supported)
575 {
576 if (!is_supported)
577 return VDP_STATUS_INVALID_POINTER;
578
579 switch (attribute) {
580 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
581 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
582 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
583 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
584 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
585 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
586 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
587 *is_supported = VDP_TRUE;
588 break;
589 default:
590 *is_supported = VDP_FALSE;
591 }
592 return VDP_STATUS_OK;
593 }
594
595 /**
596 * Query the implementation's supported for a specific attribute.
597 */
598 VdpStatus
vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device,VdpVideoMixerAttribute attribute,void * min_value,void * max_value)599 vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
600 void *min_value, void *max_value)
601 {
602 if (!(min_value && max_value))
603 return VDP_STATUS_INVALID_POINTER;
604
605 switch (attribute) {
606 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
607 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
608 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
609 *(float*)min_value = 0.0f;
610 *(float*)max_value = 1.0f;
611 break;
612 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
613 *(float*)min_value = -1.0f;
614 *(float*)max_value = 1.0f;
615 break;
616 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
617 *(uint8_t*)min_value = 0;
618 *(uint8_t*)max_value = 1;
619 break;
620 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
621 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
622 default:
623 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
624 }
625 return VDP_STATUS_OK;
626 }
627