Kodi Community Forum

Full Version: My attempt to bring HDR pass through to Kodi for Nvidia cards
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
After successfully updating the libbluray to 1.1.1 externally I felt with my little knowledge I could bring HDR pass through to Kodi. 

The HDR situation to sum up won't be solved because it requires the use of private APIs from Nvidia
You can find all the documentation here and ready to go scripts:
https://developer.nvidia.com/nvapi
https://developer.nvidia.com/high-dynami...evelopment

Or it would need microsoft to fix HDR and enable a public API, since this problem is years old, I would put my money on Linux solving it first. 

So to Windows users there's still hope. 

Someone named worleydl made a visual studio script that uses the Nvidia API to enable HDR using the code made available by Nvidia. 

https://github.com/worleydl/hdr-switcher
This will toggle your system into HDR mode.

Now you need  advancedsettings.XML into C:\Users\YOUR USER NAME HERE\AppData\Roaming\Kodi\userdata
With the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<advancedsettings>    
    <try10bitoutput>true</try10bitoutput>    
</advancedsettings>

So the switcher is basically a .exe file that I have compiled for all of you and uploaded it here
https://mega.nz/#!yM8ECYID!0Qv6VtX6437Mo...Rt-5ifyUqQ

So now comes the final problem to finally solve this. 
The exe must run with Kodi and we all want this to be just for HDR content. 
"C:\Program Files\Kodi\Switcher.exe" | "C:\Program Files\Kodi\kodi.exe"

But kodi will not launch itself as an external player using this:

<playercorefactory>
<players>
<player name="HDR" type="ExternalPlayer" audio="false" video="true">
<filename>C:\Program Files\Kodi\hdr.bat</filename>
</player> 
</players>
 <rules action="prepend">
    <rule videoresolution="4K" player="HDR"/>
  </rules>
</playercorefactory>

There's two ways around this

1. install another kodi, edit the exe and run it externally like people are trying here:
https://forum.kodi.tv/showthread.php?tid...5&page=485

Not elegant at all. 

2. Hack into the skin like this:
https://forum.kodi.tv/showthread.php?tid=140711

This will not solve the problem because will trigger Switcher.exe for all content. 

So I decided to post this today before finding a final solution because I know someone here will give a WAY better alternative to just run an exe before the default player starts for HDR content, since now the hard part is done.
This is trivial but I can't figure out an elegant and seamless solution but this is it, we can finally have kodi to output HDR Smile
If you guys need the .dll to run here they are:

vcruntime140d.dll
https://mega.nz/#!WccEEYIQ!6aEWTN4xvUtAp...TbKraGmxJU


ucrtbased.rar
https://mega.nz/#!HYVQmQQC!fzgGoYcivcNFb...sv6usBW6UM

msvcp140d .rar
https://mega.nz/#!2IEAgaCD!1fi9AhJy7VBzy...y3glt6zXU8

I can confirm it works on the latest driver 430.86 with a 1080Ti.
What is the contents of hdr.bat?
(2019-05-29, 01:06)brazen1 Wrote: [ -> ]What is the contents of hdr.bat?

Just 
"C:\Program Files\Kodi\Switcher.exe" | "C:\Program Files\Kodi\kodi.exe"

But it does not work since kodi is already running. 
you can do a shortcut for switcher.exe with some combination keys like ctrl+alt+H or something while playing HDR content to start it. 

I'm starting to look into Kodi's source to add this and compile a nvidia hrd version of kodi but don't hold your breath, I have final exams for the next 3 weeks.
I believe someone will be faster than me on this.
I know how to insert an .exe to launch prior to an external player via .bat but not VideoPlayer.  I am holding my breath.  If this gets going, there will be parks named after you and worleydl and parades at least once a year   Nod
(2019-05-29, 01:16)brazen1 Wrote: [ -> ]I know how to insert an .exe to launch prior to an external player via .bat but not VideoPlayer.  I am holding my breath.  If this gets going, there will be parks named after you and worleydl and parades at least once a year   Nod

Haven't tried it but people were talking about an addon "Kodi Callbacks" it seems it can listen to events like "onPlayBackEnded" so it must have "OnPlayBackStarts" or something.

The tricky part is to trigger it for HDR content only.

And it's not like you can't use it now, the code is present and compiled, we are just talking about automation here.
If I understand the inner works of kodi matrix this might do it:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nvapi.h"
#include "uhdDisplay.h"

if (picture.hasDisplayMetadata || picture.hasLightMetadata)
void 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);
        }
    }

}

into /xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp

Displays that do not support HDR probably will blink once but won't do anything.
If you can compile, then the code change to be able to run multiple instances of Kodi just requires a block of code containing the is Kodi already running check to be commented out, see https://github.com/jjd-uk/xbmc/commit/ea...e84e14268f

I've not built anything with it in a while, so I'm assuming it would still work.
(2019-05-29, 15:23)jjd-uk Wrote: [ -> ]If you can compile, then the code change to be able to run multiple instances of Kodi just requires a block of code containing the is Kodi already running check to be commented out, see https://github.com/jjd-uk/xbmc/commit/ea...e84e14268f

I've not built anything with it in a while, so I'm assuming it would still work.

I believe this might work, but I'm trying to add it to kodi itself. 
I know almost nothing of C but I'm working on it here:

https://github.com/fandangos/xbmc/

I believe the only problem now is syntax. 
And I've used this function

if (picture.hasDisplayMetadata || picture.hasLightMetadata)

from a really old commit made by afdechin to a Leia build, so I have no idea if this function still exists on Matrix. 

If someone that knows the way around C could take a look at my git fork and correct the syntax I believe this might be a kodi hdr ready build without the need for a switcher.exe.
I'm happy to report that the code is compiling with visual studio and the new kodi right now is able to switch into HDR mode.
First, I'm starting with HDR set all the time before trying to implement a function to detect metadata in the files to trigger it only when needed.


The last piece of the puzzle that I would like some confirmation from someone of Team Kodi is that I need to add nvapi64.lib, which is a binary, it worked when I added it manually using visual studio into the linker.
But if I understand correctly you don't add libraries like this, you need to add nvapi.h into the cmakelist.txt.

I want to add this in a way people can build using the provided buildsetup.bat from Team Kodi.

I've made a /xbmc/lib/nvapi and added the .h files.

And directed it with the main CMakeList.txt like this:
set(INCLUDES ${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/lib
${CMAKE_SOURCE_DIR}/lib/gtest/include
${CMAKE_SOURCE_DIR}/lib/nvapi
${CMAKE_SOURCE_DIR}/xbmc
${CMAKE_SOURCE_DIR}/xbmc/${PLATFORM_DIR}

inside /xbmc/lib/nvapi I'm adding another CMakeList.txt with the following:
add_library(nvapi64 nvapi.h)

Is this the proper way to add libraries to Kodi?

I really would like some feedback on this because winrenderer.cpp is already working and compiling with the HDR code.
Wow, congrats.

If you get it working, you should start a new thread with some sort of official title, an introduction with instructions and a download link. It could sit alongside the DSPlayer thread. That thread is already very popular and DSPlayer has no current developer to update it.
Well done, I'm definitely interested in this.  I'm using MadVR only for HDR passthrough and would love to see this.  Even if it ends up being a custom build, would be great to have HDR switching.
As I've said I already know how to make it switch into HDR mode. The problem is that till 19th of june I have almost an exam per day and working on it involves a real mindset. If I start working on code I can't think of anything else, that's the reason I had to give it a break for now or else I would fail those tests. 

When I forked the HDR Switcher I fixed it to be able to compile with Visual Studio 2019, but Kodi supports Visual Studio 2017, which the original HDR Switcher version is aimed to. 
So I only figure this out recently. 

I never coded in C/C++ in my life so this is a big learning curve, my luck is that places like StackOverflow exists and people there are really into helping and fixing code. 
Some mistakes I make I get an answer how to fix in 30 seconds, so those are really noob mistakes. 


I think I'm going to start it all over again when I resume, my initial assumption was to copy the switcher .cpp (.cpp is an executable for C) into winrenderer.cpp. 
There's a much cleaner way of doing this, just copying the entire uhddisplay.cpp and setting it to compile and adding the uhddisplay.h (this is the header) into winrenderer.cpp with <include> "uhddisplay.h" will let me call the HDR Switch function leaving the original executable intact. 
Also I figured out how to add a library into CMake, since the original HDR Switcher uses a .sln project file for visual studio. 

#pragma comment(lib, "nvapi64.lib")

That's the proper way. 

Of course you need to set this library location into the main CMakeLists.txt file so the compiler is able to see it. 

So this means I can have just a nvapi folder with everything inside, a CMakeLists.txt into it, making it really clean to code and figure things out. 


For some reason my attempt right now is switching into HDR when I close kodi. So I still need to figure out the best place into Kodi's code to call the function. 
My initial assumption was winrenderer.cpp. And to anyone reading this the function is just SetHdrMonitorMode(true). 
Maybe I need to move it somewhere else, maybe baserenderer.cpp. I'm not sure and this will be a ton of trial and error before I get this working properly to figure out the exact place to call for it. 

When I get this fully working I intend to make a dedicated thread about this with a ready to go build based on Kodi Matrix.
Until it's ready I intend to use this thread like a developer's blog so I can throw some ideas and sometimes read my previews attempts to figure things out. 
As I've said I never coded anything in my life but since this is more like using other's people work I believe I can make this work. 

And one final problem is to disable ToneMapping when HDR is on, this will be tricky, I need to find this in code and comment the entire section. 
Or at least this is how I think it should be done. 

I believe I'm really close to get this to work, I just need an entire couple of days to set this in the correct place and set this to compile properly.
Take the time you need, mate. And good luck with the exams.

This is super exciting for many of us so I hope you keep us updated Smile 

Cheers
Hi mate, how'd your exams go?
Pages: 1 2 3