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