From bfa02243992036bd653534616555c67e3062cdf4 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Sun, 6 Sep 2020 12:33:02 -0700 Subject: [PATCH 1/3] UI: Change the default color setting in the UI from sRGB to 709 It seems like YouTube applies nonlinear-to-linear sRGB, and linear-to nonlinear-709 transformations to uploaded videos now. This makes sRGB too dark on their platform for video players that alias 709 as sRGB, which is almost everyone. Make 709 the default to keep peace. --- UI/window-basic-main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index c22412c86..f8b013899 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -1392,7 +1392,7 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_uint(basicConfig, "Video", "FPSDen", 1); config_set_default_string(basicConfig, "Video", "ScaleType", "bicubic"); config_set_default_string(basicConfig, "Video", "ColorFormat", "NV12"); - config_set_default_string(basicConfig, "Video", "ColorSpace", "sRGB"); + config_set_default_string(basicConfig, "Video", "ColorSpace", "709"); config_set_default_string(basicConfig, "Video", "ColorRange", "Partial"); From b6afaceeaed2b9f8b8ff5f74dd69ed5b8ddae412 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Sun, 6 Sep 2020 16:19:20 -0700 Subject: [PATCH 2/3] Update VIDEO_CS_DEFAULT to mean 709 instead of 601 Consistent with modified default UI setting. --- deps/media-playback/media-playback/media.c | 12 ++++-- docs/sphinx/reference-libobs-media-io.rst | 3 +- docs/sphinx/reference-outputs.rst | 1 + libobs/media-io/video-io.h | 4 +- libobs/media-io/video-matrices.c | 4 +- libobs/media-io/video-scaler-ffmpeg.c | 12 ++---- plugins/decklink/decklink-device-instance.cpp | 2 +- plugins/mac-avcapture/av-capture.mm | 6 +-- plugins/obs-ffmpeg/jim-nvenc.c | 2 +- plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 2 +- plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 2 +- plugins/obs-ffmpeg/obs-ffmpeg-output.c | 17 ++------ plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c | 22 ++++++++-- plugins/obs-x264/obs-x264.c | 2 +- plugins/win-dshow/ffmpeg-decode.c | 42 +++++++++++++------ plugins/win-dshow/win-dshow.cpp | 8 ++-- 16 files changed, 83 insertions(+), 58 deletions(-) diff --git a/deps/media-playback/media-playback/media.c b/deps/media-playback/media-playback/media.c index e1f584e5b..55a2cc2be 100644 --- a/deps/media-playback/media-playback/media.c +++ b/deps/media-playback/media-playback/media.c @@ -112,12 +112,18 @@ static inline enum speaker_layout convert_speaker_layout(uint8_t channels) static inline enum video_colorspace convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc) { - if (s == AVCOL_SPC_BT709) { + switch (s) { + case AVCOL_SPC_BT709: return (trc == AVCOL_TRC_IEC61966_2_1) ? VIDEO_CS_SRGB : VIDEO_CS_709; + case AVCOL_SPC_FCC: + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_SMPTE170M: + case AVCOL_SPC_SMPTE240M: + return VIDEO_CS_601; + default: + return VIDEO_CS_DEFAULT; } - - return VIDEO_CS_DEFAULT; } static inline enum video_range_type convert_color_range(enum AVColorRange r) diff --git a/docs/sphinx/reference-libobs-media-io.rst b/docs/sphinx/reference-libobs-media-io.rst index 6e978cede..a86e19a18 100644 --- a/docs/sphinx/reference-libobs-media-io.rst +++ b/docs/sphinx/reference-libobs-media-io.rst @@ -39,9 +39,10 @@ Video Handler YUV color space. Can be one of the following values: - - VIDEO_CS_DEFAULT - Equivalent to VIDEO_CS_601 + - VIDEO_CS_DEFAULT - Equivalent to VIDEO_CS_709 - VIDEO_CS_601 - 601 color space - VIDEO_CS_709 - 709 color space + - VIDEO_CS_SRGB - sRGB color space --------------------- diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index 84f88e61c..e4d30cb53 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -686,6 +686,7 @@ Functions used by outputs VIDEO_CS_DEFAULT, VIDEO_CS_601, VIDEO_CS_709, + VIDEO_CS_SRGB, }; enum video_range_type { diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index 6db887ded..5cfcd2821 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -174,12 +174,12 @@ static inline const char *get_video_format_name(enum video_format format) static inline const char *get_video_colorspace_name(enum video_colorspace cs) { switch (cs) { + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: return "709"; case VIDEO_CS_SRGB: return "sRGB"; - case VIDEO_CS_601: - case VIDEO_CS_DEFAULT:; + case VIDEO_CS_601:; } return "601"; diff --git a/libobs/media-io/video-matrices.c b/libobs/media-io/video-matrices.c index ec603f799..c8e50e55d 100644 --- a/libobs/media-io/video-matrices.c +++ b/libobs/media-io/video-matrices.c @@ -171,9 +171,7 @@ bool video_format_get_parameters(enum video_colorspace color_space, matrices_initialized = true; } #endif - if (color_space == VIDEO_CS_DEFAULT) - color_space = VIDEO_CS_601; - else if (color_space == VIDEO_CS_SRGB) + if ((color_space == VIDEO_CS_DEFAULT) || (color_space == VIDEO_CS_SRGB)) color_space = VIDEO_CS_709; for (size_t i = 0; i < NUM_FORMATS; i++) { diff --git a/libobs/media-io/video-scaler-ffmpeg.c b/libobs/media-io/video-scaler-ffmpeg.c index 4d2d997f5..16a136145 100644 --- a/libobs/media-io/video-scaler-ffmpeg.c +++ b/libobs/media-io/video-scaler-ffmpeg.c @@ -91,15 +91,9 @@ static inline int get_ffmpeg_scale_type(enum video_scale_type type) static inline const int *get_ffmpeg_coeffs(enum video_colorspace cs) { - switch (cs) { - case VIDEO_CS_709: - case VIDEO_CS_SRGB: - return sws_getCoefficients(SWS_CS_ITU709); - case VIDEO_CS_DEFAULT: - case VIDEO_CS_601: - default: - return sws_getCoefficients(SWS_CS_ITU601); - } + const int colorspace = (cs == VIDEO_CS_601) ? SWS_CS_ITU601 + : SWS_CS_ITU709; + return sws_getCoefficients(colorspace); } static inline int get_ffmpeg_range_type(enum video_range_type type) diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index 6c8b3d3e0..f75cc7286 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -192,7 +192,7 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) #ifdef LOG_SETUP_VIDEO_FORMAT LOG(LOG_INFO, "Setup video format: %s, %s, %s", pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB", - activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601", + activeColorSpace == VIDEO_CS_601 ? "BT.601" : "BT.709", colorRange == VIDEO_RANGE_FULL ? "full" : "limited"); #endif } diff --git a/plugins/mac-avcapture/av-capture.mm b/plugins/mac-avcapture/av-capture.mm index 32556d69b..c44313622 100644 --- a/plugins/mac-avcapture/av-capture.mm +++ b/plugins/mac-avcapture/av-capture.mm @@ -442,11 +442,11 @@ static inline video_colorspace get_colorspace(CMFormatDescriptionRef desc) return VIDEO_CS_DEFAULT; if (CFStringCompare(static_cast(matrix), - kCVImageBufferYCbCrMatrix_ITU_R_709_2, + kCVImageBufferYCbCrMatrix_ITU_R_601_4, 0) == kCFCompareEqualTo) - return VIDEO_CS_709; + return VIDEO_CS_601; - return VIDEO_CS_601; + return VIDEO_CS_709; } static inline bool update_colorspace(av_capture *capture, diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c index 097db6432..1713e321a 100644 --- a/plugins/obs-ffmpeg/jim-nvenc.c +++ b/plugins/obs-ffmpeg/jim-nvenc.c @@ -431,12 +431,12 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) vui_params->colourDescriptionPresentFlag = 1; switch (voi->colorspace) { - case VIDEO_CS_DEFAULT: case VIDEO_CS_601: vui_params->colourPrimaries = 6; vui_params->transferCharacteristics = 6; vui_params->colourMatrix = 6; break; + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: vui_params->colourPrimaries = 1; vui_params->transferCharacteristics = 1; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index 1ff745d61..73ed76ae1 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -160,12 +160,12 @@ static void add_video_encoder_params(struct ffmpeg_muxer *stream, enum AVColorTransferCharacteristic trc = AVCOL_TRC_UNSPECIFIED; enum AVColorSpace spc = AVCOL_SPC_UNSPECIFIED; switch (info->colorspace) { - case VIDEO_CS_DEFAULT: case VIDEO_CS_601: pri = AVCOL_PRI_SMPTE170M; trc = AVCOL_TRC_SMPTE170M; spc = AVCOL_SPC_SMPTE170M; break; + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: pri = AVCOL_PRI_BT709; trc = AVCOL_TRC_BT709; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c index 74480a797..24b8a7c6d 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c @@ -241,12 +241,12 @@ static bool nvenc_update(void *data, obs_data_t *settings) enc->context->max_b_frames = bf; switch (info.colorspace) { - case VIDEO_CS_DEFAULT: case VIDEO_CS_601: enc->context->color_trc = AVCOL_TRC_SMPTE170M; enc->context->color_primaries = AVCOL_PRI_SMPTE170M; enc->context->colorspace = AVCOL_SPC_SMPTE170M; break; + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: enc->context->color_trc = AVCOL_TRC_BT709; enc->context->color_primaries = AVCOL_PRI_BT709; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c index f56a147c7..b04df3b7a 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -1088,11 +1088,11 @@ static bool try_connect(struct ffmpeg_output *output) config.color_range = voi->range == VIDEO_RANGE_FULL ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; switch (voi->colorspace) { - case VIDEO_CS_DEFAULT: case VIDEO_CS_601: config.color_primaries = AVCOL_PRI_SMPTE170M; config.color_trc = AVCOL_TRC_SMPTE170M; break; + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: config.color_primaries = AVCOL_PRI_BT709; config.color_trc = AVCOL_TRC_BT709; @@ -1104,18 +1104,9 @@ static bool try_connect(struct ffmpeg_output *output) } if (format_is_yuv(voi->format)) { - switch (voi->colorspace) { - case VIDEO_CS_DEFAULT: - case VIDEO_CS_601: - config.colorspace = AVCOL_SPC_SMPTE170M; - break; - case VIDEO_CS_709: - config.colorspace = AVCOL_SPC_BT709; - break; - case VIDEO_CS_SRGB: - config.colorspace = AVCOL_SPC_BT709; - break; - } + config.colorspace = (voi->colorspace == VIDEO_CS_601) + ? AVCOL_SPC_SMPTE170M + : AVCOL_SPC_BT709; } else { config.colorspace = AVCOL_SPC_RGB; } diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c index 9f2660a49..ee5829678 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c @@ -244,13 +244,29 @@ static bool vaapi_update(void *data, obs_data_t *settings) enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num}; enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format); - enc->context->colorspace = info.colorspace == VIDEO_CS_709 - ? AVCOL_SPC_BT709 - : AVCOL_SPC_BT470BG; enc->context->color_range = info.range == VIDEO_RANGE_FULL ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + switch (info.colorspace) { + case VIDEO_CS_601: + enc->context->color_trc = AVCOL_TRC_SMPTE170M; + enc->context->color_primaries = AVCOL_PRI_SMPTE170M; + enc->context->colorspace = AVCOL_SPC_SMPTE170M; + break; + case VIDEO_CS_DEFAULT: + case VIDEO_CS_709: + enc->context->color_trc = AVCOL_TRC_BT709; + enc->context->color_primaries = AVCOL_PRI_BT709; + enc->context->colorspace = AVCOL_SPC_BT709; + break; + case VIDEO_CS_SRGB: + enc->context->color_trc = AVCOL_TRC_IEC61966_2_1; + enc->context->color_primaries = AVCOL_PRI_BT709; + enc->context->colorspace = AVCOL_SPC_BT709; + break; + } + if (keyint_sec > 0) { enc->context->gop_size = keyint_sec * voi->fps_num / voi->fps_den; diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c index ce25453f4..41c782c20 100644 --- a/plugins/obs-x264/obs-x264.c +++ b/plugins/obs-x264/obs-x264.c @@ -468,12 +468,12 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, const char *transfer = NULL; const char *colmatrix = NULL; switch (info.colorspace) { - case VIDEO_CS_DEFAULT: case VIDEO_CS_601: colorprim = smpte170m; transfer = smpte170m; colmatrix = smpte170m; break; + case VIDEO_CS_DEFAULT: case VIDEO_CS_709: colorprim = bt709; transfer = bt709; diff --git a/plugins/win-dshow/ffmpeg-decode.c b/plugins/win-dshow/ffmpeg-decode.c index 0d7c7029b..7c4165d8a 100644 --- a/plugins/win-dshow/ffmpeg-decode.c +++ b/plugins/win-dshow/ffmpeg-decode.c @@ -270,6 +270,23 @@ bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data, return true; } +static enum video_colorspace +convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc) +{ + switch (s) { + case AVCOL_SPC_BT709: + return (trc == AVCOL_TRC_IEC61966_2_1) ? VIDEO_CS_SRGB + : VIDEO_CS_709; + case AVCOL_SPC_FCC: + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_SMPTE170M: + case AVCOL_SPC_SMPTE240M: + return VIDEO_CS_601; + default: + return VIDEO_CS_DEFAULT; + } +} + bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, size_t size, long long *ts, enum video_range_type range, @@ -344,21 +361,22 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, : VIDEO_RANGE_PARTIAL; } - if (range != frame->range) { - const bool success = video_format_get_parameters( - VIDEO_CS_601, range, frame->color_matrix, - frame->color_range_min, frame->color_range_max); - if (!success) { - blog(LOG_ERROR, - "Failed to get video format " - "parameters for video format %u", - VIDEO_CS_601); - return false; - } + const enum video_colorspace cs = convert_color_space( + decode->frame->colorspace, decode->frame->color_trc); - frame->range = range; + const bool success = video_format_get_parameters( + cs, range, frame->color_matrix, frame->color_range_min, + frame->color_range_max); + if (!success) { + blog(LOG_ERROR, + "Failed to get video format " + "parameters for video format %u", + cs); + return false; } + frame->range = range; + *ts = decode->frame->pkt_pts; frame->width = decode->frame->width; diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index e4e6ec7a4..47f02dcab 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -1072,11 +1072,11 @@ DShowInput::GetColorSpace(obs_data_t *settings) const if (astrcmpi(space, "709") == 0) return VIDEO_CS_709; - else if (astrcmpi(space, "601") == 0) + + if (astrcmpi(space, "601") == 0) return VIDEO_CS_601; - else - return (videoConfig.format == VideoFormat::HDYC) ? VIDEO_CS_709 - : VIDEO_CS_601; + + return VIDEO_CS_DEFAULT; } inline enum video_range_type From b3dcb2a0f143510200465d86cc37303992149e1e Mon Sep 17 00:00:00 2001 From: jpark37 Date: Mon, 7 Sep 2020 07:58:17 -0700 Subject: [PATCH 3/3] enc-amf: Update AMD encoder submodule --- plugins/enc-amf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/enc-amf b/plugins/enc-amf index 6e934b6b2..272f0ffb7 160000 --- a/plugins/enc-amf +++ b/plugins/enc-amf @@ -1 +1 @@ -Subproject commit 6e934b6b281cf675522ea43391376bd6bb089256 +Subproject commit 272f0ffb70e489a48d1859b1bf7291931ff1ee9b