query.c revision bf19596870a61c615f12e593f4812052ce9d9721
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 TUNGSTEN GRAPHICS 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 "vl_winsys.h"
33#include "pipe/p_screen.h"
34#include "pipe/p_defines.h"
35#include "util/u_debug.h"
36
37/**
38 * Retrieve the VDPAU version implemented by the backend.
39 */
40VdpStatus
41vlVdpGetApiVersion(uint32_t *api_version)
42{
43   if (!api_version)
44      return VDP_STATUS_INVALID_POINTER;
45
46   *api_version = 1;
47   return VDP_STATUS_OK;
48}
49
50/**
51 * Retrieve an implementation-specific string description of the implementation.
52 * This typically includes detailed version information.
53 */
54VdpStatus
55vlVdpGetInformationString(char const **information_string)
56{
57   if (!information_string)
58      return VDP_STATUS_INVALID_POINTER;
59
60   *information_string = INFORMATION_STRING;
61   return VDP_STATUS_OK;
62}
63
64/**
65 * Query the implementation's VdpVideoSurface capabilities.
66 */
67VdpStatus
68vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
69                                   VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
70{
71   vlVdpDevice *dev;
72   struct pipe_screen *pscreen;
73   uint32_t max_2d_texture_level;
74
75   if (!(is_supported && max_width && max_height))
76      return VDP_STATUS_INVALID_POINTER;
77
78   dev = vlGetDataHTAB(device);
79   if (!dev)
80      return VDP_STATUS_INVALID_HANDLE;
81
82   pscreen = dev->vscreen->pscreen;
83   if (!pscreen)
84      return VDP_STATUS_RESOURCES;
85
86   /* XXX: Current limits */
87   *is_supported = true;
88   if (surface_chroma_type != VDP_CHROMA_TYPE_420)
89      *is_supported = false;
90
91   max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
92   if (!max_2d_texture_level)
93      return VDP_STATUS_RESOURCES;
94
95   /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
96   *max_width = *max_height = pow(2,max_2d_texture_level-1);
97
98   return VDP_STATUS_OK;
99}
100
101/**
102 * Query the implementation's VdpVideoSurface GetBits/PutBits capabilities.
103 */
104VdpStatus
105vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(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   *is_supported = pscreen->is_video_format_supported
124   (
125      pscreen,
126      FormatYCBCRToPipe(bits_ycbcr_format),
127      PIPE_VIDEO_PROFILE_UNKNOWN
128   );
129
130   return VDP_STATUS_OK;
131}
132
133/**
134 * Query the implementation's VdpDecoder capabilities.
135 */
136VdpStatus
137vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
138                              VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
139                              uint32_t *max_width, uint32_t *max_height)
140{
141   vlVdpDevice *dev;
142   struct pipe_screen *pscreen;
143   enum pipe_video_profile p_profile;
144
145   if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
146      return VDP_STATUS_INVALID_POINTER;
147
148   dev = vlGetDataHTAB(device);
149   if (!dev)
150      return VDP_STATUS_INVALID_HANDLE;
151
152   pscreen = dev->vscreen->pscreen;
153   if (!pscreen)
154      return VDP_STATUS_RESOURCES;
155
156   p_profile = ProfileToPipe(profile);
157   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)	{
158      *is_supported = false;
159      return VDP_STATUS_OK;
160   }
161
162   *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_SUPPORTED);
163   if (*is_supported) {
164      *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH);
165      *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_HEIGHT);
166      *max_level = 16;
167      *max_macroblocks = (*max_width/16)*(*max_height/16);
168   } else {
169      *max_width = 0;
170      *max_height = 0;
171      *max_level = 0;
172      *max_macroblocks = 0;
173   }
174
175   return VDP_STATUS_OK;
176}
177
178/**
179 * Query the implementation's VdpOutputSurface capabilities.
180 */
181VdpStatus
182vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
183                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
184{
185   vlVdpDevice *dev;
186   struct pipe_screen *pscreen;
187   enum pipe_format format;
188
189   dev = vlGetDataHTAB(device);
190   if (!dev)
191      return VDP_STATUS_INVALID_HANDLE;
192
193   pscreen = dev->vscreen->pscreen;
194   if (!pscreen)
195      return VDP_STATUS_RESOURCES;
196
197   format = FormatRGBAToPipe(surface_rgba_format);
198   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
199      return VDP_STATUS_INVALID_RGBA_FORMAT;
200
201   if (!(is_supported && max_width && max_height))
202      return VDP_STATUS_INVALID_POINTER;
203
204   *is_supported = pscreen->is_format_supported
205   (
206      pscreen, format, PIPE_TEXTURE_3D, 1,
207      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
208   );
209   if (*is_supported) {
210      uint32_t max_2d_texture_level = pscreen->get_param(
211         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
212
213      if (!max_2d_texture_level)
214         return VDP_STATUS_ERROR;
215
216      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
217   } else {
218      *max_width = 0;
219      *max_height = 0;
220   }
221
222   return VDP_STATUS_OK;
223}
224
225/**
226 * Query the implementation's capability to perform a PutBits operation using
227 * application data matching the surface's format.
228 */
229VdpStatus
230vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
231                                                    VdpBool *is_supported)
232{
233   if (!is_supported)
234      return VDP_STATUS_INVALID_POINTER;
235
236   return VDP_STATUS_NO_IMPLEMENTATION;
237}
238
239/**
240 * Query the implementation's capability to perform a PutBits operation using
241 * application data in a specific indexed format.
242 */
243VdpStatus
244vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
245                                                  VdpRGBAFormat surface_rgba_format,
246                                                  VdpIndexedFormat bits_indexed_format,
247                                                  VdpColorTableFormat color_table_format,
248                                                  VdpBool *is_supported)
249{
250   if (!is_supported)
251      return VDP_STATUS_INVALID_POINTER;
252
253   return VDP_STATUS_NO_IMPLEMENTATION;
254}
255
256/**
257 * Query the implementation's capability to perform a PutBits operation using
258 * application data in a specific YCbCr/YUB format.
259 */
260VdpStatus
261vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
262                                                VdpYCbCrFormat bits_ycbcr_format,
263                                                VdpBool *is_supported)
264{
265   if (!is_supported)
266      return VDP_STATUS_INVALID_POINTER;
267
268   return VDP_STATUS_NO_IMPLEMENTATION;
269}
270
271/**
272 * Query the implementation's VdpBitmapSurface capabilities.
273 */
274VdpStatus
275vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
276                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
277{
278   vlVdpDevice *dev;
279   struct pipe_screen *pscreen;
280   enum pipe_format format;
281
282   dev = vlGetDataHTAB(device);
283   if (!dev)
284      return VDP_STATUS_INVALID_HANDLE;
285
286   pscreen = dev->vscreen->pscreen;
287   if (!pscreen)
288      return VDP_STATUS_RESOURCES;
289
290   format = FormatRGBAToPipe(surface_rgba_format);
291   if (format == PIPE_FORMAT_NONE)
292      return VDP_STATUS_INVALID_RGBA_FORMAT;
293
294   if (!(is_supported && max_width && max_height))
295      return VDP_STATUS_INVALID_POINTER;
296
297   *is_supported = pscreen->is_format_supported
298   (
299      pscreen, format, PIPE_TEXTURE_3D, 1,
300      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
301   );
302   if (*is_supported) {
303      uint32_t max_2d_texture_level = pscreen->get_param(
304         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
305
306      if (!max_2d_texture_level)
307         return VDP_STATUS_ERROR;
308
309      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
310   } else {
311      *max_width = 0;
312      *max_height = 0;
313   }
314
315   return VDP_STATUS_OK;
316}
317
318/**
319 * Query the implementation's support for a specific feature.
320 */
321VdpStatus
322vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
323                                   VdpBool *is_supported)
324{
325   if (!is_supported)
326      return VDP_STATUS_INVALID_POINTER;
327
328   switch (feature) {
329   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
330   case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
331      *is_supported = VDP_TRUE;
332      break;
333   default:
334      *is_supported = VDP_FALSE;
335      break;
336   }
337   return VDP_STATUS_OK;
338}
339
340/**
341 * Query the implementation's support for a specific parameter.
342 */
343VdpStatus
344vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
345                                     VdpBool *is_supported)
346{
347   if (!is_supported)
348      return VDP_STATUS_INVALID_POINTER;
349
350   switch (parameter) {
351   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
352   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
353   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
354   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
355      *is_supported = VDP_TRUE;
356      break;
357   default:
358      *is_supported = VDP_FALSE;
359      break;
360   }
361   return VDP_STATUS_OK;
362}
363
364/**
365 * Query the implementation's supported for a specific parameter.
366 */
367VdpStatus
368vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
369                                        void *min_value, void *max_value)
370{
371   vlVdpDevice *dev = vlGetDataHTAB(device);
372   struct pipe_screen *screen;
373   enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
374   if (!dev)
375      return VDP_STATUS_INVALID_HANDLE;
376   if (!(min_value && max_value))
377      return VDP_STATUS_INVALID_POINTER;
378   screen = dev->vscreen->pscreen;
379   switch (parameter) {
380   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
381      *(uint32_t*)min_value = 48;
382      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
383      break;
384   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
385      *(uint32_t*)min_value = 48;
386      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
387      break;
388
389   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
390      *(uint32_t*)min_value = 0;
391      *(uint32_t*)max_value = 4;
392      break;
393
394   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
395   default:
396      return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
397   }
398   return VDP_STATUS_OK;
399}
400
401/**
402 * Query the implementation's support for a specific attribute.
403 */
404VdpStatus
405vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
406                                     VdpBool *is_supported)
407{
408   if (!is_supported)
409      return VDP_STATUS_INVALID_POINTER;
410
411   switch (attribute) {
412   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
413   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
414   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
415   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
416   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
417   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
418   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
419      *is_supported = VDP_TRUE;
420      break;
421   default:
422      *is_supported = VDP_FALSE;
423   }
424   return VDP_STATUS_OK;
425}
426
427/**
428 * Query the implementation's supported for a specific attribute.
429 */
430VdpStatus
431vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
432                                        void *min_value, void *max_value)
433{
434   if (!(min_value && max_value))
435      return VDP_STATUS_INVALID_POINTER;
436
437   switch (attribute) {
438   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
439   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
440   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
441      *(float*)min_value = 0.f;
442      *(float*)max_value = 1.f;
443      break;
444   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
445      *(float*)min_value = -1.f;
446      *(float*)max_value = 1.f;
447      break;
448   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
449      *(uint8_t*)min_value = 0;
450      *(uint8_t*)max_value = 1;
451      break;
452   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
453   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
454   default:
455      return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
456   }
457   return VDP_STATUS_OK;
458}
459