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