错误C2664:无法从“ NvPhysicalGpuHandle”转换参数1

时间:2019-05-31 00:52:48

标签: c++

我正在尝试将Nvidia API添加到kodi中以进行HDR切换。 我没有太多的代码知识,我正在尝试将项目HDR Switcher改编为kodi函数。

使用Visual Studio将HDR Switcher编译为exe时,它可以工作并触发HDR。 现在,我需要使其与kodi配合使用,以实现无缝的HDR播放。

这使用了NVidia私有API。

如果实施,这将对许多用户有价值。

错误: 错误C2664:“ NvAPI_St atus NvAPI_GPU_GetConnectedDisplayIds(NvPhysicalGpuHandle,NV_GPU_DISPLAYIDS *,NvU32 *,NvU32)':无法转换参数 1从“ NvPhysicalGpuHandle [64]”到“ NvPhysicalGpuHandle”

#include "WinRenderer.h"
#include "RenderCapture.h"
#include "RenderFactory.h"
#include "RenderFlags.h"
#include "rendering/dx/RenderContext.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/log.h"
#include "windows/RendererDXVA.h"
#include "windows/RendererSoftware.h"
#include "windows/RendererShaders.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinSystem.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "DeviceManager.h"
#include "nvapi.h"
#include "uhdDisplay.h"


struct render_details
{
  using map = std::map<RenderMethod, int>;
  using weights_fn = std::function<void(map&, const VideoPicture&)>;
  using create_fn = std::function<CRendererBase*(CVideoSettings&)>;

  RenderMethod method;
  std::string name;
  create_fn create;
  weights_fn weights;

  template<class T>
  constexpr static render_details get(RenderMethod method, const std::string& name)
  {
    return { method, name, T::Create, T::GetWeight };
  }
};

static std::vector<render_details> RenderMethodDetails =
{
  render_details::get<CRendererSoftware>(RENDER_SW, "Software"),
  render_details::get<CRendererShaders>(RENDER_PS, "Pixel Shaders"),
  render_details::get<CRendererDXVA>(RENDER_DXVA, "DXVA"),
};

CBaseRenderer* CWinRenderer::Create(CVideoBuffer*)
{
  return new CWinRenderer();
}

bool CWinRenderer::Register()
{
  VIDEOPLAYER::CRendererFactory::RegisterRenderer("default", Create);
  return true;
}

CWinRenderer::CWinRenderer()
{
  m_format = AV_PIX_FMT_NONE;
  PreInit();
}

CWinRenderer::~CWinRenderer()
{
  CWinRenderer::UnInit();
}

CRendererBase* CWinRenderer::SelectRenderer(const VideoPicture& picture)
{
  int iRequestedMethod = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_VIDEOPLAYER_RENDERMETHOD);
  CLog::LogF(LOGDEBUG, "requested render method: %d", iRequestedMethod);

  std::map<RenderMethod, int> weights;
  for (auto& details : RenderMethodDetails)
    details.weights(weights, picture);

  RenderMethod method;
  switch (iRequestedMethod)
  {
  case RENDER_METHOD_SOFTWARE:
    if (weights[RENDER_SW])
    {
      method = RENDER_SW;
      break;
    }
    // fallback to PS
  case RENDER_METHOD_D3D_PS:
    if (weights[RENDER_PS])
    {
      method = RENDER_PS;
      break;
    }
    //fallback to DXVA
  case RENDER_METHOD_DXVA:
    if (weights[RENDER_DXVA])
    {
      method = RENDER_DXVA;
      break;
    }
    // fallback to AUTO
  case RENDER_METHOD_AUTO:
  default:
  {
    const auto it = std::max_element(weights.begin(), weights.end(),
      [](auto& w1, auto& w2) { return w1.second < w2.second; });

    if (it != weights.end())
    {
      method = it->first;
      break;
    }

    // there is no elements in weights, so no renderer which supports incoming video buffer
    CLog::LogF(LOGERROR, "unable to select render method for video buffer");
    return nullptr;
  }
  }

  const auto it = std::find_if(RenderMethodDetails.begin(), RenderMethodDetails.end(),
    [method](render_details& d) { return d.method == method; });

  if (it != RenderMethodDetails.end())
  {
    CLog::LogF(LOGDEBUG, "selected render method: {}", it->name);
    return it->create(m_videoSettings);
  }

  // something goes really wrong
  return nullptr;
}

CRect CWinRenderer::GetScreenRect() const
{
  CRect screenRect(0.f, 0.f,
    static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()),
    static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()));

  switch (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode())
  {
  case RENDER_STEREO_MODE_SPLIT_HORIZONTAL:
    screenRect.y2 *= 2;
    break;
  case RENDER_STEREO_MODE_SPLIT_VERTICAL:
    screenRect.x2 *= 2;
    break;
  default:
    break;
  }

  return screenRect;
}

bool CWinRenderer::Configure(const VideoPicture &picture, float fps, unsigned int orientation)
{
  m_sourceWidth       = picture.iWidth;
  m_sourceHeight      = picture.iHeight;
  m_renderOrientation = orientation;
  m_fps = fps;
  m_iFlags = GetFlagsChromaPosition(picture.chroma_position)
           | GetFlagsColorMatrix(picture.color_space, picture.iWidth, picture.iHeight)
           | GetFlagsColorPrimaries(picture.color_primaries)
           | GetFlagsStereoMode(picture.stereoMode);
  m_format = picture.videoBuffer->GetFormat();

  // calculate the input frame aspect ratio
  CalculateFrameAspectRatio(picture.iDisplayWidth, picture.iDisplayHeight);
  SetViewMode(m_videoSettings.m_ViewMode);
  // if (picture.hasDisplayMetadata || picture.hasLightMetadata) {
  SetHdrMonitorMode(true);
    // } 
  ManageRenderArea();


  m_renderer.reset(SelectRenderer(picture));
  if (!m_renderer || !m_renderer->Configure(picture, fps, orientation))
  {
    m_renderer.reset();
    return false;
  }

  m_bConfigured = true;
  return true;
}
static bool first = true;

void CWinRenderer::SetHdrMonitorMode(bool enableHDR)
{
    if (first)
    {
        NvAPI_Initialize();
        first = false;
    }

    NvAPI_Status nvStatus = NVAPI_OK;
    NvDisplayHandle hNvDisplay = NULL;

    // get first display handle which should work for all NVAPI calls for all GPUs
    if ((nvStatus = NvAPI_EnumNvidiaDisplayHandle(0, &hNvDisplay)) != NVAPI_OK)
    {
        printf("NvAPI_EnumNvidiaDisplayHandle returned error code %d\r\n", nvStatus);

        return;
    }

    NvU32 gpuCount = 0;
    NvU32 maxDisplayIndex = 0;
    NvPhysicalGpuHandle ahGPU[NVAPI_MAX_PHYSICAL_GPUS] = {};

    // get the list of displays connected, populate the dynamic components
    nvStatus = NvAPI_EnumPhysicalGPUs(ahGPU, &gpuCount);

    if (NVAPI_OK != nvStatus)
    {
        printf("NvAPI_EnumPhysicalGPUs returned error code %d\r\n", nvStatus);

        return;
    }

    for (NvU32 i = 0; i < gpuCount; ++i)
    {
        NvU32 displayIdCount = 16;
        NvU32 flags = 0;
        NV_GPU_DISPLAYIDS displayIdArray[16] = {};
        displayIdArray[0].version = NV_GPU_DISPLAYIDS_VER;

        nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU, displayIdArray, &displayIdCount, flags);

        if (NVAPI_OK == nvStatus)
        {
            printf("Display count %d\r\n", displayIdCount);

            for (maxDisplayIndex = 0; maxDisplayIndex < displayIdCount; ++maxDisplayIndex)
            {
                printf("Display tested %d\r\n", maxDisplayIndex);

                NV_HDR_CAPABILITIES hdrCapabilities = {};

                hdrCapabilities.version = NV_HDR_CAPABILITIES_VER;

                if (NVAPI_OK == NvAPI_Disp_GetHdrCapabilities(displayIdArray[maxDisplayIndex].displayId, &hdrCapabilities))
                {
                    if (hdrCapabilities.isST2084EotfSupported)
                    {
                        printf("Display %d supports ST2084 EOTF\r\n", maxDisplayIndex);

                        NV_HDR_COLOR_DATA hdrColorData = {};

                        memset(&hdrColorData, 0, sizeof(hdrColorData));

                        hdrColorData.version = NV_HDR_COLOR_DATA_VER;
                        hdrColorData.cmd = NV_HDR_CMD_SET;
                        hdrColorData.static_metadata_descriptor_id = NV_STATIC_METADATA_TYPE_1;

                        hdrColorData.hdrMode = enableHDR ? NV_HDR_MODE_UHDBD : NV_HDR_MODE_OFF;


                        nvStatus = NvAPI_Disp_HdrColorControl(displayIdArray[maxDisplayIndex].displayId, &hdrColorData);

                        if (NVAPI_OK == nvStatus)
                        {
                            printf("NvAPI_Disp_SethdrColorData call has succeeded: ");
                        }
                        else
                        {
                            NvAPI_ShortString szDesc;
                            NvAPI_GetErrorMessage(nvStatus, szDesc);
                            printf("NvAPI_Disp_HdrColorControl returned %s (%x)\r\n", szDesc, nvStatus);
                        }
                    }
                }
                else
                {
                    NvAPI_ShortString szDesc;
                    NvAPI_GetErrorMessage(nvStatus, szDesc);
                    printf("NvAPI_Disp_GetHdrCapabilities returned %s (%x)\r\n", szDesc, nvStatus);
                }
            }
        }
        else
        {
            NvAPI_ShortString szDesc;
            NvAPI_GetErrorMessage(nvStatus, szDesc);
            printf("NvAPI_GPU_GetConnectedDisplayIds returned %s (%x)\r\n", szDesc, nvStatus);
        }
    }
  }  

int CWinRenderer::NextBuffer() const
{
  return m_renderer->NextBuffer();
}

void CWinRenderer::AddVideoPicture(const VideoPicture &picture, int index)
{
  m_renderer->AddVideoPicture(picture, index);
}

void CWinRenderer::Update()
{
  if (!m_bConfigured)
    return;

  ManageRenderArea();
  m_renderer->ManageTextures();
}

void CWinRenderer::RenderUpdate(int index, int index2, bool clear, unsigned int flags, unsigned int alpha)
{
  if (!m_bConfigured)
    return;

  if (clear)
    CServiceBroker::GetWinSystem()->GetGfxContext().Clear(DX::Windowing()->UseLimitedColor() ? 0x101010 : 0);
  DX::Windowing()->SetAlphaBlendEnable(alpha < 255);

  ManageRenderArea();
  m_renderer->Render(index, index2, DX::Windowing()->GetBackBuffer(), 
                     m_sourceRect, m_destRect, GetScreenRect(), flags);
}

bool CWinRenderer::RenderCapture(CRenderCapture* capture)
{
  if (!m_bConfigured)
    return false;

  capture->BeginRender();
  if (capture->GetState() != CAPTURESTATE_FAILED)
  {
    const CRect destRect(0, 0, static_cast<float>(capture->GetWidth()), static_cast<float>(capture->GetHeight()));

    m_renderer->Render(capture->GetTarget(), m_sourceRect, destRect, GetScreenRect());
    capture->EndRender();

    return true;
  }

  return false;
}

void CWinRenderer::SetBufferSize(int numBuffers)
{
  if (!m_bConfigured)
    return;

  m_renderer->SetBufferSize(numBuffers);
}

void CWinRenderer::PreInit()
{
  CSingleLock lock(CServiceBroker::GetWinSystem()->GetGfxContext());
  m_bConfigured = false;
  UnInit();
}

void CWinRenderer::UnInit()
{
  CSingleLock lock(CServiceBroker::GetWinSystem()->GetGfxContext());

  m_renderer.reset();
  m_bConfigured = false;
}

bool CWinRenderer::Flush(bool saveBuffers)
{
  if (!m_bConfigured)
    return false;

  return m_renderer->Flush(saveBuffers);
}

bool CWinRenderer::Supports(ERENDERFEATURE feature)
{
  if(feature == RENDERFEATURE_BRIGHTNESS)
    return true;

  if(feature == RENDERFEATURE_CONTRAST)
    return true;

  if (feature == RENDERFEATURE_STRETCH         ||
      feature == RENDERFEATURE_NONLINSTRETCH   ||
      feature == RENDERFEATURE_ZOOM            ||
      feature == RENDERFEATURE_VERTICAL_SHIFT  ||
      feature == RENDERFEATURE_PIXEL_RATIO     ||
      feature == RENDERFEATURE_ROTATION        ||
      feature == RENDERFEATURE_POSTPROCESS     ||
      feature == RENDERFEATURE_TONEMAP)
    return true;

  return false;
}

bool CWinRenderer::Supports(ESCALINGMETHOD method)
{
  if (!m_bConfigured)
    return false;

  return m_renderer->Supports(method);
}

bool CWinRenderer::WantsDoublePass()
{
  if (!m_bConfigured)
    return false;

  return m_renderer->WantsDoublePass();
}

bool CWinRenderer::ConfigChanged(const VideoPicture& picture)
{
  if (!m_bConfigured)
    return true;

  return picture.videoBuffer->GetFormat() != m_format;
}

CRenderInfo CWinRenderer::GetRenderInfo()
{
  if (!m_bConfigured)
    return {};

  return m_renderer->GetRenderInfo();
}

void CWinRenderer::ReleaseBuffer(int idx)
{
  if (!m_bConfigured)
    return;

  m_renderer->ReleaseBuffer(idx);
}

bool CWinRenderer::NeedBuffer(int idx)
{
  if (!m_bConfigured)
    return false;

  return m_renderer->NeedBuffer(idx);
}


´´´

1 个答案:

答案 0 :(得分:0)

更改

nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU, displayIdArray, &displayIdCount, flags);

nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU[i], displayIdArray, &displayIdCount, flags);

感谢@ 1201ProgramAlarm