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