diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini index a4ac9cde8..f140d603f 100644 --- a/obs/data/locale/en-US.ini +++ b/obs/data/locale/en-US.ini @@ -309,6 +309,17 @@ Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Advanced" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Output" Basic.Settings.Output.Simple.SavePath="Recording Path" +Basic.Settings.Output.Simple.RecordingQuality="Recording Quality" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Same as stream" +Basic.Settings.Output.Simple.RecordingQuality.Small="High Quality, Medium File Size" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Indistinguishable Quality, Large File Size" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless Quality, Tremendously Large File Size" +Basic.Settings.Output.Simple.Warn.Encoder="Warning: Recording with a software encoder at a different quality than the stream will require extra CPU usage if you stream and record at the same time." +Basic.Settings.Output.Simple.Warn.Lossless="Warning: Lossless quality generates tremendously large file sizes! Lossless quality can use upward of 7 gigabytes of disk space per minute at high resolutions and framerates. Lossless is not recommended for long recordings unless you have a very large amount of disk space available." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Are you sure you want to use lossless quality?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless quality warning!" +Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 low CPU usage preset, increases file size)" Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Automatically Reconnect" diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui index 9e5991dae..a41afd5b9 100644 --- a/obs/forms/OBSBasicSettings.ui +++ b/obs/forms/OBSBasicSettings.ui @@ -6,8 +6,8 @@ 0 0 - 937 - 653 + 896 + 667 @@ -363,6 +363,342 @@ 0 + + + + + 0 + 0 + + + + Basic.Settings.Output.Adv.Streaming + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 170 + 0 + + + + Basic.Settings.Output.VideoBitrate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 200 + + + 1000000 + + + 2000 + + + + + + + Basic.Settings.Output.AudioBitrate + + + + + + + 8 + + + + 32 + + + + + 48 + + + + + 64 + + + + + 80 + + + + + 96 + + + + + 112 + + + + + 128 + + + + + 160 + + + + + 192 + + + + + 256 + + + + + 320 + + + + + + + + Basic.Settings.Output.Advanced + + + true + + + + + + + + ultrafast + + + + + superfast + + + + + veryfast + + + + + faster + + + + + fast + + + + + medium + + + + + slow + + + + + slower + + + + + + + + true + + + Basic.Settings.Output.EncoderPreset + + + + + + + Basic.Settings.Output.CustomEncoderSettings + + + + + + + + + + + + + + 0 + 0 + + + + Basic.Settings.Output.Adv.Recording + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + true + + + Browse + + + + + + + + + + 170 + 0 + + + + Basic.Settings.Output.Simple.SavePath + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + flv + + + + + mp4 + + + + + mov + + + + + mkv + + + + + ts + + + + + + + + Basic.Settings.Output.Format + + + + + + + + + + Basic.Settings.Output.Simple.RecordingQuality + + + + + + + + + + Basic.Settings.Output.Encoder + + + + + + + + + + 10 + + + 10 + + + 10 + + + 10 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -378,260 +714,6 @@ 0 - - - - - 0 - 0 - - - - - QFormLayout::AllNonFixedFieldsGrow - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 170 - 0 - - - - Basic.Settings.Output.Simple.SavePath - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - true - - - - - - - true - - - Browse - - - - - - - - - Basic.Settings.Output.Format - - - - - - - - flv - - - - - mp4 - - - - - mov - - - - - mkv - - - - - ts - - - - - - - - Basic.Settings.Output.VideoBitrate - - - - - - - 200 - - - 1000000 - - - 2000 - - - - - - - Basic.Settings.Output.AudioBitrate - - - - - - - 8 - - - - 32 - - - - - 48 - - - - - 64 - - - - - 80 - - - - - 96 - - - - - 112 - - - - - 128 - - - - - 160 - - - - - 192 - - - - - 256 - - - - - 320 - - - - - - - - Basic.Settings.Output.Advanced - - - true - - - - - - - true - - - Basic.Settings.Output.EncoderPreset - - - - - - - - ultrafast - - - - - superfast - - - - - veryfast - - - - - faster - - - - - fast - - - - - medium - - - - - slow - - - - - slower - - - - - - - - Basic.Settings.Output.CustomEncoderSettings - - - - - - - - - @@ -2138,8 +2220,8 @@ 0 0 - 98 - 28 + 63 + 16 @@ -2526,8 +2608,8 @@ 0 0 - 711 - 566 + 735 + 618 diff --git a/obs/window-basic-main-outputs.cpp b/obs/window-basic-main-outputs.cpp index cbdd18823..ebd8f1514 100644 --- a/obs/window-basic-main-outputs.cpp +++ b/obs/window-basic-main-outputs.cpp @@ -104,18 +104,36 @@ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate, /* ------------------------------------------------------------------------ */ struct SimpleOutput : BasicOutputHandler { - OBSEncoder aac; - OBSEncoder h264; + OBSEncoder aacStreaming; + OBSEncoder h264Streaming; + OBSEncoder aacRecording; + OBSEncoder h264Recording; - string aacEncoderID; + string aacRecEncID; + string aacStreamEncID; + + string videoEncoder; + string videoQuality; + bool usingRecordingPreset = false; + bool ffmpegOutput = false; + bool lowCPUx264 = false; SimpleOutput(OBSBasic *main_); + int CalcCRF(int crf); + + void UpdateRecordingSettings_x264_crf(int crf); + void UpdateRecordingSettings(); + void UpdateRecordingAudioSettings(); virtual void Update() override; void SetupOutputs(); int GetAudioBitrate() const; + void LoadRecordingPreset_x264(); + void LoadRecordingPreset_Lossless(); + void LoadRecordingPreset(); + virtual bool StartStreaming(obs_service_t *service) override; virtual bool StartRecording() override; virtual void StopStreaming() override; @@ -125,6 +143,68 @@ struct SimpleOutput : BasicOutputHandler { virtual bool RecordingActive() const override; }; +void SimpleOutput::LoadRecordingPreset_Lossless() +{ + fileOutput = obs_output_create("ffmpeg_output", + "simple_ffmpeg_output", nullptr, nullptr); + if (!fileOutput) + throw "Failed to create recording FFmpeg output " + "(simple output)"; + obs_output_release(fileOutput); + + obs_data_t *settings = obs_data_create(); + obs_data_set_string(settings, "format_name", "avi"); + obs_data_set_string(settings, "video_encoder", "huffyuv"); + obs_data_set_int(settings, "audio_bitrate", 512); + obs_data_set_string(settings, "audio_encoder", "ac3"); + + obs_output_update(fileOutput, settings); + obs_data_release(settings); +} + +void SimpleOutput::LoadRecordingPreset_x264() +{ + h264Recording = obs_video_encoder_create("obs_x264", + "simple_h264_recording", nullptr, nullptr); + if (!h264Recording) + throw "Failed to create h264 recording encoder (simple output)"; + obs_encoder_release(h264Recording); + + if (!CreateAACEncoder(aacRecording, aacRecEncID, 192, + "simple_aac_recording", 0)) + throw "Failed to create aac recording encoder (simple output)"; +} + +void SimpleOutput::LoadRecordingPreset() +{ + const char *quality = config_get_string(main->Config(), "SimpleOutput", + "RecQuality"); + const char *encoder = config_get_string(main->Config(), "SimpleOutput", + "RecEncoder"); + + videoEncoder = encoder; + videoQuality = quality; + ffmpegOutput = false; + + if (strcmp(quality, "Stream") == 0) { + h264Recording = h264Streaming; + aacRecording = aacStreaming; + usingRecordingPreset = false; + return; + + } else if (strcmp(quality, "Lossless") == 0) { + LoadRecordingPreset_Lossless(); + usingRecordingPreset = true; + ffmpegOutput = true; + return; + + } else { + lowCPUx264 = strcmp(encoder, SIMPLE_ENCODER_X264_LOWCPU) == 0; + LoadRecordingPreset_x264(); + usingRecordingPreset = true; + } +} + SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) { streamOutput = obs_output_create("rtmp_output", "simple_stream", @@ -133,21 +213,15 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) throw "Failed to create stream output (simple output)"; obs_output_release(streamOutput); - fileOutput = obs_output_create("ffmpeg_muxer", "simple_file_output", - nullptr, nullptr); - if (!fileOutput) - throw "Failed to create recording output (simple output)"; - obs_output_release(fileOutput); + h264Streaming = obs_video_encoder_create("obs_x264", + "simple_h264_stream", nullptr, nullptr); + if (!h264Streaming) + throw "Failed to create h264 streaming encoder (simple output)"; + obs_encoder_release(h264Streaming); - h264 = obs_video_encoder_create("obs_x264", "simple_h264", nullptr, - nullptr); - if (!h264) - throw "Failed to create h264 encoder (simple output)"; - obs_encoder_release(h264); - - if (!CreateAACEncoder(aac, aacEncoderID, GetAudioBitrate(), + if (!CreateAACEncoder(aacStreaming, aacStreamEncID, GetAudioBitrate(), "simple_aac", 0)) - throw "Failed to create audio encoder (simple output)"; + throw "Failed to create aac streaming encoder (simple output)"; streamDelayStarting.Connect(obs_output_get_signal_handler(streamOutput), "starting", OBSStreamStarting, this); @@ -159,6 +233,17 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) stopStreaming.Connect(obs_output_get_signal_handler(streamOutput), "stop", OBSStopStreaming, this); + LoadRecordingPreset(); + + if (!ffmpegOutput) { + fileOutput = obs_output_create("ffmpeg_muxer", + "simple_file_output", nullptr, nullptr); + if (!fileOutput) + throw "Failed to create recording output " + "(simple output)"; + obs_output_release(fileOutput); + } + startRecording.Connect(obs_output_get_signal_handler(fileOutput), "start", OBSStartRecording, this); stopRecording.Connect(obs_output_get_signal_handler(fileOutput), @@ -202,20 +287,89 @@ void SimpleOutput::Update() enum video_format format = video_output_get_format(video); if (format != VIDEO_FORMAT_NV12 && format != VIDEO_FORMAT_I420) - obs_encoder_set_preferred_video_format(h264, VIDEO_FORMAT_NV12); + obs_encoder_set_preferred_video_format(h264Streaming, + VIDEO_FORMAT_NV12); - obs_encoder_update(h264, h264Settings); - obs_encoder_update(aac, aacSettings); + obs_encoder_update(h264Streaming, h264Settings); + obs_encoder_update(aacStreaming, aacSettings); obs_data_release(h264Settings); obs_data_release(aacSettings); } +void SimpleOutput::UpdateRecordingAudioSettings() +{ + obs_data_t *settings = obs_data_create(); + obs_data_set_int(settings, "bitrate", 192); + obs_data_set_bool(settings, "cbr", true); + + obs_encoder_update(aacRecording, settings); + + obs_data_release(settings); +} + +#define CROSS_DIST_CUTOFF 2000.0 + +int SimpleOutput::CalcCRF(int crf) +{ + int cx = config_get_uint(main->Config(), "Video", "OutputCX"); + int cy = config_get_uint(main->Config(), "Video", "OutputCY"); + double fCX = double(cx); + double fCY = double(cy); + + if (lowCPUx264) + crf -= 2; + + double crossDist = sqrt(fCX * fCX + fCY * fCY); + double crfResReduction = + fmin(CROSS_DIST_CUTOFF, crossDist) / CROSS_DIST_CUTOFF; + crfResReduction = (1.0 - crfResReduction) * 10.0; + + return crf - int(crfResReduction); +} + +void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf) +{ + obs_data_t *settings = obs_data_create(); + obs_data_set_int(settings, "bitrate", 1000); + obs_data_set_int(settings, "buffer_size", 0); + obs_data_set_int(settings, "crf", crf); + obs_data_set_bool(settings, "use_bufsize", true); + obs_data_set_bool(settings, "cbr", false); + obs_data_set_string(settings, "profile", "high"); + obs_data_set_string(settings, "preset", + lowCPUx264 ? "ultrafast" : "veryfast"); + + obs_encoder_update(h264Recording, settings); + + obs_data_release(settings); +} + +void SimpleOutput::UpdateRecordingSettings() +{ + if (astrcmp_n(videoEncoder.c_str(), "x264", 4) == 0) { + if (videoQuality == "Small") + UpdateRecordingSettings_x264_crf(CalcCRF(23)); + else if (videoQuality == "HQ") + UpdateRecordingSettings_x264_crf(CalcCRF(16)); + } +} + inline void SimpleOutput::SetupOutputs() { SimpleOutput::Update(); - obs_encoder_set_video(h264, obs_get_video()); - obs_encoder_set_audio(aac, obs_get_audio()); + obs_encoder_set_video(h264Streaming, obs_get_video()); + obs_encoder_set_audio(aacStreaming, obs_get_audio()); + + if (usingRecordingPreset) { + if (ffmpegOutput) { + obs_output_set_media(fileOutput, obs_get_video(), + obs_get_audio()); + } else { + obs_encoder_set_video(h264Recording, obs_get_video()); + obs_encoder_set_audio(aacRecording, obs_get_audio()); + } + } } bool SimpleOutput::StartStreaming(obs_service_t *service) @@ -223,8 +377,8 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) if (!Active()) SetupOutputs(); - obs_output_set_video_encoder(streamOutput, h264); - obs_output_set_audio_encoder(streamOutput, aac, 0); + obs_output_set_video_encoder(streamOutput, h264Streaming); + obs_output_set_audio_encoder(streamOutput, aacStreaming, 0); obs_output_set_service(streamOutput, service); bool reconnect = config_get_bool(main->Config(), "Output", @@ -257,6 +411,13 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) bool SimpleOutput::StartRecording() { + if (usingRecordingPreset) { + if (!ffmpegOutput) + UpdateRecordingSettings(); + } else if (!obs_output_active(streamOutput)) { + Update(); + } + if (!Active()) SetupOutputs(); @@ -283,15 +444,18 @@ bool SimpleOutput::StartRecording() if (lastChar != '/' && lastChar != '\\') strPath += "/"; - strPath += GenerateTimeDateFilename(format); + strPath += GenerateTimeDateFilename(ffmpegOutput ? "avi" : format); SetupOutputs(); - obs_output_set_video_encoder(fileOutput, h264); - obs_output_set_audio_encoder(fileOutput, aac, 0); + if (!ffmpegOutput) { + obs_output_set_video_encoder(fileOutput, h264Recording); + obs_output_set_audio_encoder(fileOutput, aacRecording, 0); + } obs_data_t *settings = obs_data_create(); - obs_data_set_string(settings, "path", strPath.c_str()); + obs_data_set_string(settings, ffmpegOutput ? "url" : "path", + strPath.c_str()); obs_output_update(fileOutput, settings); diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 8aaa5b4a0..8efd71287 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -659,6 +659,10 @@ bool OBSBasic::InitBasicConfigDefaults() false); config_set_default_string(basicConfig, "SimpleOutput", "Preset", "veryfast"); + config_set_default_string(basicConfig, "SimpleOutput", "RecQuality", + "Stream"); + config_set_default_string(basicConfig, "SimpleOutput", "RecEncoder", + SIMPLE_ENCODER_X264); config_set_default_bool (basicConfig, "AdvOut", "ApplyServiceSettings", true); diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index 981d35e65..0421b2e28 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -47,6 +47,9 @@ class QNetworkReply; #define AUX_AUDIO_2 Str("AuxAudioDevice2") #define AUX_AUDIO_3 Str("AuxAudioDevice3") +#define SIMPLE_ENCODER_X264 "x264" +#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" + struct BasicOutputHandler; enum class QtDataRole { diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index 341e4d4af..43e05e60b 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -272,6 +272,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->simpleOutAdvanced, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutPreset, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutCustom, EDIT_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->simpleOutRecQuality, COMBO_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->simpleOutRecEncoder, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutEncoder, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutUseRescale, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->advOutRescale, CBEDIT_CHANGED, OUTPUTS_CHANGED); @@ -426,6 +428,14 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) hotkeyUnregistered.Connect(obs_get_signal_handler(), "hotkey_unregister", ReloadHotkeysIgnore, this); + FillSimpleRecordingValues(); + connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), + this, SLOT(SimpleRecordingQualityChanged())); + connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), + this, SLOT(SimpleRecordingQualityLosslessWarning(int))); + connect(ui->simpleOutRecEncoder, SIGNAL(currentIndexChanged(int)), + this, SLOT(SimpleRecordingEncoderChanged())); + LoadSettings(false); // Add warning checks to advanced output recording section controls @@ -438,6 +448,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) connect(ui->advOutRecTrack4, SIGNAL(clicked()), this, SLOT(AdvOutRecCheckWarnings())); AdvOutRecCheckWarnings(); + + SimpleRecordingQualityChanged(); } void OBSBasicSettings::SaveCombo(QComboBox *widget, const char *section, @@ -1006,6 +1018,10 @@ void OBSBasicSettings::LoadSimpleOutputSettings() "Preset"); const char *custom = config_get_string(main->Config(), "SimpleOutput", "x264Settings"); + const char *recQual = config_get_string(main->Config(), "SimpleOutput", + "RecQuality"); + const char *recEnc = config_get_string(main->Config(), "SimpleOutput", + "RecEncoder"); ui->simpleOutputPath->setText(path); ui->simpleOutputVBitrate->setValue(videoBitrate); @@ -1019,6 +1035,14 @@ void OBSBasicSettings::LoadSimpleOutputSettings() ui->simpleOutAdvanced->setChecked(advanced); ui->simpleOutPreset->setCurrentText(preset); ui->simpleOutCustom->setText(custom); + + idx = ui->simpleOutRecQuality->findData(QString(recQual)); + if (idx == -1) idx = 0; + ui->simpleOutRecQuality->setCurrentIndex(idx); + + idx = ui->simpleOutRecEncoder->findData(QString(recEnc)); + if (idx == -1) idx = 0; + ui->simpleOutRecEncoder->setCurrentIndex(idx); } void OBSBasicSettings::LoadAdvOutputStreamingSettings() @@ -2078,6 +2102,8 @@ void OBSBasicSettings::SaveOutputSettings() SaveCheckBox(ui->simpleOutAdvanced, "SimpleOutput", "UseAdvanced"); SaveCombo(ui->simpleOutPreset, "SimpleOutput", "Preset"); SaveEdit(ui->simpleOutCustom, "SimpleOutput", "x264Settings"); + SaveComboData(ui->simpleOutRecQuality, "SimpleOutput", "RecQuality"); + SaveComboData(ui->simpleOutRecEncoder, "SimpleOutput", "RecEncoder"); SaveCheckBox(ui->advOutApplyService, "AdvOut", "ApplyServiceSettings"); SaveComboData(ui->advOutEncoder, "AdvOut", "Encoder"); @@ -2750,3 +2776,111 @@ void OBSBasicSettings::UpdateStreamDelayEstimate() else UpdateAdvOutStreamDelayEstimate(); } + +void OBSBasicSettings::FillSimpleRecordingValues() +{ +#define ADD_QUALITY(str) \ + ui->simpleOutRecQuality->addItem( \ + QTStr("Basic.Settings.Output.Simple.RecordingQuality." \ + str), \ + QString(str)); +#define ENCODER_STR(str) QTStr("Basic.Settings.Output.Simple.Encoder." str) + + ADD_QUALITY("Stream"); + ADD_QUALITY("Small"); + ADD_QUALITY("HQ"); + ADD_QUALITY("Lossless"); + + ui->simpleOutRecEncoder->addItem( + ENCODER_STR("Software"), + QString(SIMPLE_ENCODER_X264)); + ui->simpleOutRecEncoder->addItem( + ENCODER_STR("SoftwareLowCPU"), + QString(SIMPLE_ENCODER_X264_LOWCPU)); +#undef ADD_QUALITY +#undef ENCODER_STR +} + +void OBSBasicSettings::SimpleRecordingQualityChanged() +{ + QString qual = ui->simpleOutRecQuality->currentData().toString(); + bool streamQuality = qual == "Stream"; + bool losslessQuality = !streamQuality && qual == "Lossless"; + + bool showEncoder = !streamQuality && !losslessQuality; + ui->simpleOutRecEncoder->setVisible(showEncoder); + ui->simpleOutRecEncoderLabel->setVisible(showEncoder); + ui->simpleOutRecFormat->setVisible(!losslessQuality); + ui->simpleOutRecFormatLabel->setVisible(!losslessQuality); + + SimpleRecordingEncoderChanged(); +} + +#define SIMPLE_OUTPUT_WARNING(str) \ + QTStr("Basic.Settings.Output.Simple.Warn." str) + +void OBSBasicSettings::SimpleRecordingEncoderChanged() +{ + QString qual = ui->simpleOutRecQuality->currentData().toString(); + QString warning; + + delete simpleOutRecWarning; + + if (qual == "Stream") { + return; + + } else if (qual == "Lossless") { + warning = SIMPLE_OUTPUT_WARNING("Lossless"); + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("Encoder"); + + } else { + QString enc = ui->simpleOutRecEncoder->currentData().toString(); + if (enc != SIMPLE_ENCODER_X264 && + enc != SIMPLE_ENCODER_X264_LOWCPU) + return; + + warning = SIMPLE_OUTPUT_WARNING("Encoder"); + } + + simpleOutRecWarning = new QLabel(warning, this); + simpleOutRecWarning->setObjectName("warningLabel"); + simpleOutRecWarning->setWordWrap(true); + ui->simpleOutInfoLayout->addWidget(simpleOutRecWarning); +} + +void OBSBasicSettings::SimpleRecordingQualityLosslessWarning(int idx) +{ + if (idx == lastSimpleRecQualityIdx || idx == -1) + return; + + QString qual = ui->simpleOutRecQuality->itemData(idx).toString(); + + if (loading) { + lastSimpleRecQualityIdx = idx; + return; + } + + if (qual == "Lossless") { + QMessageBox::StandardButton button; + + QString warningString = + SIMPLE_OUTPUT_WARNING("Lossless") + + QString("\n\n") + + SIMPLE_OUTPUT_WARNING("Lossless.Msg"); + + button = QMessageBox::question(this, + SIMPLE_OUTPUT_WARNING("Lossless.Title"), + warningString, + QMessageBox::Yes | QMessageBox::No); + + if (button == QMessageBox::No) { + QMetaObject::invokeMethod(ui->simpleOutRecQuality, + "setCurrentIndex", Qt::QueuedConnection, + Q_ARG(int, lastSimpleRecQualityIdx)); + return; + } + } + + lastSimpleRecQualityIdx = idx; +} diff --git a/obs/window-basic-settings.hpp b/obs/window-basic-settings.hpp index fee3595e2..662fe601c 100644 --- a/obs/window-basic-settings.hpp +++ b/obs/window-basic-settings.hpp @@ -97,6 +97,8 @@ private: bool loading = true; std::string savedTheme; + int lastSimpleRecQualityIdx = 0; + OBSFFFormatDesc formats; OBSPropertiesView *streamProperties = nullptr; @@ -104,6 +106,7 @@ private: OBSPropertiesView *recordEncoderProps = nullptr; QPointer advOutRecWarning; + QPointer simpleOutRecWarning; using AudioSource_t = std::tuple