performance impact and precision of colour formats

tari3x

New Member
Could you recommend a good primer on the available colour formats? So far it seems that only RGB gives me truly lossless reproduction, but it is also the one that hits performance very hard.

Some particular questions I'd like to be able to answer:
* What is the "native" format that the raw capture is in? If it's not RGB then why is RGB the most accurate, and if it is RGB then why is RGB most expensive to convert to?

* At what point does colourspace conversion happen? Is it part of the encoding or is it separate? If choosing RGB is a problem, should I even try solving this problem by looking for a different encoder?

* I heard that there is "no support for RGB on the GPU". Does this make sense? Does this mean that if I choose nvenc, there's no way for me to get accurate colour reproduction?
 
Oh, and should I expect I444 captures to be lossless? They are sadly not, even though the difference is small. Is this due to float precision, or maybe something about full vs partial colour range?
 
...should I expect I444 captures to be lossless? They are sadly not, even though the difference is small.
Hardly believable that you'll be able to distinguish RGB and I444 when all processing was done OK.

The source in OBS is "digital data" (video or audio) and they can be "any" format - thus, OBS converts all color spaces (sample rates) to same base before data can be encoded to new stream (file). Some encoders do not support RGB (I444 etc), so NV12 is forced (in most cases).

Look for color guides (they usually has more info about the subject):
 
Thanks for the pointer! I did look through those, but didn't find a guide that would answer my questions.

> The source in OBS is "digital data" (video or audio) and they can be "any" format - thus, OBS converts all color spaces (sample rates) to same base before data can be encoded to new stream (file). Some encoders do not support RGB (I444 etc), so NV12 is forced (in most cases).

Is there a way to find out what format my particular source is?

Your description makes it sound like OBS might be going via NV12 when I choose RGB. I think that's not the case since I don't loose colour precision with that setting. So sadly my original questions still stand.

> Hardly believable that you'll be able to distinguish RGB and I444 when all processing was done OK.

So I guess it wasn't done OK. Is there a way for me to find out what went wrong?

Reading I want to record actully lossless video (full range RGB, no subsampling) it seams like RGB performance loss is a well-known issue but I don't think that thread explains where it comes from.
 
As another data point, I tried dxtory and it seems to capture lossless RGB without too much struggle. This makes me think that there's some inefficiency that is endemic to OBS, but I can't find it documented anywhere.
 
Reading I want to record actully lossless video (full range RGB, no subsampling) it seams like RGB performance loss is a well-known issue but I don't think that thread explains where it comes from.
It was fixed. I updated the thread for the actual fix (PR).

Without OBS log-file hard to tell what is wrong with your setup.

OBS has special lossless mode for Output Mode: Simple.

To test color issues people usually uses test tables (test charts) and special equipment. Consumers - usually using their own eyes (if not color blinded, in case color blindness present - you usually asking other person to check if colors are OK, it is normal practice). Simple color test charts were in the Guides section of the forum: https://obsproject.com/forum/resources/categories/guides-studio.8/ maybe you miss them.
 
It was fixed. I updated the thread for the actual fix (PR).
Sorry - that PR talks about adding colour range and colourspace data, whereas what I am asking is why RGB is so slow compared to the rest - something that multiple users in multiple threads have observed and something that @koala referred to in the thread I mentioned.
To test color issues people usually uses test tables (test charts) and special equipment. Consumers - usually using their own eyes (if not color blinded, in case color blindness present - you usually asking other person to check if colors are OK, it is normal practice). Simple color test charts were in the Guides section of the forum: https://obsproject.com/forum/resources/categories/guides-studio.8/ maybe you miss them.
Sorry, I think we're talking past each other. My I444 and RGB are different, it's not difficult to see. I want to understand why.
 
...why RGB is so slow compared to the rest
It takes a lot of bus bandwidth. But what is the "rest" here, is it x264 + NV12?

...My I444 and RGB are different, it's not difficult to see. I want to understand why.
You recording image that you know how it should look like. Then you playback the recording and compare. By looking at the colors that are not same you making assumption what may gonna wrong. You making changes (settings, equipment, software) and then repeat until issue fixed.
Man, really, I don't know what you see on your PC. I can only guess here.
 
yuv444 is an example. It is same size as RGB, so it should be taking the same bandwidth.
Performance issues requires exact conditions to talk about.
For my PC, and custom build of OBS, performance for the:
  • Output Mode: Advanced, software x264 encoder with crf=0 and I444 is highly depends on used Preset ("ultrafast" has lowest impact).
  • Output Mode: Simple and Lossless quality with RGB setting (it was named "RGB" in old OBS I'm using), has lower impact on CPU than "veryfast" preset of x264, I444, CRF=0.
but for your PC, and your version of OBS results can be absolutely different.

...I'm best off trying to figure this out by myself. Thanks all!
Good luck!

Small color inaccuracies for I444 conversions are quite possible (about 1 bit for all three color components). Where was possible, OBS uses simplifications in processing to keep quality/performance balance. My opinion - the "RGB" is preferable in case you chose Output Mode: Simple and Lossless quality for OBS up to v28 (FFmpeg libs that are shipped with OBS are changed time to time, so it also may impact both quality and performance from build to build, OBS uses FFmpeg for encoding in lossless mode). So, for lossless 8-bit recordings I'm choosing Output Mode: Simple, Lossless quality, RGB - read it as "BGRA (8-bit)" setting, Full range, color space Rec. 709 or sRGB (at your wish).

Was it helpful?
 
Not getting any traction there either? Perhaps, OBS is not the right tool or it just requires a more powerful PC? I tested & 30FPS is doable with a 12900k/3090 but 60 is a non starter. YMMV
 
@rockbottom strange... If I remember it right, the first implementation of HW NVIDIA encoders in OBS used FFmpeg libs, so encoding was done in the similar way as FFmpeg encodes videos from the disk (or other source) - read frame to RAM>upload it to VRAM>encode by GPU>download to RAM>save frame to disk. Then "native" texture sharing version was implemented and "upload to VRAM" step was excluded. HW based encoders at that time didn't supported "RGB textures" only planes from NV12 format were supported, so there were designed "fallback" mechanism to back to FFmpeg version of encoder if NV12 is not available. Today I see HEVC in the logs and seems that it also expects YUV planes as input. Maybe everything simply works as it should?
 
Still falling back.

Also noticed OP has HAGS enabled....

9:30:08.308: video settings reset:
09:30:08.308: base resolution: 3840x2160
09:30:08.308: output resolution: 3840x2160
09:30:08.308: downscale filter: Bicubic
09:30:08.308: fps: 30/1
09:30:08.308: format: BGRA
09:30:08.308: YUV mode: None
09:30:08.308: GPU conversion not available for format: 7
09:30:08.308: NV12 texture support not available
09:30:08.328: Settings changed (advanced)
09:30:08.329: ------------------------------------------------
09:30:12.264: [jim-nvenc] nv12/p010 not active, falling back to ffmpeg
09:30:12.264: ---------------------------------
09:30:12.264: [FFmpeg NVENC encoder: 'advanced_video_recording'] settings:
09:30:12.264: encoder: NVIDIA NVENC HEVC (FFmpeg)
09:30:12.264: rate_control: lossless
09:30:12.264: bitrate: 0
09:30:12.264: cqp: 0
09:30:12.264: keyint: 30
09:30:12.264: preset: p5
09:30:12.264: tuning: hq
09:30:12.264: multipass: disabled
09:30:12.264: profile: main
09:30:12.264: width: 3840
09:30:12.264: height: 2160
09:30:12.264: b-frames: 0
09:30:12.264: psycho-aq: 0
09:30:12.264: GPU: 0
09:30:12.264:
09:30:12.460: ---------------------------------
09:30:12.460: [FFmpeg pcm_s24le encoder: 'Track1'] bitrate: 0, channels: 2, channel_layout: stereo
09:30:12.460:
09:30:12.476: ==== Recording Start ===============================================
09:30:12.476: [ffmpeg muxer: 'adv_file_output'] Writing file 'D:/2023-08-10_09-30-12.mkv'...
09:30:32.772: [ffmpeg muxer: 'adv_file_output'] Output of file 'D:/2023-08-10_09-30-12.mkv' stopped
09:30:32.772: Output 'adv_file_output': stopping
09:30:32.772: Output 'adv_file_output': Total frames output: 605
09:30:32.772: Output 'adv_file_output': Total drawn frames: 609
09:30:32.772: ==== Recording Stop ================================================
09:30:41.024: Number of remaining views: 1
09:30:41.024: ---------------------------------
09:30:41.024: video settings reset:
09:30:41.024: base resolution: 3840x2160
09:30:41.024: output resolution: 3840x2160
09:30:41.024: downscale filter: Bicubic
09:30:41.024: fps: 60/1
09:30:41.024: format: BGRA
09:30:41.024: YUV mode: None
09:30:41.024: GPU conversion not available for format: 7
09:30:41.024: NV12 texture support not available
09:30:41.040: Settings changed (video)
09:30:41.040: ------------------------------------------------
09:30:45.799: [jim-nvenc] nv12/p010 not active, falling back to ffmpeg
09:30:45.799: ---------------------------------
09:30:45.799: [FFmpeg NVENC encoder: 'advanced_video_recording'] settings:
09:30:45.799: encoder: NVIDIA NVENC HEVC (FFmpeg)
09:30:45.799: rate_control: lossless
09:30:45.799: bitrate: 0
09:30:45.799: cqp: 0
09:30:45.799: keyint: 60
09:30:45.799: preset: p5
09:30:45.799: tuning: hq
09:30:45.799: multipass: disabled
09:30:45.799: profile: main
09:30:45.799: width: 3840
09:30:45.799: height: 2160
09:30:45.799: b-frames: 0
09:30:45.799: psycho-aq: 0
09:30:45.799: GPU: 0
09:30:45.799:
09:30:45.917: ---------------------------------
09:30:45.918: [FFmpeg pcm_s24le encoder: 'Track1'] bitrate: 0, channels: 2, channel_layout: stereo
09:30:45.918:
09:30:45.931: ==== Recording Start ===============================================
09:30:45.931: [ffmpeg muxer: 'adv_file_output'] Writing file 'D:/2023-08-10_09-30-45.mkv'...
09:31:10.638: [NVIDIA NVENC HEVC (FFmpeg) encoder: 'advanced_video_recording'] Encoding queue duration surpassed 5 seconds, terminating encoder
09:31:10.638: Error encoding with encoder 'advanced_video_recording'
09:31:10.641: [ffmpeg muxer: 'adv_file_output'] Output of file 'D:/2023-08-10_09-30-45.mkv' stopped
09:31:10.641: Output 'adv_file_output': stopping
09:31:10.641: Output 'adv_file_output': Total frames output: 1179
09:31:10.641: Output 'adv_file_output': Total drawn frames: 1482
09:31:10.641: ==== Recording Stop ================================================
09:31:10.644: Video stopped, number of skipped frames due to encoding lag: 1080/1181 (91.4%)
09:31:39.690: Number of remaining views: 1
 
30FPS recordings look fantastic, I can't tell the difference from the original....

Op, set the scaling of your monitors @ 100%, both are @ 150.
 
BTW, I'm not sure if it's doing anything in this scenario or any with OBS other than speeding things up a bit, but I do have Resizable BAR enabled.
 
I did some more tests, it's definitely the encoder crapping out @ 60FPS. Not sure what's causing it.

OP, you should be fine @ 30FPS too, there's not much CPU load.

Stats for the 60FPS recording, the video thread is nasty, didn't see that on the first look.

15:15:07.323: obs_hotkey_thread(25 ms): min=0.001 ms, median=0.003 ms, max=0.263 ms, 99th percentile=0.098 ms, 100% below 25 ms
15:15:07.323: audio_thread(Audio): min=0.006 ms, median=0.033 ms, max=1.114 ms, 99th percentile=0.655 ms
15:15:07.323: ┗receive_audio: min=0.002 ms, median=0.022 ms, max=1.063 ms, 99th percentile=0.842 ms, 0.275029 calls per parent call
15:15:07.323: ┣buffer_audio: min=0 ms, median=0 ms, max=0.006 ms, 99th percentile=0.001 ms
15:15:07.323: ┗do_encode: min=0.004 ms, median=0.019 ms, max=1.06 ms, 99th percentile=0.838 ms
15:15:07.323: ┣encode(Track1): min=0.002 ms, median=0.011 ms, max=0.028 ms, 99th percentile=0.019 ms
15:15:07.323: ┗send_packet: min=0.001 ms, median=0.008 ms, max=1.045 ms, 99th percentile=0.822 ms
15:15:07.323: obs_graphics_thread(16.6667 ms): min=0.04 ms, median=0.234 ms, max=494.777 ms, 99th percentile=2.35 ms, 99.9442% below 16.667 ms
15:15:07.323: ┣tick_sources: min=0.001 ms, median=0.011 ms, max=493.455 ms, 99th percentile=0.022 ms
15:15:07.323: ┣output_frame: min=0.037 ms, median=0.159 ms, max=12.809 ms, 99th percentile=2.258 ms
15:15:07.323: ┃ ┣gs_context(video->graphics): min=0.037 ms, median=0.157 ms, max=12.809 ms, 99th percentile=0.546 ms
15:15:07.323: ┃ ┃ ┣render_video: min=0.002 ms, median=0.026 ms, max=12.713 ms, 99th percentile=0.444 ms
15:15:07.323: ┃ ┃ ┃ ┣render_main_texture: min=0.002 ms, median=0.022 ms, max=12.712 ms, 99th percentile=0.435 ms
15:15:07.323: ┃ ┃ ┃ ┗stage_output_texture: min=0.001 ms, median=0.004 ms, max=0.105 ms, 99th percentile=0.077 ms, 0.279494 calls per parent call
15:15:07.323: ┃ ┃ ┣gs_flush: min=0.021 ms, median=0.082 ms, max=0.353 ms, 99th percentile=0.165 ms
15:15:07.323: ┃ ┃ ┗download_frame: min=0 ms, median=0.056 ms, max=0.187 ms, 99th percentile=0.174 ms, 0.279494 calls per parent call
15:15:07.323: ┃ ┗output_video_data: min=0 ms, median=0.001 ms, max=4.89 ms, 99th percentile=3.535 ms, 0.279308 calls per parent call
15:15:07.323: ┗render_displays: min=0 ms, median=0.051 ms, max=2.329 ms, 99th percentile=0.088 ms
15:15:07.323: video_thread(video): min=0.001 ms, median=87.566 ms, max=1457.2 ms, 99th percentile=1220.77 ms
15:15:07.323: ┗receive_video: min=1.666 ms, median=1.82 ms, max=9.771 ms, 99th percentile=3.99 ms, 10.9273 calls per parent call
15:15:07.323: ┗do_encode: min=1.666 ms, median=1.82 ms, max=9.77 ms, 99th percentile=3.989 ms
15:15:07.323: ┣encode(advanced_video_recording): min=1.654 ms, median=1.788 ms, max=8.395 ms, 99th percentile=3.272 ms
15:15:07.323: ┗send_packet: min=0.003 ms, median=0.018 ms, max=2.512 ms, 99th percentile=0.853 ms
15:15:07.323: =================================================
15:15:07.323: == Profiler Time Between Calls ==================
15:15:07.323: obs_hotkey_thread(25 ms): min=24.973 ms, median=25.913 ms, max=26.373 ms, 6.1149% within ±2% of 25 ms (0% lower, 93.8851% higher)
15:15:07.323: obs_graphics_thread(16.6667 ms): min=5.158 ms, median=16.667 ms, max=494.784 ms, 99.8883% within ±2% of 16.667 ms (0.0558347% lower, 0.0558347% higher)
15:15:07.323: =================================================
15:15:07.530: Number of memory leaks: 0
 
Last edited:
Acceptable @ 30

15:12:46.974: obs_hotkey_thread(25 ms): min=0.001 ms, median=0.003 ms, max=0.182 ms, 99th percentile=0.089 ms, 100% below 25 ms
15:12:46.974: audio_thread(Audio): min=0.005 ms, median=0.095 ms, max=7.225 ms, 99th percentile=3.371 ms
15:12:46.974: ┗receive_audio: min=0.002 ms, median=0.066 ms, max=7.188 ms, 99th percentile=4.007 ms, 0.749877 calls per parent call
15:12:46.974: ┣buffer_audio: min=0 ms, median=0 ms, max=0.011 ms, 99th percentile=0.001 ms
15:12:46.974: ┗do_encode: min=0.005 ms, median=0.064 ms, max=7.186 ms, 99th percentile=4.004 ms
15:12:46.974: ┣encode(Track1): min=0.003 ms, median=0.01 ms, max=0.069 ms, 99th percentile=0.018 ms
15:12:46.974: ┗send_packet: min=0.001 ms, median=0.052 ms, max=7.176 ms, 99th percentile=3.99 ms
15:12:46.974: obs_graphics_thread(33.3333 ms): min=0.059 ms, median=2.204 ms, max=557.597 ms, 99th percentile=4.215 ms, 99.9215% below 33.333 ms
15:12:46.974: ┣tick_sources: min=0.001 ms, median=0.014 ms, max=556.413 ms, 99th percentile=0.029 ms
15:12:46.974: ┣output_frame: min=0.054 ms, median=2.126 ms, max=10.019 ms, 99th percentile=4.074 ms
15:12:46.974: ┃ ┣gs_context(video->graphics): min=0.054 ms, median=0.284 ms, max=10.019 ms, 99th percentile=0.559 ms
15:12:46.974: ┃ ┃ ┣render_video: min=0.003 ms, median=0.215 ms, max=9.973 ms, 99th percentile=0.442 ms
15:12:46.974: ┃ ┃ ┃ ┣render_main_texture: min=0.002 ms, median=0.211 ms, max=9.972 ms, 99th percentile=0.436 ms
15:12:46.974: ┃ ┃ ┃ ┗stage_output_texture: min=0.001 ms, median=0.003 ms, max=0.068 ms, 99th percentile=0.015 ms, 0.761867 calls per parent call
15:12:46.974: ┃ ┃ ┣gs_flush: min=0.027 ms, median=0.085 ms, max=0.503 ms, 99th percentile=0.185 ms
15:12:46.974: ┃ ┃ ┗download_frame: min=0 ms, median=0.002 ms, max=0.153 ms, 99th percentile=0.088 ms, 0.761867 calls per parent call
15:12:46.974: ┃ ┗output_video_data: min=1.739 ms, median=1.896 ms, max=6.926 ms, 99th percentile=3.558 ms, 0.761475 calls per parent call
15:12:46.974: ┗render_displays: min=0 ms, median=0.058 ms, max=0.643 ms, 99th percentile=0.106 ms
15:12:46.974: video_thread(video): min=20.019 ms, median=21.889 ms, max=34.208 ms, 99th percentile=26.011 ms
15:12:46.974: ┗receive_video: min=1.816 ms, median=3.032 ms, max=15.368 ms, 99th percentile=6.996 ms
15:12:46.974: ┗do_encode: min=1.816 ms, median=3.031 ms, max=15.368 ms, 99th percentile=6.995 ms
15:12:46.974: ┣encode(advanced_video_recording): min=1.778 ms, median=2.555 ms, max=15.006 ms, 99th percentile=3.145 ms
15:12:46.974: ┗send_packet: min=0.014 ms, median=0.498 ms, max=5.802 ms, 99th percentile=4.073 ms
15:12:46.974: =================================================
15:12:46.974: == Profiler Time Between Calls ==================
15:12:46.974: obs_hotkey_thread(25 ms): min=24.951 ms, median=25.913 ms, max=26.036 ms, 5.90174% within ±2% of 25 ms (0% lower, 94.0983% higher)
15:12:46.974: obs_graphics_thread(33.3333 ms): min=9.064 ms, median=33.333 ms, max=557.602 ms, 99.843% within ±2% of 33.333 ms (0.0784929% lower, 0.0784929% higher)
15:12:46.974: =================================================
15:12:47.185: Number of memory leaks: 0
 
Back
Top