Skip to content

Commit b191c7c

Browse files
committed
UI: Apply settings gathered by Pre-stream wizard
Applies selected settings to the simple encoder setup. Use the Custom Encoder Settings to set specific settings. Additionally, changes the output resolution so the canvas layout is not changed possibly right before a stream. Next to add gating so this wizard only shows in output Simple Mode.
1 parent 993c6f8 commit b191c7c

11 files changed

Lines changed: 245 additions & 45 deletions

UI/common-settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class CommonSettings {
3131

3232
/* Stream Encoder ——————————————————————————————————*/
3333
static int GetVideoBitrateInUse(config_t *config);
34+
static void SetAllVideoBitrates(config_t *config, int newBitrate);
3435

3536
private:
3637
// Reused Strings

UI/pre-stream-wizard/page-input-display.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ QWizardPage *SettingsInputPage(StreamWizard::EncoderSettingsRequest *settings)
2323
QWidget *formContainer = new QWidget();
2424
QFormLayout *form = new QFormLayout(formContainer);
2525

26-
form->addRow("Server Url",
27-
new QLabel(QString::fromUtf8(settings->serverUrl)));
28-
form->addRow("Service",
29-
new QLabel(QString::fromUtf8(settings->serviceName)));
3026
form->addRow("Video Width",
3127
new QLabel(QString::number(settings->videoWidth)));
3228
form->addRow("Video Height",

UI/pre-stream-wizard/page-start-prompt.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ StartPage::StartPage(Destination dest, LaunchContext launchContext,
3333
resCurrentButton_->setChecked(true);
3434
}
3535
}
36+
37+
void StartPage::initializePage()
38+
{
39+
// emit defaul resolution check
40+
if (destination_ == Destination::Facebook &&
41+
res720Button_->isChecked()) {
42+
emit userSelectedResolution(QSize(1280, 720));
43+
}
44+
}
45+
3646
void StartPage::createLayout()
3747
{
3848
QVBoxLayout *mainlayout = new QVBoxLayout(this);
@@ -104,17 +114,17 @@ void StartPage::createLayout()
104114
void StartPage::connectRadioButtons()
105115
{
106116
connect(res720Button_, &QRadioButton::clicked, [=]() {
107-
selectedVideoSize_ = QSize(1280, 720);
108-
emit userSelectedResolution(selectedVideoSize_);
117+
QSize selectedVideoSize = QSize(1280, 720);
118+
emit userSelectedResolution(selectedVideoSize);
109119
});
110120
connect(res1080Button_, &QRadioButton::clicked, [=]() {
111-
selectedVideoSize_ = QSize(1920, 1080);
112-
emit userSelectedResolution(selectedVideoSize_);
121+
QSize selectedVideoSize = QSize(1920, 1080);
122+
emit userSelectedResolution(selectedVideoSize);
113123
});
114124
connect(resCurrentButton_, &QRadioButton::clicked, [=]() {
115-
selectedVideoSize_ = QSize(startVideoSize_.width(),
116-
startVideoSize_.height());
117-
emit userSelectedResolution(selectedVideoSize_);
125+
QSize selectedVideoSize = QSize(startVideoSize_.width(),
126+
startVideoSize_.height());
127+
emit userSelectedResolution(selectedVideoSize);
118128
});
119129
}
120130

UI/pre-stream-wizard/page-start-prompt.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class StartPage : public QWizardPage {
1717
StartPage(Destination dest, LaunchContext launchContext,
1818
QSize videoSize, QWidget *parent = nullptr);
1919

20+
void initializePage() override;
21+
2022
signals:
2123
// emitted selected resolution from start page radio buttons
2224
void userSelectedResolution(QSize newVideoSize);
@@ -28,7 +30,6 @@ class StartPage : public QWizardPage {
2830
QSize startVideoSize_;
2931

3032
// Selected settings
31-
QSize selectedVideoSize_;
3233
QRadioButton *res720Button_;
3334
QRadioButton *res1080Button_;
3435
QRadioButton *resCurrentButton_;

UI/pre-stream-wizard/pre-stream-current-settings.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ struct EncoderSettingsRequest {
5353
//// Stream
5454
StreamProtocol protocol; // Expandable but only supports RTMPS for now
5555
VideoType videoType; // LIVE or VOD (but always live for OBS)
56-
char *serverUrl;
57-
char *serviceName;
5856

5957
///// Video Settings
6058
int videoWidth;

UI/pre-stream-wizard/pre-stream-wizard.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void PreStreamWizard::requestSettings()
8181
connect(fbProvider,
8282
&FacebookEncoderSettingsProvider::returnErrorDescription,
8383
this, &PreStreamWizard::providerError);
84+
8485
fbProvider->setEncoderRequest(currentSettings_);
8586
fbProvider->run();
8687

@@ -132,6 +133,11 @@ void PreStreamWizard::onPageChanged(int id)
132133

133134
case Page_Complete:
134135
setButtons(FinishOnly);
136+
if (newSettingsMap_ != nullptr && !newSettingsMap_.isNull()) {
137+
// ToDo: messaging in edge case this could be empty
138+
// and still make it here?
139+
emit applySettings(newSettingsMap_);
140+
};
135141
break;
136142

137143
case Page_Error:

UI/pre-stream-wizard/pre-stream-wizard.hpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,6 @@ class PreStreamWizard : public QWizard {
5656
void setButtons(ButtonLayout layout);
5757

5858
signals:
59-
// User left the wizard with intention to continue streaming
60-
void userSkippedWizard(void);
61-
62-
// User canceled, also canceling intent to stream.
63-
void userAbortedStream(void);
64-
65-
// User ready to start stream
66-
// If newSettings is not null, they should be applied before stream
67-
// If newSettings is null, user or wizard did not opt to apply changes.
68-
void
69-
startStreamWithSettings(QSharedPointer<SettingsMap> newSettingsOrNull);
70-
7159
// Apply settings, don't start stream. e.g., is configuring from settings
7260
void applySettings(QSharedPointer<SettingsMap> newSettings);
7361

UI/streaming-settings-util.cpp

Lines changed: 177 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "common-settings.hpp"
44
#include <util/config-file.h>
55

6+
#include <QPair>
7+
68
/*
79
We are detecting the stream settings so if they're using a large canvas but
810
already have the rescaler on, they will be streaming correctly.
@@ -32,8 +34,7 @@ void UpdateStreamingResolution(int *resolutionXY, bool isRescaled,
3234
};
3335

3436
QSharedPointer<StreamWizard::EncoderSettingsRequest>
35-
StreamingSettingsUtility::makeEncoderSettingsFromCurrentState(
36-
config_t *config, obs_data_t *settings)
37+
StreamingSettingsUtility::makeEncoderSettingsFromCurrentState(config_t *config)
3738
{
3839
QSharedPointer<StreamWizard::EncoderSettingsRequest> currentSettings(
3940
new StreamWizard::EncoderSettingsRequest());
@@ -43,12 +44,6 @@ StreamingSettingsUtility::makeEncoderSettingsFromCurrentState(
4344
currentSettings->videoType = StreamWizard::VideoType::live;
4445
// only live and rmpts is supported for now
4546
currentSettings->protocol = StreamWizard::StreamProtocol::rtmps;
46-
47-
currentSettings->serverUrl =
48-
bstrdup(obs_data_get_string(settings, "server"));
49-
currentSettings->serviceName =
50-
bstrdup(obs_data_get_string(settings, "service"));
51-
5247
/* Video */
5348
bool isRescaled = config_get_bool(config, "AdvOut", "Rescale");
5449
int resolutionXY[2] = {0, 0};
@@ -73,3 +68,177 @@ StreamingSettingsUtility::makeEncoderSettingsFromCurrentState(
7368

7469
return currentSettings;
7570
};
71+
72+
/*
73+
* StreamWizard::SettingsMap is sparse in that it wont have all keys
74+
* as well, the user can opt out of settings being applied.
75+
* The map looks like [ SettingsResponseKeys : QPair<QVariant, bool> ]
76+
* AKA [KEY : SetttingPair<Setting_Value_Variant, User_Wants_Setting_Bool> ]
77+
* if the key is available, it means the wizard provider added a value for it
78+
* but the bool in the QPair is false if the user selected in the wizard not to
79+
* apply the setting. A case would be we suggest a 720p stream but the user
80+
* knows their account supports 1080 so disabled the setting from applying.
81+
82+
* Returns TRUE is map contrains something for the key and it is marked true
83+
*/
84+
bool CheckInMapAndSelected(StreamWizard::SettingsMap *map, const char *key)
85+
{
86+
if (!map->contains(key)) {
87+
return false;
88+
}
89+
const QPair<QVariant, bool> settingPair = map->value(key);
90+
return settingPair.second;
91+
}
92+
93+
// Helper Functions for ::applyWizardSettings
94+
int intFromMap(StreamWizard::SettingsMap *map, const char *key)
95+
{
96+
QPair<QVariant, bool> settingPair = map->value(key);
97+
QVariant data = settingPair.first;
98+
return data.toInt();
99+
}
100+
101+
QString stringFromMap(StreamWizard::SettingsMap *map, const char *key)
102+
{
103+
QPair<QVariant, bool> settingPair = map->value(key);
104+
QVariant data = settingPair.first;
105+
return data.toString();
106+
}
107+
108+
double doubleFromMap(StreamWizard::SettingsMap *map, const char *key)
109+
{
110+
QPair<QVariant, bool> settingPair = map->value(key);
111+
QVariant data = settingPair.first;
112+
return data.toDouble();
113+
}
114+
115+
bool boolFromMap(StreamWizard::SettingsMap *map, const char *key)
116+
{
117+
QPair<QVariant, bool> settingPair = map->value(key);
118+
QVariant data = settingPair.first;
119+
return data.toBool();
120+
}
121+
122+
/*
123+
* Given a settings map [ SettingsResponseKeys : QPair<QVariant, bool> ] apply
124+
* settings that are in the sparse map as well selected by the user (which is
125+
* marked by the bool in the pair).
126+
* Apply to Basic encoder settings.
127+
* Possible later goal: autoconfig advanced settings too
128+
*/
129+
void StreamingSettingsUtility::applyWizardSettings(
130+
QSharedPointer<StreamWizard::SettingsMap> newSettings, config_t *config)
131+
{
132+
133+
if (newSettings == nullptr || newSettings.isNull())
134+
return;
135+
136+
// scope to function usage
137+
using namespace StreamWizard;
138+
139+
SettingsMap *map = newSettings.data();
140+
141+
QStringList x264SettingList;
142+
config_set_bool(config, "SimpleOutput", "UseAdvanced", true);
143+
144+
// Resolution must have both
145+
if (CheckInMapAndSelected(map, SettingsResponseKeys.videoHeight) &&
146+
CheckInMapAndSelected(map, SettingsResponseKeys.videoWidth)) {
147+
148+
int canvasX = intFromMap(map, SettingsResponseKeys.videoWidth);
149+
int canvasY = intFromMap(map, SettingsResponseKeys.videoHeight);
150+
config_set_uint(config, "Video", "OutputCX", canvasX);
151+
config_set_uint(config, "Video", "OutputCY", canvasY);
152+
}
153+
154+
//TODO: FPS is hacky but covers all integer and standard drop frame cases
155+
if (CheckInMapAndSelected(map, SettingsResponseKeys.framerate)) {
156+
double currentFPS = CommonSettings::GetConfigFPSDouble(config);
157+
double newFPS =
158+
doubleFromMap(map, SettingsResponseKeys.framerate);
159+
if (abs(currentFPS - newFPS) >
160+
0.001) { // Only change if different
161+
if (abs(floor(newFPS) - newFPS) >
162+
0.01) { // Is a drop-frame FPS
163+
int num = ceil(newFPS) * 1000;
164+
int den = 1001;
165+
config_set_uint(config, "Video", "FPSType",
166+
2); // Fraction
167+
config_set_uint(config, "Video", "FPSNum", num);
168+
config_set_uint(config, "Video", "FPSDen", den);
169+
} else { // Is integer FPS
170+
config_set_uint(config, "Video", "FPSType",
171+
1); // Integer
172+
config_set_uint(config, "Video", "FPSInt",
173+
(int)floor(newFPS));
174+
}
175+
}
176+
}
177+
178+
if (CheckInMapAndSelected(map, SettingsResponseKeys.videoBitrate)) {
179+
int newBitrate =
180+
intFromMap(map, SettingsResponseKeys.videoBitrate);
181+
config_set_int(config, "SimpleOutput", "VBitrate", newBitrate);
182+
}
183+
184+
if (CheckInMapAndSelected(map, SettingsResponseKeys.h264Profile)) {
185+
QString profile =
186+
stringFromMap(map, SettingsResponseKeys.h264Profile);
187+
profile = profile.toLower();
188+
x264SettingList.append("profile=" + profile);
189+
}
190+
191+
if (CheckInMapAndSelected(map, SettingsResponseKeys.h264Level)) {
192+
QString levelString =
193+
stringFromMap(map, SettingsResponseKeys.h264Level);
194+
x264SettingList.append("level=" + levelString);
195+
}
196+
197+
if (CheckInMapAndSelected(map, SettingsResponseKeys.gopSizeInFrames)) {
198+
int gopSize =
199+
intFromMap(map, SettingsResponseKeys.gopSizeInFrames);
200+
x264SettingList.append("keyint=" + QString::number(gopSize));
201+
}
202+
203+
if (CheckInMapAndSelected(map, SettingsResponseKeys.gopType)) {
204+
QString gopType =
205+
stringFromMap(map, SettingsResponseKeys.gopType);
206+
x264SettingList.append("slice_mode=" + gopType);
207+
}
208+
209+
if (CheckInMapAndSelected(map, SettingsResponseKeys.gopClosed)) {
210+
bool gopClose =
211+
boolFromMap(map, SettingsResponseKeys.gopClosed);
212+
if (gopClose) {
213+
x264SettingList.append("open_gop=0");
214+
} else {
215+
x264SettingList.append("open_gop=1");
216+
}
217+
}
218+
219+
if (CheckInMapAndSelected(map, SettingsResponseKeys.gopBFrames)) {
220+
int bFrames = intFromMap(map, SettingsResponseKeys.gopBFrames);
221+
x264SettingList.append("bframes=" + QString::number(bFrames));
222+
}
223+
224+
if (CheckInMapAndSelected(map, SettingsResponseKeys.gopRefFrames)) {
225+
int refFrames =
226+
intFromMap(map, SettingsResponseKeys.gopRefFrames);
227+
x264SettingList.append("ref=" + QString::number(refFrames));
228+
}
229+
230+
// SettingsResponseKeys.streamRateControlMode defaults to CBR in Simple
231+
// encoder mode. Can add later for advanced panel.
232+
233+
if (CheckInMapAndSelected(map, SettingsResponseKeys.streamBufferSize)) {
234+
int bufferSize =
235+
intFromMap(map, SettingsResponseKeys.streamBufferSize);
236+
x264SettingList.append("bufsize=" +
237+
QString::number(bufferSize));
238+
}
239+
240+
QString x264String = x264SettingList.join(" ");
241+
const char *x264_c_String = x264String.toStdString().c_str();
242+
config_set_string(config, "SimpleOutput", "x264Settings",
243+
x264_c_String);
244+
};

UI/streaming-settings-util.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ class StreamingSettingsUtility : public QObject {
1414
public:
1515
// Uses current settings in OBS
1616
static QSharedPointer<StreamWizard::EncoderSettingsRequest>
17-
makeEncoderSettingsFromCurrentState(config_t *config,
18-
obs_data_t *settings);
17+
makeEncoderSettingsFromCurrentState(config_t *config);
18+
19+
static void applyWizardSettings(
20+
QSharedPointer<StreamWizard::SettingsMap> newSettings,
21+
config_t *config);
1922
};

0 commit comments

Comments
 (0)