obsproject / obs-studio

OBS Studio - Free and open source software for live streaming and screen recording
https://obsproject.com
GNU General Public License v2.0
57.87k stars 7.75k forks source link

Streaming forces 4:2:0 Chroma Subsampling (NV12) #3517

Open WinterPhoenix opened 3 years ago

WinterPhoenix commented 3 years ago

Platform

Operating system and version: Windows 10 1909 (Build 18363.1082) OBS Studio version: 26.0.0

Expected Behavior

With a Custom Stream Service set, OBS should respect the Color Format setting (in this case, I444). Recording is not affected by this.

Current Behavior

4:2:0 Chroma Subsampling is forced no matter what Stream service is selected, even a Custom one that supports 4:4:4.

Log File:

18:26:57.905: CPU Name: AMD Ryzen 7 3700X 8-Core Processor             
18:26:57.905: CPU Speed: 3593MHz
18:26:57.905: Physical Cores: 8, Logical Cores: 16
18:26:57.905: Physical Memory: 32687MB Total, 17993MB Free
18:26:57.905: Windows Version: 10.0 Build 18363 (release: 1909; revision: 1082; 64-bit)
18:26:57.905: Running as administrator: true
18:26:57.905: Aero is Enabled (Aero is always on for windows 8 and above)
18:26:57.905: Windows 10 Gaming Features:
18:26:57.905:   Game DVR: Off
18:26:57.905:   Game Mode: Off
18:26:57.906: Sec. Software Status:
18:26:57.906:   Windows Defender Antivirus: enabled (AV)
18:26:57.907:   Windows Firewall: enabled (FW)
18:26:57.907: Current Date/Time: 2020-09-29, 18:26:57
18:26:57.907: Browser Hardware Acceleration: true
18:26:57.907: Portable mode: false
18:26:58.214: OBS 26.0.0 (64-bit, windows)
18:26:58.214: ---------------------------------
18:26:58.215: ---------------------------------
18:26:58.215: audio settings reset:
18:26:58.215:   samples per sec: 48000
18:26:58.215:   speakers:        2
18:26:58.215: ---------------------------------
18:26:58.216: Initializing D3D11...
18:26:58.216: Available Video Adapters: 
18:26:58.217:   Adapter 0: AMD Radeon RX 5700 XT
18:26:58.217:     Dedicated VRAM: 3891011584
18:26:58.217:     Shared VRAM:    4252499968
18:26:58.217:     PCI ID:         1002:731f
18:26:58.218:     Driver Version: 27.20.12029.1000
18:26:58.218:     output 0: pos={0, 0}, size={1920, 1080}, attached=true, refresh=144, name=27GL650F
18:26:58.218:     output 1: pos={1920, 0}, size={1920, 1080}, attached=true, refresh=60, name=VS248
18:26:58.218:     output 2: pos={-1920, 0}, size={1920, 1080}, attached=true, refresh=60, name=VS248
18:26:58.219: Loading up D3D11 on adapter AMD Radeon RX 5700 XT (0)
18:26:58.239: D3D11 loaded successfully, feature level used: b000
18:26:58.239: DXGI increase maximum frame latency success
18:26:58.239: D3D11 GPU priority setup success
18:26:58.578: ---------------------------------
18:26:58.578: video settings reset:
18:26:58.578:   base resolution:   1920x1080
18:26:58.578:   output resolution: 1920x1080
18:26:58.578:   downscale filter:  Lanczos
18:26:58.578:   fps:               25/1
18:26:58.578:   format:            I444
18:26:58.578:   YUV mode:          sRGB/Full
18:26:58.578: NV12 texture support not available
18:26:58.586: Audio monitoring device:
18:26:58.586:   name: Default
18:26:58.586:   id: default
18:26:58.586: ---------------------------------
18:26:58.591: [CoreAudio encoder]: Adding CoreAudio AAC encoder
18:26:58.592: Failed to load 'en-US' text for module: 'decklink-ouput-ui.dll'
18:26:58.771: [AMF] Version 2.7.0 loaded (Compiled: 1.4.14.0, Runtime: 1.4.17.0, Library: 1;4;17;0;20.20.29.01;202009092047;CL#2169548).
18:26:58.853: [AMF] [Capability Manager] Testing Direct3D 11 Adapter 'AMD Radeon RX 5700 XT (VEN_1002/DEV_731f/SUB_e4101da2/REV_00c1)':
18:26:58.853:   H264/AVC: Supported
18:26:58.853:   H265/HEVC: Supported
18:26:58.853: 
18:26:58.864: [obs-browser]: Version 2.8.7
18:26:59.312: [Stream Effects] Loading Version 0.7.1 (Build 0)
18:26:59.317: [tuna] Loading v1.4.0
18:26:59.317: [tuna] libobs version 26.0.0 is invalid. Tuna expects 24.0.3 for VLC sources to work
18:26:59.317: [tuna] User force enabled VLC support
18:26:59.330: [tuna] Loaded libVLC. VLC source support enabled
18:26:59.395: [tuna] Registered Spotify (id: spotify)
18:26:59.395: [tuna] Registered MPD (id: mpd)
18:26:59.395: [tuna] Registered VLC (id: vlc)
18:26:59.395: [tuna] Registered Window Title (id: window)
18:26:59.395: [tuna] Loaded 1 outputs
18:26:59.397: VLC found, VLC video source enabled
18:26:59.402: A DeckLink iterator could not be created.  The DeckLink drivers may not be installed
18:26:59.403: No blackmagic support
18:26:59.405: ---------------------------------
18:26:59.405:   Loaded Modules:
18:26:59.405:     win-wasapi.dll
18:26:59.405:     win-mf.dll
18:26:59.405:     win-dshow.dll
18:26:59.405:     win-decklink.dll
18:26:59.405:     win-capture.dll
18:26:59.405:     vlc-video.dll
18:26:59.405:     tuna.dll
18:26:59.405:     text-freetype2.dll
18:26:59.405:     rtmp-services.dll
18:26:59.405:     obs-x264.dll
18:26:59.405:     obs-vst.dll
18:26:59.405:     obs-transitions.dll
18:26:59.405:     obs-text.dll
18:26:59.405:     obs-stream-effects.dll
18:26:59.405:     obs-qsv11.dll
18:26:59.405:     obs-outputs.dll
18:26:59.405:     obs-filters.dll
18:26:59.405:     obs-ffmpeg.dll
18:26:59.405:     obs-browser.dll
18:26:59.405:     image-source.dll
18:26:59.405:     frontend-tools.dll
18:26:59.405:     enc-amf.dll
18:26:59.405:     decklink-ouput-ui.dll
18:26:59.405:     coreaudio-encoder.dll
18:26:59.405: ---------------------------------
18:26:59.405: ==== Startup complete ===============================================
18:26:59.414: All scene data cleared
18:26:59.414: ------------------------------------------------
18:26:59.467: WASAPI: Device 'Headphones (2- Realtek(R) Audio)' [48000 Hz] initialized
18:26:59.467: [Loaded global audio device]: 'Desktop Audio'
18:26:59.517: WASAPI: Device 'Realtek Digital Output (2- Realtek(R) Audio)' [48000 Hz] initialized
18:26:59.517: [Loaded global audio device]: 'Desktop Audio 2'
18:26:59.553: WASAPI: Device 'Yeti Mic (Yeti Stereo Microphone)' [48000 Hz] initialized
18:26:59.553: [Loaded global audio device]: 'Mic/Aux'
18:26:59.611: adding 42 milliseconds of audio buffering, total audio buffering is now 42 milliseconds (source: Mic/Aux)
18:26:59.611: 
18:26:59.936: [window-capture: 'Window Capture'] update settings:
18:26:59.936:   executable: hammer.exe
18:26:59.936:   method selected: Automatic
18:26:59.936:   method chosen: BitBlt
18:26:59.936: 
18:27:00.025: [duplicator-monitor-capture: 'Center Monitor'] update settings:
18:27:00.025:   display: 1 (1920x1080)
18:27:00.025:   cursor: true
18:27:00.510: Switched to scene 'Movie Night'
18:27:00.510: ------------------------------------------------
18:27:00.510: Loaded scenes:
18:27:00.510: - scene 'Movie Night':
18:27:00.510:     - source: 'VLC' (game_capture)
18:27:00.510:     - source: 'Epilepsy Warning' (text_gdiplus)
18:27:00.510:     - source: 'Rating' (text_gdiplus)
18:27:00.510:     - source: 'Setting Up' (text_gdiplus)
18:27:00.510:     - source: 'Playing Tonight' (text_gdiplus)
18:27:00.510:     - source: 'Technical Difficulties' (text_gdiplus)
18:27:00.510:     - source: 'Waiting For Players...' (text_gdiplus)
18:27:00.510:     - source: 'Spotify: Background' (color_source)
18:27:00.510:     - source: 'Spotify: Song Title' (text_gdiplus)
18:27:00.510:     - source: 'Voting' (text_gdiplus)
18:27:00.510:     - source: 'Enjoy? Donate' (group)
18:27:00.510:         - source: 'Enjoy? Part 2' (text_gdiplus_v2)
18:27:00.510:         - source: 'Enjoy? Part 1' (text_gdiplus_v2)
18:27:00.510:     - source: 'Chroma Image' (image_source)
18:27:00.510: - scene 'Dev Showcase':
18:27:00.510:     - source: 'Background' (image_source)
18:27:00.510:     - source: 'Discord Status' (browser_source)
18:27:00.510:         - monitoring: monitor only
18:27:00.510:     - source: 'Twitch Chat' (browser_source)
18:27:00.510:         - monitoring: monitor only
18:27:00.510:     - source: 'Center Monitor Background' (color_source)
18:27:00.510:     - source: 'Center Monitor' (monitor_capture)
18:27:00.510:     - source: 'Discord Dev Chat' (browser_source)
18:27:00.510:         - monitoring: monitor only
18:27:00.510:     - source: 'Discord Lobby Chat' (browser_source)
18:27:00.510:     - filter: 'Blur' (obs-stream-effects-filter-blur)
18:27:00.510: - scene 'Dev Showcase Starting':
18:27:00.510:     - source: 'Dev Showcase' (scene)
18:27:00.510:         - filter: 'Blur' (obs-stream-effects-filter-blur)
18:27:00.510:     - source: 'Starting' (image_source)
18:27:00.510: - scene 'Game Streaming':
18:27:00.510:     - source: 'Window Capture' (window_capture)
18:27:00.510:     - source: 'Starting 2' (image_source)
18:27:00.510: ------------------------------------------------
18:27:12.661: ---------------------------------
18:27:12.661: [x264 encoder: 'streaming_h264'] preset: faster
18:27:12.661: [x264 encoder: 'streaming_h264'] settings:
18:27:12.661:   rate_control: CBR
18:27:12.661:   bitrate:      8000
18:27:12.661:   buffer size:  8000
18:27:12.661:   crf:          0
18:27:12.661:   fps_num:      25
18:27:12.661:   fps_den:      1
18:27:12.661:   width:        1920
18:27:12.661:   height:       1080
18:27:12.661:   keyint:       25
18:27:12.661: 
18:27:12.667: [CoreAudio AAC: 'avc_aac_stream']: settings:
18:27:12.667:   mode:          AAC
18:27:12.667:   bitrate:       192
18:27:12.667:   sample rate:   48000
18:27:12.667:   cbr:           on
18:27:12.667:   output buffer: 1536
18:27:12.667: [rtmp stream: 'adv_stream'] Connecting to RTMP URL rtmp://192.168.0.100/live/winter...
18:27:12.668: [rtmp stream: 'adv_stream'] Interface: Intel(R) I211 Gigabit Network Connection #2 (ethernet, 1000 mbps)
18:27:12.753: [rtmp stream: 'adv_stream'] Connection to rtmp://192.168.0.100/live/winter successful
18:27:12.753: [rtmp stream: 'adv_stream'] New socket loop enabled by user
18:27:12.760: ==== Streaming Start ===============================================
18:27:14.715: socket_thread_windows: Increasing send buffer to ISB 131072 (buffer: 0 / 1048576)
18:27:15.753: socket_thread_windows: Increasing send buffer to ISB 262144 (buffer: 58496 / 1048576)
18:27:15.753: socket_thread_windows: Increasing send buffer to ISB 524288 (buffer: 0 / 1048576)
18:27:22.032: [rtmp stream: 'adv_stream'] User stopped the stream
18:27:22.033: socket_thread_windows: Normal exit
18:27:22.033: Output 'adv_stream': stopping
18:27:22.033: Output 'adv_stream': Total frames output: 183
18:27:22.033: Output 'adv_stream': Total drawn frames: 235
18:27:22.050: ==== Streaming Stop ================================================

Steps to Reproduce

  1. Grab the test charts from Suslik V's OBS Studio: Color Space, Color Format, Color Range settings Guide
  2. Ensure your monitor can output 4:4:4 subsampling natively by viewing the Test Chart that matches your monitor's resolution in full screen
  3. Create an nginx RTMP server using this Guide. Use the latest stable version of nginx and this forked version of the RTMP module
  4. Set the following settings in OBS:
    • Color Format: I444
    • Color Space: sRGB or 709
    • Color Range: Full
    • Base (Canvas) and Output (Scaled) Resolutions must match!
  5. Create an Image Source with the size of Test Chart matches your OBS Canvas Resolution
  6. Create a Recording, then review it to make sure 4:4:4 is working with recording (if not, check the settings above!)
  7. Point OBS to your Custom RTMP stream service, and observe the output as it forces 4:2:0 subsampling

Additional information

Not respecting user-selected Video Color settings is confusing to users, and particularly non-helpful to those in this scenario who are expecting to be able to accurately reproduce colors through streaming video.

I understand the motivations behind wanting to maintain the widest amount of support possible, however this is not something that should extend to scenarios where the user is deliberately trying to utilize OBS to its fullest potential.

Xaymar commented 3 years ago

This affects any encoder that trusts the preferred video format to be correct. For streaming, the preferred video format is set to NV12, unless the color format is set to I420/NV12 already. To my knowledge, only obs-x264 and obs-ffmpeg-nvenc actually use this. jim_nvenc doesn't specify a get_video_info function, and enc-amf uses whatever is in the video info (but it can only do NV12 anyway due to hardware restrictions).

kotarou3 commented 2 years ago

I ran into this issue on Linux, and made a small hacky workaround using LD_PRELOAD:

// Compile with: gcc -std=c11 obs-override-forced-nv12.c -shared -fPIC -o obs-override-forced-nv12.so
// Activate with: LD_PRELOAD=/path/to/obs-override-forced-nv12.so obs

#define _GNU_SOURCE
#include <dlfcn.h>
#include <threads.h>

void obs_encoder_set_preferred_video_format(void* encoder, int format) {
    static thread_local void *(*orig)(void*, int) = NULL;
    if (!orig)
        orig = dlsym(RTLD_NEXT, "obs_encoder_set_preferred_video_format");

    #define VIDEO_FORMAT_NV12 2
    if (format == VIDEO_FORMAT_NV12)
        return;
    orig(encoder, format);
}

Of course a proper fix would be to have some checkbox in the UI, but this is good enough for me

erickskrauch commented 1 year ago

Since we have native handlers for SRT and RIST and can stream h265, it would be logical to remove forced subsampling for those protocols.

We use OBS to stream the image to the director's computer and the forced subsampling causes colors lost. It would be great if we could stream on SRT in an honest 4:4:4 and Full-color range.