From 915379a99d1deb7dbc0b80bbe1b333382236e49f Mon Sep 17 00:00:00 2001 From: pkv Date: Thu, 16 Apr 2020 21:14:44 +0200 Subject: [PATCH 1/4] obs-x264: Allow repeat_headers and annexb parameters to be set The repeat_headers parameter is currently hard-coded to false and can not be changed. For mpegts container and allow better compatibility with broadcast mpegts decoders, it is mandatory to repeat the sps/pps headers regularly. This commit enables this parameter to be set either by the user or the service (ex: udp or srt w/ mpegts container). The b_annexb enables compatibility with Annex B bitstream which is better for streaming formats than avcc. --- plugins/obs-x264/obs-x264.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c index 5ab7da819..a6efae3d1 100644 --- a/plugins/obs-x264/obs-x264.c +++ b/plugins/obs-x264/obs-x264.c @@ -110,6 +110,7 @@ static void obs_x264_defaults(obs_data_t *settings) obs_data_set_default_string(settings, "profile", ""); obs_data_set_default_string(settings, "tune", ""); obs_data_set_default_string(settings, "x264opts", ""); + obs_data_set_default_bool(settings, "repeat_headers", false); } static inline void add_strings(obs_property_t *list, const char *const *strings) @@ -172,6 +173,7 @@ static obs_properties_t *obs_x264_props(void *unused) obs_properties_t *props = obs_properties_create(); obs_property_t *list; obs_property_t *p; + obs_property_t *headers; list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL, OBS_COMBO_TYPE_LIST, @@ -222,6 +224,10 @@ static obs_properties_t *obs_x264_props(void *unused) obs_properties_add_text(props, "x264opts", TEXT_X264_OPTS, OBS_TEXT_DEFAULT); + headers = obs_properties_add_bool(props, "repeat_headers", + "repeat_headers"); + obs_property_set_visible(headers, false); + return props; } @@ -583,6 +589,7 @@ static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings, char *tune = bstrdup(obs_data_get_string(settings, "tune")); struct obs_x264_options options = obs_x264_parse_options( obs_data_get_string(settings, "x264opts")); + bool repeat_headers = obs_data_get_bool(settings, "repeat_headers"); bool success = true; @@ -603,6 +610,12 @@ static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings, success = reset_x264_params(obsx264, preset, tune); } + if (repeat_headers) { + obsx264->params.b_repeat_headers = 1; + obsx264->params.b_annexb = 1; + obsx264->params.b_aud = 1; + } + if (success) { update_params(obsx264, settings, &options, update); if (!update) { @@ -613,8 +626,6 @@ static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings, apply_x264_profile(obsx264, profile); } - obsx264->params.b_repeat_headers = false; - obs_x264_free_options(options); bfree(preset); bfree(profile); From 73ac96ac7cc46dbe6be086af51fcdc96bc3b390e Mon Sep 17 00:00:00 2001 From: pkv Date: Thu, 16 Apr 2020 21:21:07 +0200 Subject: [PATCH 2/4] obs-ffmpeg: Allow video headers repetition in IDR and bitstream for jim-nvenc This commit adds a repeat_headers setting which will allow sps/pps repetition and AUDs(access unit delimiters) . Repetition is ensured by h264config->repeatSPSPPS & h264config->disableSPSPPS; the two parameters are set by nvenc to true on default. When video headers repetition is required, we set the second in jim-nvenc to false so that SPS/PPS are written into bitstream. The first parameter could be omitted but is exposed since repetition of video headers might not be required. When headers repetition is enabled, we also enable AUD to facilitate decoding. Typically the video headers repetition will be useful for mpegts and DVB broadcast decoders. --- plugins/obs-ffmpeg/jim-nvenc.c | 8 ++++++++ plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c index 097db6432..b112a2f2c 100644 --- a/plugins/obs-ffmpeg/jim-nvenc.c +++ b/plugins/obs-ffmpeg/jim-nvenc.c @@ -426,6 +426,14 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) config->gopLength = gop_size; config->frameIntervalP = 1 + bf; h264_config->idrPeriod = gop_size; + + bool repeat_headers = obs_data_get_bool(settings, "repeat_headers"); + if (repeat_headers) { + h264_config->repeatSPSPPS = 1; + h264_config->disableSPSPPS = 0; + h264_config->outputAUD = 1; + } + vui_params->videoSignalTypePresentFlag = 1; vui_params->videoFullRangeFlag = (voi->range == VIDEO_RANGE_FULL); vui_params->colourDescriptionPresentFlag = 1; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c index 74480a797..b667665ab 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c @@ -477,6 +477,7 @@ void nvenc_defaults(obs_data_t *settings) obs_data_set_default_bool(settings, "psycho_aq", true); obs_data_set_default_int(settings, "gpu", 0); obs_data_set_default_int(settings, "bf", 2); + obs_data_set_default_bool(settings, "repeat_headers", false); } static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, @@ -576,6 +577,9 @@ obs_properties_t *nvenc_properties_internal(bool ffmpeg) obs_module_text("NVENC.PsychoVisualTuning")); obs_property_set_long_description( p, obs_module_text("NVENC.PsychoVisualTuning.ToolTip")); + p = obs_properties_add_bool(props, "repeat_headers", + "repeat_headers"); + obs_property_set_visible(p, false); } obs_properties_add_int(props, "gpu", obs_module_text("GPU"), 0, 8, 1); From 3521fb976c80a00904142766eca7e2f64b39e8ca Mon Sep 17 00:00:00 2001 From: pkv Date: Thu, 16 Apr 2020 23:25:10 +0200 Subject: [PATCH 3/4] rtmp-services/rtmp-custom: Apply repeat_headers video setting to srt output If the video encoder allows video headers repetition at IDR frames, and if the output is not rtmp (so srt, udp, etc with mpegts container), this commit enables application of this setting from the custom service (since srt is available through that service). --- plugins/rtmp-services/rtmp-custom.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plugins/rtmp-services/rtmp-custom.c b/plugins/rtmp-services/rtmp-custom.c index 921be2fe3..6879eb99c 100644 --- a/plugins/rtmp-services/rtmp-custom.c +++ b/plugins/rtmp-services/rtmp-custom.c @@ -1,4 +1,5 @@ #include +#include struct rtmp_custom { char *server, *key; @@ -109,6 +110,19 @@ static const char *rtmp_custom_password(void *data) return service->password; } +#define RTMP_PROTOCOL "rtmp" + +static void rtmp_custom_apply_settings(void *data, obs_data_t *video_settings, + obs_data_t *audio_settings) +{ + struct rtmp_custom *service = data; + if (service->server != NULL && video_settings != NULL && + strncmp(service->server, RTMP_PROTOCOL, strlen(RTMP_PROTOCOL)) != + 0) { + obs_data_set_bool(video_settings, "repeat_headers", true); + } +} + struct obs_service_info rtmp_custom_service = { .id = "rtmp_custom", .get_name = rtmp_custom_name, @@ -120,4 +134,5 @@ struct obs_service_info rtmp_custom_service = { .get_key = rtmp_custom_key, .get_username = rtmp_custom_username, .get_password = rtmp_custom_password, + .apply_encoder_settings = rtmp_custom_apply_settings, }; From e0c6ac3675680d98d0b0726381d26c6d65b24660 Mon Sep 17 00:00:00 2001 From: pkv Date: Thu, 16 Apr 2020 23:57:37 +0200 Subject: [PATCH 4/4] UI: Apply custom_rtmp service settings to srt output --- UI/window-basic-main-outputs.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp index 708cb270a..06d41eb57 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp @@ -1278,6 +1278,15 @@ inline void AdvancedOutput::SetupStreaming() obs_output_set_audio_encoder(streamOutput, streamAudioEnc, 0); obs_encoder_set_scaled_size(h264Streaming, cx, cy); obs_encoder_set_video(h264Streaming, obs_get_video()); + + const char *id = obs_service_get_id(main->GetService()); + if (strcmp(id, "rtmp_custom") == 0) { + obs_data_t *settings = obs_data_create(); + obs_service_apply_encoder_settings(main->GetService(), settings, + nullptr); + obs_encoder_update(h264Streaming, settings); + obs_data_release(settings); + } } inline void AdvancedOutput::SetupRecording()