Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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_CAP_SUPPORTED);
  182.    if (*is_supported) {
  183.       *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH);
  184.       *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_HEIGHT);
  185.       *max_level = 16;
  186.       *max_macroblocks = (*max_width/16)*(*max_height/16);
  187.    } else {
  188.       *max_width = 0;
  189.       *max_height = 0;
  190.       *max_level = 0;
  191.       *max_macroblocks = 0;
  192.    }
  193.    pipe_mutex_unlock(dev->mutex);
  194.  
  195.    return VDP_STATUS_OK;
  196. }
  197.  
  198. /**
  199.  * Query the implementation's VdpOutputSurface capabilities.
  200.  */
  201. VdpStatus
  202. vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
  203.                                     VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
  204. {
  205.    vlVdpDevice *dev;
  206.    struct pipe_screen *pscreen;
  207.    enum pipe_format format;
  208.  
  209.    dev = vlGetDataHTAB(device);
  210.    if (!dev)
  211.       return VDP_STATUS_INVALID_HANDLE;
  212.  
  213.    pscreen = dev->vscreen->pscreen;
  214.    if (!pscreen)
  215.       return VDP_STATUS_RESOURCES;
  216.  
  217.    format = FormatRGBAToPipe(surface_rgba_format);
  218.    if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
  219.       return VDP_STATUS_INVALID_RGBA_FORMAT;
  220.  
  221.    if (!(is_supported && max_width && max_height))
  222.       return VDP_STATUS_INVALID_POINTER;
  223.  
  224.    pipe_mutex_lock(dev->mutex);
  225.    *is_supported = pscreen->is_format_supported
  226.    (
  227.       pscreen, format, PIPE_TEXTURE_3D, 1,
  228.       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
  229.    );
  230.    if (*is_supported) {
  231.       uint32_t max_2d_texture_level = pscreen->get_param(
  232.          pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
  233.  
  234.       if (!max_2d_texture_level) {
  235.          pipe_mutex_unlock(dev->mutex);
  236.          return VDP_STATUS_ERROR;
  237.       }
  238.  
  239.       *max_width = *max_height = pow(2, max_2d_texture_level - 1);
  240.    } else {
  241.       *max_width = 0;
  242.       *max_height = 0;
  243.    }
  244.    pipe_mutex_unlock(dev->mutex);
  245.  
  246.    return VDP_STATUS_OK;
  247. }
  248.  
  249. /**
  250.  * Query the implementation's capability to perform a PutBits operation using
  251.  * application data matching the surface's format.
  252.  */
  253. VdpStatus
  254. vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
  255.                                                     VdpBool *is_supported)
  256. {
  257.    vlVdpDevice *dev;
  258.    struct pipe_screen *pscreen;
  259.    enum pipe_format format;
  260.  
  261.    dev = vlGetDataHTAB(device);
  262.    if (!dev)
  263.       return VDP_STATUS_INVALID_HANDLE;
  264.  
  265.    pscreen = dev->vscreen->pscreen;
  266.    if (!pscreen)
  267.       return VDP_STATUS_ERROR;
  268.  
  269.    format = FormatRGBAToPipe(surface_rgba_format);
  270.    if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
  271.       return VDP_STATUS_INVALID_RGBA_FORMAT;
  272.  
  273.    if (!is_supported)
  274.       return VDP_STATUS_INVALID_POINTER;
  275.  
  276.    pipe_mutex_lock(dev->mutex);
  277.    *is_supported = pscreen->is_format_supported
  278.    (
  279.       pscreen, format, PIPE_TEXTURE_2D, 1,
  280.       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
  281.    );
  282.    pipe_mutex_unlock(dev->mutex);
  283.  
  284.    return VDP_STATUS_OK;
  285. }
  286.  
  287. /**
  288.  * Query the implementation's capability to perform a PutBits operation using
  289.  * application data in a specific indexed format.
  290.  */
  291. VdpStatus
  292. vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
  293.                                                   VdpRGBAFormat surface_rgba_format,
  294.                                                   VdpIndexedFormat bits_indexed_format,
  295.                                                   VdpColorTableFormat color_table_format,
  296.                                                   VdpBool *is_supported)
  297. {
  298.    vlVdpDevice *dev;
  299.    struct pipe_screen *pscreen;
  300.    enum pipe_format rgba_format, index_format, colortbl_format;
  301.  
  302.    dev = vlGetDataHTAB(device);
  303.    if (!dev)
  304.       return VDP_STATUS_INVALID_HANDLE;
  305.  
  306.    pscreen = dev->vscreen->pscreen;
  307.    if (!pscreen)
  308.       return VDP_STATUS_ERROR;
  309.  
  310.    rgba_format = FormatRGBAToPipe(surface_rgba_format);
  311.    if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
  312.       return VDP_STATUS_INVALID_RGBA_FORMAT;
  313.  
  314.    index_format = FormatIndexedToPipe(bits_indexed_format);
  315.    if (index_format == PIPE_FORMAT_NONE)
  316.        return VDP_STATUS_INVALID_INDEXED_FORMAT;
  317.  
  318.    colortbl_format = FormatColorTableToPipe(color_table_format);
  319.    if (colortbl_format == PIPE_FORMAT_NONE)
  320.        return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
  321.  
  322.    if (!is_supported)
  323.       return VDP_STATUS_INVALID_POINTER;
  324.  
  325.    pipe_mutex_lock(dev->mutex);
  326.    *is_supported = pscreen->is_format_supported
  327.    (
  328.       pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
  329.       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
  330.    );
  331.  
  332.    *is_supported &= pscreen->is_format_supported
  333.    (
  334.       pscreen, index_format, PIPE_TEXTURE_2D, 1,
  335.       PIPE_BIND_SAMPLER_VIEW
  336.    );
  337.  
  338.    *is_supported &= pscreen->is_format_supported
  339.    (
  340.       pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
  341.       PIPE_BIND_SAMPLER_VIEW
  342.    );
  343.    pipe_mutex_unlock(dev->mutex);
  344.  
  345.    return VDP_STATUS_OK;
  346. }
  347.  
  348. /**
  349.  * Query the implementation's capability to perform a PutBits operation using
  350.  * application data in a specific YCbCr/YUB format.
  351.  */
  352. VdpStatus
  353. vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
  354.                                                 VdpYCbCrFormat bits_ycbcr_format,
  355.                                                 VdpBool *is_supported)
  356. {
  357.    vlVdpDevice *dev;
  358.    struct pipe_screen *pscreen;
  359.    enum pipe_format rgba_format, ycbcr_format;
  360.  
  361.    dev = vlGetDataHTAB(device);
  362.    if (!dev)
  363.       return VDP_STATUS_INVALID_HANDLE;
  364.  
  365.    pscreen = dev->vscreen->pscreen;
  366.    if (!pscreen)
  367.       return VDP_STATUS_ERROR;
  368.  
  369.    rgba_format = FormatRGBAToPipe(surface_rgba_format);
  370.    if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
  371.       return VDP_STATUS_INVALID_RGBA_FORMAT;
  372.  
  373.    ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format);
  374.    if (ycbcr_format == PIPE_FORMAT_NONE)
  375.        return VDP_STATUS_INVALID_INDEXED_FORMAT;
  376.  
  377.    if (!is_supported)
  378.       return VDP_STATUS_INVALID_POINTER;
  379.  
  380.    pipe_mutex_lock(dev->mutex);
  381.    *is_supported = pscreen->is_format_supported
  382.    (
  383.       pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
  384.       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
  385.    );
  386.  
  387.    *is_supported &= pscreen->is_video_format_supported
  388.    (
  389.       pscreen, ycbcr_format,
  390.       PIPE_VIDEO_PROFILE_UNKNOWN
  391.    );
  392.    pipe_mutex_unlock(dev->mutex);
  393.  
  394.    return VDP_STATUS_OK;
  395. }
  396.  
  397. /**
  398.  * Query the implementation's VdpBitmapSurface capabilities.
  399.  */
  400. VdpStatus
  401. vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
  402.                                     VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
  403. {
  404.    vlVdpDevice *dev;
  405.    struct pipe_screen *pscreen;
  406.    enum pipe_format format;
  407.  
  408.    dev = vlGetDataHTAB(device);
  409.    if (!dev)
  410.       return VDP_STATUS_INVALID_HANDLE;
  411.  
  412.    pscreen = dev->vscreen->pscreen;
  413.    if (!pscreen)
  414.       return VDP_STATUS_RESOURCES;
  415.  
  416.    format = FormatRGBAToPipe(surface_rgba_format);
  417.    if (format == PIPE_FORMAT_NONE)
  418.       return VDP_STATUS_INVALID_RGBA_FORMAT;
  419.  
  420.    if (!(is_supported && max_width && max_height))
  421.       return VDP_STATUS_INVALID_POINTER;
  422.  
  423.    pipe_mutex_lock(dev->mutex);
  424.    *is_supported = pscreen->is_format_supported
  425.    (
  426.       pscreen, format, PIPE_TEXTURE_3D, 1,
  427.       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
  428.    );
  429.    if (*is_supported) {
  430.       uint32_t max_2d_texture_level = pscreen->get_param(
  431.          pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
  432.  
  433.       if (!max_2d_texture_level) {
  434.          pipe_mutex_unlock(dev->mutex);
  435.          return VDP_STATUS_ERROR;
  436.       }
  437.  
  438.       *max_width = *max_height = pow(2, max_2d_texture_level - 1);
  439.    } else {
  440.       *max_width = 0;
  441.       *max_height = 0;
  442.    }
  443.    pipe_mutex_unlock(dev->mutex);
  444.  
  445.    return VDP_STATUS_OK;
  446. }
  447.  
  448. /**
  449.  * Query the implementation's support for a specific feature.
  450.  */
  451. VdpStatus
  452. vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
  453.                                    VdpBool *is_supported)
  454. {
  455.    if (!is_supported)
  456.       return VDP_STATUS_INVALID_POINTER;
  457.  
  458.    switch (feature) {
  459.    case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
  460.    case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
  461.       *is_supported = VDP_TRUE;
  462.       break;
  463.    default:
  464.       *is_supported = VDP_FALSE;
  465.       break;
  466.    }
  467.    return VDP_STATUS_OK;
  468. }
  469.  
  470. /**
  471.  * Query the implementation's support for a specific parameter.
  472.  */
  473. VdpStatus
  474. vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
  475.                                      VdpBool *is_supported)
  476. {
  477.    if (!is_supported)
  478.       return VDP_STATUS_INVALID_POINTER;
  479.  
  480.    switch (parameter) {
  481.    case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
  482.    case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
  483.    case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
  484.    case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
  485.       *is_supported = VDP_TRUE;
  486.       break;
  487.    default:
  488.       *is_supported = VDP_FALSE;
  489.       break;
  490.    }
  491.    return VDP_STATUS_OK;
  492. }
  493.  
  494. /**
  495.  * Query the implementation's supported for a specific parameter.
  496.  */
  497. VdpStatus
  498. vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
  499.                                         void *min_value, void *max_value)
  500. {
  501.    vlVdpDevice *dev = vlGetDataHTAB(device);
  502.    struct pipe_screen *screen;
  503.    enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
  504.  
  505.    if (!dev)
  506.       return VDP_STATUS_INVALID_HANDLE;
  507.    if (!(min_value && max_value))
  508.       return VDP_STATUS_INVALID_POINTER;
  509.  
  510.    pipe_mutex_lock(dev->mutex);
  511.    screen = dev->vscreen->pscreen;
  512.    switch (parameter) {
  513.    case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
  514.       *(uint32_t*)min_value = 48;
  515.       *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
  516.       break;
  517.    case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
  518.       *(uint32_t*)min_value = 48;
  519.       *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
  520.       break;
  521.  
  522.    case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
  523.       *(uint32_t*)min_value = 0;
  524.       *(uint32_t*)max_value = 4;
  525.       break;
  526.  
  527.    case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
  528.    default:
  529.       pipe_mutex_unlock(dev->mutex);
  530.       return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
  531.    }
  532.    pipe_mutex_unlock(dev->mutex);
  533.    return VDP_STATUS_OK;
  534. }
  535.  
  536. /**
  537.  * Query the implementation's support for a specific attribute.
  538.  */
  539. VdpStatus
  540. vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
  541.                                      VdpBool *is_supported)
  542. {
  543.    if (!is_supported)
  544.       return VDP_STATUS_INVALID_POINTER;
  545.  
  546.    switch (attribute) {
  547.    case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
  548.    case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
  549.    case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
  550.    case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
  551.    case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
  552.    case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
  553.    case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
  554.       *is_supported = VDP_TRUE;
  555.       break;
  556.    default:
  557.       *is_supported = VDP_FALSE;
  558.    }
  559.    return VDP_STATUS_OK;
  560. }
  561.  
  562. /**
  563.  * Query the implementation's supported for a specific attribute.
  564.  */
  565. VdpStatus
  566. vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
  567.                                         void *min_value, void *max_value)
  568. {
  569.    if (!(min_value && max_value))
  570.       return VDP_STATUS_INVALID_POINTER;
  571.  
  572.    switch (attribute) {
  573.    case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
  574.    case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
  575.    case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
  576.       *(float*)min_value = 0.f;
  577.       *(float*)max_value = 1.f;
  578.       break;
  579.    case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
  580.       *(float*)min_value = -1.f;
  581.       *(float*)max_value = 1.f;
  582.       break;
  583.    case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
  584.       *(uint8_t*)min_value = 0;
  585.       *(uint8_t*)max_value = 1;
  586.       break;
  587.    case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
  588.    case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
  589.    default:
  590.       return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
  591.    }
  592.    return VDP_STATUS_OK;
  593. }
  594.