Subversion Repositories Kolibri OS

Rev

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