• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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