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