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