Skip to content

Add support for BT.2100 color space on NDI input#1334

Merged
Trouffman merged 5 commits into
DistroAV:masterfrom
BitRate27:colorspacespeedup
Aug 27, 2025
Merged

Add support for BT.2100 color space on NDI input#1334
Trouffman merged 5 commits into
DistroAV:masterfrom
BitRate27:colorspacespeedup

Conversation

@BitRate27

@BitRate27 BitRate27 commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

This PR adds the ability for the user to select BT.2100 as the color space for the an NDI source. It also moves the calculation of the color space conversion matrices to when the user changes the option, instead of recalculating on every frame.

This issue is reported in issue 1333 and is fixed by this PR.

Testing can be done by using the Test Patterns App in NDI Tools. Selecting the HDR option will send NDI in the BT.2100 color space.

@RayneYoruka
RayneYoruka requested a review from Trouffman August 8, 2025 22:21

@Trouffman Trouffman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple notes :
When selecting the source to be BT2100 this set the colorspace to value "5", even tho this is defined as 3 in the plugin code (L64) -> this seems to be the order defined by OBS in video-io.h.

Changing from VIDEO_CS_2100_HLG to VIDEO_CS_2100_PQ give 4 and VIDEO_CS_DEFAULT give 0, which is the order it is defined in video-io

Maybe the following need to be revised, if this even used ?

#define PROP_YUV_SPACE_BT601 1
#define PROP_YUV_SPACE_BT709 2
#define PROP_YUV_SPACE_BT2100 3

Documentation note :

  • Let's highlight that we use Rec. 2100 color space, HLG transfer type. Because OBS let user pick 2100 PQ or HLG.
  • Let's document also why we only use 2100 HLG.

@BitRate27

Copy link
Copy Markdown
Contributor Author

@Trouffman I have to respectfully disagree with your changes. Changing the switch statement in prop_to_colorspace to return VIDEO_CS_DEFAULT for the new BT2100 nullifies this new addition as there is no way to get the matrix parameters for BT2100_HLG from the video_format_get_parameters. Also, the #defines for the PROPs in ndi-source have no relation to the actual values used in OBS, as that is what the prop_to_colorspace function does.

I made a new commit to back out your changes.

Regarding documenting why we only use HLG:

  1. I could only select HLG in the Test Pattern App from NDI
  2. It seems there is no difference in the parameters as video_format_get_parameters in OBS will override HLG with PQ.
	if ((color_space == VIDEO_CS_DEFAULT) || (color_space == VIDEO_CS_SRGB))
		color_space = VIDEO_CS_709;
	else if (color_space == VIDEO_CS_2100_HLG)
		color_space = VIDEO_CS_2100_PQ;

Providing a way for the user to choose between HLG and PQ actually has no effect. So it was just labeled BT2100.
OBS allows the user to choose the colorspace of the output, and it may indeed distinguish between HLG and PQ, but this change is on the input side and it seems to not distinguish between HLG and PQ. Maybe this is something we can bring up with OBS, but I am not very knowledgeable in this area to take it further.

@Trouffman

Copy link
Copy Markdown
Collaborator

Thanks for the details! No problem on the override!

Next step : confirm proper behavior is observed and this will be merged!

@BitRate27

BitRate27 commented Aug 27, 2025

Copy link
Copy Markdown
Contributor Author

I don't know a way to verify the resulting color conversion within OBS is correct. All we can do is to make sure the parameters output by video_format_get_parameters are different for all 6 combinations (3 color space x 2 range):

07:56:43.260: [distroav] '2100Full' yuv_colorspace=5, yuv_range=2
07:56:43.260:   color_matrix=[1.000 0.000 1.475 -0.738 1.000 -0.165 -0.571 0.368 1.000 1.881 0.000 -0.942 0.000 0.000 0.000 1.000]
07:56:43.260:   color_range_min=[0.000 0.000 0.000]
07:56:43.260:   color_range_max=[1.000 1.000 1.000]
07:58:23.659: [distroav] '709Full' yuv_colorspace=2, yuv_range=2
07:58:23.659:   color_matrix=[1.000 0.000 1.575 -0.790 1.000 -0.187 -0.468 0.329 1.000 1.856 0.000 -0.931 0.000 0.000 0.000 1.000]
07:58:23.659:   color_range_min=[0.000 0.000 0.000]
07:58:23.659:   color_range_max=[1.000 1.000 1.000]
07:59:11.759: [distroav] '601Full' yuv_colorspace=1, yuv_range=2
07:59:11.759:   color_matrix=[1.000 0.000 1.402 -0.704 1.000 -0.344 -0.714 0.531 1.000 1.772 0.000 -0.889 0.000 0.000 0.000 1.000]
07:59:11.759:   color_range_min=[0.000 0.000 0.000]
07:59:11.759:   color_range_max=[1.000 1.000 1.000]
07:56:29.159: [distroav] '2100Lim' yuv_colorspace=5, yuv_range=1
07:56:29.159:   color_matrix=[1.168 0.000 1.684 -0.916 1.168 -0.188 -0.652 0.347 1.168 2.148 0.000 -1.148 0.000 0.000 0.000 1.000]
07:56:29.159:   color_range_min=[0.063 0.063 0.063]
07:56:29.159:   color_range_max=[0.919 0.938 0.938]
07:58:16.759: [distroav] '709Lim' yuv_colorspace=2, yuv_range=1
07:58:16.759:   color_matrix=[1.164 0.000 1.793 -0.973 1.164 -0.213 -0.533 0.301 1.164 2.112 0.000 -1.133 0.000 0.000 0.000 1.000]
07:58:16.759:   color_range_min=[0.063 0.063 0.063]
07:58:16.759:   color_range_max=[0.922 0.941 0.941]
07:59:07.160: [distroav] '601Lim' yuv_colorspace=1, yuv_range=1
07:59:07.160:   color_matrix=[1.164 0.000 1.596 -0.874 1.164 -0.392 -0.813 0.532 1.164 2.017 0.000 -1.086 0.000 0.000 0.000 1.000]
07:59:07.160:   color_range_min=[0.063 0.063 0.063]
07:59:07.160:   color_range_max=[0.922 0.941 0.941]

This shows that all 6 combinations do indeed produce different parameters. To verify the Output color space selection is independent of the input color space, I changed the Output color space to 2100 HLG and Full and dumped the parameters for the 2100Full input settings and got the same parameters.

*With OBS Output colorspace 2100 HLG and Full Range

08:12:28.077: [distroav] '2100Lim' yuv_colorspace=5, yuv_range=1
08:12:28.077:   color_matrix=[1.168 0.000 1.684 -0.916 1.168 -0.188 -0.652 0.347 1.168 2.148 0.000 -1.148 0.000 0.000 0.000 1.000]
08:12:28.077:   color_range_min=[0.063 0.063 0.063]
08:12:28.077:   color_range_max=[0.919 0.938 0.938]

@Trouffman

Copy link
Copy Markdown
Collaborator

I have experience the same on MacOs for testing. Good to go then.

@Trouffman
Trouffman merged commit 8f7cd0d into DistroAV:master Aug 27, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants