clang-format: Apply formatting
Code submissions have continually suffered from formatting inconsistencies that constantly have to be addressed. Using clang-format simplifies this by making code formatting more consistent, and allows automation of the code formatting so that maintainers can focus more on the code itself instead of code formatting.master
parent
53615ee10f
commit
f53df7da64
|
@ -87,8 +87,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
|
|||
forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0);
|
||||
|
||||
forceMonoContainer->layout()->addWidget(forceMono);
|
||||
forceMonoContainer->layout()->setAlignment(forceMono,
|
||||
Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
forceMonoContainer->layout()->setAlignment(
|
||||
forceMono, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
|
||||
balance->setOrientation(Qt::Horizontal);
|
||||
balance->setMinimum(0);
|
||||
|
@ -98,8 +98,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
|
|||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
const char *speakers = config_get_string(main->Config(), "Audio",
|
||||
"ChannelSetup");
|
||||
const char *speakers =
|
||||
config_get_string(main->Config(), "Audio", "ChannelSetup");
|
||||
|
||||
if (strcmp(speakers, "Mono") == 0)
|
||||
balance->setEnabled(false);
|
||||
|
@ -156,32 +156,32 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
|
|||
mixerContainer->layout()->addWidget(mixer5);
|
||||
mixerContainer->layout()->addWidget(mixer6);
|
||||
|
||||
QWidget::connect(volume, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(volumeChanged(double)));
|
||||
QWidget::connect(forceMono, SIGNAL(clicked(bool)),
|
||||
this, SLOT(downmixMonoChanged(bool)));
|
||||
QWidget::connect(balance, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(balanceChanged(int)));
|
||||
QWidget::connect(balance, SIGNAL(doubleClicked()),
|
||||
this, SLOT(ResetBalance()));
|
||||
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(syncOffsetChanged(int)));
|
||||
QWidget::connect(volume, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(volumeChanged(double)));
|
||||
QWidget::connect(forceMono, SIGNAL(clicked(bool)), this,
|
||||
SLOT(downmixMonoChanged(bool)));
|
||||
QWidget::connect(balance, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(balanceChanged(int)));
|
||||
QWidget::connect(balance, SIGNAL(doubleClicked()), this,
|
||||
SLOT(ResetBalance()));
|
||||
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(syncOffsetChanged(int)));
|
||||
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
|
||||
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(monitoringTypeChanged(int)));
|
||||
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(monitoringTypeChanged(int)));
|
||||
#endif
|
||||
QWidget::connect(mixer1, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer1Changed(bool)));
|
||||
QWidget::connect(mixer2, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer2Changed(bool)));
|
||||
QWidget::connect(mixer3, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer3Changed(bool)));
|
||||
QWidget::connect(mixer4, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer4Changed(bool)));
|
||||
QWidget::connect(mixer5, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer5Changed(bool)));
|
||||
QWidget::connect(mixer6, SIGNAL(clicked(bool)),
|
||||
this, SLOT(mixer6Changed(bool)));
|
||||
QWidget::connect(mixer1, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer1Changed(bool)));
|
||||
QWidget::connect(mixer2, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer2Changed(bool)));
|
||||
QWidget::connect(mixer3, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer3Changed(bool)));
|
||||
QWidget::connect(mixer4, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer4Changed(bool)));
|
||||
QWidget::connect(mixer5, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer5Changed(bool)));
|
||||
QWidget::connect(mixer6, SIGNAL(clicked(bool)), this,
|
||||
SLOT(mixer6Changed(bool)));
|
||||
|
||||
setObjectName(sourceName);
|
||||
}
|
||||
|
@ -225,7 +225,6 @@ void OBSAdvAudioCtrl::OBSSourceFlagsChanged(void *param, calldata_t *calldata)
|
|||
uint32_t flags = (uint32_t)calldata_int(calldata, "flags");
|
||||
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
|
||||
"SourceFlagsChanged", Q_ARG(uint32_t, flags));
|
||||
|
||||
}
|
||||
|
||||
void OBSAdvAudioCtrl::OBSSourceVolumeChanged(void *param, calldata_t *calldata)
|
||||
|
@ -246,7 +245,8 @@ void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata)
|
|||
{
|
||||
uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers");
|
||||
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
|
||||
"SourceMixersChanged", Q_ARG(uint32_t, mixers));
|
||||
"SourceMixersChanged",
|
||||
Q_ARG(uint32_t, mixers));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -335,14 +335,13 @@ void OBSAdvAudioCtrl::ResetBalance()
|
|||
balance->setValue(50);
|
||||
}
|
||||
|
||||
|
||||
void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
|
||||
{
|
||||
int64_t cur_val = obs_source_get_sync_offset(source);
|
||||
|
||||
if (cur_val / NSEC_PER_MSEC != milliseconds)
|
||||
obs_source_set_sync_offset(source,
|
||||
int64_t(milliseconds) * NSEC_PER_MSEC);
|
||||
obs_source_set_sync_offset(source, int64_t(milliseconds) *
|
||||
NSEC_PER_MSEC);
|
||||
}
|
||||
|
||||
void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
|
||||
|
@ -374,8 +373,10 @@ static inline void setMixer(obs_source_t *source, const int mixerIdx,
|
|||
uint32_t mixers = obs_source_get_audio_mixers(source);
|
||||
uint32_t new_mixers = mixers;
|
||||
|
||||
if (checked) new_mixers |= (1<<mixerIdx);
|
||||
else new_mixers &= ~(1<<mixerIdx);
|
||||
if (checked)
|
||||
new_mixers |= (1 << mixerIdx);
|
||||
else
|
||||
new_mixers &= ~(1 << mixerIdx);
|
||||
|
||||
obs_source_set_audio_mixers(source, new_mixers);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,7 @@ using namespace std;
|
|||
Q_DECLARE_METATYPE(OBSScene);
|
||||
Q_DECLARE_METATYPE(OBSSource);
|
||||
|
||||
template <typename T>
|
||||
static T GetOBSRef(QListWidgetItem *item)
|
||||
template<typename T> static T GetOBSRef(QListWidgetItem *item)
|
||||
{
|
||||
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
|
||||
}
|
||||
|
@ -30,13 +29,13 @@ template<typename T> struct OBSStudioCallback {
|
|||
T callback;
|
||||
void *private_data;
|
||||
|
||||
inline OBSStudioCallback(T cb, void *p) :
|
||||
callback(cb), private_data(p)
|
||||
{}
|
||||
inline OBSStudioCallback(T cb, void *p) : callback(cb), private_data(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> inline size_t GetCallbackIdx(
|
||||
vector<OBSStudioCallback<T>> &callbacks,
|
||||
template<typename T>
|
||||
inline size_t GetCallbackIdx(vector<OBSStudioCallback<T>> &callbacks,
|
||||
T callback, void *private_data)
|
||||
{
|
||||
for (size_t i = 0; i < callbacks.size(); i++) {
|
||||
|
@ -101,12 +100,12 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
void obs_frontend_set_current_scene(obs_source_t *scene) override
|
||||
{
|
||||
if (main->IsPreviewProgramMode()) {
|
||||
QMetaObject::invokeMethod(main, "TransitionToScene",
|
||||
WaitConnection(),
|
||||
QMetaObject::invokeMethod(
|
||||
main, "TransitionToScene", WaitConnection(),
|
||||
Q_ARG(OBSSource, OBSSource(scene)));
|
||||
} else {
|
||||
QMetaObject::invokeMethod(main, "SetCurrentScene",
|
||||
WaitConnection(),
|
||||
QMetaObject::invokeMethod(
|
||||
main, "SetCurrentScene", WaitConnection(),
|
||||
Q_ARG(OBSSource, OBSSource(scene)),
|
||||
Q_ARG(bool, false));
|
||||
}
|
||||
|
@ -132,11 +131,12 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
return tr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_transition(
|
||||
obs_source_t *transition) override
|
||||
void
|
||||
obs_frontend_set_current_transition(obs_source_t *transition) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main, "SetTransition",
|
||||
Q_ARG(OBSSource, OBSSource(transition)));
|
||||
Q_ARG(OBSSource,
|
||||
OBSSource(transition)));
|
||||
}
|
||||
|
||||
int obs_frontend_get_transition_duration(void) override
|
||||
|
@ -146,15 +146,14 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
|
||||
void obs_frontend_set_transition_duration(int duration) override
|
||||
{
|
||||
QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue",
|
||||
Q_ARG(int, duration));
|
||||
QMetaObject::invokeMethod(main->ui->transitionDuration,
|
||||
"setValue", Q_ARG(int, duration));
|
||||
}
|
||||
|
||||
void obs_frontend_get_scene_collections(
|
||||
std::vector<std::string> &strings) override
|
||||
{
|
||||
auto addCollection = [&](const char *name, const char *)
|
||||
{
|
||||
auto addCollection = [&](const char *name, const char *) {
|
||||
strings.emplace_back(name);
|
||||
return true;
|
||||
};
|
||||
|
@ -164,8 +163,8 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
|
||||
char *obs_frontend_get_current_scene_collection(void) override
|
||||
{
|
||||
const char *cur_name = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
const char *cur_name = config_get_string(
|
||||
App()->GlobalConfig(), "Basic", "SceneCollection");
|
||||
return bstrdup(cur_name);
|
||||
}
|
||||
|
||||
|
@ -189,12 +188,10 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
}
|
||||
}
|
||||
|
||||
bool obs_frontend_add_scene_collection(
|
||||
const char *name) override
|
||||
bool obs_frontend_add_scene_collection(const char *name) override
|
||||
{
|
||||
bool success = false;
|
||||
QMetaObject::invokeMethod(main,
|
||||
"AddSceneCollection",
|
||||
QMetaObject::invokeMethod(main, "AddSceneCollection",
|
||||
WaitConnection(),
|
||||
Q_RETURN_ARG(bool, success),
|
||||
Q_ARG(bool, true),
|
||||
|
@ -202,11 +199,10 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
return success;
|
||||
}
|
||||
|
||||
void obs_frontend_get_profiles(
|
||||
std::vector<std::string> &strings) override
|
||||
{
|
||||
auto addProfile = [&](const char *name, const char *)
|
||||
void
|
||||
obs_frontend_get_profiles(std::vector<std::string> &strings) override
|
||||
{
|
||||
auto addProfile = [&](const char *name, const char *) {
|
||||
strings.emplace_back(name);
|
||||
return true;
|
||||
};
|
||||
|
@ -223,8 +219,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
|
||||
void obs_frontend_set_current_profile(const char *profile) override
|
||||
{
|
||||
QList<QAction*> menuActions =
|
||||
main->ui->profileMenu->actions();
|
||||
QList<QAction *> menuActions = main->ui->profileMenu->actions();
|
||||
QString qstrProfile = QT_UTF8(profile);
|
||||
|
||||
for (int i = 0; i < menuActions.count(); i++) {
|
||||
|
@ -297,12 +292,12 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
}
|
||||
|
||||
void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data) override
|
||||
obs_frontend_cb callback,
|
||||
void *private_data) override
|
||||
{
|
||||
main->ui->menuTools->setEnabled(true);
|
||||
|
||||
auto func = [private_data, callback] ()
|
||||
{
|
||||
auto func = [private_data, callback]() {
|
||||
callback(private_data);
|
||||
};
|
||||
|
||||
|
@ -364,10 +359,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
return App()->GlobalConfig();
|
||||
}
|
||||
|
||||
void obs_frontend_save(void) override
|
||||
{
|
||||
main->SaveProject();
|
||||
}
|
||||
void obs_frontend_save(void) override { main->SaveProject(); }
|
||||
|
||||
void obs_frontend_defer_save_begin(void) override
|
||||
{
|
||||
|
@ -382,8 +374,8 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) override
|
||||
{
|
||||
size_t idx = GetCallbackIdx(saveCallbacks, callback,
|
||||
private_data);
|
||||
size_t idx =
|
||||
GetCallbackIdx(saveCallbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
saveCallbacks.emplace_back(callback, private_data);
|
||||
}
|
||||
|
@ -391,8 +383,8 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) override
|
||||
{
|
||||
size_t idx = GetCallbackIdx(saveCallbacks, callback,
|
||||
private_data);
|
||||
size_t idx =
|
||||
GetCallbackIdx(saveCallbacks, callback, private_data);
|
||||
if (idx == (size_t)-1)
|
||||
return;
|
||||
|
||||
|
@ -483,11 +475,13 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||
return source;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_preview_scene(obs_source_t *scene) override
|
||||
void
|
||||
obs_frontend_set_current_preview_scene(obs_source_t *scene) override
|
||||
{
|
||||
if (main->IsPreviewProgramMode()) {
|
||||
QMetaObject::invokeMethod(main, "SetCurrentScene",
|
||||
Q_ARG(OBSSource, OBSSource(scene)),
|
||||
Q_ARG(OBSSource,
|
||||
OBSSource(scene)),
|
||||
Q_ARG(bool, false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
|
|||
{
|
||||
obs_combo_format format = obs_property_list_format(prop);
|
||||
if (format != OBS_COMBO_FORMAT_INT) {
|
||||
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate "
|
||||
blog(LOG_ERROR,
|
||||
"Encoder '%s' (%s) returned bitrate "
|
||||
"OBS_PROPERTY_LIST property of unhandled "
|
||||
"format %d",
|
||||
EncoderName(id), id, static_cast<int>(format));
|
||||
|
@ -60,24 +61,21 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
|
|||
if (obs_property_list_item_disabled(prop, i))
|
||||
continue;
|
||||
|
||||
int bitrate = static_cast<int>(
|
||||
obs_property_list_item_int(prop, i));
|
||||
int bitrate =
|
||||
static_cast<int>(obs_property_list_item_int(prop, i));
|
||||
bitrateMap[bitrate] = id;
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleSampleRate(obs_property_t *prop, const char *id)
|
||||
{
|
||||
auto ReleaseData = [](obs_data_t *data)
|
||||
{
|
||||
obs_data_release(data);
|
||||
};
|
||||
auto ReleaseData = [](obs_data_t *data) { obs_data_release(data); };
|
||||
std::unique_ptr<obs_data_t, decltype(ReleaseData)> data{
|
||||
obs_encoder_defaults(id),
|
||||
ReleaseData};
|
||||
obs_encoder_defaults(id), ReleaseData};
|
||||
|
||||
if (!data) {
|
||||
blog(LOG_ERROR, "Failed to get defaults for encoder '%s' (%s) "
|
||||
blog(LOG_ERROR,
|
||||
"Failed to get defaults for encoder '%s' (%s) "
|
||||
"while populating bitrate map",
|
||||
EncoderName(id), id);
|
||||
return;
|
||||
|
@ -90,8 +88,8 @@ static void HandleSampleRate(obs_property_t* prop, const char *id)
|
|||
return;
|
||||
}
|
||||
|
||||
uint32_t sampleRate = config_get_uint(main->Config(), "Audio",
|
||||
"SampleRate");
|
||||
uint32_t sampleRate =
|
||||
config_get_uint(main->Config(), "Audio", "SampleRate");
|
||||
|
||||
obs_data_set_int(data.get(), "samplerate", sampleRate);
|
||||
|
||||
|
@ -100,23 +98,22 @@ static void HandleSampleRate(obs_property_t* prop, const char *id)
|
|||
|
||||
static void HandleEncoderProperties(const char *id)
|
||||
{
|
||||
auto DestroyProperties = [](obs_properties_t *props)
|
||||
{
|
||||
auto DestroyProperties = [](obs_properties_t *props) {
|
||||
obs_properties_destroy(props);
|
||||
};
|
||||
std::unique_ptr<obs_properties_t, decltype(DestroyProperties)> props{
|
||||
obs_get_encoder_properties(id),
|
||||
DestroyProperties};
|
||||
obs_get_encoder_properties(id), DestroyProperties};
|
||||
|
||||
if (!props) {
|
||||
blog(LOG_ERROR, "Failed to get properties for encoder "
|
||||
blog(LOG_ERROR,
|
||||
"Failed to get properties for encoder "
|
||||
"'%s' (%s)",
|
||||
EncoderName(id), id);
|
||||
return;
|
||||
}
|
||||
|
||||
obs_property_t *samplerate = obs_properties_get(props.get(),
|
||||
"samplerate");
|
||||
obs_property_t *samplerate =
|
||||
obs_properties_get(props.get(), "samplerate");
|
||||
if (samplerate)
|
||||
HandleSampleRate(samplerate, id);
|
||||
|
||||
|
@ -130,12 +127,14 @@ static void HandleEncoderProperties(const char *id)
|
|||
case OBS_PROPERTY_LIST:
|
||||
return HandleListProperty(bitrate, id);
|
||||
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate property "
|
||||
"of unhandled type %d", EncoderName(id), id,
|
||||
static_cast<int>(type));
|
||||
blog(LOG_ERROR,
|
||||
"Encoder '%s' (%s) returned bitrate property "
|
||||
"of unhandled type %d",
|
||||
EncoderName(id), id, static_cast<int>(type));
|
||||
}
|
||||
|
||||
static const char *GetCodec(const char *id)
|
||||
|
@ -146,8 +145,7 @@ static const char *GetCodec(const char *id)
|
|||
static const string aac_ = "AAC";
|
||||
static void PopulateBitrateMap()
|
||||
{
|
||||
call_once(populateBitrateMap, []()
|
||||
{
|
||||
call_once(populateBitrateMap, []() {
|
||||
struct obs_audio_info aoi;
|
||||
obs_get_audio_info(&aoi);
|
||||
uint32_t output_channels = get_audio_channels(aoi.speakers);
|
||||
|
@ -156,8 +154,7 @@ static void PopulateBitrateMap()
|
|||
|
||||
const char *id = nullptr;
|
||||
for (size_t i = 0; obs_enum_encoder_types(i, &id); i++) {
|
||||
auto Compare = [=](const string &val)
|
||||
{
|
||||
auto Compare = [=](const string &val) {
|
||||
return val == NullToEmpty(id);
|
||||
};
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ void Auth::Load()
|
|||
{
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
const char *typeStr = config_get_string(main->Config(), "Auth", "Type");
|
||||
if (!typeStr) typeStr = "";
|
||||
if (!typeStr)
|
||||
typeStr = "";
|
||||
|
||||
main->auth = Create(typeStr);
|
||||
if (main->auth) {
|
||||
|
|
|
@ -19,13 +19,14 @@ protected:
|
|||
|
||||
ErrorInfo(std::string message_, std::string error_)
|
||||
: message(message_), error(error_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
enum class Type {
|
||||
None,
|
||||
OAuth_StreamKey
|
||||
OAuth_StreamKey,
|
||||
};
|
||||
|
||||
struct Def {
|
||||
|
|
|
@ -26,24 +26,16 @@ extern QCefCookieManager *panel_cookies;
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define MIXER_AUTH_URL \
|
||||
"https://obsproject.com/app-auth/mixer?action=redirect"
|
||||
#define MIXER_TOKEN_URL \
|
||||
"https://obsproject.com/app-auth/mixer-token"
|
||||
#define MIXER_AUTH_URL "https://obsproject.com/app-auth/mixer?action=redirect"
|
||||
#define MIXER_TOKEN_URL "https://obsproject.com/app-auth/mixer-token"
|
||||
|
||||
#define MIXER_SCOPE_VERSION 1
|
||||
|
||||
static Auth::Def mixerDef = {
|
||||
"Mixer",
|
||||
Auth::Type::OAuth_StreamKey
|
||||
};
|
||||
static Auth::Def mixerDef = {"Mixer", Auth::Type::OAuth_StreamKey};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
MixerAuth::MixerAuth(const Def &d)
|
||||
: OAuthStreamKey(d)
|
||||
{
|
||||
}
|
||||
MixerAuth::MixerAuth(const Def &d) : OAuthStreamKey(d) {}
|
||||
|
||||
bool MixerAuth::GetChannelInfo(bool allow_retry)
|
||||
try {
|
||||
|
@ -74,19 +66,12 @@ try {
|
|||
auto func = [&]() {
|
||||
success = GetRemoteFile(
|
||||
"https://mixer.com/api/v1/users/current",
|
||||
output,
|
||||
error,
|
||||
nullptr,
|
||||
"application/json",
|
||||
nullptr,
|
||||
headers,
|
||||
nullptr,
|
||||
5);
|
||||
output, error, nullptr, "application/json",
|
||||
nullptr, headers, nullptr, 5);
|
||||
};
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
func,
|
||||
QTStr("Auth.LoadingChannel.Title"),
|
||||
func, QTStr("Auth.LoadingChannel.Title"),
|
||||
QTStr("Auth.LoadingChannel.Text").arg(service()));
|
||||
if (!success || output.empty())
|
||||
throw ErrorInfo("Failed to get user info from remote",
|
||||
|
@ -98,7 +83,8 @@ try {
|
|||
|
||||
error = json["error"].string_value();
|
||||
if (!error.empty())
|
||||
throw ErrorInfo(error,
|
||||
throw ErrorInfo(
|
||||
error,
|
||||
json["error_description"].string_value());
|
||||
|
||||
id = std::to_string(json["channel"]["id"].int_value());
|
||||
|
@ -115,21 +101,13 @@ try {
|
|||
output.clear();
|
||||
|
||||
auto func = [&]() {
|
||||
success = GetRemoteFile(
|
||||
url.c_str(),
|
||||
output,
|
||||
error,
|
||||
nullptr,
|
||||
"application/json",
|
||||
nullptr,
|
||||
headers,
|
||||
nullptr,
|
||||
5);
|
||||
success = GetRemoteFile(url.c_str(), output, error, nullptr,
|
||||
"application/json", nullptr, headers,
|
||||
nullptr, 5);
|
||||
};
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
func,
|
||||
QTStr("Auth.LoadingChannel.Title"),
|
||||
func, QTStr("Auth.LoadingChannel.Title"),
|
||||
QTStr("Auth.LoadingChannel.Text").arg(service()));
|
||||
if (!success || output.empty())
|
||||
throw ErrorInfo("Failed to get stream key from remote", error);
|
||||
|
@ -140,7 +118,8 @@ try {
|
|||
|
||||
error = json["error"].string_value();
|
||||
if (!error.empty())
|
||||
throw ErrorInfo(error, json["error_description"].string_value());
|
||||
throw ErrorInfo(error,
|
||||
json["error_description"].string_value());
|
||||
|
||||
std::string key_suffix = json["streamKey"].string_value();
|
||||
|
||||
|
@ -161,13 +140,12 @@ try {
|
|||
} catch (ErrorInfo info) {
|
||||
QString title = QTStr("Auth.ChannelFailure.Title");
|
||||
QString text = QTStr("Auth.ChannelFailure.Text")
|
||||
.arg(service(), info.message.c_str(), info.error.c_str());
|
||||
.arg(service(), info.message.c_str(),
|
||||
info.error.c_str());
|
||||
|
||||
QMessageBox::warning(OBSBasic::Get(), title, text);
|
||||
|
||||
blog(LOG_WARNING, "%s: %s: %s",
|
||||
__FUNCTION__,
|
||||
info.message.c_str(),
|
||||
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
|
||||
info.error.c_str());
|
||||
return false;
|
||||
}
|
||||
|
@ -184,9 +162,7 @@ void MixerAuth::SaveInternal()
|
|||
OAuthStreamKey::SaveInternal();
|
||||
}
|
||||
|
||||
static inline std::string get_config_str(
|
||||
OBSBasic *main,
|
||||
const char *section,
|
||||
static inline std::string get_config_str(OBSBasic *main, const char *section,
|
||||
const char *name)
|
||||
{
|
||||
const char *val = config_get_string(main->Config(), section, name);
|
||||
|
@ -252,8 +228,8 @@ void MixerAuth::LoadUI()
|
|||
if (firstLoad) {
|
||||
chat->setVisible(true);
|
||||
} else {
|
||||
const char *dockStateStr = config_get_string(main->Config(),
|
||||
service(), "DockState");
|
||||
const char *dockStateStr = config_get_string(
|
||||
main->Config(), service(), "DockState");
|
||||
QByteArray dockState =
|
||||
QByteArray::fromBase64(QByteArray(dockStateStr));
|
||||
main->restoreState(dockState);
|
||||
|
@ -328,9 +304,6 @@ static void DeleteCookies()
|
|||
|
||||
void RegisterMixerAuth()
|
||||
{
|
||||
OAuth::RegisterOAuth(
|
||||
mixerDef,
|
||||
CreateMixerAuth,
|
||||
MixerAuth::Login,
|
||||
OAuth::RegisterOAuth(mixerDef, CreateMixerAuth, MixerAuth::Login,
|
||||
DeleteCookies);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ extern QCefCookieManager *panel_cookies;
|
|||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
|
||||
: QDialog (parent),
|
||||
get_token (token)
|
||||
: QDialog(parent), get_token(token)
|
||||
{
|
||||
if (!cef) {
|
||||
return;
|
||||
|
@ -46,14 +45,13 @@ OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
|
|||
return;
|
||||
}
|
||||
|
||||
connect(cefWidget, SIGNAL(titleChanged(const QString &)),
|
||||
this, SLOT(setWindowTitle(const QString &)));
|
||||
connect(cefWidget, SIGNAL(urlChanged(const QString &)),
|
||||
this, SLOT(urlChanged(const QString &)));
|
||||
connect(cefWidget, SIGNAL(titleChanged(const QString &)), this,
|
||||
SLOT(setWindowTitle(const QString &)));
|
||||
connect(cefWidget, SIGNAL(urlChanged(const QString &)), this,
|
||||
SLOT(urlChanged(const QString &)));
|
||||
|
||||
QPushButton *close = new QPushButton(QTStr("Cancel"));
|
||||
connect(close, &QAbstractButton::clicked,
|
||||
this, &QDialog::reject);
|
||||
connect(close, &QAbstractButton::clicked, this, &QDialog::reject);
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout();
|
||||
bottomLayout->addStretch();
|
||||
|
@ -148,9 +146,7 @@ void OAuth::SaveInternal()
|
|||
config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer);
|
||||
}
|
||||
|
||||
static inline std::string get_config_str(
|
||||
OBSBasic *main,
|
||||
const char *section,
|
||||
static inline std::string get_config_str(OBSBasic *main, const char *section,
|
||||
const char *name)
|
||||
{
|
||||
const char *val = config_get_string(main->Config(), section, name);
|
||||
|
@ -163,11 +159,9 @@ bool OAuth::LoadInternal()
|
|||
refresh_token = get_config_str(main, service(), "RefreshToken");
|
||||
token = get_config_str(main, service(), "Token");
|
||||
expire_time = config_get_uint(main->Config(), service(), "ExpireTime");
|
||||
currentScopeVer = (int)config_get_int(main->Config(), service(),
|
||||
"ScopeVer");
|
||||
return implicit
|
||||
? !token.empty()
|
||||
: !refresh_token.empty();
|
||||
currentScopeVer =
|
||||
(int)config_get_int(main->Config(), service(), "ScopeVer");
|
||||
return implicit ? !token.empty() : !refresh_token.empty();
|
||||
}
|
||||
|
||||
bool OAuth::TokenExpired()
|
||||
|
@ -191,8 +185,8 @@ try {
|
|||
return true;
|
||||
} else {
|
||||
QString title = QTStr("Auth.InvalidScope.Title");
|
||||
QString text = QTStr("Auth.InvalidScope.Text")
|
||||
.arg(service());
|
||||
QString text =
|
||||
QTStr("Auth.InvalidScope.Text").arg(service());
|
||||
|
||||
QMessageBox::warning(OBSBasic::Get(), title, text);
|
||||
}
|
||||
|
@ -217,21 +211,13 @@ try {
|
|||
bool success = false;
|
||||
|
||||
auto func = [&]() {
|
||||
success = GetRemoteFile(
|
||||
url,
|
||||
output,
|
||||
error,
|
||||
nullptr,
|
||||
success = GetRemoteFile(url, output, error, nullptr,
|
||||
"application/x-www-form-urlencoded",
|
||||
post_data.c_str(),
|
||||
std::vector<std::string>(),
|
||||
nullptr,
|
||||
5);
|
||||
std::vector<std::string>(), nullptr, 5);
|
||||
};
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
func,
|
||||
QTStr("Auth.Authing.Title"),
|
||||
ExecThreadedWithoutBlocking(func, QTStr("Auth.Authing.Title"),
|
||||
QTStr("Auth.Authing.Text").arg(service()));
|
||||
if (!success || output.empty())
|
||||
throw ErrorInfo("Failed to get token from remote", error);
|
||||
|
@ -250,7 +236,8 @@ try {
|
|||
}
|
||||
}
|
||||
if (!error.empty())
|
||||
throw ErrorInfo(error, json["error_description"].string_value());
|
||||
throw ErrorInfo(error,
|
||||
json["error_description"].string_value());
|
||||
|
||||
/* -------------------------- */
|
||||
/* success! */
|
||||
|
@ -264,7 +251,8 @@ try {
|
|||
refresh_token = json["refresh_token"].string_value();
|
||||
if (refresh_token.empty())
|
||||
throw ErrorInfo("Failed to get refresh token from "
|
||||
"remote", error);
|
||||
"remote",
|
||||
error);
|
||||
|
||||
currentScopeVer = scope_ver;
|
||||
}
|
||||
|
@ -275,14 +263,13 @@ try {
|
|||
if (!retry) {
|
||||
QString title = QTStr("Auth.AuthFailure.Title");
|
||||
QString text = QTStr("Auth.AuthFailure.Text")
|
||||
.arg(service(), info.message.c_str(), info.error.c_str());
|
||||
.arg(service(), info.message.c_str(),
|
||||
info.error.c_str());
|
||||
|
||||
QMessageBox::warning(OBSBasic::Get(), title, text);
|
||||
}
|
||||
|
||||
blog(LOG_WARNING, "%s: %s: %s",
|
||||
__FUNCTION__,
|
||||
info.message.c_str(),
|
||||
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
|
||||
info.error.c_str());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ public:
|
|||
static void DeleteCookies(const std::string &service);
|
||||
|
||||
static void RegisterOAuth(const Def &d, create_cb create,
|
||||
login_cb login, delete_cookies_cb delete_cookies);
|
||||
login_cb login,
|
||||
delete_cookies_cb delete_cookies);
|
||||
|
||||
protected:
|
||||
std::string refresh_token;
|
||||
|
|
|
@ -22,23 +22,17 @@ extern QCefCookieManager *panel_cookies;
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define RESTREAM_AUTH_URL "https://obsproject.com/app-auth/restream?action=redirect"
|
||||
#define RESTREAM_AUTH_URL \
|
||||
"https://obsproject.com/app-auth/restream?action=redirect"
|
||||
#define RESTREAM_TOKEN_URL "https://obsproject.com/app-auth/restream-token"
|
||||
#define RESTREAM_STREAMKEY_URL "https://api.restream.io/v2/user/streamKey"
|
||||
#define RESTREAM_SCOPE_VERSION 1
|
||||
|
||||
|
||||
static Auth::Def restreamDef = {
|
||||
"Restream",
|
||||
Auth::Type::OAuth_StreamKey
|
||||
};
|
||||
static Auth::Def restreamDef = {"Restream", Auth::Type::OAuth_StreamKey};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
RestreamAuth::RestreamAuth(const Def &d)
|
||||
: OAuthStreamKey(d)
|
||||
{
|
||||
}
|
||||
RestreamAuth::RestreamAuth(const Def &d) : OAuthStreamKey(d) {}
|
||||
|
||||
bool RestreamAuth::GetChannelInfo()
|
||||
try {
|
||||
|
@ -66,21 +60,13 @@ try {
|
|||
bool success;
|
||||
|
||||
auto func = [&]() {
|
||||
success = GetRemoteFile(
|
||||
RESTREAM_STREAMKEY_URL,
|
||||
output,
|
||||
error,
|
||||
nullptr,
|
||||
"application/json",
|
||||
nullptr,
|
||||
headers,
|
||||
nullptr,
|
||||
5);
|
||||
success = GetRemoteFile(RESTREAM_STREAMKEY_URL, output, error,
|
||||
nullptr, "application/json", nullptr,
|
||||
headers, nullptr, 5);
|
||||
};
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
func,
|
||||
QTStr("Auth.LoadingChannel.Title"),
|
||||
func, QTStr("Auth.LoadingChannel.Title"),
|
||||
QTStr("Auth.LoadingChannel.Text").arg(service()));
|
||||
if (!success || output.empty())
|
||||
throw ErrorInfo("Failed to get stream key from remote", error);
|
||||
|
@ -91,7 +77,8 @@ try {
|
|||
|
||||
error = json["error"].string_value();
|
||||
if (!error.empty())
|
||||
throw ErrorInfo(error, json["error_description"].string_value());
|
||||
throw ErrorInfo(error,
|
||||
json["error_description"].string_value());
|
||||
|
||||
key_ = json["streamKey"].string_value();
|
||||
|
||||
|
@ -99,13 +86,12 @@ try {
|
|||
} catch (ErrorInfo info) {
|
||||
QString title = QTStr("Auth.ChannelFailure.Title");
|
||||
QString text = QTStr("Auth.ChannelFailure.Text")
|
||||
.arg(service(), info.message.c_str(), info.error.c_str());
|
||||
.arg(service(), info.message.c_str(),
|
||||
info.error.c_str());
|
||||
|
||||
QMessageBox::warning(OBSBasic::Get(), title, text);
|
||||
|
||||
blog(LOG_WARNING, "%s: %s: %s",
|
||||
__FUNCTION__,
|
||||
info.message.c_str(),
|
||||
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
|
||||
info.error.c_str());
|
||||
return false;
|
||||
}
|
||||
|
@ -118,9 +104,7 @@ void RestreamAuth::SaveInternal()
|
|||
OAuthStreamKey::SaveInternal();
|
||||
}
|
||||
|
||||
static inline std::string get_config_str(
|
||||
OBSBasic *main,
|
||||
const char *section,
|
||||
static inline std::string get_config_str(OBSBasic *main, const char *section,
|
||||
const char *name)
|
||||
{
|
||||
const char *val = config_get_string(main->Config(), section, name);
|
||||
|
@ -201,10 +185,9 @@ void RestreamAuth::LoadUI()
|
|||
if (firstLoad) {
|
||||
chat->setVisible(true);
|
||||
info->setVisible(true);
|
||||
}
|
||||
else {
|
||||
const char *dockStateStr = config_get_string(main->Config(),
|
||||
service(), "DockState");
|
||||
} else {
|
||||
const char *dockStateStr = config_get_string(
|
||||
main->Config(), service(), "DockState");
|
||||
QByteArray dockState =
|
||||
QByteArray::fromBase64(QByteArray(dockStateStr));
|
||||
main->restoreState(dockState);
|
||||
|
@ -227,8 +210,7 @@ bool RestreamAuth::RetryLogin()
|
|||
std::string client_id = RESTREAM_CLIENTID;
|
||||
deobfuscate_str(&client_id[0], RESTREAM_HASH);
|
||||
|
||||
return GetToken(RESTREAM_TOKEN_URL, client_id,
|
||||
RESTREAM_SCOPE_VERSION,
|
||||
return GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION,
|
||||
QT_TO_UTF8(login.GetCode()), true);
|
||||
}
|
||||
|
||||
|
@ -275,9 +257,6 @@ static void DeleteCookies()
|
|||
|
||||
void RegisterRestreamAuth()
|
||||
{
|
||||
OAuth::RegisterOAuth(
|
||||
restreamDef,
|
||||
CreateRestreamAuth,
|
||||
RestreamAuth::Login,
|
||||
DeleteCookies);
|
||||
OAuth::RegisterOAuth(restreamDef, CreateRestreamAuth,
|
||||
RestreamAuth::Login, DeleteCookies);
|
||||
}
|
||||
|
|
|
@ -24,24 +24,17 @@ extern QCefCookieManager *panel_cookies;
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define TWITCH_AUTH_URL \
|
||||
"https://obsproject.com/app-auth/twitch?action=redirect"
|
||||
#define TWITCH_TOKEN_URL \
|
||||
"https://obsproject.com/app-auth/twitch-token"
|
||||
#define ACCEPT_HEADER \
|
||||
"Accept: application/vnd.twitchtv.v5+json"
|
||||
#define TWITCH_AUTH_URL "https://obsproject.com/app-auth/twitch?action=redirect"
|
||||
#define TWITCH_TOKEN_URL "https://obsproject.com/app-auth/twitch-token"
|
||||
#define ACCEPT_HEADER "Accept: application/vnd.twitchtv.v5+json"
|
||||
|
||||
#define TWITCH_SCOPE_VERSION 1
|
||||
|
||||
static Auth::Def twitchDef = {
|
||||
"Twitch",
|
||||
Auth::Type::OAuth_StreamKey
|
||||
};
|
||||
static Auth::Def twitchDef = {"Twitch", Auth::Type::OAuth_StreamKey};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TwitchAuth::TwitchAuth(const Def &d)
|
||||
: OAuthStreamKey(d)
|
||||
TwitchAuth::TwitchAuth(const Def &d) : OAuthStreamKey(d)
|
||||
{
|
||||
if (!cef)
|
||||
return;
|
||||
|
@ -51,8 +44,8 @@ TwitchAuth::TwitchAuth(const Def &d)
|
|||
this);
|
||||
uiLoadTimer.setSingleShot(true);
|
||||
uiLoadTimer.setInterval(500);
|
||||
connect(&uiLoadTimer, &QTimer::timeout,
|
||||
this, &TwitchAuth::TryLoadSecondaryUIPanes);
|
||||
connect(&uiLoadTimer, &QTimer::timeout, this,
|
||||
&TwitchAuth::TryLoadSecondaryUIPanes);
|
||||
}
|
||||
|
||||
bool TwitchAuth::GetChannelInfo()
|
||||
|
@ -83,29 +76,21 @@ try {
|
|||
bool success = false;
|
||||
|
||||
auto func = [&]() {
|
||||
success = GetRemoteFile(
|
||||
"https://api.twitch.tv/kraken/channel",
|
||||
output,
|
||||
error,
|
||||
&error_code,
|
||||
"application/json",
|
||||
nullptr,
|
||||
headers,
|
||||
nullptr,
|
||||
5);
|
||||
success = GetRemoteFile("https://api.twitch.tv/kraken/channel",
|
||||
output, error, &error_code,
|
||||
"application/json", nullptr, headers,
|
||||
nullptr, 5);
|
||||
};
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
func,
|
||||
QTStr("Auth.LoadingChannel.Title"),
|
||||
func, QTStr("Auth.LoadingChannel.Title"),
|
||||
QTStr("Auth.LoadingChannel.Text").arg(service()));
|
||||
if (error_code == 403) {
|
||||
OBSMessageBox::warning(OBSBasic::Get(),
|
||||
Str("TwitchAuth.TwoFactorFail.Title"),
|
||||
Str("TwitchAuth.TwoFactorFail.Text"),
|
||||
true);
|
||||
blog(LOG_WARNING, "%s: %s",
|
||||
__FUNCTION__,
|
||||
blog(LOG_WARNING, "%s: %s", __FUNCTION__,
|
||||
"Got 403 from Twitch, user probably does not "
|
||||
"have two-factor authentication enabled on "
|
||||
"their account");
|
||||
|
@ -125,10 +110,10 @@ try {
|
|||
if (RetryLogin()) {
|
||||
return GetChannelInfo();
|
||||
}
|
||||
throw ErrorInfo(error,
|
||||
json["message"].string_value());
|
||||
throw ErrorInfo(error, json["message"].string_value());
|
||||
}
|
||||
throw ErrorInfo(error, json["error_description"].string_value());
|
||||
throw ErrorInfo(error,
|
||||
json["error_description"].string_value());
|
||||
}
|
||||
|
||||
name = json["name"].string_value();
|
||||
|
@ -138,13 +123,12 @@ try {
|
|||
} catch (ErrorInfo info) {
|
||||
QString title = QTStr("Auth.ChannelFailure.Title");
|
||||
QString text = QTStr("Auth.ChannelFailure.Text")
|
||||
.arg(service(), info.message.c_str(), info.error.c_str());
|
||||
.arg(service(), info.message.c_str(),
|
||||
info.error.c_str());
|
||||
|
||||
QMessageBox::warning(OBSBasic::Get(), title, text);
|
||||
|
||||
blog(LOG_WARNING, "%s: %s: %s",
|
||||
__FUNCTION__,
|
||||
info.message.c_str(),
|
||||
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
|
||||
info.error.c_str());
|
||||
return false;
|
||||
}
|
||||
|
@ -160,9 +144,7 @@ void TwitchAuth::SaveInternal()
|
|||
OAuthStreamKey::SaveInternal();
|
||||
}
|
||||
|
||||
static inline std::string get_config_str(
|
||||
OBSBasic *main,
|
||||
const char *section,
|
||||
static inline std::string get_config_str(OBSBasic *main, const char *section,
|
||||
const char *name)
|
||||
{
|
||||
const char *val = config_get_string(main->Config(), section, name);
|
||||
|
@ -266,8 +248,8 @@ void TwitchAuth::LoadUI()
|
|||
if (firstLoad) {
|
||||
chat->setVisible(true);
|
||||
} else {
|
||||
const char *dockStateStr = config_get_string(main->Config(),
|
||||
service(), "DockState");
|
||||
const char *dockStateStr = config_get_string(
|
||||
main->Config(), service(), "DockState");
|
||||
QByteArray dockState =
|
||||
QByteArray::fromBase64(QByteArray(dockStateStr));
|
||||
main->restoreState(dockState);
|
||||
|
@ -376,15 +358,15 @@ void TwitchAuth::LoadSecondaryUIPanes()
|
|||
stat->setVisible(false);
|
||||
feed->setVisible(false);
|
||||
} else {
|
||||
uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General",
|
||||
"LastVersion");
|
||||
uint32_t lastVersion = config_get_int(App()->GlobalConfig(),
|
||||
"General", "LastVersion");
|
||||
|
||||
if (lastVersion <= MAKE_SEMANTIC_VERSION(23, 0, 2)) {
|
||||
feed->setVisible(false);
|
||||
}
|
||||
|
||||
const char *dockStateStr = config_get_string(main->Config(),
|
||||
service(), "DockState");
|
||||
const char *dockStateStr = config_get_string(
|
||||
main->Config(), service(), "DockState");
|
||||
QByteArray dockState =
|
||||
QByteArray::fromBase64(QByteArray(dockStateStr));
|
||||
main->restoreState(dockState);
|
||||
|
@ -405,21 +387,21 @@ void TwitchAuth::TryLoadSecondaryUIPanes()
|
|||
{
|
||||
QPointer<TwitchAuth> this_ = this;
|
||||
|
||||
auto cb = [this_] (bool found)
|
||||
{
|
||||
auto cb = [this_](bool found) {
|
||||
if (!this_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
QMetaObject::invokeMethod(&this_->uiLoadTimer,
|
||||
"start");
|
||||
QMetaObject::invokeMethod(&this_->uiLoadTimer, "start");
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes");
|
||||
QMetaObject::invokeMethod(this_,
|
||||
"LoadSecondaryUIPanes");
|
||||
}
|
||||
};
|
||||
|
||||
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", cb);
|
||||
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token",
|
||||
cb);
|
||||
}
|
||||
|
||||
bool TwitchAuth::RetryLogin()
|
||||
|
@ -429,7 +411,8 @@ bool TwitchAuth::RetryLogin()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
|
||||
std::shared_ptr<TwitchAuth> auth =
|
||||
std::make_shared<TwitchAuth>(twitchDef);
|
||||
std::string client_id = TWITCH_CLIENTID;
|
||||
deobfuscate_str(&client_id[0], TWITCH_HASH);
|
||||
|
||||
|
@ -444,7 +427,8 @@ std::shared_ptr<Auth> TwitchAuth::Login(QWidget *parent)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
|
||||
std::shared_ptr<TwitchAuth> auth =
|
||||
std::make_shared<TwitchAuth>(twitchDef);
|
||||
|
||||
std::string client_id = TWITCH_CLIENTID;
|
||||
deobfuscate_str(&client_id[0], TWITCH_HASH);
|
||||
|
@ -475,9 +459,6 @@ static void DeleteCookies()
|
|||
|
||||
void RegisterTwitchAuth()
|
||||
{
|
||||
OAuth::RegisterOAuth(
|
||||
twitchDef,
|
||||
CreateTwitchAuth,
|
||||
TwitchAuth::Login,
|
||||
OAuth::RegisterOAuth(twitchDef, CreateTwitchAuth, TwitchAuth::Login,
|
||||
DeleteCookies);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ OBSCrashReport::OBSCrashReport(QWidget *parent, const char *text)
|
|||
|
||||
setLayout(mainLayout);
|
||||
|
||||
QWidget::connect(copyButton, SIGNAL(clicked()),
|
||||
this, SLOT(CopyClicked()));
|
||||
QWidget::connect(exitButton, SIGNAL(clicked()),
|
||||
this, SLOT(ExitClicked()));
|
||||
QWidget::connect(copyButton, SIGNAL(clicked()), this,
|
||||
SLOT(CopyClicked()));
|
||||
QWidget::connect(exitButton, SIGNAL(clicked()), this,
|
||||
SLOT(ExitClicked()));
|
||||
|
||||
resize(800, 600);
|
||||
setWindowTitle("Oops, OBS has crashed!");
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#define SUPPORTS_FRACTIONAL_SCALING
|
||||
#endif
|
||||
|
||||
static inline void GetScaleAndCenterPos(
|
||||
int baseCX, int baseCY, int windowCX, int windowCY,
|
||||
int &x, int &y, float &scale)
|
||||
static inline void GetScaleAndCenterPos(int baseCX, int baseCY, int windowCX,
|
||||
int windowCY, int &x, int &y,
|
||||
float &scale)
|
||||
{
|
||||
double windowAspect, baseAspect;
|
||||
int newCX, newCY;
|
||||
|
@ -45,8 +45,8 @@ static inline void GetScaleAndCenterPos(
|
|||
y = windowCY / 2 - newCY / 2;
|
||||
}
|
||||
|
||||
static inline void GetCenterPosFromFixedScale(
|
||||
int baseCX, int baseCY, int windowCX, int windowCY,
|
||||
static inline void GetCenterPosFromFixedScale(int baseCX, int baseCY,
|
||||
int windowCX, int windowCY,
|
||||
int &x, int &y, float scale)
|
||||
{
|
||||
x = (float(windowCX) - float(baseCX) * scale) / 2.0f;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent)
|
||||
{
|
||||
connect(this, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(intValChanged(int)));
|
||||
connect(this, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(intValChanged(int)));
|
||||
}
|
||||
|
||||
void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
|
||||
|
|
|
@ -11,8 +11,8 @@ class DoubleSlider : public SliderIgnoreScroll {
|
|||
public:
|
||||
DoubleSlider(QWidget *parent = nullptr);
|
||||
|
||||
void setDoubleConstraints(double newMin, double newMax,
|
||||
double newStep, double val);
|
||||
void setDoubleConstraints(double newMin, double newMax, double newStep,
|
||||
double val);
|
||||
|
||||
signals:
|
||||
void doubleValChanged(double val);
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
#include <QListWidget>
|
||||
|
||||
class FocusList : public QListWidget
|
||||
{
|
||||
class FocusList : public QListWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
#include "decklink-ui-main.h"
|
||||
|
||||
DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui_Output)
|
||||
: QDialog(parent), ui(new Ui_Output)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -20,8 +19,10 @@ DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
|
|||
connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput()));
|
||||
connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput()));
|
||||
|
||||
connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput()));
|
||||
connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput()));
|
||||
connect(ui->startPreviewOutput, SIGNAL(released()), this,
|
||||
SLOT(StartPreviewOutput()));
|
||||
connect(ui->stopPreviewOutput, SIGNAL(released()), this,
|
||||
SLOT(StopPreviewOutput()));
|
||||
}
|
||||
|
||||
void DecklinkOutputUI::ShowHideDialog()
|
||||
|
@ -43,25 +44,26 @@ void DecklinkOutputUI::SetupPropertiesView()
|
|||
if (data)
|
||||
obs_data_apply(settings, data);
|
||||
|
||||
propertiesView = new OBSPropertiesView(settings,
|
||||
"decklink_output",
|
||||
(PropertiesReloadCallback) obs_get_output_properties,
|
||||
170);
|
||||
propertiesView = new OBSPropertiesView(
|
||||
settings, "decklink_output",
|
||||
(PropertiesReloadCallback)obs_get_output_properties, 170);
|
||||
|
||||
ui->propertiesLayout->addWidget(propertiesView);
|
||||
obs_data_release(settings);
|
||||
|
||||
connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged()));
|
||||
connect(propertiesView, SIGNAL(Changed()), this,
|
||||
SLOT(PropertiesChanged()));
|
||||
}
|
||||
|
||||
void DecklinkOutputUI::SaveSettings()
|
||||
{
|
||||
BPtr<char> modulePath = obs_module_get_config_path(obs_current_module(), "");
|
||||
BPtr<char> modulePath =
|
||||
obs_module_get_config_path(obs_current_module(), "");
|
||||
|
||||
os_mkdirs(modulePath);
|
||||
|
||||
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
|
||||
"decklinkOutputProps.json");
|
||||
BPtr<char> path = obs_module_get_config_path(
|
||||
obs_current_module(), "decklinkOutputProps.json");
|
||||
|
||||
obs_data_t *settings = propertiesView->GetSettings();
|
||||
if (settings)
|
||||
|
@ -79,15 +81,15 @@ void DecklinkOutputUI::SetupPreviewPropertiesView()
|
|||
if (data)
|
||||
obs_data_apply(settings, data);
|
||||
|
||||
previewPropertiesView = new OBSPropertiesView(settings,
|
||||
"decklink_output",
|
||||
(PropertiesReloadCallback) obs_get_output_properties,
|
||||
170);
|
||||
previewPropertiesView = new OBSPropertiesView(
|
||||
settings, "decklink_output",
|
||||
(PropertiesReloadCallback)obs_get_output_properties, 170);
|
||||
|
||||
ui->previewPropertiesLayout->addWidget(previewPropertiesView);
|
||||
obs_data_release(settings);
|
||||
|
||||
connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged()));
|
||||
connect(previewPropertiesView, SIGNAL(Changed()), this,
|
||||
SLOT(PreviewPropertiesChanged()));
|
||||
}
|
||||
|
||||
void DecklinkOutputUI::SavePreviewSettings()
|
||||
|
@ -96,15 +98,14 @@ void DecklinkOutputUI::SavePreviewSettings()
|
|||
|
||||
os_mkdirs(modulePath);
|
||||
|
||||
char *path = obs_module_get_config_path(obs_current_module(),
|
||||
"decklinkPreviewOutputProps.json");
|
||||
char *path = obs_module_get_config_path(
|
||||
obs_current_module(), "decklinkPreviewOutputProps.json");
|
||||
|
||||
obs_data_t *settings = previewPropertiesView->GetSettings();
|
||||
if (settings)
|
||||
obs_data_save_json_safe(settings, path, "tmp", "bak");
|
||||
}
|
||||
|
||||
|
||||
void DecklinkOutputUI::StartOutput()
|
||||
{
|
||||
SaveSettings();
|
||||
|
@ -121,7 +122,6 @@ void DecklinkOutputUI::PropertiesChanged()
|
|||
SaveSettings();
|
||||
}
|
||||
|
||||
|
||||
void DecklinkOutputUI::StartPreviewOutput()
|
||||
{
|
||||
SavePreviewSettings();
|
||||
|
|
|
@ -37,8 +37,8 @@ static struct preview_output context = {0};
|
|||
|
||||
OBSData load_settings()
|
||||
{
|
||||
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
|
||||
"decklinkOutputProps.json");
|
||||
BPtr<char> path = obs_module_get_config_path(
|
||||
obs_current_module(), "decklinkOutputProps.json");
|
||||
BPtr<char> jsonData = os_quick_read_utf8_file(path);
|
||||
if (!!jsonData) {
|
||||
obs_data_t *data = obs_data_create_from_json(jsonData);
|
||||
|
@ -58,7 +58,8 @@ void output_start()
|
|||
|
||||
if (settings != nullptr) {
|
||||
output = obs_output_create("decklink_output",
|
||||
"decklink_output", settings, NULL);
|
||||
"decklink_output", settings,
|
||||
NULL);
|
||||
|
||||
obs_output_start(output);
|
||||
obs_data_release(settings);
|
||||
|
@ -77,11 +78,10 @@ void output_stop()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
OBSData load_preview_settings()
|
||||
{
|
||||
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
|
||||
"decklinkPreviewOutputProps.json");
|
||||
BPtr<char> path = obs_module_get_config_path(
|
||||
obs_current_module(), "decklinkPreviewOutputProps.json");
|
||||
BPtr<char> jsonData = os_quick_read_utf8_file(path);
|
||||
if (!!jsonData) {
|
||||
obs_data_t *data = obs_data_create_from_json(jsonData);
|
||||
|
@ -103,8 +103,9 @@ void preview_output_start()
|
|||
OBSData settings = load_preview_settings();
|
||||
|
||||
if (settings != nullptr) {
|
||||
context.output = obs_output_create("decklink_output",
|
||||
"decklink_preview_output", settings, NULL);
|
||||
context.output = obs_output_create(
|
||||
"decklink_output", "decklink_preview_output",
|
||||
settings, NULL);
|
||||
|
||||
obs_get_video_info(&context.ovi);
|
||||
|
||||
|
@ -112,11 +113,14 @@ void preview_output_start()
|
|||
uint32_t height = context.ovi.base_height;
|
||||
|
||||
obs_enter_graphics();
|
||||
context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE);
|
||||
context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA);
|
||||
context.texrender =
|
||||
gs_texrender_create(GS_BGRA, GS_ZS_NONE);
|
||||
context.stagesurface =
|
||||
gs_stagesurface_create(width, height, GS_BGRA);
|
||||
obs_leave_graphics();
|
||||
|
||||
const video_output_info *mainVOI = video_output_get_info(obs_get_video());
|
||||
const video_output_info *mainVOI =
|
||||
video_output_get_info(obs_get_video());
|
||||
|
||||
video_output_info vi = {0};
|
||||
vi.format = VIDEO_FORMAT_BGRA;
|
||||
|
@ -131,15 +135,21 @@ void preview_output_start()
|
|||
|
||||
video_output_open(&context.video_queue, &vi);
|
||||
|
||||
obs_frontend_add_event_callback(on_preview_scene_changed, &context);
|
||||
obs_frontend_add_event_callback(
|
||||
on_preview_scene_changed, &context);
|
||||
if (obs_frontend_preview_program_mode_active()) {
|
||||
context.current_source = obs_frontend_get_current_preview_scene();
|
||||
context.current_source =
|
||||
obs_frontend_get_current_preview_scene();
|
||||
} else {
|
||||
context.current_source = obs_frontend_get_current_scene();
|
||||
context.current_source =
|
||||
obs_frontend_get_current_scene();
|
||||
}
|
||||
obs_add_main_render_callback(render_preview_source, &context);
|
||||
obs_add_main_render_callback(render_preview_source,
|
||||
&context);
|
||||
|
||||
obs_output_set_media(context.output, context.video_queue, obs_get_audio());
|
||||
obs_output_set_media(context.output,
|
||||
context.video_queue,
|
||||
obs_get_audio());
|
||||
obs_output_start(context.output);
|
||||
|
||||
preview_output_running = true;
|
||||
|
@ -153,8 +163,10 @@ void preview_output_stop()
|
|||
obs_output_stop(context.output);
|
||||
video_output_stop(context.video_queue);
|
||||
|
||||
obs_remove_main_render_callback(render_preview_source, &context);
|
||||
obs_frontend_remove_event_callback(on_preview_scene_changed, &context);
|
||||
obs_remove_main_render_callback(render_preview_source,
|
||||
&context);
|
||||
obs_frontend_remove_event_callback(on_preview_scene_changed,
|
||||
&context);
|
||||
|
||||
obs_source_release(context.current_source);
|
||||
|
||||
|
@ -197,7 +209,8 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
|
|||
{
|
||||
auto ctx = (struct preview_output *)param;
|
||||
|
||||
if (!ctx->current_source) return;
|
||||
if (!ctx->current_source)
|
||||
return;
|
||||
|
||||
uint32_t width = obs_source_get_base_width(ctx->current_source);
|
||||
uint32_t height = obs_source_get_base_height(ctx->current_source);
|
||||
|
@ -209,7 +222,8 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
|
|||
vec4_zero(&background);
|
||||
|
||||
gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0);
|
||||
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
|
||||
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f,
|
||||
100.0f);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
|
||||
|
@ -220,16 +234,23 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
|
|||
gs_texrender_end(ctx->texrender);
|
||||
|
||||
struct video_frame output_frame;
|
||||
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns()))
|
||||
{
|
||||
gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender));
|
||||
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1,
|
||||
os_gettime_ns())) {
|
||||
gs_stage_texture(
|
||||
ctx->stagesurface,
|
||||
gs_texrender_get_texture(ctx->texrender));
|
||||
|
||||
if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) {
|
||||
if (gs_stagesurface_map(ctx->stagesurface,
|
||||
&ctx->video_data,
|
||||
&ctx->video_linesize)) {
|
||||
uint32_t linesize = output_frame.linesize[0];
|
||||
for (uint32_t i = 0; i < ctx->ovi.base_height; i++) {
|
||||
for (uint32_t i = 0; i < ctx->ovi.base_height;
|
||||
i++) {
|
||||
uint32_t dst_offset = linesize * i;
|
||||
uint32_t src_offset = ctx->video_linesize * i;
|
||||
memcpy(output_frame.data[0] + dst_offset,
|
||||
uint32_t src_offset =
|
||||
ctx->video_linesize * i;
|
||||
memcpy(output_frame.data[0] +
|
||||
dst_offset,
|
||||
ctx->video_data + src_offset,
|
||||
linesize);
|
||||
}
|
||||
|
@ -254,9 +275,7 @@ void addOutputUI(void)
|
|||
doUI = new DecklinkOutputUI(window);
|
||||
obs_frontend_pop_ui_translation();
|
||||
|
||||
auto cb = []() {
|
||||
doUI->ShowHideDialog();
|
||||
};
|
||||
auto cb = []() { doUI->ShowHideDialog(); };
|
||||
|
||||
action->connect(action, &QAction::triggered, cb);
|
||||
}
|
||||
|
@ -271,7 +290,8 @@ static void OBSEvent(enum obs_frontend_event event, void *)
|
|||
|
||||
OBSData previewSettings = load_preview_settings();
|
||||
|
||||
if (previewSettings && obs_data_get_bool(previewSettings, "auto_start"))
|
||||
if (previewSettings &&
|
||||
obs_data_get_bool(previewSettings, "auto_start"))
|
||||
preview_output_start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,27 +39,18 @@ void cleanupDisplay()
|
|||
static bool ewmhIsSupported()
|
||||
{
|
||||
Display *display = disp();
|
||||
Atom netSupportingWmCheck = XInternAtom(display,
|
||||
"_NET_SUPPORTING_WM_CHECK", true);
|
||||
Atom netSupportingWmCheck =
|
||||
XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true);
|
||||
Atom actualType;
|
||||
int format = 0;
|
||||
unsigned long num = 0, bytes = 0;
|
||||
unsigned char *data = NULL;
|
||||
Window ewmh_window = 0;
|
||||
|
||||
int status = XGetWindowProperty(
|
||||
display,
|
||||
DefaultRootWindow(display),
|
||||
netSupportingWmCheck,
|
||||
0L,
|
||||
1L,
|
||||
false,
|
||||
XA_WINDOW,
|
||||
&actualType,
|
||||
&format,
|
||||
&num,
|
||||
&bytes,
|
||||
&data);
|
||||
int status = XGetWindowProperty(display, DefaultRootWindow(display),
|
||||
netSupportingWmCheck, 0L, 1L, false,
|
||||
XA_WINDOW, &actualType, &format, &num,
|
||||
&bytes, &data);
|
||||
|
||||
if (status == Success) {
|
||||
if (num > 0) {
|
||||
|
@ -72,19 +63,10 @@ static bool ewmhIsSupported()
|
|||
}
|
||||
|
||||
if (ewmh_window) {
|
||||
status = XGetWindowProperty(
|
||||
display,
|
||||
ewmh_window,
|
||||
netSupportingWmCheck,
|
||||
0L,
|
||||
1L,
|
||||
false,
|
||||
XA_WINDOW,
|
||||
&actualType,
|
||||
&format,
|
||||
&num,
|
||||
&bytes,
|
||||
&data);
|
||||
status = XGetWindowProperty(display, ewmh_window,
|
||||
netSupportingWmCheck, 0L, 1L, false,
|
||||
XA_WINDOW, &actualType, &format,
|
||||
&num, &bytes, &data);
|
||||
if (status != Success || num == 0 ||
|
||||
ewmh_window != ((Window *)data)[0]) {
|
||||
ewmh_window = 0;
|
||||
|
@ -116,19 +98,10 @@ static std::vector<Window> getTopLevelWindows()
|
|||
for (int i = 0; i < ScreenCount(disp()); ++i) {
|
||||
Window rootWin = RootWindow(disp(), i);
|
||||
|
||||
int status = XGetWindowProperty(
|
||||
disp(),
|
||||
rootWin,
|
||||
netClList,
|
||||
0L,
|
||||
~0L,
|
||||
false,
|
||||
AnyPropertyType,
|
||||
&actualType,
|
||||
&format,
|
||||
&num,
|
||||
&bytes,
|
||||
(uint8_t**)&data);
|
||||
int status = XGetWindowProperty(disp(), rootWin, netClList, 0L,
|
||||
~0L, false, AnyPropertyType,
|
||||
&actualType, &format, &num,
|
||||
&bytes, (uint8_t **)&data);
|
||||
|
||||
if (status != Success) {
|
||||
continue;
|
||||
|
@ -150,8 +123,7 @@ static std::string GetWindowTitle(size_t i)
|
|||
char *name;
|
||||
|
||||
int status = XFetchName(disp(), w, &name);
|
||||
if (status >= Success && name != nullptr)
|
||||
{
|
||||
if (status >= Success && name != nullptr) {
|
||||
std::string str(name);
|
||||
windowTitle = str;
|
||||
}
|
||||
|
@ -186,18 +158,8 @@ void GetCurrentWindowTitle(string &title)
|
|||
|
||||
Window rootWin = RootWindow(disp(), 0);
|
||||
|
||||
XGetWindowProperty(
|
||||
disp(),
|
||||
rootWin,
|
||||
active,
|
||||
0L,
|
||||
~0L,
|
||||
false,
|
||||
AnyPropertyType,
|
||||
&actualType,
|
||||
&format,
|
||||
&num,
|
||||
&bytes,
|
||||
XGetWindowProperty(disp(), rootWin, active, 0L, ~0L, false,
|
||||
AnyPropertyType, &actualType, &format, &num, &bytes,
|
||||
(uint8_t **)&data);
|
||||
|
||||
int status = XFetchName(disp(), data[0], &name);
|
||||
|
|
|
@ -69,10 +69,7 @@ struct SwitcherData {
|
|||
}
|
||||
}
|
||||
|
||||
inline ~SwitcherData()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
inline ~SwitcherData() { Stop(); }
|
||||
};
|
||||
|
||||
static SwitcherData *switcher = nullptr;
|
||||
|
@ -84,8 +81,7 @@ static inline QString MakeSwitchName(const QString &scene,
|
|||
}
|
||||
|
||||
SceneSwitcher::SceneSwitcher(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui_SceneSwitcher)
|
||||
: QDialog(parent), ui(new Ui_SceneSwitcher)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -121,11 +117,10 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
|
|||
|
||||
for (auto &s : switcher->switches) {
|
||||
string sceneName = GetWeakSourceName(s.scene);
|
||||
QString text = MakeSwitchName(sceneName.c_str(),
|
||||
s.window.c_str());
|
||||
QString text =
|
||||
MakeSwitchName(sceneName.c_str(), s.window.c_str());
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(text,
|
||||
ui->switches);
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, s.window.c_str());
|
||||
}
|
||||
|
||||
|
@ -149,8 +144,7 @@ int SceneSwitcher::FindByData(const QString &window)
|
|||
|
||||
for (int i = 0; i < count; i++) {
|
||||
QListWidgetItem *item = ui->switches->item(i);
|
||||
QString itemWindow =
|
||||
item->data(Qt::UserRole).toString();
|
||||
QString itemWindow = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemWindow == window) {
|
||||
idx = i;
|
||||
|
@ -206,15 +200,15 @@ void SceneSwitcher::on_add_clicked()
|
|||
if (idx == -1) {
|
||||
try {
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switches.emplace_back(source,
|
||||
windowName.toUtf8().constData());
|
||||
switcher->switches.emplace_back(
|
||||
source, windowName.toUtf8().constData());
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(text,
|
||||
ui->switches);
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, v);
|
||||
} catch (const regex_error &) {
|
||||
QMessageBox::warning(this,
|
||||
obs_module_text("InvalidRegex.Title"),
|
||||
QMessageBox::warning(
|
||||
this, obs_module_text("InvalidRegex.Title"),
|
||||
obs_module_text("InvalidRegex.Text"));
|
||||
}
|
||||
} else {
|
||||
|
@ -274,8 +268,7 @@ void SceneSwitcher::on_startAtLaunch_toggled(bool value)
|
|||
|
||||
void SceneSwitcher::UpdateNonMatchingScene(const QString &name)
|
||||
{
|
||||
obs_source_t *scene = obs_get_source_by_name(
|
||||
name.toUtf8().constData());
|
||||
obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->nonMatchingScene = ws;
|
||||
|
@ -303,8 +296,7 @@ void SceneSwitcher::on_noMatchSwitch_clicked()
|
|||
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
|
||||
const QString &text)
|
||||
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString &text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
@ -357,8 +349,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
for (SceneSwitch &s : switcher->switches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(
|
||||
s.scene);
|
||||
obs_source_t *source =
|
||||
obs_weak_source_get_source(s.scene);
|
||||
if (source) {
|
||||
const char *n = obs_source_get_name(source);
|
||||
obs_data_set_string(array_obj, "scene", n);
|
||||
|
@ -389,8 +381,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
} else {
|
||||
switcher->m.lock();
|
||||
|
||||
obs_data_t *obj = obs_data_get_obj(save_data,
|
||||
"auto-scene-switcher");
|
||||
obs_data_t *obj =
|
||||
obs_data_get_obj(save_data, "auto-scene-switcher");
|
||||
obs_data_array_t *array = obs_data_get_array(obj, "switches");
|
||||
size_t count = obs_data_array_count(array);
|
||||
|
||||
|
@ -420,8 +412,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
obs_data_get_string(array_obj, "window_title");
|
||||
|
||||
switcher->switches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
window);
|
||||
GetWeakSourceByName(scene), window);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
@ -482,12 +473,12 @@ void SwitcherData::Thread()
|
|||
scene = s.scene;
|
||||
break;
|
||||
}
|
||||
} catch (const regex_error &) {}
|
||||
} catch (const regex_error &) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!match && switchIfNotMatching &&
|
||||
nonMatchingScene) {
|
||||
if (!match && switchIfNotMatching && nonMatchingScene) {
|
||||
match = true;
|
||||
scene = nonMatchingScene;
|
||||
}
|
||||
|
@ -547,8 +538,7 @@ extern "C" void InitSceneSwitcher()
|
|||
|
||||
switcher = new SwitcherData;
|
||||
|
||||
auto cb = [] ()
|
||||
{
|
||||
auto cb = []() {
|
||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||
|
||||
QMainWindow *window =
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "captions-handler.hpp"
|
||||
|
||||
captions_handler::captions_handler(
|
||||
captions_cb callback,
|
||||
captions_handler::captions_handler(captions_cb callback,
|
||||
enum audio_format format,
|
||||
uint32_t sample_rate)
|
||||
: cb(callback)
|
||||
|
@ -10,24 +9,16 @@ captions_handler::captions_handler(
|
|||
throw CAPTIONS_ERROR_GENERIC_FAIL;
|
||||
}
|
||||
|
||||
bool captions_handler::reset_resampler(
|
||||
enum audio_format format,
|
||||
bool captions_handler::reset_resampler(enum audio_format format,
|
||||
uint32_t sample_rate)
|
||||
try {
|
||||
obs_audio_info ai;
|
||||
if (!obs_get_audio_info(&ai))
|
||||
throw std::string("Failed to get OBS audio info");
|
||||
|
||||
resample_info src = {
|
||||
ai.samples_per_sec,
|
||||
AUDIO_FORMAT_FLOAT_PLANAR,
|
||||
ai.speakers
|
||||
};
|
||||
resample_info dst = {
|
||||
sample_rate,
|
||||
format,
|
||||
SPEAKERS_MONO
|
||||
};
|
||||
resample_info src = {ai.samples_per_sec, AUDIO_FORMAT_FLOAT_PLANAR,
|
||||
ai.speakers};
|
||||
resample_info dst = {sample_rate, format, SPEAKERS_MONO};
|
||||
|
||||
if (!resampler.reset(dst, src))
|
||||
throw std::string("Failed to create audio resampler");
|
||||
|
@ -46,9 +37,9 @@ void captions_handler::push_audio(const audio_data *audio)
|
|||
uint64_t ts_offset;
|
||||
bool success;
|
||||
|
||||
success = audio_resampler_resample(resampler,
|
||||
out, &frames, &ts_offset,
|
||||
(const uint8_t *const *)audio->data, audio->frames);
|
||||
success = audio_resampler_resample(resampler, out, &frames, &ts_offset,
|
||||
(const uint8_t *const *)audio->data,
|
||||
audio->frames);
|
||||
if (success)
|
||||
pcm_data(out[0], frames);
|
||||
}
|
||||
|
|
|
@ -9,10 +9,7 @@ class resampler_obj {
|
|||
audio_resampler_t *resampler = nullptr;
|
||||
|
||||
public:
|
||||
inline ~resampler_obj()
|
||||
{
|
||||
audio_resampler_destroy(resampler);
|
||||
}
|
||||
inline ~resampler_obj() { audio_resampler_destroy(resampler); }
|
||||
|
||||
inline bool reset(const resample_info &dst, const resample_info &src)
|
||||
{
|
||||
|
@ -38,10 +35,7 @@ class captions_handler {
|
|||
resampler_obj resampler;
|
||||
|
||||
protected:
|
||||
inline void callback(const std::string &text)
|
||||
{
|
||||
cb(text);
|
||||
}
|
||||
inline void callback(const std::string &text) { cb(text); }
|
||||
|
||||
virtual void pcm_data(const void *data, size_t frames) = 0;
|
||||
|
||||
|
@ -50,9 +44,7 @@ protected:
|
|||
|
||||
public:
|
||||
/* throw std::string for errors shown to users */
|
||||
captions_handler(
|
||||
captions_cb callback,
|
||||
enum audio_format format,
|
||||
captions_handler(captions_cb callback, enum audio_format format,
|
||||
uint32_t sample_rate);
|
||||
virtual ~captions_handler() {}
|
||||
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
using namespace std;
|
||||
|
||||
#if 0
|
||||
#define debugfunc(format, ...) blog(LOG_DEBUG, "[Captions] %s(" format ")", \
|
||||
__FUNCTION__, ##__VA_ARGS__)
|
||||
#define debugfunc(format, ...) \
|
||||
blog(LOG_DEBUG, "[Captions] %s(" format ")", __FUNCTION__, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define debugfunc(format, ...)
|
||||
#endif
|
||||
|
||||
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_) :
|
||||
handler(handler_),
|
||||
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_)
|
||||
: handler(handler_),
|
||||
samplerate(samplerate_),
|
||||
event(CreateEvent(nullptr, false, false, nullptr))
|
||||
{
|
||||
|
@ -134,8 +135,7 @@ STDMETHODIMP CaptionStream::Read(void *data, ULONG bytes, ULONG *read_bytes)
|
|||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
|
||||
ULONG*)
|
||||
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, ULONG *)
|
||||
{
|
||||
debugfunc("data, %lu, written_bytes", bytes);
|
||||
UNUSED_PARAMETER(bytes);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
class CircleBuf {
|
||||
circlebuf buf = {};
|
||||
|
||||
public:
|
||||
inline ~CircleBuf() { circlebuf_free(&buf); }
|
||||
inline operator circlebuf *() { return &buf; }
|
||||
|
@ -54,8 +55,8 @@ public:
|
|||
|
||||
// ISequentialStream methods
|
||||
STDMETHODIMP Read(void *data, ULONG bytes, ULONG *read_bytes) override;
|
||||
STDMETHODIMP Write(const void *data, ULONG bytes, ULONG *written_bytes)
|
||||
override;
|
||||
STDMETHODIMP Write(const void *data, ULONG bytes,
|
||||
ULONG *written_bytes) override;
|
||||
|
||||
// IStream methods
|
||||
STDMETHODIMP Seek(LARGE_INTEGER move, DWORD origin,
|
||||
|
@ -74,13 +75,13 @@ public:
|
|||
STDMETHODIMP Clone(IStream **stream) override;
|
||||
|
||||
// ISpStreamFormat methods
|
||||
STDMETHODIMP GetFormat(GUID *guid, WAVEFORMATEX **co_mem_wfex_out)
|
||||
override;
|
||||
STDMETHODIMP GetFormat(GUID *guid,
|
||||
WAVEFORMATEX **co_mem_wfex_out) override;
|
||||
|
||||
// ISpAudio methods
|
||||
STDMETHODIMP SetState(SPAUDIOSTATE state, ULONGLONG reserved) override;
|
||||
STDMETHODIMP SetFormat(REFGUID guid_ref, const WAVEFORMATEX *wfex)
|
||||
override;
|
||||
STDMETHODIMP SetFormat(REFGUID guid_ref,
|
||||
const WAVEFORMATEX *wfex) override;
|
||||
STDMETHODIMP GetStatus(SPAUDIOSTATUS *status) override;
|
||||
STDMETHODIMP SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info) override;
|
||||
STDMETHODIMP GetBufferInfo(SPAUDIOBUFFERINFO *buf_info) override;
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
#include "captions-mssapi.hpp"
|
||||
|
||||
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
|
||||
##__VA_ARGS__)
|
||||
#define do_log(type, format, ...) \
|
||||
blog(type, "[Captions] " format, ##__VA_ARGS__)
|
||||
|
||||
#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
mssapi_captions::mssapi_captions(
|
||||
captions_cb callback,
|
||||
const std::string &lang) try
|
||||
: captions_handler(callback, AUDIO_FORMAT_16BIT, 16000)
|
||||
{
|
||||
mssapi_captions::mssapi_captions(captions_cb callback, const std::string &lang)
|
||||
try : captions_handler(callback, AUDIO_FORMAT_16BIT, 16000) {
|
||||
HRESULT hr;
|
||||
|
||||
std::wstring wlang;
|
||||
|
@ -133,8 +130,8 @@ try {
|
|||
ISpRecoResult *result = event.RecoResult();
|
||||
|
||||
CoTaskMemPtr<wchar_t> text;
|
||||
hr = result->GetText((ULONG)-1, (ULONG)-1,
|
||||
true, &text, nullptr);
|
||||
hr = result->GetText((ULONG)-1, (ULONG)-1, true,
|
||||
&text, nullptr);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
|
@ -168,12 +165,7 @@ void mssapi_captions::pcm_data(const void *data, size_t frames)
|
|||
}
|
||||
|
||||
captions_handler_info mssapi_info = {
|
||||
[] () -> std::string
|
||||
{
|
||||
return "Microsoft Speech-to-Text";
|
||||
},
|
||||
[] (captions_cb cb, const std::string &lang) -> captions_handler *
|
||||
{
|
||||
[]() -> std::string { return "Microsoft Speech-to-Text"; },
|
||||
[](captions_cb cb, const std::string &lang) -> captions_handler * {
|
||||
return new mssapi_captions(cb, lang);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
|
||||
#include "captions-mssapi.hpp"
|
||||
|
||||
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
|
||||
##__VA_ARGS__)
|
||||
#define do_log(type, format, ...) \
|
||||
blog(type, "[Captions] " format, ##__VA_ARGS__)
|
||||
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
@ -74,9 +74,9 @@ struct locale_info {
|
|||
inline locale_info() {}
|
||||
inline locale_info(const locale_info &) = delete;
|
||||
inline locale_info(locale_info &&li)
|
||||
: name(std::move(li.name)),
|
||||
id(li.id)
|
||||
{}
|
||||
: name(std::move(li.name)), id(li.id)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void get_valid_locale_names(vector<locale_info> &names);
|
||||
|
@ -84,16 +84,14 @@ static bool valid_lang(LANGID id);
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
CaptionsDialog::CaptionsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui_CaptionsDialog)
|
||||
CaptionsDialog::CaptionsDialog(QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui_CaptionsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
auto cb = [this] (obs_source_t *source)
|
||||
{
|
||||
auto cb = [this](obs_source_t *source) {
|
||||
uint32_t caps = obs_source_get_output_flags(source);
|
||||
QString name = obs_source_get_name(source);
|
||||
|
||||
|
@ -111,8 +109,11 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) :
|
|||
ui->source->blockSignals(true);
|
||||
ui->source->addItem(QStringLiteral(""));
|
||||
ui->source->setCurrentIndex(0);
|
||||
obs_enum_sources([] (void *data, obs_source_t *source) {
|
||||
return (*static_cast<cb_t*>(data))(source);}, &cb);
|
||||
obs_enum_sources(
|
||||
[](void *data, obs_source_t *source) {
|
||||
return (*static_cast<cb_t *>(data))(source);
|
||||
},
|
||||
&cb);
|
||||
ui->source->blockSignals(false);
|
||||
|
||||
for (auto &ht : captions->handler_types) {
|
||||
|
@ -245,8 +246,7 @@ void obs_captions::start()
|
|||
|
||||
auto pair = handler_types.find(handler_id);
|
||||
if (pair == handler_types.end()) {
|
||||
warn("Failed to find handler '%s'",
|
||||
handler_id.c_str());
|
||||
warn("Failed to find handler '%s'", handler_id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -271,13 +271,13 @@ void obs_captions::start()
|
|||
}
|
||||
|
||||
try {
|
||||
captions_handler *h = pair->second.create(caption_text,
|
||||
lang_name);
|
||||
captions_handler *h =
|
||||
pair->second.create(caption_text, lang_name);
|
||||
handler.reset(h);
|
||||
|
||||
OBSSource s = OBSGetStrongRef(source);
|
||||
obs_source_add_audio_capture_callback(s,
|
||||
audio_capture, nullptr);
|
||||
obs_source_add_audio_capture_callback(s, audio_capture,
|
||||
nullptr);
|
||||
|
||||
} catch (std::string text) {
|
||||
QWidget *window =
|
||||
|
@ -285,10 +285,10 @@ void obs_captions::start()
|
|||
|
||||
warn("Failed to create handler: %s", text.c_str());
|
||||
|
||||
QMessageBox::warning(window,
|
||||
QMessageBox::warning(
|
||||
window,
|
||||
obs_module_text("Captions.Error.GenericFail"),
|
||||
text.c_str());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,8 +297,8 @@ void obs_captions::stop()
|
|||
{
|
||||
OBSSource s = OBSGetStrongRef(source);
|
||||
if (s)
|
||||
obs_source_remove_audio_capture_callback(s,
|
||||
audio_capture, nullptr);
|
||||
obs_source_remove_audio_capture_callback(s, audio_capture,
|
||||
nullptr);
|
||||
handler.reset();
|
||||
}
|
||||
|
||||
|
@ -332,42 +332,18 @@ static void get_valid_locale_names(vector<locale_info> &locales)
|
|||
char locale_name[256];
|
||||
|
||||
static const LANGID default_locales[] = {
|
||||
0x0409,
|
||||
0x0401,
|
||||
0x0402,
|
||||
0x0403,
|
||||
0x0404,
|
||||
0x0405,
|
||||
0x0406,
|
||||
0x0407,
|
||||
0x0408,
|
||||
0x040a,
|
||||
0x040b,
|
||||
0x040c,
|
||||
0x040d,
|
||||
0x040e,
|
||||
0x040f,
|
||||
0x0410,
|
||||
0x0411,
|
||||
0x0412,
|
||||
0x0413,
|
||||
0x0414,
|
||||
0x0415,
|
||||
0x0416,
|
||||
0x0417,
|
||||
0x0418,
|
||||
0x0419,
|
||||
0x041a,
|
||||
0
|
||||
};
|
||||
0x0409, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
|
||||
0x0407, 0x0408, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e,
|
||||
0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
|
||||
0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0};
|
||||
|
||||
/* ---------------------------------- */
|
||||
|
||||
LANGID def_id = GetUserDefaultUILanguage();
|
||||
LANGID id = def_id;
|
||||
if (valid_lang(id) && get_locale_name(id, locale_name)) {
|
||||
dstr_copy(cur.name, obs_module_text(
|
||||
"Captions.CurrentSystemLanguage"));
|
||||
dstr_copy(cur.name,
|
||||
obs_module_text("Captions.CurrentSystemLanguage"));
|
||||
dstr_replace(cur.name, "%1", locale_name);
|
||||
cur.id = id;
|
||||
|
||||
|
@ -381,8 +357,7 @@ static void get_valid_locale_names(vector<locale_info> &locales)
|
|||
while (*locale) {
|
||||
id = *locale;
|
||||
|
||||
if (id != def_id &&
|
||||
valid_lang(id) &&
|
||||
if (id != def_id && valid_lang(id) &&
|
||||
get_locale_name(id, locale_name)) {
|
||||
|
||||
dstr_copy(cur.name, locale_name);
|
||||
|
@ -447,8 +422,8 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*)
|
|||
captions->source_name = obs_data_get_string(obj, "source");
|
||||
captions->lang_id = (int)obs_data_get_int(obj, "lang_id");
|
||||
captions->handler_id = obs_data_get_string(obj, "provider");
|
||||
captions->source = GetWeakSourceByName(
|
||||
captions->source_name.c_str());
|
||||
captions->source =
|
||||
GetWeakSourceByName(captions->source_name.c_str());
|
||||
obs_data_release(obj);
|
||||
|
||||
if (enabled)
|
||||
|
@ -463,12 +438,10 @@ extern "C" void InitCaptions()
|
|||
|
||||
captions = new obs_captions;
|
||||
|
||||
auto cb = [] ()
|
||||
{
|
||||
auto cb = []() {
|
||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||
|
||||
QWidget *window =
|
||||
(QWidget*)obs_frontend_get_main_window();
|
||||
QWidget *window = (QWidget *)obs_frontend_get_main_window();
|
||||
|
||||
CaptionsDialog dialog(window);
|
||||
dialog.exec();
|
||||
|
|
|
@ -13,8 +13,7 @@ using namespace std;
|
|||
OutputTimer *ot;
|
||||
|
||||
OutputTimer::OutputTimer(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui_OutputTimer)
|
||||
: QDialog(parent), ui(new Ui_OutputTimer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -78,9 +77,7 @@ void OutputTimer::StreamTimerStart()
|
|||
int minutes = ui->streamingTimerMinutes->value();
|
||||
int seconds = ui->streamingTimerSeconds->value();
|
||||
|
||||
int total = (((hours * 3600) +
|
||||
(minutes * 60)) +
|
||||
seconds) * 1000;
|
||||
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
|
||||
|
||||
if (total == 0)
|
||||
total = 1000;
|
||||
|
@ -112,9 +109,7 @@ void OutputTimer::RecordTimerStart()
|
|||
int minutes = ui->recordingTimerMinutes->value();
|
||||
int seconds = ui->recordingTimerSeconds->value();
|
||||
|
||||
int total = (((hours * 3600) +
|
||||
(minutes * 60)) +
|
||||
seconds) * 1000;
|
||||
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
|
||||
|
||||
if (total == 0)
|
||||
total = 1000;
|
||||
|
@ -248,8 +243,7 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
|
|||
|
||||
obs_data_release(obj);
|
||||
} else {
|
||||
obs_data_t *obj = obs_data_get_obj(save_data,
|
||||
"output-timer");
|
||||
obs_data_t *obj = obs_data_get_obj(save_data, "output-timer");
|
||||
|
||||
if (!obj)
|
||||
obj = obs_data_create();
|
||||
|
@ -277,9 +271,7 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void FreeOutputTimer()
|
||||
{
|
||||
}
|
||||
extern "C" void FreeOutputTimer() {}
|
||||
|
||||
static void OBSEvent(enum obs_frontend_event event, void *)
|
||||
{
|
||||
|
@ -308,10 +300,7 @@ extern "C" void InitOutputTimer()
|
|||
|
||||
ot = new OutputTimer(window);
|
||||
|
||||
auto cb = [] ()
|
||||
{
|
||||
ot->ShowHideDialog();
|
||||
};
|
||||
auto cb = []() { ot->ShowHideDialog(); };
|
||||
|
||||
obs_frontend_pop_ui_translation();
|
||||
|
||||
|
|
|
@ -92,11 +92,10 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
|
|||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
QPushButton *clearButton = new QPushButton(tr("Clear"));
|
||||
connect(clearButton, &QPushButton::clicked,
|
||||
this, &ScriptLogWindow::ClearWindow);
|
||||
connect(clearButton, &QPushButton::clicked, this,
|
||||
&ScriptLogWindow::ClearWindow);
|
||||
QPushButton *closeButton = new QPushButton(tr("Close"));
|
||||
connect(closeButton, &QPushButton::clicked,
|
||||
this, &QDialog::hide);
|
||||
connect(closeButton, &QPushButton::clicked, this, &QDialog::hide);
|
||||
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(clearButton);
|
||||
|
@ -112,8 +111,8 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
|
|||
resize(600, 400);
|
||||
|
||||
config_t *global_config = obs_frontend_get_global_config();
|
||||
const char *geom = config_get_string(global_config,
|
||||
"ScriptLogWindow", "geometry");
|
||||
const char *geom =
|
||||
config_get_string(global_config, "ScriptLogWindow", "geometry");
|
||||
if (geom != nullptr) {
|
||||
QByteArray ba = QByteArray::fromBase64(QByteArray(geom));
|
||||
restoreGeometry(ba);
|
||||
|
@ -121,15 +120,14 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
|
|||
|
||||
setWindowTitle(obs_module_text("ScriptLogWindow"));
|
||||
|
||||
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved,
|
||||
this, &ScriptLogWindow::ScrollChanged);
|
||||
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved, this,
|
||||
&ScriptLogWindow::ScrollChanged);
|
||||
}
|
||||
|
||||
ScriptLogWindow::~ScriptLogWindow()
|
||||
{
|
||||
config_t *global_config = obs_frontend_get_global_config();
|
||||
config_set_string(global_config,
|
||||
"ScriptLogWindow", "geometry",
|
||||
config_set_string(global_config, "ScriptLogWindow", "geometry",
|
||||
saveGeometry().toBase64().constData());
|
||||
}
|
||||
|
||||
|
@ -180,17 +178,15 @@ void ScriptLogWindow::Clear()
|
|||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
ScriptsTool::ScriptsTool()
|
||||
: QWidget (nullptr),
|
||||
ui (new Ui_ScriptsTool)
|
||||
ScriptsTool::ScriptsTool() : QWidget(nullptr), ui(new Ui_ScriptsTool)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
RefreshLists();
|
||||
|
||||
#if PYTHON_UI
|
||||
config_t *config = obs_frontend_get_global_config();
|
||||
const char *path = config_get_string(config, "Python",
|
||||
"Path" ARCH_NAME);
|
||||
const char *path =
|
||||
config_get_string(config, "Python", "Path" ARCH_NAME);
|
||||
ui->pythonPath->setText(path);
|
||||
ui->pythonPathLabel->setText(obs_module_text(PYTHONPATH_LABEL_TEXT));
|
||||
#else
|
||||
|
@ -217,8 +213,8 @@ void ScriptsTool::RemoveScript(const char *path)
|
|||
|
||||
const char *script_path = obs_script_get_path(script);
|
||||
if (strcmp(script_path, path) == 0) {
|
||||
scriptData->scripts.erase(
|
||||
scriptData->scripts.begin() + i);
|
||||
scriptData->scripts.erase(scriptData->scripts.begin() +
|
||||
i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +319,8 @@ void ScriptsTool::on_addScripts_clicked()
|
|||
|
||||
scriptData->scripts.emplace_back(script);
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(script_file);
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(script_file);
|
||||
item->setData(Qt::UserRole, QString(file));
|
||||
ui->scripts->addItem(item);
|
||||
|
||||
|
@ -343,8 +340,10 @@ void ScriptsTool::on_removeScripts_clicked()
|
|||
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
|
||||
|
||||
for (QListWidgetItem *item : items)
|
||||
RemoveScript(item->data(Qt::UserRole).toString()
|
||||
.toUtf8().constData());
|
||||
RemoveScript(item->data(Qt::UserRole)
|
||||
.toString()
|
||||
.toUtf8()
|
||||
.constData());
|
||||
RefreshLists();
|
||||
}
|
||||
|
||||
|
@ -352,8 +351,10 @@ void ScriptsTool::on_reloadScripts_clicked()
|
|||
{
|
||||
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
|
||||
for (QListWidgetItem *item : items)
|
||||
ReloadScript(item->data(Qt::UserRole).toString()
|
||||
.toUtf8().constData());
|
||||
ReloadScript(item->data(Qt::UserRole)
|
||||
.toString()
|
||||
.toUtf8()
|
||||
.constData());
|
||||
|
||||
on_scripts_currentRowChanged(ui->scripts->currentRow());
|
||||
}
|
||||
|
@ -368,9 +369,7 @@ void ScriptsTool::on_pythonPathBrowse_clicked()
|
|||
{
|
||||
QString curPath = ui->pythonPath->text();
|
||||
QString newPath = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
ui->pythonPathLabel->text(),
|
||||
curPath);
|
||||
this, ui->pythonPathLabel->text(), curPath);
|
||||
|
||||
if (newPath.isEmpty())
|
||||
return;
|
||||
|
@ -412,8 +411,8 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
|
|||
return;
|
||||
}
|
||||
|
||||
QByteArray array = ui->scripts->item(row)->data(Qt::UserRole)
|
||||
.toString().toUtf8();
|
||||
QByteArray array =
|
||||
ui->scripts->item(row)->data(Qt::UserRole).toString().toUtf8();
|
||||
const char *path = array.constData();
|
||||
|
||||
obs_script_t *script = scriptData->FindScript(path);
|
||||
|
@ -425,7 +424,8 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
|
|||
OBSData settings = obs_script_get_settings(script);
|
||||
obs_data_release(settings);
|
||||
|
||||
propertiesView = new OBSPropertiesView(settings, script,
|
||||
propertiesView = new OBSPropertiesView(
|
||||
settings, script,
|
||||
(PropertiesReloadCallback)obs_script_get_properties,
|
||||
(PropertiesUpdateCallback)obs_script_update);
|
||||
ui->propertiesLayout->addWidget(propertiesView);
|
||||
|
@ -457,8 +457,7 @@ static void obs_event(enum obs_frontend_event event, void *)
|
|||
|
||||
static void load_script_data(obs_data_t *load_data, bool, void *)
|
||||
{
|
||||
obs_data_array_t *array = obs_data_get_array(load_data,
|
||||
"scripts-tool");
|
||||
obs_data_array_t *array = obs_data_get_array(load_data, "scripts-tool");
|
||||
|
||||
delete scriptData;
|
||||
scriptData = new ScriptData;
|
||||
|
@ -515,15 +514,13 @@ static void script_log(void *, obs_script_t *script, int log_level,
|
|||
|
||||
if (script) {
|
||||
qmsg = QStringLiteral("[%1] %2").arg(
|
||||
obs_script_get_file(script),
|
||||
message);
|
||||
obs_script_get_file(script), message);
|
||||
} else {
|
||||
qmsg = QStringLiteral("[Unknown Script] %1").arg(message);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(scriptLogWindow, "AddLogMsg",
|
||||
Q_ARG(int, log_level),
|
||||
Q_ARG(QString, qmsg));
|
||||
Q_ARG(int, log_level), Q_ARG(QString, qmsg));
|
||||
}
|
||||
|
||||
extern "C" void InitScripts()
|
||||
|
@ -538,8 +535,8 @@ extern "C" void InitScripts()
|
|||
|
||||
#if PYTHON_UI
|
||||
config_t *config = obs_frontend_get_global_config();
|
||||
const char *python_path = config_get_string(config, "Python",
|
||||
"Path" ARCH_NAME);
|
||||
const char *python_path =
|
||||
config_get_string(config, "Python", "Path" ARCH_NAME);
|
||||
|
||||
if (!obs_scripting_python_loaded() && python_path && *python_path)
|
||||
obs_scripting_load_python(python_path);
|
||||
|
@ -547,8 +544,7 @@ extern "C" void InitScripts()
|
|||
|
||||
scriptData = new ScriptData;
|
||||
|
||||
auto cb = [] ()
|
||||
{
|
||||
auto cb = []() {
|
||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||
|
||||
if (!scriptsWindow) {
|
||||
|
|
|
@ -8,8 +8,7 @@ class HScrollArea : public QScrollArea {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
inline HScrollArea(QWidget *parent = nullptr)
|
||||
: QScrollArea(parent)
|
||||
inline HScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
|
||||
{
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
}
|
||||
|
|
|
@ -105,32 +105,34 @@ void OBSHotkeyEdit::mousePressEvent(QMouseEvent *event)
|
|||
new_key.key = OBS_KEY_MOUSE3;
|
||||
break;
|
||||
|
||||
#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \
|
||||
new_key.key = OBS_KEY_MOUSE ## j; break;
|
||||
MAP_BUTTON( 1, 4);
|
||||
MAP_BUTTON( 2, 5);
|
||||
MAP_BUTTON( 3, 6);
|
||||
MAP_BUTTON( 4, 7);
|
||||
MAP_BUTTON( 5, 8);
|
||||
MAP_BUTTON( 6, 9);
|
||||
MAP_BUTTON( 7, 10);
|
||||
MAP_BUTTON( 8, 11);
|
||||
MAP_BUTTON( 9, 12);
|
||||
MAP_BUTTON(10, 13);
|
||||
MAP_BUTTON(11, 14);
|
||||
MAP_BUTTON(12, 15);
|
||||
MAP_BUTTON(13, 16);
|
||||
MAP_BUTTON(14, 17);
|
||||
MAP_BUTTON(15, 18);
|
||||
MAP_BUTTON(16, 19);
|
||||
MAP_BUTTON(17, 20);
|
||||
MAP_BUTTON(18, 21);
|
||||
MAP_BUTTON(19, 22);
|
||||
MAP_BUTTON(20, 23);
|
||||
MAP_BUTTON(21, 24);
|
||||
MAP_BUTTON(22, 25);
|
||||
MAP_BUTTON(23, 26);
|
||||
MAP_BUTTON(24, 27);
|
||||
#define MAP_BUTTON(i, j) \
|
||||
case Qt::ExtraButton##i: \
|
||||
new_key.key = OBS_KEY_MOUSE##j; \
|
||||
break;
|
||||
MAP_BUTTON(1, 4)
|
||||
MAP_BUTTON(2, 5)
|
||||
MAP_BUTTON(3, 6)
|
||||
MAP_BUTTON(4, 7)
|
||||
MAP_BUTTON(5, 8)
|
||||
MAP_BUTTON(6, 9)
|
||||
MAP_BUTTON(7, 10)
|
||||
MAP_BUTTON(8, 11)
|
||||
MAP_BUTTON(9, 12)
|
||||
MAP_BUTTON(10, 13)
|
||||
MAP_BUTTON(11, 14)
|
||||
MAP_BUTTON(12, 15)
|
||||
MAP_BUTTON(13, 16)
|
||||
MAP_BUTTON(14, 17)
|
||||
MAP_BUTTON(15, 18)
|
||||
MAP_BUTTON(16, 19)
|
||||
MAP_BUTTON(17, 20)
|
||||
MAP_BUTTON(18, 21)
|
||||
MAP_BUTTON(19, 22)
|
||||
MAP_BUTTON(20, 23)
|
||||
MAP_BUTTON(21, 24)
|
||||
MAP_BUTTON(22, 25)
|
||||
MAP_BUTTON(23, 26)
|
||||
MAP_BUTTON(24, 27)
|
||||
#undef MAP_BUTTON
|
||||
}
|
||||
|
||||
|
@ -183,13 +185,13 @@ void OBSHotkeyEdit::ClearKey()
|
|||
|
||||
void OBSHotkeyEdit::InitSignalHandler()
|
||||
{
|
||||
layoutChanged = {obs_get_signal_handler(),
|
||||
"hotkey_layout_change",
|
||||
[](void *this_, calldata_t*)
|
||||
{
|
||||
layoutChanged = {
|
||||
obs_get_signal_handler(), "hotkey_layout_change",
|
||||
[](void *this_, calldata_t *) {
|
||||
auto edit = static_cast<OBSHotkeyEdit *>(this_);
|
||||
QMetaObject::invokeMethod(edit, "ReloadKeyLayout");
|
||||
}, this};
|
||||
},
|
||||
this};
|
||||
}
|
||||
|
||||
void OBSHotkeyEdit::ReloadKeyLayout()
|
||||
|
@ -210,10 +212,8 @@ void OBSHotkeyWidget::SetKeyCombinations(
|
|||
bool OBSHotkeyWidget::Changed() const
|
||||
{
|
||||
return changed ||
|
||||
std::any_of(begin(edits), end(edits), [](OBSHotkeyEdit *edit)
|
||||
{
|
||||
return edit->changed;
|
||||
});
|
||||
std::any_of(begin(edits), end(edits),
|
||||
[](OBSHotkeyEdit *edit) { return edit->changed; });
|
||||
}
|
||||
|
||||
void OBSHotkeyWidget::Apply()
|
||||
|
@ -249,21 +249,19 @@ void OBSHotkeyWidget::Save(std::vector<obs_key_combination_t> &combinations)
|
|||
GetCombinations(combinations);
|
||||
Apply();
|
||||
|
||||
auto AtomicUpdate = [&]()
|
||||
{
|
||||
auto AtomicUpdate = [&]() {
|
||||
ignoreChangedBindings = true;
|
||||
|
||||
obs_hotkey_load_bindings(id,
|
||||
combinations.data(), combinations.size());
|
||||
obs_hotkey_load_bindings(id, combinations.data(),
|
||||
combinations.size());
|
||||
|
||||
ignoreChangedBindings = false;
|
||||
};
|
||||
using AtomicUpdate_t = decltype(&AtomicUpdate);
|
||||
|
||||
obs_hotkey_update_atomic([](void *d)
|
||||
{
|
||||
(*static_cast<AtomicUpdate_t>(d))();
|
||||
}, static_cast<void*>(&AtomicUpdate));
|
||||
obs_hotkey_update_atomic(
|
||||
[](void *d) { (*static_cast<AtomicUpdate_t>(d))(); },
|
||||
static_cast<void *>(&AtomicUpdate));
|
||||
}
|
||||
|
||||
void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
|
||||
|
@ -285,10 +283,11 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
|
|||
clear->setFlat(true);
|
||||
clear->setEnabled(!obs_key_combination_is_empty(combo));
|
||||
|
||||
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
|
||||
[=](obs_key_combination_t new_combo)
|
||||
{
|
||||
clear->setEnabled(!obs_key_combination_is_empty(new_combo));
|
||||
QObject::connect(
|
||||
edit, &OBSHotkeyEdit::KeyChanged,
|
||||
[=](obs_key_combination_t new_combo) {
|
||||
clear->setEnabled(
|
||||
!obs_key_combination_is_empty(new_combo));
|
||||
revert->setEnabled(edit->original != new_combo);
|
||||
});
|
||||
|
||||
|
@ -303,25 +302,18 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
|
|||
remove->setFixedSize(24, 24);
|
||||
remove->setFlat(true);
|
||||
|
||||
auto CurrentIndex = [&, remove]
|
||||
{
|
||||
auto res = std::find(begin(removeButtons),
|
||||
end(removeButtons),
|
||||
auto CurrentIndex = [&, remove] {
|
||||
auto res = std::find(begin(removeButtons), end(removeButtons),
|
||||
remove);
|
||||
return std::distance(begin(removeButtons), res);
|
||||
};
|
||||
|
||||
QObject::connect(add, &QPushButton::clicked,
|
||||
[&, CurrentIndex]
|
||||
{
|
||||
QObject::connect(add, &QPushButton::clicked, [&, CurrentIndex] {
|
||||
AddEdit({0, OBS_KEY_NONE}, CurrentIndex() + 1);
|
||||
});
|
||||
|
||||
QObject::connect(remove, &QPushButton::clicked,
|
||||
[&, CurrentIndex]
|
||||
{
|
||||
RemoveEdit(CurrentIndex());
|
||||
});
|
||||
[&, CurrentIndex] { RemoveEdit(CurrentIndex()); });
|
||||
|
||||
QHBoxLayout *subLayout = new QHBoxLayout;
|
||||
subLayout->setContentsMargins(0, 4, 0, 0);
|
||||
|
@ -346,16 +338,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
|
|||
|
||||
layout()->insertLayout(idx, subLayout);
|
||||
|
||||
QObject::connect(revert, &QPushButton::clicked,
|
||||
edit, &OBSHotkeyEdit::ResetKey);
|
||||
QObject::connect(clear, &QPushButton::clicked,
|
||||
edit, &OBSHotkeyEdit::ClearKey);
|
||||
QObject::connect(revert, &QPushButton::clicked, edit,
|
||||
&OBSHotkeyEdit::ResetKey);
|
||||
QObject::connect(clear, &QPushButton::clicked, edit,
|
||||
&OBSHotkeyEdit::ClearKey);
|
||||
|
||||
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
|
||||
[&](obs_key_combination)
|
||||
{
|
||||
emit KeyChanged();
|
||||
});
|
||||
[&](obs_key_combination) { emit KeyChanged(); });
|
||||
}
|
||||
|
||||
void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal)
|
||||
|
@ -393,25 +382,26 @@ void OBSHotkeyWidget::BindingsChanged(void *data, calldata_t *param)
|
|||
|
||||
void OBSHotkeyWidget::HandleChangedBindings(obs_hotkey_id id_)
|
||||
{
|
||||
if (ignoreChangedBindings || id != id_) return;
|
||||
if (ignoreChangedBindings || id != id_)
|
||||
return;
|
||||
|
||||
std::vector<obs_key_combination_t> bindings;
|
||||
auto LoadBindings = [&](obs_hotkey_binding_t *binding)
|
||||
{
|
||||
if (obs_hotkey_binding_get_hotkey_id(binding) != id) return;
|
||||
auto LoadBindings = [&](obs_hotkey_binding_t *binding) {
|
||||
if (obs_hotkey_binding_get_hotkey_id(binding) != id)
|
||||
return;
|
||||
|
||||
auto get_combo = obs_hotkey_binding_get_key_combination;
|
||||
bindings.push_back(get_combo(binding));
|
||||
};
|
||||
using LoadBindings_t = decltype(&LoadBindings);
|
||||
|
||||
obs_enum_hotkey_bindings([](void *data,
|
||||
size_t, obs_hotkey_binding_t *binding)
|
||||
{
|
||||
obs_enum_hotkey_bindings(
|
||||
[](void *data, size_t, obs_hotkey_binding_t *binding) {
|
||||
auto LoadBindings = *static_cast<LoadBindings_t>(data);
|
||||
LoadBindings(binding);
|
||||
return true;
|
||||
}, static_cast<void*>(&LoadBindings));
|
||||
},
|
||||
static_cast<void *>(&LoadBindings));
|
||||
|
||||
while (edits.size() > 0)
|
||||
RemoveEdit(edits.size() - 1, false);
|
||||
|
|
|
@ -45,10 +45,8 @@ class OBSHotkeyEdit : public QLineEdit {
|
|||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
OBSHotkeyEdit(obs_key_combination_t original,
|
||||
QWidget *parent=nullptr)
|
||||
: QLineEdit(parent),
|
||||
original(original)
|
||||
OBSHotkeyEdit(obs_key_combination_t original, QWidget *parent = nullptr)
|
||||
: QLineEdit(parent), original(original)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// disable the input cursor on OSX, focus should be clear
|
||||
|
@ -64,6 +62,7 @@ public:
|
|||
obs_key_combination_t original;
|
||||
obs_key_combination_t key;
|
||||
bool changed = false;
|
||||
|
||||
protected:
|
||||
OBSSignal layoutChanged;
|
||||
|
||||
|
@ -99,8 +98,7 @@ public:
|
|||
name(name),
|
||||
bindingsChanged(obs_get_signal_handler(),
|
||||
"hotkey_bindings_changed",
|
||||
&OBSHotkeyWidget::BindingsChanged,
|
||||
this)
|
||||
&OBSHotkeyWidget::BindingsChanged, this)
|
||||
{
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->setSpacing(0);
|
||||
|
|
5
UI/obf.c
5
UI/obf.c
|
@ -13,9 +13,8 @@ void deobfuscate_str(char *str, uint64_t val)
|
|||
int pos = i / 2;
|
||||
bool bottom = (i % 2) == 0;
|
||||
uint8_t *ch = (uint8_t *)str;
|
||||
uint8_t xor = bottom ?
|
||||
LOWER_HALFBYTE(dec_val[pos]) :
|
||||
UPPER_HALFBYTE(dec_val[pos]);
|
||||
uint8_t xor = bottom ? LOWER_HALFBYTE(dec_val[pos])
|
||||
: UPPER_HALFBYTE(dec_val[pos]);
|
||||
|
||||
*ch ^= xor;
|
||||
|
||||
|
|
420
UI/obs-app.cpp
420
UI/obs-app.cpp
|
@ -91,10 +91,8 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
|||
|
||||
QObject *CreateShortcutFilter()
|
||||
{
|
||||
return new OBSEventFilter([](QObject *obj, QEvent *event)
|
||||
{
|
||||
auto mouse_event = [](QMouseEvent &event)
|
||||
{
|
||||
return new OBSEventFilter([](QObject *obj, QEvent *event) {
|
||||
auto mouse_event = [](QMouseEvent &event) {
|
||||
obs_key_combination_t hotkey = {0, OBS_KEY_NONE};
|
||||
bool pressed = event.type() == QEvent::MouseButtonPress;
|
||||
|
||||
|
@ -110,8 +108,10 @@ QObject *CreateShortcutFilter()
|
|||
hotkey.key = OBS_KEY_MOUSE3;
|
||||
break;
|
||||
|
||||
#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \
|
||||
hotkey.key = OBS_KEY_MOUSE ## j; break;
|
||||
#define MAP_BUTTON(i, j) \
|
||||
case Qt::ExtraButton##i: \
|
||||
hotkey.key = OBS_KEY_MOUSE##j; \
|
||||
break;
|
||||
MAP_BUTTON(1, 4);
|
||||
MAP_BUTTON(2, 5);
|
||||
MAP_BUTTON(3, 6);
|
||||
|
@ -146,8 +146,7 @@ QObject *CreateShortcutFilter()
|
|||
return true;
|
||||
};
|
||||
|
||||
auto key_event = [&](QKeyEvent *event)
|
||||
{
|
||||
auto key_event = [&](QKeyEvent *event) {
|
||||
QDialog *dialog = qobject_cast<QDialog *>(obj);
|
||||
|
||||
obs_key_combination_t hotkey = {0, OBS_KEY_NONE};
|
||||
|
@ -217,10 +216,8 @@ string CurrentTimeString()
|
|||
size_t written = strftime(buf, sizeof(buf), "%X", &tstruct);
|
||||
if (ratio_less<system_clock::period, seconds::period>::value &&
|
||||
written && (sizeof(buf) - written) > 5) {
|
||||
auto tp_secs =
|
||||
time_point_cast<seconds>(tp);
|
||||
auto millis =
|
||||
duration_cast<milliseconds>(tp - tp_secs).count();
|
||||
auto tp_secs = time_point_cast<seconds>(tp);
|
||||
auto millis = duration_cast<milliseconds>(tp - tp_secs).count();
|
||||
|
||||
snprintf(buf + written, sizeof(buf) - written, ".%03u",
|
||||
static_cast<unsigned>(millis));
|
||||
|
@ -307,10 +304,10 @@ static inline bool too_many_repeated_entries(fstream &logFile, const char *msg,
|
|||
}
|
||||
|
||||
if (rep_count > MAX_REPEATED_LINES) {
|
||||
logFile << CurrentTimeString() <<
|
||||
": Last log entry repeated for " <<
|
||||
to_string(rep_count - MAX_REPEATED_LINES) <<
|
||||
" more lines" << endl;
|
||||
logFile << CurrentTimeString()
|
||||
<< ": Last log entry repeated for "
|
||||
<< to_string(rep_count - MAX_REPEATED_LINES)
|
||||
<< " more lines" << endl;
|
||||
}
|
||||
|
||||
last_msg_ptr = msg;
|
||||
|
@ -393,36 +390,36 @@ bool OBSApp::InitGlobalConfigDefaults()
|
|||
"PreviewProgramMode", false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SceneDuplicationMode", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SwapScenesMode", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SnappingEnabled", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"ScreenSnapping", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SourceSnapping", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"CenterSnapping", false);
|
||||
config_set_default_double(globalConfig, "BasicWindow",
|
||||
"SnapDistance", 10.0);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "SwapScenesMode",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "SnappingEnabled",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "ScreenSnapping",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "SourceSnapping",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "CenterSnapping",
|
||||
false);
|
||||
config_set_default_double(globalConfig, "BasicWindow", "SnapDistance",
|
||||
10.0);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"RecordWhenStreaming", false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"KeepRecordingWhenStreamStops", false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SysTrayEnabled", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "SysTrayEnabled",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SysTrayWhenStarted", false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"SaveProjectors", false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"ShowTransitions", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "SaveProjectors",
|
||||
false);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "ShowTransitions",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"ShowListboxToolbars", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"ShowStatusBar", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow",
|
||||
"StudioModeLabels", true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "ShowStatusBar",
|
||||
true);
|
||||
config_set_default_bool(globalConfig, "BasicWindow", "StudioModeLabels",
|
||||
true);
|
||||
|
||||
if (!config_get_bool(globalConfig, "General", "Pre21Defaults")) {
|
||||
config_set_default_string(globalConfig, "General",
|
||||
|
@ -550,8 +547,8 @@ static string GetProfileDirFromName(const char *name)
|
|||
if (config.Open(path, CONFIG_OPEN_EXISTING) != 0)
|
||||
continue;
|
||||
|
||||
const char *curName = config_get_string(config, "General",
|
||||
"Name");
|
||||
const char *curName =
|
||||
config_get_string(config, "General", "Name");
|
||||
if (astrcmpi(curName, name) == 0) {
|
||||
outputPath = ent.path;
|
||||
break;
|
||||
|
@ -621,28 +618,32 @@ bool OBSApp::UpdatePre22MultiviewLayout(const char *layout)
|
|||
return false;
|
||||
|
||||
if (astrcmpi(layout, "horizontaltop") == 0) {
|
||||
config_set_int(globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
config_set_int(
|
||||
globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
static_cast<int>(
|
||||
MultiviewLayout::HORIZONTAL_TOP_8_SCENES));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (astrcmpi(layout, "horizontalbottom") == 0) {
|
||||
config_set_int(globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
config_set_int(
|
||||
globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
static_cast<int>(
|
||||
MultiviewLayout::HORIZONTAL_BOTTOM_8_SCENES));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (astrcmpi(layout, "verticalleft") == 0) {
|
||||
config_set_int(globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
config_set_int(
|
||||
globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
static_cast<int>(
|
||||
MultiviewLayout::VERTICAL_LEFT_8_SCENES));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (astrcmpi(layout, "verticalright") == 0) {
|
||||
config_set_int(globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
config_set_int(
|
||||
globalConfig, "BasicWindow", "MultiviewLayout",
|
||||
static_cast<int>(
|
||||
MultiviewLayout::VERTICAL_RIGHT_8_SCENES));
|
||||
return true;
|
||||
|
@ -656,8 +657,7 @@ bool OBSApp::InitGlobalConfig()
|
|||
char path[512];
|
||||
bool changed = false;
|
||||
|
||||
int len = GetConfigPath(path, sizeof(path),
|
||||
"obs-studio/global.ini");
|
||||
int len = GetConfigPath(path, sizeof(path), "obs-studio/global.ini");
|
||||
if (len <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -672,19 +672,18 @@ bool OBSApp::InitGlobalConfig()
|
|||
string path = GetSceneCollectionFileFromName(
|
||||
opt_starting_collection.c_str());
|
||||
if (!path.empty()) {
|
||||
config_set_string(globalConfig,
|
||||
"Basic", "SceneCollection",
|
||||
config_set_string(globalConfig, "Basic",
|
||||
"SceneCollection",
|
||||
opt_starting_collection.c_str());
|
||||
config_set_string(globalConfig,
|
||||
"Basic", "SceneCollectionFile",
|
||||
path.c_str());
|
||||
config_set_string(globalConfig, "Basic",
|
||||
"SceneCollectionFile", path.c_str());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt_starting_profile.empty()) {
|
||||
string path = GetProfileDirFromName(
|
||||
opt_starting_profile.c_str());
|
||||
string path =
|
||||
GetProfileDirFromName(opt_starting_profile.c_str());
|
||||
if (!path.empty()) {
|
||||
config_set_string(globalConfig, "Basic", "Profile",
|
||||
opt_starting_profile.c_str());
|
||||
|
@ -695,10 +694,11 @@ bool OBSApp::InitGlobalConfig()
|
|||
}
|
||||
|
||||
if (!config_has_user_value(globalConfig, "General", "Pre19Defaults")) {
|
||||
uint32_t lastVersion = config_get_int(globalConfig, "General",
|
||||
"LastVersion");
|
||||
uint32_t lastVersion =
|
||||
config_get_int(globalConfig, "General", "LastVersion");
|
||||
bool useOldDefaults = lastVersion &&
|
||||
lastVersion < MAKE_SEMANTIC_VERSION(19, 0, 0);
|
||||
lastVersion <
|
||||
MAKE_SEMANTIC_VERSION(19, 0, 0);
|
||||
|
||||
config_set_bool(globalConfig, "General", "Pre19Defaults",
|
||||
useOldDefaults);
|
||||
|
@ -706,10 +706,11 @@ bool OBSApp::InitGlobalConfig()
|
|||
}
|
||||
|
||||
if (!config_has_user_value(globalConfig, "General", "Pre21Defaults")) {
|
||||
uint32_t lastVersion = config_get_int(globalConfig, "General",
|
||||
"LastVersion");
|
||||
uint32_t lastVersion =
|
||||
config_get_int(globalConfig, "General", "LastVersion");
|
||||
bool useOldDefaults = lastVersion &&
|
||||
lastVersion < MAKE_SEMANTIC_VERSION(21, 0, 0);
|
||||
lastVersion <
|
||||
MAKE_SEMANTIC_VERSION(21, 0, 0);
|
||||
|
||||
config_set_bool(globalConfig, "General", "Pre21Defaults",
|
||||
useOldDefaults);
|
||||
|
@ -717,10 +718,11 @@ bool OBSApp::InitGlobalConfig()
|
|||
}
|
||||
|
||||
if (!config_has_user_value(globalConfig, "General", "Pre23Defaults")) {
|
||||
uint32_t lastVersion = config_get_int(globalConfig, "General",
|
||||
"LastVersion");
|
||||
uint32_t lastVersion =
|
||||
config_get_int(globalConfig, "General", "LastVersion");
|
||||
bool useOldDefaults = lastVersion &&
|
||||
lastVersion < MAKE_SEMANTIC_VERSION(23, 0, 0);
|
||||
lastVersion <
|
||||
MAKE_SEMANTIC_VERSION(23, 0, 0);
|
||||
|
||||
config_set_bool(globalConfig, "General", "Pre23Defaults",
|
||||
useOldDefaults);
|
||||
|
@ -729,8 +731,8 @@ bool OBSApp::InitGlobalConfig()
|
|||
|
||||
if (config_has_user_value(globalConfig, "BasicWindow",
|
||||
"MultiviewLayout")) {
|
||||
const char *layout = config_get_string(globalConfig,
|
||||
"BasicWindow", "MultiviewLayout");
|
||||
const char *layout = config_get_string(
|
||||
globalConfig, "BasicWindow", "MultiviewLayout");
|
||||
changed |= UpdatePre22MultiviewLayout(layout);
|
||||
}
|
||||
|
||||
|
@ -743,8 +745,8 @@ bool OBSApp::InitGlobalConfig()
|
|||
bool OBSApp::InitLocale()
|
||||
{
|
||||
ProfileScope("OBSApp::InitLocale");
|
||||
const char *lang = config_get_string(globalConfig, "General",
|
||||
"Language");
|
||||
const char *lang =
|
||||
config_get_string(globalConfig, "General", "Language");
|
||||
|
||||
locale = lang;
|
||||
|
||||
|
@ -761,8 +763,8 @@ bool OBSApp::InitLocale()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool userLocale = config_has_user_value(globalConfig, "General",
|
||||
"Language");
|
||||
bool userLocale =
|
||||
config_has_user_value(globalConfig, "General", "Language");
|
||||
bool defaultLang = astrcmpi(lang, DEFAULT_LANG) == 0;
|
||||
|
||||
if (userLocale && defaultLang)
|
||||
|
@ -808,15 +810,14 @@ bool OBSApp::InitLocale()
|
|||
return true;
|
||||
}
|
||||
|
||||
void OBSApp::AddExtraThemeColor(QPalette &pal, int group,
|
||||
const char *name, uint32_t color)
|
||||
void OBSApp::AddExtraThemeColor(QPalette &pal, int group, const char *name,
|
||||
uint32_t color)
|
||||
{
|
||||
std::function<void(QPalette::ColorGroup)> func;
|
||||
|
||||
#define DEF_PALETTE_ASSIGN(name) \
|
||||
do { \
|
||||
func = [&] (QPalette::ColorGroup group) \
|
||||
{ \
|
||||
func = [&](QPalette::ColorGroup group) { \
|
||||
pal.setColor(group, QPalette::name, \
|
||||
QColor::fromRgb(color)); \
|
||||
}; \
|
||||
|
@ -900,16 +901,19 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
|||
cf_parser_parse(cfp, data, path);
|
||||
|
||||
while (cf_go_to_token(cfp, "OBSTheme", nullptr)) {
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
int group = -1;
|
||||
|
||||
if (cf_token_is(cfp, ":")) {
|
||||
ret = cf_next_token_should_be(cfp, ":", nullptr,
|
||||
nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
if (cf_token_is(cfp, "disabled")) {
|
||||
group = QPalette::Disabled;
|
||||
|
@ -921,13 +925,16 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cf_token_is(cfp, "{")) continue;
|
||||
if (!cf_token_is(cfp, "{"))
|
||||
continue;
|
||||
|
||||
for (;;) {
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
ret = cf_token_is_type(cfp, CFTOKEN_NAME, "name",
|
||||
nullptr);
|
||||
|
@ -937,11 +944,12 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
|||
DStr name;
|
||||
dstr_copy_strref(name, &cfp->cur_token->str);
|
||||
|
||||
ret = cf_next_token_should_be(cfp, ":", ";",
|
||||
nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
ret = cf_next_token_should_be(cfp, ":", ";", nullptr);
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
const char *array;
|
||||
uint32_t color = 0;
|
||||
|
@ -953,24 +961,30 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
|||
} else if (cf_token_is(cfp, "rgb")) {
|
||||
ret = cf_next_token_should_be(cfp, "(", ";",
|
||||
nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
array = cfp->cur_token->str.array;
|
||||
color |= strtol(array, nullptr, 10) << 16;
|
||||
|
||||
ret = cf_next_token_should_be(cfp, ",", ";",
|
||||
nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
array = cfp->cur_token->str.array;
|
||||
color |= strtol(array, nullptr, 10) << 8;
|
||||
|
||||
ret = cf_next_token_should_be(cfp, ",", ";",
|
||||
nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
if (!cf_next_token(cfp)) return;
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
if (!cf_next_token(cfp))
|
||||
return;
|
||||
|
||||
array = cfp->cur_token->str.array;
|
||||
color |= strtol(array, nullptr, 10);
|
||||
|
@ -982,13 +996,15 @@ void OBSApp::ParseExtraThemeData(const char *path)
|
|||
color = 0;
|
||||
}
|
||||
|
||||
if (!cf_go_to_token(cfp, ";", nullptr)) return;
|
||||
if (!cf_go_to_token(cfp, ";", nullptr))
|
||||
return;
|
||||
|
||||
AddExtraThemeColor(pal, group, name->array, color);
|
||||
}
|
||||
|
||||
ret = cf_token_should_be(cfp, "}", "}", nullptr);
|
||||
if (ret != PARSE_SUCCESS) continue;
|
||||
if (ret != PARSE_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
|
||||
setPalette(pal);
|
||||
|
@ -1003,8 +1019,7 @@ bool OBSApp::SetTheme(std::string name, std::string path)
|
|||
char userDir[512];
|
||||
name = "themes/" + name + ".qss";
|
||||
string temp = "obs-studio/" + name;
|
||||
int ret = GetConfigPath(userDir, sizeof(userDir),
|
||||
temp.c_str());
|
||||
int ret = GetConfigPath(userDir, sizeof(userDir), temp.c_str());
|
||||
|
||||
if (ret > 0 && QFile::exists(userDir)) {
|
||||
path = string(userDir);
|
||||
|
@ -1027,13 +1042,12 @@ bool OBSApp::InitTheme()
|
|||
{
|
||||
defaultPalette = palette();
|
||||
|
||||
const char *themeName = config_get_string(globalConfig, "General",
|
||||
"CurrentTheme");
|
||||
const char *themeName =
|
||||
config_get_string(globalConfig, "General", "CurrentTheme");
|
||||
|
||||
if (!themeName) {
|
||||
/* Use deprecated "Theme" value if available */
|
||||
themeName = config_get_string(globalConfig,
|
||||
"General", "Theme");
|
||||
themeName = config_get_string(globalConfig, "General", "Theme");
|
||||
if (!themeName)
|
||||
themeName = DEFAULT_THEME;
|
||||
if (!themeName)
|
||||
|
@ -1047,8 +1061,7 @@ bool OBSApp::InitTheme()
|
|||
}
|
||||
|
||||
OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
|
||||
: QApplication(argc, argv),
|
||||
profilerNameStore(store)
|
||||
: QApplication(argc, argv), profilerNameStore(store)
|
||||
{
|
||||
sleepInhibitor = os_inhibit_sleep_create("OBS Video/audio");
|
||||
|
||||
|
@ -1058,17 +1071,17 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
|
|||
OBSApp::~OBSApp()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool disableAudioDucking = config_get_bool(globalConfig, "Audio",
|
||||
"DisableAudioDucking");
|
||||
bool disableAudioDucking =
|
||||
config_get_bool(globalConfig, "Audio", "DisableAudioDucking");
|
||||
if (disableAudioDucking)
|
||||
DisableAudioDucking(false);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool vsyncDiabled = config_get_bool(globalConfig, "Video",
|
||||
"DisableOSXVSync");
|
||||
bool resetVSync = config_get_bool(globalConfig, "Video",
|
||||
"ResetOSXVSyncOnExit");
|
||||
bool vsyncDiabled =
|
||||
config_get_bool(globalConfig, "Video", "DisableOSXVSync");
|
||||
bool resetVSync =
|
||||
config_get_bool(globalConfig, "Video", "ResetOSXVSyncOnExit");
|
||||
if (vsyncDiabled && resetVSync)
|
||||
EnableOSXVSync(true);
|
||||
#endif
|
||||
|
@ -1190,15 +1203,15 @@ void OBSApp::AppInit()
|
|||
}
|
||||
|
||||
if (!config_has_user_value(globalConfig, "Basic", "SceneCollection")) {
|
||||
config_set_string(globalConfig, "Basic",
|
||||
"SceneCollection", Str("Untitled"));
|
||||
config_set_string(globalConfig, "Basic",
|
||||
"SceneCollectionFile", Str("Untitled"));
|
||||
config_set_string(globalConfig, "Basic", "SceneCollection",
|
||||
Str("Untitled"));
|
||||
config_set_string(globalConfig, "Basic", "SceneCollectionFile",
|
||||
Str("Untitled"));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
bool disableAudioDucking = config_get_bool(globalConfig, "Audio",
|
||||
"DisableAudioDucking");
|
||||
bool disableAudioDucking =
|
||||
config_get_bool(globalConfig, "Audio", "DisableAudioDucking");
|
||||
if (disableAudioDucking)
|
||||
DisableAudioDucking(true);
|
||||
#endif
|
||||
|
@ -1220,11 +1233,10 @@ void OBSApp::AppInit()
|
|||
|
||||
const char *OBSApp::GetRenderModule() const
|
||||
{
|
||||
const char *renderer = config_get_string(globalConfig, "Video",
|
||||
"Renderer");
|
||||
const char *renderer =
|
||||
config_get_string(globalConfig, "Video", "Renderer");
|
||||
|
||||
return (astrcmpi(renderer, "Direct3D 11") == 0) ?
|
||||
DL_D3D11 : DL_OPENGL;
|
||||
return (astrcmpi(renderer, "Direct3D 11") == 0) ? DL_D3D11 : DL_OPENGL;
|
||||
}
|
||||
|
||||
static bool StartupOBS(const char *locale, profiler_name_store_t *store)
|
||||
|
@ -1239,8 +1251,7 @@ static bool StartupOBS(const char *locale, profiler_name_store_t *store)
|
|||
|
||||
inline void OBSApp::ResetHotkeyState(bool inFocus)
|
||||
{
|
||||
obs_hotkey_enable_background_press(
|
||||
inFocus || enableHotkeysInFocus);
|
||||
obs_hotkey_enable_background_press(inFocus || enableHotkeysInFocus);
|
||||
}
|
||||
|
||||
void OBSApp::EnableInFocusHotkeys(bool enable)
|
||||
|
@ -1268,22 +1279,22 @@ bool OBSApp::OBSInit()
|
|||
return false;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool browserHWAccel = config_get_bool(globalConfig, "General",
|
||||
"BrowserHWAccel");
|
||||
bool browserHWAccel =
|
||||
config_get_bool(globalConfig, "General", "BrowserHWAccel");
|
||||
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel);
|
||||
obs_apply_private_data(settings);
|
||||
obs_data_release(settings);
|
||||
|
||||
blog(LOG_INFO, "Current Date/Time: %s", CurrentDateTimeString().c_str());
|
||||
blog(LOG_INFO, "Current Date/Time: %s",
|
||||
CurrentDateTimeString().c_str());
|
||||
|
||||
blog(LOG_INFO, "Browser Hardware Acceleration: %s",
|
||||
browserHWAccel ? "true" : "false");
|
||||
#endif
|
||||
|
||||
blog(LOG_INFO, "Portable mode: %s",
|
||||
portable_mode ? "true" : "false");
|
||||
blog(LOG_INFO, "Portable mode: %s", portable_mode ? "true" : "false");
|
||||
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
||||
|
@ -1295,10 +1306,8 @@ bool OBSApp::OBSInit()
|
|||
mainWindow->OBSInit();
|
||||
|
||||
connect(this, &QGuiApplication::applicationStateChanged,
|
||||
[this](Qt::ApplicationState state)
|
||||
{
|
||||
ResetHotkeyState(
|
||||
state != Qt::ApplicationActive);
|
||||
[this](Qt::ApplicationState state) {
|
||||
ResetHotkeyState(state != Qt::ApplicationActive);
|
||||
});
|
||||
ResetHotkeyState(applicationState() != Qt::ApplicationActive);
|
||||
return true;
|
||||
|
@ -1311,9 +1320,8 @@ string OBSApp::GetVersionString() const
|
|||
#ifdef HAVE_OBSCONFIG_H
|
||||
ver << OBS_VERSION;
|
||||
#else
|
||||
ver << LIBOBS_API_MAJOR_VER << "." <<
|
||||
LIBOBS_API_MINOR_VER << "." <<
|
||||
LIBOBS_API_PATCH_VER;
|
||||
ver << LIBOBS_API_MAJOR_VER << "." << LIBOBS_API_MINOR_VER << "."
|
||||
<< LIBOBS_API_PATCH_VER;
|
||||
|
||||
#endif
|
||||
ver << " (";
|
||||
|
@ -1432,19 +1440,30 @@ static uint64_t convert_log_name(bool has_prefix, const char *name)
|
|||
|
||||
if (has_prefix) {
|
||||
string temp;
|
||||
if (!get_token(lex, temp, BASETOKEN_ALPHA)) return 0;
|
||||
if (!get_token(lex, temp, BASETOKEN_ALPHA))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!get_token(lex, year, BASETOKEN_DIGIT)) return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0;
|
||||
if (!get_token(lex, month, BASETOKEN_DIGIT)) return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0;
|
||||
if (!get_token(lex, day, BASETOKEN_DIGIT)) return 0;
|
||||
if (!get_token(lex, hour, BASETOKEN_DIGIT)) return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0;
|
||||
if (!get_token(lex, minute, BASETOKEN_DIGIT)) return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0;
|
||||
if (!get_token(lex, second, BASETOKEN_DIGIT)) return 0;
|
||||
if (!get_token(lex, year, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER))
|
||||
return 0;
|
||||
if (!get_token(lex, month, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER))
|
||||
return 0;
|
||||
if (!get_token(lex, day, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
if (!get_token(lex, hour, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER))
|
||||
return 0;
|
||||
if (!get_token(lex, minute, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
if (!expect_token(lex, "-", BASETOKEN_OTHER))
|
||||
return 0;
|
||||
if (!get_token(lex, second, BASETOKEN_DIGIT))
|
||||
return 0;
|
||||
|
||||
stringstream timestring;
|
||||
timestring << year << month << day << hour << minute << second;
|
||||
|
@ -1469,8 +1488,8 @@ static void delete_oldest_file(bool has_prefix, const char *location)
|
|||
if (entry->directory || *entry->d_name == '.')
|
||||
continue;
|
||||
|
||||
uint64_t ts = convert_log_name(has_prefix,
|
||||
entry->d_name);
|
||||
uint64_t ts =
|
||||
convert_log_name(has_prefix, entry->d_name);
|
||||
|
||||
if (ts) {
|
||||
if (ts < oldest_ts) {
|
||||
|
@ -1506,8 +1525,8 @@ static void get_last_log(bool has_prefix, const char *subdir_to_use,
|
|||
if (entry->directory || *entry->d_name == '.')
|
||||
continue;
|
||||
|
||||
uint64_t ts = convert_log_name(has_prefix,
|
||||
entry->d_name);
|
||||
uint64_t ts =
|
||||
convert_log_name(has_prefix, entry->d_name);
|
||||
|
||||
if (ts > highest_ts) {
|
||||
last = entry->d_name;
|
||||
|
@ -1527,14 +1546,9 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace)
|
|||
|
||||
cur_time = localtime(&now);
|
||||
snprintf(file, sizeof(file), "%d-%02d-%02d%c%02d-%02d-%02d.%s",
|
||||
cur_time->tm_year+1900,
|
||||
cur_time->tm_mon+1,
|
||||
cur_time->tm_mday,
|
||||
noSpace ? '_' : ' ',
|
||||
cur_time->tm_hour,
|
||||
cur_time->tm_min,
|
||||
cur_time->tm_sec,
|
||||
extension);
|
||||
cur_time->tm_year + 1900, cur_time->tm_mon + 1,
|
||||
cur_time->tm_mday, noSpace ? '_' : ' ', cur_time->tm_hour,
|
||||
cur_time->tm_min, cur_time->tm_sec, extension);
|
||||
|
||||
return string(file);
|
||||
}
|
||||
|
@ -1548,8 +1562,8 @@ string GenerateSpecifiedFilename(const char *extension, bool noSpace,
|
|||
if ((strcmp(extension, "mp4") == 0) && autoRemux)
|
||||
extension = "mkv";
|
||||
|
||||
BPtr<char> filename = os_generate_formatted_filename(extension,
|
||||
!noSpace, format);
|
||||
BPtr<char> filename =
|
||||
os_generate_formatted_filename(extension, !noSpace, format);
|
||||
|
||||
remuxFilename = string(filename);
|
||||
remuxAfterRecord = autoRemux;
|
||||
|
@ -1597,11 +1611,9 @@ static void create_log_file(fstream &logFile)
|
|||
#ifdef _WIN32
|
||||
BPtr<wchar_t> wpath;
|
||||
os_utf8_to_wcs_ptr(path, 0, &wpath);
|
||||
logFile.open(wpath,
|
||||
ios_base::in | ios_base::out | ios_base::trunc);
|
||||
logFile.open(wpath, ios_base::in | ios_base::out | ios_base::trunc);
|
||||
#else
|
||||
logFile.open(path,
|
||||
ios_base::in | ios_base::out | ios_base::trunc);
|
||||
logFile.open(path, ios_base::in | ios_base::out | ios_base::trunc);
|
||||
#endif
|
||||
|
||||
if (logFile.is_open()) {
|
||||
|
@ -1612,13 +1624,11 @@ static void create_log_file(fstream &logFile)
|
|||
}
|
||||
}
|
||||
|
||||
static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store)
|
||||
{
|
||||
static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) {
|
||||
profiler_name_store_free(store);
|
||||
};
|
||||
|
||||
using ProfilerNameStore =
|
||||
std::unique_ptr<profiler_name_store_t,
|
||||
using ProfilerNameStore = std::unique_ptr<profiler_name_store_t,
|
||||
decltype(ProfilerNameStoreRelease)>;
|
||||
|
||||
ProfilerNameStore CreateNameStore()
|
||||
|
@ -1627,8 +1637,7 @@ ProfilerNameStore CreateNameStore()
|
|||
ProfilerNameStoreRelease};
|
||||
}
|
||||
|
||||
static auto SnapshotRelease = [](profiler_snapshot_t *snap)
|
||||
{
|
||||
static auto SnapshotRelease = [](profiler_snapshot_t *snap) {
|
||||
profile_snapshot_free(snap);
|
||||
};
|
||||
|
||||
|
@ -1662,8 +1671,7 @@ static void SaveProfilerData(const ProfilerSnapshot &snap)
|
|||
static_cast<const char *>(path));
|
||||
}
|
||||
|
||||
static auto ProfilerFree = [](void *)
|
||||
{
|
||||
static auto ProfilerFree = [](void *) {
|
||||
profiler_stop();
|
||||
|
||||
auto snap = GetSnapshot();
|
||||
|
@ -1683,9 +1691,8 @@ static int run_program(fstream &logFile, int argc, char *argv[])
|
|||
|
||||
auto profilerNameStore = CreateNameStore();
|
||||
|
||||
std::unique_ptr<void, decltype(ProfilerFree)>
|
||||
prof_release(static_cast<void*>(&ProfilerFree),
|
||||
ProfilerFree);
|
||||
std::unique_ptr<void, decltype(ProfilerFree)> prof_release(
|
||||
static_cast<void *>(&ProfilerFree), ProfilerFree);
|
||||
|
||||
profiler_start();
|
||||
profile_register_root(run_program_init, 0);
|
||||
|
@ -1771,7 +1778,8 @@ run:
|
|||
for (int i = 2; i < argc; ++i) {
|
||||
stor << " " << argv[i];
|
||||
}
|
||||
blog(LOG_INFO, "Command Line Arguments: %s", stor.str().c_str());
|
||||
blog(LOG_INFO, "Command Line Arguments: %s",
|
||||
stor.str().c_str());
|
||||
}
|
||||
|
||||
if (!program.OBSInit())
|
||||
|
@ -1863,8 +1871,8 @@ static void load_debug_privilege(void)
|
|||
tp.Privileges[0].Luid = val;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
AdjustTokenPrivileges(token, false, &tp,
|
||||
sizeof(tp), NULL, NULL);
|
||||
AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
CloseHandle(token);
|
||||
|
@ -1989,8 +1997,8 @@ bool WindowPositionValid(QRect rect)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool arg_is(const char *arg,
|
||||
const char *long_form, const char *short_form)
|
||||
static inline bool arg_is(const char *arg, const char *long_form,
|
||||
const char *short_form)
|
||||
{
|
||||
return (long_form && strcmp(arg, long_form) == 0) ||
|
||||
(short_form && strcmp(arg, short_form) == 0);
|
||||
|
@ -2100,8 +2108,8 @@ static bool update_reconnect(ConfigFile &config)
|
|||
if (!mode)
|
||||
return false;
|
||||
|
||||
const char *section = (strcmp(mode, "Advanced") == 0) ?
|
||||
"AdvOut" : "SimpleOutput";
|
||||
const char *section = (strcmp(mode, "Advanced") == 0) ? "AdvOut"
|
||||
: "SimpleOutput";
|
||||
|
||||
if (move_reconnect_settings(config, section)) {
|
||||
config_remove_value(config, "SimpleOutput", "Reconnect");
|
||||
|
@ -2196,12 +2204,11 @@ static void upgrade_settings(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (config) {
|
||||
const char *sEnc = config_get_string(config,
|
||||
"AdvOut", "Encoder");
|
||||
const char *rEnc = config_get_string(config,
|
||||
"AdvOut", "RecEncoder");
|
||||
const char *sEnc = config_get_string(
|
||||
config, "AdvOut", "Encoder");
|
||||
const char *rEnc = config_get_string(
|
||||
config, "AdvOut", "RecEncoder");
|
||||
|
||||
/* replace "cbr" option with "rate_control" for
|
||||
* each profile's encoder data */
|
||||
|
@ -2227,7 +2234,8 @@ static void upgrade_settings(void)
|
|||
os_closedir(dir);
|
||||
}
|
||||
|
||||
void ctrlc_handler (int s) {
|
||||
void ctrlc_handler(int s)
|
||||
{
|
||||
UNUSED_PARAMETER(s);
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
@ -2247,7 +2255,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
sigaction(SIGINT, &sig_handler, NULL);
|
||||
|
||||
|
||||
/* Block SIGPIPE in all threads, this can happen if a thread calls write on
|
||||
a closed pipe. */
|
||||
sigset_t sigpipe_mask;
|
||||
|
@ -2301,13 +2308,16 @@ int main(int argc, char *argv[])
|
|||
opt_start_replaybuffer = true;
|
||||
|
||||
} else if (arg_is(argv[i], "--collection", nullptr)) {
|
||||
if (++i < argc) opt_starting_collection = argv[i];
|
||||
if (++i < argc)
|
||||
opt_starting_collection = argv[i];
|
||||
|
||||
} else if (arg_is(argv[i], "--profile", nullptr)) {
|
||||
if (++i < argc) opt_starting_profile = argv[i];
|
||||
if (++i < argc)
|
||||
opt_starting_profile = argv[i];
|
||||
|
||||
} else if (arg_is(argv[i], "--scene", nullptr)) {
|
||||
if (++i < argc) opt_starting_scene = argv[i];
|
||||
if (++i < argc)
|
||||
opt_starting_scene = argv[i];
|
||||
|
||||
} else if (arg_is(argv[i], "--minimize-to-tray", nullptr)) {
|
||||
opt_minimize_tray = true;
|
||||
|
@ -2319,30 +2329,30 @@ int main(int argc, char *argv[])
|
|||
opt_allow_opengl = true;
|
||||
|
||||
} else if (arg_is(argv[i], "--help", "-h")) {
|
||||
std::cout <<
|
||||
"--help, -h: Get list of available commands.\n\n" <<
|
||||
"--startstreaming: Automatically start streaming.\n" <<
|
||||
"--startrecording: Automatically start recording.\n" <<
|
||||
"--startreplaybuffer: Start replay buffer.\n\n" <<
|
||||
"--collection <string>: Use specific scene collection."
|
||||
<< "\n" <<
|
||||
"--profile <string>: Use specific profile.\n" <<
|
||||
"--scene <string>: Start with specific scene.\n\n" <<
|
||||
"--studio-mode: Enable studio mode.\n" <<
|
||||
"--minimize-to-tray: Minimize to system tray.\n" <<
|
||||
"--portable, -p: Use portable mode.\n" <<
|
||||
"--multi, -m: Don't warn when launching multiple instances.\n\n" <<
|
||||
"--verbose: Make log more verbose.\n" <<
|
||||
"--always-on-top: Start in 'always on top' mode.\n\n" <<
|
||||
"--unfiltered_log: Make log unfiltered.\n\n" <<
|
||||
"--allow-opengl: Allow OpenGL on Windows.\n\n" <<
|
||||
"--version, -V: Get current version.\n";
|
||||
std::cout
|
||||
<< "--help, -h: Get list of available commands.\n\n"
|
||||
<< "--startstreaming: Automatically start streaming.\n"
|
||||
<< "--startrecording: Automatically start recording.\n"
|
||||
<< "--startreplaybuffer: Start replay buffer.\n\n"
|
||||
<< "--collection <string>: Use specific scene collection."
|
||||
<< "\n"
|
||||
<< "--profile <string>: Use specific profile.\n"
|
||||
<< "--scene <string>: Start with specific scene.\n\n"
|
||||
<< "--studio-mode: Enable studio mode.\n"
|
||||
<< "--minimize-to-tray: Minimize to system tray.\n"
|
||||
<< "--portable, -p: Use portable mode.\n"
|
||||
<< "--multi, -m: Don't warn when launching multiple instances.\n\n"
|
||||
<< "--verbose: Make log more verbose.\n"
|
||||
<< "--always-on-top: Start in 'always on top' mode.\n\n"
|
||||
<< "--unfiltered_log: Make log unfiltered.\n\n"
|
||||
<< "--allow-opengl: Allow OpenGL on Windows.\n\n"
|
||||
<< "--version, -V: Get current version.\n";
|
||||
|
||||
exit(0);
|
||||
|
||||
} else if (arg_is(argv[i], "--version", "-V")) {
|
||||
std::cout << "OBS Studio - " <<
|
||||
App()->GetVersionString() << "\n";
|
||||
std::cout << "OBS Studio - "
|
||||
<< App()->GetVersionString() << "\n";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,13 +36,15 @@
|
|||
|
||||
std::string CurrentTimeString();
|
||||
std::string CurrentDateTimeString();
|
||||
std::string GenerateTimeDateFilename(const char *extension, bool noSpace=false);
|
||||
std::string GenerateTimeDateFilename(const char *extension,
|
||||
bool noSpace = false);
|
||||
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace,
|
||||
const char *format);
|
||||
QObject *CreateShortcutFilter();
|
||||
|
||||
struct BaseLexer {
|
||||
lexer lex;
|
||||
|
||||
public:
|
||||
inline BaseLexer() { lexer_init(&lex); }
|
||||
inline ~BaseLexer() { lexer_free(&lex); }
|
||||
|
@ -56,7 +58,8 @@ public:
|
|||
virtual bool isEmpty() const override { return false; }
|
||||
|
||||
virtual QString translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation, int n) const override;
|
||||
const char *disambiguation,
|
||||
int n) const override;
|
||||
};
|
||||
|
||||
typedef std::function<void()> VoidFunc;
|
||||
|
@ -78,7 +81,6 @@ private:
|
|||
|
||||
bool enableHotkeysInFocus = true;
|
||||
|
||||
|
||||
std::deque<obs_frontend_translate_ui_cb> translatorHooks;
|
||||
|
||||
bool UpdatePre22MultiviewLayout(const char *layout);
|
||||
|
@ -93,8 +95,8 @@ private:
|
|||
QPalette defaultPalette;
|
||||
|
||||
void ParseExtraThemeData(const char *path);
|
||||
void AddExtraThemeColor(QPalette &pal, int group,
|
||||
const char *name, uint32_t color);
|
||||
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
|
||||
uint32_t color);
|
||||
|
||||
public:
|
||||
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
|
||||
|
@ -109,10 +111,7 @@ public:
|
|||
|
||||
inline config_t *GlobalConfig() const { return globalConfig; }
|
||||
|
||||
inline const char *GetLocale() const
|
||||
{
|
||||
return locale.c_str();
|
||||
}
|
||||
inline const char *GetLocale() const { return locale.c_str(); }
|
||||
|
||||
inline const char *GetTheme() const { return theme.c_str(); }
|
||||
bool SetTheme(std::string name, std::string path = "");
|
||||
|
@ -146,15 +145,18 @@ public:
|
|||
|
||||
inline void IncrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor) return;
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs++ == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, true);
|
||||
}
|
||||
|
||||
inline void DecrementSleepInhibition()
|
||||
{
|
||||
if (!sleepInhibitor) return;
|
||||
if (sleepInhibitRefs == 0) return;
|
||||
if (!sleepInhibitor)
|
||||
return;
|
||||
if (sleepInhibitRefs == 0)
|
||||
return;
|
||||
if (--sleepInhibitRefs == 0)
|
||||
os_inhibit_sleep_set_active(sleepInhibitor, false);
|
||||
}
|
||||
|
@ -164,10 +166,7 @@ public:
|
|||
translatorHooks.emplace_front(cb);
|
||||
}
|
||||
|
||||
inline void PopUITranslation()
|
||||
{
|
||||
translatorHooks.pop_front();
|
||||
}
|
||||
inline void PopUITranslation() { translatorHooks.pop_front(); }
|
||||
|
||||
public slots:
|
||||
void Exec(VoidFunc func);
|
||||
|
@ -182,12 +181,21 @@ char *GetConfigPathPtr(const char *name);
|
|||
int GetProgramDataPath(char *path, size_t size, const char *name);
|
||||
char *GetProgramDataPathPtr(const char *name);
|
||||
|
||||
inline OBSApp *App() {return static_cast<OBSApp*>(qApp);}
|
||||
inline OBSApp *App()
|
||||
{
|
||||
return static_cast<OBSApp *>(qApp);
|
||||
}
|
||||
|
||||
inline config_t *GetGlobalConfig() {return App()->GlobalConfig();}
|
||||
inline config_t *GetGlobalConfig()
|
||||
{
|
||||
return App()->GlobalConfig();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> GetLocaleNames();
|
||||
inline const char *Str(const char *lookup) {return App()->GetString(lookup);}
|
||||
inline const char *Str(const char *lookup)
|
||||
{
|
||||
return App()->GetString(lookup);
|
||||
}
|
||||
#define QTStr(lookupVal) QString::fromUtf8(Str(lookupVal))
|
||||
|
||||
bool GetFileSafeName(const char *name, std::string &file);
|
||||
|
@ -197,8 +205,8 @@ bool WindowPositionValid(QRect rect);
|
|||
|
||||
static inline int GetProfilePath(char *path, size_t size, const char *file)
|
||||
{
|
||||
OBSMainWindow *window = reinterpret_cast<OBSMainWindow*>(
|
||||
App()->GetMainWindow());
|
||||
OBSMainWindow *window =
|
||||
reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
|
||||
return window->GetProfilePath(path, size, file);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,22 +59,19 @@ static char **convert_string_list(vector<string> &strings)
|
|||
|
||||
void *obs_frontend_get_main_window(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_main_window()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_main_window()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void *obs_frontend_get_main_window_handle(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_main_window_handle()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_main_window_handle()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void *obs_frontend_get_system_tray(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_system_tray()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_system_tray()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -99,30 +96,31 @@ char **obs_frontend_get_scene_names(void)
|
|||
|
||||
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_get_scenes(sources);
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_get_scenes(sources);
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_scene(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_scene()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_current_scene()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_scene(obs_source_t *scene)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_set_current_scene(scene);
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_set_current_scene(scene);
|
||||
}
|
||||
|
||||
void obs_frontend_get_transitions(struct obs_frontend_source_list *sources)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_get_transitions(sources);
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_get_transitions(sources);
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_transition(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_transition()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_current_transition()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -134,8 +132,7 @@ void obs_frontend_set_current_transition(obs_source_t *transition)
|
|||
|
||||
int obs_frontend_get_transition_duration(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_transition_duration()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_transition_duration()
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
@ -170,8 +167,7 @@ void obs_frontend_set_current_scene_collection(const char *collection)
|
|||
|
||||
bool obs_frontend_add_scene_collection(const char *name)
|
||||
{
|
||||
return callbacks_valid()
|
||||
? c->obs_frontend_add_scene_collection(name)
|
||||
return callbacks_valid() ? c->obs_frontend_add_scene_collection(name)
|
||||
: false;
|
||||
}
|
||||
|
||||
|
@ -187,8 +183,7 @@ char **obs_frontend_get_profiles(void)
|
|||
|
||||
char *obs_frontend_get_current_profile(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_profile()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_current_profile()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -200,57 +195,59 @@ void obs_frontend_set_current_profile(const char *profile)
|
|||
|
||||
void obs_frontend_streaming_start(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_streaming_start();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_streaming_start();
|
||||
}
|
||||
|
||||
void obs_frontend_streaming_stop(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_streaming_stop();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_streaming_stop();
|
||||
}
|
||||
|
||||
bool obs_frontend_streaming_active(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_streaming_active()
|
||||
: false;
|
||||
return !!callbacks_valid() ? c->obs_frontend_streaming_active() : false;
|
||||
}
|
||||
|
||||
void obs_frontend_recording_start(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_recording_start();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_recording_start();
|
||||
}
|
||||
|
||||
void obs_frontend_recording_stop(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_recording_stop();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_recording_stop();
|
||||
}
|
||||
|
||||
bool obs_frontend_recording_active(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_recording_active()
|
||||
: false;
|
||||
return !!callbacks_valid() ? c->obs_frontend_recording_active() : false;
|
||||
}
|
||||
|
||||
void obs_frontend_replay_buffer_start(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_replay_buffer_start();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_replay_buffer_start();
|
||||
}
|
||||
|
||||
void obs_frontend_replay_buffer_save(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_replay_buffer_save();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_replay_buffer_save();
|
||||
}
|
||||
|
||||
void obs_frontend_replay_buffer_stop(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_replay_buffer_stop();
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_replay_buffer_stop();
|
||||
}
|
||||
|
||||
bool obs_frontend_replay_buffer_active(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_replay_buffer_active()
|
||||
return !!callbacks_valid() ? c->obs_frontend_replay_buffer_active()
|
||||
: false;
|
||||
}
|
||||
|
||||
|
@ -262,7 +259,8 @@ void *obs_frontend_add_tools_menu_qaction(const char *name)
|
|||
}
|
||||
|
||||
void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data)
|
||||
obs_frontend_cb callback,
|
||||
void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_add_tools_menu_item(name, callback,
|
||||
|
@ -271,9 +269,7 @@ void obs_frontend_add_tools_menu_item(const char *name,
|
|||
|
||||
void *obs_frontend_add_dock(void *dock)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_add_dock(dock)
|
||||
: nullptr;
|
||||
return !!callbacks_valid() ? c->obs_frontend_add_dock(dock) : nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
|
||||
|
@ -292,36 +288,31 @@ void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
|
|||
|
||||
obs_output_t *obs_frontend_get_streaming_output(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_streaming_output()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_streaming_output()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_recording_output(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_recording_output()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_recording_output()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_replay_buffer_output(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_replay_buffer_output()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_replay_buffer_output()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_profile_config(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_profile_config()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_profile_config()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_global_config(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_global_config()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_global_config()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -391,8 +382,7 @@ void obs_frontend_set_streaming_service(obs_service_t *service)
|
|||
|
||||
obs_service_t *obs_frontend_get_streaming_service(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_streaming_service()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_streaming_service()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
@ -429,15 +419,12 @@ void obs_frontend_set_preview_enabled(bool enable)
|
|||
|
||||
bool obs_frontend_preview_enabled(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_preview_enabled()
|
||||
: false;
|
||||
return !!callbacks_valid() ? c->obs_frontend_preview_enabled() : false;
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_preview_scene(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_preview_scene()
|
||||
return !!callbacks_valid() ? c->obs_frontend_get_current_preview_scene()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ enum obs_frontend_event {
|
|||
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED,
|
||||
|
||||
OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP,
|
||||
OBS_FRONTEND_EVENT_FINISHED_LOADING
|
||||
OBS_FRONTEND_EVENT_FINISHED_LOADING,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -54,8 +54,8 @@ struct obs_frontend_source_list {
|
|||
DARRAY(obs_source_t *) sources;
|
||||
};
|
||||
|
||||
static inline void obs_frontend_source_list_free(
|
||||
struct obs_frontend_source_list *source_list)
|
||||
static inline void
|
||||
obs_frontend_source_list_free(struct obs_frontend_source_list *source_list)
|
||||
{
|
||||
size_t num = source_list->sources.num;
|
||||
for (size_t i = 0; i < num; i++)
|
||||
|
@ -89,8 +89,8 @@ EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources);
|
|||
EXPORT obs_source_t *obs_frontend_get_current_scene(void);
|
||||
EXPORT void obs_frontend_set_current_scene(obs_source_t *scene);
|
||||
|
||||
EXPORT void obs_frontend_get_transitions(
|
||||
struct obs_frontend_source_list *sources);
|
||||
EXPORT void
|
||||
obs_frontend_get_transitions(struct obs_frontend_source_list *sources);
|
||||
EXPORT obs_source_t *obs_frontend_get_current_transition(void);
|
||||
EXPORT void obs_frontend_set_current_transition(obs_source_t *transition);
|
||||
EXPORT int obs_frontend_get_transition_duration(void);
|
||||
|
@ -109,7 +109,8 @@ typedef void (*obs_frontend_cb)(void *private_data);
|
|||
|
||||
EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name);
|
||||
EXPORT void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data);
|
||||
obs_frontend_cb callback,
|
||||
void *private_data);
|
||||
|
||||
/* takes QDockWidget and returns QAction */
|
||||
EXPORT void *obs_frontend_add_dock(void *dock);
|
||||
|
@ -138,8 +139,8 @@ EXPORT void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
|
|||
typedef bool (*obs_frontend_translate_ui_cb)(const char *text,
|
||||
const char **out);
|
||||
|
||||
EXPORT void obs_frontend_push_ui_translation(
|
||||
obs_frontend_translate_ui_cb translate);
|
||||
EXPORT void
|
||||
obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate);
|
||||
EXPORT void obs_frontend_pop_ui_translation(void);
|
||||
|
||||
#endif //!SWIG
|
||||
|
|
|
@ -11,28 +11,28 @@ struct obs_frontend_callbacks {
|
|||
virtual void *obs_frontend_get_main_window_handle(void) = 0;
|
||||
virtual void *obs_frontend_get_system_tray(void) = 0;
|
||||
|
||||
virtual void obs_frontend_get_scenes(
|
||||
struct obs_frontend_source_list *sources)=0;
|
||||
virtual void
|
||||
obs_frontend_get_scenes(struct obs_frontend_source_list *sources) = 0;
|
||||
virtual obs_source_t *obs_frontend_get_current_scene(void) = 0;
|
||||
virtual void obs_frontend_set_current_scene(obs_source_t *scene) = 0;
|
||||
|
||||
virtual void obs_frontend_get_transitions(
|
||||
struct obs_frontend_source_list *sources) = 0;
|
||||
virtual obs_source_t *obs_frontend_get_current_transition(void) = 0;
|
||||
virtual void obs_frontend_set_current_transition(
|
||||
obs_source_t *transition)=0;
|
||||
virtual void
|
||||
obs_frontend_set_current_transition(obs_source_t *transition) = 0;
|
||||
virtual int obs_frontend_get_transition_duration(void) = 0;
|
||||
virtual void obs_frontend_set_transition_duration(int duration) = 0;
|
||||
|
||||
virtual void obs_frontend_get_scene_collections(
|
||||
std::vector<std::string> &strings) = 0;
|
||||
virtual char *obs_frontend_get_current_scene_collection(void) = 0;
|
||||
virtual void obs_frontend_set_current_scene_collection(
|
||||
const char *collection)=0;
|
||||
virtual void
|
||||
obs_frontend_set_current_scene_collection(const char *collection) = 0;
|
||||
virtual bool obs_frontend_add_scene_collection(const char *name) = 0;
|
||||
|
||||
virtual void obs_frontend_get_profiles(
|
||||
std::vector<std::string> &strings)=0;
|
||||
virtual void
|
||||
obs_frontend_get_profiles(std::vector<std::string> &strings) = 0;
|
||||
virtual char *obs_frontend_get_current_profile(void) = 0;
|
||||
virtual void obs_frontend_set_current_profile(const char *profile) = 0;
|
||||
|
||||
|
@ -51,14 +51,17 @@ struct obs_frontend_callbacks {
|
|||
|
||||
virtual void *obs_frontend_add_tools_menu_qaction(const char *name) = 0;
|
||||
virtual void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data)=0;
|
||||
obs_frontend_cb callback,
|
||||
void *private_data) = 0;
|
||||
|
||||
virtual void *obs_frontend_add_dock(void *dock) = 0;
|
||||
|
||||
virtual void obs_frontend_add_event_callback(
|
||||
obs_frontend_event_cb callback, void *private_data)=0;
|
||||
virtual void obs_frontend_remove_event_callback(
|
||||
obs_frontend_event_cb callback, void *private_data)=0;
|
||||
virtual void
|
||||
obs_frontend_add_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data) = 0;
|
||||
virtual void
|
||||
obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data) = 0;
|
||||
|
||||
virtual obs_output_t *obs_frontend_get_streaming_output(void) = 0;
|
||||
virtual obs_output_t *obs_frontend_get_recording_output(void) = 0;
|
||||
|
@ -70,22 +73,26 @@ struct obs_frontend_callbacks {
|
|||
virtual void obs_frontend_save(void) = 0;
|
||||
virtual void obs_frontend_defer_save_begin(void) = 0;
|
||||
virtual void obs_frontend_defer_save_end(void) = 0;
|
||||
virtual void obs_frontend_add_save_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
virtual void obs_frontend_remove_save_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
virtual void
|
||||
obs_frontend_add_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) = 0;
|
||||
virtual void
|
||||
obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) = 0;
|
||||
|
||||
virtual void obs_frontend_add_preload_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
virtual void obs_frontend_remove_preload_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
virtual void
|
||||
obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) = 0;
|
||||
virtual void
|
||||
obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
|
||||
void *private_data) = 0;
|
||||
|
||||
virtual void obs_frontend_push_ui_translation(
|
||||
obs_frontend_translate_ui_cb translate) = 0;
|
||||
virtual void obs_frontend_pop_ui_translation(void) = 0;
|
||||
|
||||
virtual void obs_frontend_set_streaming_service(
|
||||
obs_service_t *service)=0;
|
||||
virtual void
|
||||
obs_frontend_set_streaming_service(obs_service_t *service) = 0;
|
||||
virtual obs_service_t *obs_frontend_get_streaming_service(void) = 0;
|
||||
virtual void obs_frontend_save_streaming_service() = 0;
|
||||
|
||||
|
@ -97,7 +104,8 @@ struct obs_frontend_callbacks {
|
|||
virtual void obs_frontend_set_preview_enabled(bool enable) = 0;
|
||||
|
||||
virtual obs_source_t *obs_frontend_get_current_preview_scene(void) = 0;
|
||||
virtual void obs_frontend_set_current_preview_scene(obs_source_t *scene)=0;
|
||||
virtual void
|
||||
obs_frontend_set_current_preview_scene(obs_source_t *scene) = 0;
|
||||
|
||||
virtual void on_load(obs_data_t *settings) = 0;
|
||||
virtual void on_preload(obs_data_t *settings) = 0;
|
||||
|
@ -105,5 +113,5 @@ struct obs_frontend_callbacks {
|
|||
virtual void on_event(enum obs_frontend_event event) = 0;
|
||||
};
|
||||
|
||||
EXPORT void obs_frontend_set_callbacks_internal(
|
||||
obs_frontend_callbacks *callbacks);
|
||||
EXPORT void
|
||||
obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks);
|
||||
|
|
|
@ -79,8 +79,8 @@ static vector<string> GetUserPreferredLocales()
|
|||
vector<string> result;
|
||||
|
||||
ULONG num, length = 0;
|
||||
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
|
||||
nullptr, &length))
|
||||
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, nullptr,
|
||||
&length))
|
||||
return result;
|
||||
|
||||
vector<wchar_t> buffer(length);
|
||||
|
@ -176,8 +176,8 @@ void SetAeroEnabled(bool enable)
|
|||
return;
|
||||
}
|
||||
|
||||
func = reinterpret_cast<decltype(func)>(GetProcAddress(dwm,
|
||||
"DwmEnableComposition"));
|
||||
func = reinterpret_cast<decltype(func)>(
|
||||
GetProcAddress(dwm, "DwmEnableComposition"));
|
||||
if (!func) {
|
||||
failed = true;
|
||||
return;
|
||||
|
@ -208,11 +208,13 @@ void SetProcessPriority(const char *priority)
|
|||
if (strcmp(priority, "High") == 0)
|
||||
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
else if (strcmp(priority, "AboveNormal") == 0)
|
||||
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
|
||||
SetPriorityClass(GetCurrentProcess(),
|
||||
ABOVE_NORMAL_PRIORITY_CLASS);
|
||||
else if (strcmp(priority, "Normal") == 0)
|
||||
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
|
||||
else if (strcmp(priority, "BelowNormal") == 0)
|
||||
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
|
||||
SetPriorityClass(GetCurrentProcess(),
|
||||
BELOW_NORMAL_PRIORITY_CLASS);
|
||||
else if (strcmp(priority, "Idle") == 0)
|
||||
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
|
||||
}
|
||||
|
@ -233,8 +235,8 @@ bool DisableAudioDucking(bool disable)
|
|||
ComPtr<IAudioSessionControl> sessionControl;
|
||||
ComPtr<IAudioSessionControl2> sessionControl2;
|
||||
|
||||
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator),
|
||||
nullptr, CLSCTX_INPROC_SERVER,
|
||||
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IMMDeviceEnumerator),
|
||||
(void **)&devEmum);
|
||||
if (FAILED(result))
|
||||
|
|
|
@ -48,6 +48,7 @@ struct RunOnceMutexData;
|
|||
|
||||
class RunOnceMutex {
|
||||
RunOnceMutexData *data = nullptr;
|
||||
|
||||
public:
|
||||
RunOnceMutex(RunOnceMutexData *data_) : data(data_) {}
|
||||
RunOnceMutex(const RunOnceMutex &rom) = delete;
|
||||
|
|
|
@ -37,23 +37,18 @@ using namespace std;
|
|||
|
||||
static inline QColor color_from_int(long long val)
|
||||
{
|
||||
return QColor( val & 0xff,
|
||||
(val >> 8) & 0xff,
|
||||
(val >> 16) & 0xff,
|
||||
return QColor(val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff,
|
||||
(val >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static inline long long color_to_int(QColor color)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift) {
|
||||
return ((val & 0xff) << shift);
|
||||
};
|
||||
|
||||
return shift(color.red(), 0) |
|
||||
shift(color.green(), 8) |
|
||||
shift(color.blue(), 16) |
|
||||
shift(color.alpha(), 24);
|
||||
return shift(color.red(), 0) | shift(color.green(), 8) |
|
||||
shift(color.blue(), 16) | shift(color.alpha(), 24);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -68,14 +63,9 @@ struct frame_rate_tag {
|
|||
|
||||
frame_rate_tag() = default;
|
||||
|
||||
explicit frame_rate_tag(tag_type type)
|
||||
: type(type)
|
||||
{}
|
||||
explicit frame_rate_tag(tag_type type) : type(type) {}
|
||||
|
||||
explicit frame_rate_tag(const char *val)
|
||||
: type(USER),
|
||||
val(val)
|
||||
{}
|
||||
explicit frame_rate_tag(const char *val) : type(USER), val(val) {}
|
||||
|
||||
static frame_rate_tag simple() { return frame_rate_tag{SIMPLE}; }
|
||||
static frame_rate_tag rational() { return frame_rate_tag{RATIONAL}; }
|
||||
|
@ -182,7 +172,8 @@ void OBSPropertiesView::GetScrollPos(int &h, int &v)
|
|||
|
||||
OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj_,
|
||||
PropertiesReloadCallback reloadCallback,
|
||||
PropertiesUpdateCallback callback_, int minSize_)
|
||||
PropertiesUpdateCallback callback_,
|
||||
int minSize_)
|
||||
: VScrollArea(nullptr),
|
||||
properties(nullptr, obs_properties_destroy),
|
||||
settings(settings_),
|
||||
|
@ -196,7 +187,8 @@ OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj_,
|
|||
}
|
||||
|
||||
OBSPropertiesView::OBSPropertiesView(OBSData settings_, const char *type_,
|
||||
PropertiesReloadCallback reloadCallback_, int minSize_)
|
||||
PropertiesReloadCallback reloadCallback_,
|
||||
int minSize_)
|
||||
: VScrollArea(nullptr),
|
||||
properties(nullptr, obs_properties_destroy),
|
||||
settings(settings_),
|
||||
|
@ -263,10 +255,9 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
|
|||
subLayout->addWidget(show);
|
||||
|
||||
WidgetInfo *info = new WidgetInfo(this, prop, edit);
|
||||
connect(show, &QAbstractButton::toggled,
|
||||
info, &WidgetInfo::TogglePasswordText);
|
||||
connect(show, &QAbstractButton::toggled, [=](bool hide)
|
||||
{
|
||||
connect(show, &QAbstractButton::toggled, info,
|
||||
&WidgetInfo::TogglePasswordText);
|
||||
connect(show, &QAbstractButton::toggled, [=](bool hide) {
|
||||
show->setText(hide ? QTStr("Hide") : QTStr("Show"));
|
||||
});
|
||||
children.emplace_back(info);
|
||||
|
@ -276,8 +267,8 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
|
|||
|
||||
edit->setToolTip(QT_UTF8(obs_property_long_description(prop)));
|
||||
|
||||
connect(edit, SIGNAL(textEdited(const QString &)),
|
||||
info, SLOT(ControlChanged()));
|
||||
connect(edit, SIGNAL(textEdited(const QString &)), info,
|
||||
SLOT(ControlChanged()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -356,10 +347,10 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout,
|
|||
slider->setOrientation(Qt::Horizontal);
|
||||
subLayout->addWidget(slider);
|
||||
|
||||
connect(slider, SIGNAL(valueChanged(int)),
|
||||
spin, SLOT(setValue(int)));
|
||||
connect(spin, SIGNAL(valueChanged(int)),
|
||||
slider, SLOT(setValue(int)));
|
||||
connect(slider, SIGNAL(valueChanged(int)), spin,
|
||||
SLOT(setValue(int)));
|
||||
connect(spin, SIGNAL(valueChanged(int)), slider,
|
||||
SLOT(setValue(int)));
|
||||
}
|
||||
|
||||
connect(spin, SIGNAL(valueChanged(int)), info, SLOT(ControlChanged()));
|
||||
|
@ -404,10 +395,10 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout,
|
|||
slider->setOrientation(Qt::Horizontal);
|
||||
subLayout->addWidget(slider);
|
||||
|
||||
connect(slider, SIGNAL(doubleValChanged(double)),
|
||||
spin, SLOT(setValue(double)));
|
||||
connect(spin, SIGNAL(valueChanged(double)),
|
||||
slider, SLOT(setDoubleVal(double)));
|
||||
connect(slider, SIGNAL(doubleValChanged(double)), spin,
|
||||
SLOT(setValue(double)));
|
||||
connect(spin, SIGNAL(valueChanged(double)), slider,
|
||||
SLOT(setDoubleVal(double)));
|
||||
}
|
||||
|
||||
connect(spin, SIGNAL(valueChanged(double)), info,
|
||||
|
@ -485,7 +476,8 @@ static string from_obs_data_autoselect(obs_data_t *data, const char *name,
|
|||
{
|
||||
return from_obs_data<obs_data_get_autoselect_int,
|
||||
obs_data_get_autoselect_double,
|
||||
obs_data_get_autoselect_string>(data, name, format);
|
||||
obs_data_get_autoselect_string>(data, name,
|
||||
format);
|
||||
}
|
||||
|
||||
QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
|
||||
|
@ -537,7 +529,6 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
QAbstractItemModel *model = combo->model();
|
||||
warning = idx != -1 &&
|
||||
model->flags(model->index(idx, 0)) == Qt::NoItemFlags;
|
||||
|
@ -554,8 +545,7 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
|
|||
return combo;
|
||||
}
|
||||
|
||||
static void NewButton(QLayout *layout, WidgetInfo *info,
|
||||
const char *themeIcon,
|
||||
static void NewButton(QLayout *layout, WidgetInfo *info, const char *themeIcon,
|
||||
void (WidgetInfo::*method)())
|
||||
{
|
||||
QPushButton *button = new QPushButton();
|
||||
|
@ -597,8 +587,7 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
|
|||
WidgetInfo *info = new WidgetInfo(this, prop, list);
|
||||
|
||||
QVBoxLayout *sideLayout = new QVBoxLayout();
|
||||
NewButton(sideLayout, info, "addIconSmall",
|
||||
&WidgetInfo::EditListAdd);
|
||||
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
|
||||
NewButton(sideLayout, info, "removeIconSmall",
|
||||
&WidgetInfo::EditListRemove);
|
||||
NewButton(sideLayout, info, "configIconSmall",
|
||||
|
@ -657,8 +646,10 @@ void OBSPropertiesView::AddColor(obs_property_t *prop, QFormLayout *layout,
|
|||
colorLabel->setPalette(palette);
|
||||
colorLabel->setStyleSheet(
|
||||
QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexArgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexArgb)));
|
||||
.arg(palette.color(QPalette::Window)
|
||||
.name(QColor::HexArgb))
|
||||
.arg(palette.color(QPalette::WindowText)
|
||||
.name(QColor::HexArgb)));
|
||||
colorLabel->setAutoFillBackground(true);
|
||||
colorLabel->setAlignment(Qt::AlignCenter);
|
||||
colorLabel->setToolTip(QT_UTF8(obs_property_long_description(prop)));
|
||||
|
@ -692,16 +683,22 @@ static void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false)
|
|||
if (size) {
|
||||
if (limit) {
|
||||
int max_size = font.pointSize();
|
||||
if (max_size < 28) max_size = 28;
|
||||
if (size > max_size) size = max_size;
|
||||
if (max_size < 28)
|
||||
max_size = 28;
|
||||
if (size > max_size)
|
||||
size = max_size;
|
||||
}
|
||||
font.setPointSize(size);
|
||||
}
|
||||
|
||||
if (flags & OBS_FONT_BOLD) font.setBold(true);
|
||||
if (flags & OBS_FONT_ITALIC) font.setItalic(true);
|
||||
if (flags & OBS_FONT_UNDERLINE) font.setUnderline(true);
|
||||
if (flags & OBS_FONT_STRIKEOUT) font.setStrikeOut(true);
|
||||
if (flags & OBS_FONT_BOLD)
|
||||
font.setBold(true);
|
||||
if (flags & OBS_FONT_ITALIC)
|
||||
font.setItalic(true);
|
||||
if (flags & OBS_FONT_UNDERLINE)
|
||||
font.setUnderline(true);
|
||||
if (flags & OBS_FONT_STRIKEOUT)
|
||||
font.setStrikeOut(true);
|
||||
}
|
||||
|
||||
void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
|
||||
|
@ -751,26 +748,17 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
|
|||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct default_delete<obs_data_t> {
|
||||
void operator()(obs_data_t *data)
|
||||
{
|
||||
obs_data_release(data);
|
||||
}
|
||||
template<> struct default_delete<obs_data_t> {
|
||||
void operator()(obs_data_t *data) { obs_data_release(data); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_delete<obs_data_item_t> {
|
||||
void operator()(obs_data_item_t *item)
|
||||
{
|
||||
obs_data_item_release(&item);
|
||||
}
|
||||
template<> struct default_delete<obs_data_item_t> {
|
||||
void operator()(obs_data_item_t *item) { obs_data_item_release(&item); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static double make_epsilon(T val)
|
||||
template<typename T> static double make_epsilon(T val)
|
||||
{
|
||||
return val * 0.00001;
|
||||
}
|
||||
|
@ -793,7 +781,8 @@ static bool matches_range(media_frames_per_second &match,
|
|||
|
||||
static bool matches_ranges(media_frames_per_second &best_match,
|
||||
media_frames_per_second fps,
|
||||
const frame_rate_ranges_t &fps_ranges, bool exact=false)
|
||||
const frame_rate_ranges_t &fps_ranges,
|
||||
bool exact = false)
|
||||
{
|
||||
auto convert_fn = media_frames_per_second_to_frame_interval;
|
||||
auto val = convert_fn(fps);
|
||||
|
@ -830,7 +819,6 @@ static bool matches_ranges(media_frames_per_second &best_match,
|
|||
match = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return match;
|
||||
|
@ -845,15 +833,9 @@ static media_frames_per_second make_fps(uint32_t num, uint32_t den)
|
|||
}
|
||||
|
||||
static const common_frame_rate common_fps[] = {
|
||||
{"60", {60, 1}},
|
||||
{"59.94", {60000, 1001}},
|
||||
{"50", {50, 1}},
|
||||
{"48", {48, 1}},
|
||||
{"30", {30, 1}},
|
||||
{"29.97", {30000, 1001}},
|
||||
{"25", {25, 1}},
|
||||
{"24", {24, 1}},
|
||||
{"23.976", {24000, 1001}},
|
||||
{"60", {60, 1}}, {"59.94", {60000, 1001}}, {"50", {50, 1}},
|
||||
{"48", {48, 1}}, {"30", {30, 1}}, {"29.97", {30000, 1001}},
|
||||
{"25", {25, 1}}, {"24", {24, 1}}, {"23.976", {24000, 1001}},
|
||||
};
|
||||
|
||||
static void UpdateSimpleFPSSelection(OBSFrameRatePropertyWidget *fpsProps,
|
||||
|
@ -885,8 +867,7 @@ static void UpdateSimpleFPSSelection(OBSFrameRatePropertyWidget *fpsProps,
|
|||
static void AddFPSRanges(vector<common_frame_rate> &items,
|
||||
const frame_rate_ranges_t &ranges)
|
||||
{
|
||||
auto InsertFPS = [&](media_frames_per_second fps)
|
||||
{
|
||||
auto InsertFPS = [&](media_frames_per_second fps) {
|
||||
auto fps_val = media_frames_per_second_to_fps(fps);
|
||||
|
||||
auto end_ = end(items);
|
||||
|
@ -911,8 +892,9 @@ static void AddFPSRanges(vector<common_frame_rate> &items,
|
|||
}
|
||||
}
|
||||
|
||||
static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps,
|
||||
bool &selected, const media_frames_per_second *current_fps)
|
||||
static QWidget *
|
||||
CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, bool &selected,
|
||||
const media_frames_per_second *current_fps)
|
||||
{
|
||||
auto widget = new QWidget{};
|
||||
widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
@ -938,10 +920,11 @@ static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps,
|
|||
|
||||
for (const auto &item : items) {
|
||||
auto var = QVariant::fromValue(item.fps);
|
||||
auto name = item.fps_name ?
|
||||
QString(item.fps_name) :
|
||||
QString("%1")
|
||||
.arg(media_frames_per_second_to_fps(item.fps));
|
||||
auto name = item.fps_name
|
||||
? QString(item.fps_name)
|
||||
: QString("%1").arg(
|
||||
media_frames_per_second_to_fps(
|
||||
item.fps));
|
||||
combo->addItem(name, var);
|
||||
|
||||
bool select = current_fps && *current_fps == item.fps;
|
||||
|
@ -991,7 +974,8 @@ static void UpdateRationalFPSWidgets(OBSFrameRatePropertyWidget *fpsProps,
|
|||
}
|
||||
|
||||
static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps,
|
||||
bool &selected, const media_frames_per_second *current_fps)
|
||||
bool &selected,
|
||||
const media_frames_per_second *current_fps)
|
||||
{
|
||||
auto widget = new QWidget{};
|
||||
widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
@ -1043,8 +1027,8 @@ static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps,
|
|||
return widget;
|
||||
}
|
||||
|
||||
static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop,
|
||||
bool &warning, const char *option,
|
||||
static OBSFrameRatePropertyWidget *
|
||||
CreateFrameRateWidget(obs_property_t *prop, bool &warning, const char *option,
|
||||
media_frames_per_second *current_fps,
|
||||
frame_rate_ranges_t &fps_ranges)
|
||||
{
|
||||
|
@ -1084,8 +1068,7 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop,
|
|||
auto stack = widget->modeDisplay = new QStackedWidget{};
|
||||
|
||||
bool match_found = option_found;
|
||||
auto AddWidget = [&](decltype(CreateRationalFPS) func)
|
||||
{
|
||||
auto AddWidget = [&](decltype(CreateRationalFPS) func) {
|
||||
bool selected = false;
|
||||
stack->addWidget(func(widget, selected, current_fps));
|
||||
|
||||
|
@ -1149,16 +1132,14 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop,
|
|||
|
||||
static void UpdateMinMaxLabels(OBSFrameRatePropertyWidget *w)
|
||||
{
|
||||
auto Hide = [&](bool hide)
|
||||
{
|
||||
auto Hide = [&](bool hide) {
|
||||
w->minLabel->setHidden(hide);
|
||||
w->maxLabel->setHidden(hide);
|
||||
};
|
||||
|
||||
auto variant = w->modeSelect->currentData();
|
||||
if (!variant.canConvert<frame_rate_tag>() ||
|
||||
variant.value<frame_rate_tag>().type !=
|
||||
frame_rate_tag::RATIONAL) {
|
||||
variant.value<frame_rate_tag>().type != frame_rate_tag::RATIONAL) {
|
||||
Hide(true);
|
||||
return;
|
||||
}
|
||||
|
@ -1199,8 +1180,7 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w)
|
|||
media_frames_per_second *valid_fps = nullptr;
|
||||
if (obs_data_item_get_autoselect_frames_per_second(obj.get(), &fps,
|
||||
nullptr) ||
|
||||
obs_data_item_get_frames_per_second(obj.get(), &fps,
|
||||
nullptr))
|
||||
obs_data_item_get_frames_per_second(obj.get(), &fps, nullptr))
|
||||
valid_fps = &fps;
|
||||
|
||||
const char *option = nullptr;
|
||||
|
@ -1229,9 +1209,10 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w)
|
|||
auto convert_to_frame_interval =
|
||||
media_frames_per_second_to_frame_interval;
|
||||
|
||||
w->currentFPS->setText(QString("FPS: %1")
|
||||
.arg(convert_to_fps(*valid_fps)));
|
||||
w->timePerFrame->setText(QString("Frame Interval: %1 ms")
|
||||
w->currentFPS->setText(
|
||||
QString("FPS: %1").arg(convert_to_fps(*valid_fps)));
|
||||
w->timePerFrame->setText(
|
||||
QString("Frame Interval: %1 ms")
|
||||
.arg(convert_to_frame_interval(*valid_fps) * 1000));
|
||||
}
|
||||
|
||||
|
@ -1290,9 +1271,7 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning,
|
|||
|
||||
auto comboIndexChanged = static_cast<void (QComboBox::*)(int)>(
|
||||
&QComboBox::currentIndexChanged);
|
||||
connect(combo, comboIndexChanged, stack,
|
||||
[=](int index)
|
||||
{
|
||||
connect(combo, comboIndexChanged, stack, [=](int index) {
|
||||
bool out_of_bounds = index >= stack->count();
|
||||
auto idx = out_of_bounds ? stack->count() - 1 : index;
|
||||
stack->setCurrentIndex(idx);
|
||||
|
@ -1304,34 +1283,30 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning,
|
|||
emit info->ControlChanged();
|
||||
});
|
||||
|
||||
connect(widget->simpleFPS, comboIndexChanged, [=](int)
|
||||
{
|
||||
connect(widget->simpleFPS, comboIndexChanged, [=](int) {
|
||||
if (widget->updating)
|
||||
return;
|
||||
|
||||
emit info->ControlChanged();
|
||||
});
|
||||
|
||||
connect(widget->fpsRange, comboIndexChanged, [=](int)
|
||||
{
|
||||
connect(widget->fpsRange, comboIndexChanged, [=](int) {
|
||||
if (widget->updating)
|
||||
return;
|
||||
|
||||
UpdateFPSLabels(widget);
|
||||
});
|
||||
|
||||
auto sbValueChanged = static_cast<void (QSpinBox::*)(int)>(
|
||||
&QSpinBox::valueChanged);
|
||||
connect(widget->numEdit, sbValueChanged, [=](int)
|
||||
{
|
||||
auto sbValueChanged =
|
||||
static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged);
|
||||
connect(widget->numEdit, sbValueChanged, [=](int) {
|
||||
if (widget->updating)
|
||||
return;
|
||||
|
||||
emit info->ControlChanged();
|
||||
});
|
||||
|
||||
connect(widget->denEdit, sbValueChanged, [=](int)
|
||||
{
|
||||
connect(widget->denEdit, sbValueChanged, [=](int) {
|
||||
if (widget->updating)
|
||||
return;
|
||||
|
||||
|
@ -1433,10 +1408,8 @@ void OBSPropertiesView::AddProperty(obs_property_t *property,
|
|||
if (widget && !obs_property_enabled(property))
|
||||
widget->setEnabled(false);
|
||||
|
||||
if (!label &&
|
||||
type != OBS_PROPERTY_BOOL &&
|
||||
type != OBS_PROPERTY_BUTTON &&
|
||||
type != OBS_PROPERTY_GROUP)
|
||||
if (!label && type != OBS_PROPERTY_BOOL &&
|
||||
type != OBS_PROPERTY_BUTTON && type != OBS_PROPERTY_GROUP)
|
||||
label = new QLabel(QT_UTF8(obs_property_description(property)));
|
||||
|
||||
if (warning && label) //TODO: select color based on background color
|
||||
|
@ -1466,7 +1439,8 @@ void OBSPropertiesView::SignalChanged()
|
|||
}
|
||||
|
||||
static bool FrameRateChangedVariant(const QVariant &variant,
|
||||
media_frames_per_second &fps, obs_data_item_t *&obj,
|
||||
media_frames_per_second &fps,
|
||||
obs_data_item_t *&obj,
|
||||
const media_frames_per_second *valid_fps)
|
||||
{
|
||||
if (!variant.canConvert<media_frames_per_second>())
|
||||
|
@ -1481,7 +1455,8 @@ static bool FrameRateChangedVariant(const QVariant &variant,
|
|||
}
|
||||
|
||||
static bool FrameRateChangedCommon(OBSFrameRatePropertyWidget *w,
|
||||
obs_data_item_t *&obj, const media_frames_per_second *valid_fps)
|
||||
obs_data_item_t *&obj,
|
||||
const media_frames_per_second *valid_fps)
|
||||
{
|
||||
media_frames_per_second fps{};
|
||||
if (!FrameRateChangedVariant(w->simpleFPS->currentData(), fps, obj,
|
||||
|
@ -1493,7 +1468,8 @@ static bool FrameRateChangedCommon(OBSFrameRatePropertyWidget *w,
|
|||
}
|
||||
|
||||
static bool FrameRateChangedRational(OBSFrameRatePropertyWidget *w,
|
||||
obs_data_item_t *&obj, const media_frames_per_second *valid_fps)
|
||||
obs_data_item_t *&obj,
|
||||
const media_frames_per_second *valid_fps)
|
||||
{
|
||||
auto num = w->numEdit->value();
|
||||
auto den = w->denEdit->value();
|
||||
|
@ -1519,10 +1495,7 @@ static bool FrameRateChanged(QWidget *widget, const char *name,
|
|||
if (!variant.canConvert<frame_rate_tag>())
|
||||
return false;
|
||||
|
||||
auto StopUpdating = [&](void*)
|
||||
{
|
||||
w->updating = false;
|
||||
};
|
||||
auto StopUpdating = [&](void *) { w->updating = false; };
|
||||
unique_ptr<void, decltype(StopUpdating)> signalGuard(
|
||||
static_cast<void *>(w), StopUpdating);
|
||||
w->updating = true;
|
||||
|
@ -1532,8 +1505,7 @@ static bool FrameRateChanged(QWidget *widget, const char *name,
|
|||
|
||||
unique_ptr<obs_data_item_t> obj{obs_data_item_byname(settings, name)};
|
||||
auto obj_ptr = obj.get();
|
||||
auto CheckObj = [&]()
|
||||
{
|
||||
auto CheckObj = [&]() {
|
||||
if (!obj_ptr)
|
||||
obj.release();
|
||||
};
|
||||
|
@ -1614,17 +1586,17 @@ bool WidgetInfo::PathChanged(const char *setting)
|
|||
QString path;
|
||||
|
||||
if (type == OBS_PATH_DIRECTORY)
|
||||
path = QFileDialog::getExistingDirectory(view,
|
||||
QT_UTF8(desc), QT_UTF8(default_path),
|
||||
path = QFileDialog::getExistingDirectory(
|
||||
view, QT_UTF8(desc), QT_UTF8(default_path),
|
||||
QFileDialog::ShowDirsOnly |
|
||||
QFileDialog::DontResolveSymlinks);
|
||||
else if (type == OBS_PATH_FILE)
|
||||
path = QFileDialog::getOpenFileName(view,
|
||||
QT_UTF8(desc), QT_UTF8(default_path),
|
||||
path = QFileDialog::getOpenFileName(view, QT_UTF8(desc),
|
||||
QT_UTF8(default_path),
|
||||
QT_UTF8(filter));
|
||||
else if (type == OBS_PATH_FILE_SAVE)
|
||||
path = QFileDialog::getSaveFileName(view,
|
||||
QT_UTF8(desc), QT_UTF8(default_path),
|
||||
path = QFileDialog::getSaveFileName(view, QT_UTF8(desc),
|
||||
QT_UTF8(default_path),
|
||||
QT_UTF8(filter));
|
||||
|
||||
if (path.isEmpty())
|
||||
|
@ -1697,10 +1669,11 @@ bool WidgetInfo::ColorChanged(const char *setting)
|
|||
label->setText(color.name(QColor::HexArgb));
|
||||
QPalette palette = QPalette(color);
|
||||
label->setPalette(palette);
|
||||
label->setStyleSheet(
|
||||
QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window).name(QColor::HexArgb))
|
||||
.arg(palette.color(QPalette::WindowText).name(QColor::HexArgb)));
|
||||
label->setStyleSheet(QString("background-color :%1; color: %2;")
|
||||
.arg(palette.color(QPalette::Window)
|
||||
.name(QColor::HexArgb))
|
||||
.arg(palette.color(QPalette::WindowText)
|
||||
.name(QColor::HexArgb)));
|
||||
|
||||
obs_data_set_int(view->settings, setting, color_to_int(color));
|
||||
|
||||
|
@ -1722,10 +1695,12 @@ bool WidgetInfo::FontChanged(const char *setting)
|
|||
|
||||
if (!font_obj) {
|
||||
QFont initial;
|
||||
font = QFontDialog::getFont(&success, initial, view, "Pick a Font", options);
|
||||
font = QFontDialog::getFont(&success, initial, view,
|
||||
"Pick a Font", options);
|
||||
} else {
|
||||
MakeQFont(font_obj, font);
|
||||
font = QFontDialog::getFont(&success, font, view, "Pick a Font", options);
|
||||
font = QFontDialog::getFont(&success, font, view, "Pick a Font",
|
||||
options);
|
||||
obs_data_release(font_obj);
|
||||
}
|
||||
|
||||
|
@ -1758,7 +1733,8 @@ void WidgetInfo::GroupChanged(const char *setting)
|
|||
{
|
||||
QGroupBox *groupbox = static_cast<QGroupBox *>(widget);
|
||||
obs_data_set_bool(view->settings, setting,
|
||||
groupbox->isCheckable() ? groupbox->isChecked() : true);
|
||||
groupbox->isCheckable() ? groupbox->isChecked()
|
||||
: true);
|
||||
}
|
||||
|
||||
void WidgetInfo::EditableListChanged()
|
||||
|
@ -1772,10 +1748,8 @@ void WidgetInfo::EditableListChanged()
|
|||
obs_data_t *arrayItem = obs_data_create();
|
||||
obs_data_set_string(arrayItem, "value",
|
||||
QT_TO_UTF8(item->text()));
|
||||
obs_data_set_bool(arrayItem, "selected",
|
||||
item->isSelected());
|
||||
obs_data_set_bool(arrayItem, "hidden",
|
||||
item->isHidden());
|
||||
obs_data_set_bool(arrayItem, "selected", item->isSelected());
|
||||
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
|
||||
obs_data_array_push_back(array, arrayItem);
|
||||
obs_data_release(arrayItem);
|
||||
}
|
||||
|
@ -1806,13 +1780,26 @@ void WidgetInfo::ControlChanged()
|
|||
obs_property_type type = obs_property_get_type(property);
|
||||
|
||||
switch (type) {
|
||||
case OBS_PROPERTY_INVALID: return;
|
||||
case OBS_PROPERTY_BOOL: BoolChanged(setting); break;
|
||||
case OBS_PROPERTY_INT: IntChanged(setting); break;
|
||||
case OBS_PROPERTY_FLOAT: FloatChanged(setting); break;
|
||||
case OBS_PROPERTY_TEXT: TextChanged(setting); break;
|
||||
case OBS_PROPERTY_LIST: ListChanged(setting); break;
|
||||
case OBS_PROPERTY_BUTTON: ButtonClicked(); return;
|
||||
case OBS_PROPERTY_INVALID:
|
||||
return;
|
||||
case OBS_PROPERTY_BOOL:
|
||||
BoolChanged(setting);
|
||||
break;
|
||||
case OBS_PROPERTY_INT:
|
||||
IntChanged(setting);
|
||||
break;
|
||||
case OBS_PROPERTY_FLOAT:
|
||||
FloatChanged(setting);
|
||||
break;
|
||||
case OBS_PROPERTY_TEXT:
|
||||
TextChanged(setting);
|
||||
break;
|
||||
case OBS_PROPERTY_LIST:
|
||||
ListChanged(setting);
|
||||
break;
|
||||
case OBS_PROPERTY_BUTTON:
|
||||
ButtonClicked();
|
||||
return;
|
||||
case OBS_PROPERTY_COLOR:
|
||||
if (!ColorChanged(setting))
|
||||
return;
|
||||
|
@ -1825,12 +1812,15 @@ void WidgetInfo::ControlChanged()
|
|||
if (!PathChanged(setting))
|
||||
return;
|
||||
break;
|
||||
case OBS_PROPERTY_EDITABLE_LIST: break;
|
||||
case OBS_PROPERTY_EDITABLE_LIST:
|
||||
break;
|
||||
case OBS_PROPERTY_FRAME_RATE:
|
||||
if (!FrameRateChanged(widget, setting, view->settings))
|
||||
return;
|
||||
break;
|
||||
case OBS_PROPERTY_GROUP: GroupChanged(setting); return;
|
||||
case OBS_PROPERTY_GROUP:
|
||||
GroupChanged(setting);
|
||||
return;
|
||||
}
|
||||
|
||||
if (view->callback && !view->deferUpdate)
|
||||
|
@ -1858,8 +1848,8 @@ class EditableItemDialog : public QDialog {
|
|||
curPath = default_path;
|
||||
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
App()->GetMainWindow(), QTStr("Browse"),
|
||||
curPath, filter);
|
||||
App()->GetMainWindow(), QTStr("Browse"), curPath,
|
||||
filter);
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
|
@ -1867,8 +1857,8 @@ class EditableItemDialog : public QDialog {
|
|||
}
|
||||
|
||||
public:
|
||||
EditableItemDialog(QWidget *parent, const QString &text,
|
||||
bool browse, const char *filter_ = nullptr,
|
||||
EditableItemDialog(QWidget *parent, const QString &text, bool browse,
|
||||
const char *filter_ = nullptr,
|
||||
const char *default_path_ = nullptr)
|
||||
: QDialog(parent),
|
||||
filter(QT_UTF8(filter_)),
|
||||
|
@ -1894,8 +1884,7 @@ public:
|
|||
}
|
||||
|
||||
QDialogButtonBox::StandardButtons buttons =
|
||||
QDialogButtonBox::Ok |
|
||||
QDialogButtonBox::Cancel;
|
||||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(buttons);
|
||||
buttonBox->setCenterButtons(true);
|
||||
|
@ -1915,8 +1904,8 @@ public:
|
|||
|
||||
void WidgetInfo::EditListAdd()
|
||||
{
|
||||
enum obs_editable_list_type type = obs_property_editable_list_type(
|
||||
property);
|
||||
enum obs_editable_list_type type =
|
||||
obs_property_editable_list_type(property);
|
||||
|
||||
if (type == OBS_EDITABLE_LIST_TYPE_STRINGS) {
|
||||
EditListAddText();
|
||||
|
@ -1929,20 +1918,19 @@ void WidgetInfo::EditListAdd()
|
|||
QAction *action;
|
||||
|
||||
action = new QAction(QTStr("Basic.PropertiesWindow.AddFiles"), this);
|
||||
connect(action, &QAction::triggered,
|
||||
this, &WidgetInfo::EditListAddFiles);
|
||||
connect(action, &QAction::triggered, this,
|
||||
&WidgetInfo::EditListAddFiles);
|
||||
popup.addAction(action);
|
||||
|
||||
action = new QAction(QTStr("Basic.PropertiesWindow.AddDir"), this);
|
||||
connect(action, &QAction::triggered,
|
||||
this, &WidgetInfo::EditListAddDir);
|
||||
connect(action, &QAction::triggered, this, &WidgetInfo::EditListAddDir);
|
||||
popup.addAction(action);
|
||||
|
||||
if (type == OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS) {
|
||||
action = new QAction(QTStr("Basic.PropertiesWindow.AddURL"),
|
||||
this);
|
||||
connect(action, &QAction::triggered,
|
||||
this, &WidgetInfo::EditListAddText);
|
||||
connect(action, &QAction::triggered, this,
|
||||
&WidgetInfo::EditListAddText);
|
||||
popup.addAction(action);
|
||||
}
|
||||
|
||||
|
@ -1955,8 +1943,8 @@ void WidgetInfo::EditListAddText()
|
|||
const char *desc = obs_property_description(property);
|
||||
|
||||
EditableItemDialog dialog(widget->window(), QString(), false);
|
||||
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry").arg(
|
||||
QT_UTF8(desc));
|
||||
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
|
||||
.arg(QT_UTF8(desc));
|
||||
dialog.setWindowTitle(title);
|
||||
if (dialog.exec() == QDialog::Rejected)
|
||||
return;
|
||||
|
@ -2024,8 +2012,8 @@ void WidgetInfo::EditListRemove()
|
|||
void WidgetInfo::EditListEdit()
|
||||
{
|
||||
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
|
||||
enum obs_editable_list_type type = obs_property_editable_list_type(
|
||||
property);
|
||||
enum obs_editable_list_type type =
|
||||
obs_property_editable_list_type(property);
|
||||
const char *desc = obs_property_description(property);
|
||||
const char *filter = obs_property_editable_list_filter(property);
|
||||
QList<QListWidgetItem *> selectedItems = list->selectedItems();
|
||||
|
@ -2041,8 +2029,7 @@ void WidgetInfo::EditListEdit()
|
|||
|
||||
if (pathDir.exists())
|
||||
path = QFileDialog::getExistingDirectory(
|
||||
App()->GetMainWindow(),
|
||||
QTStr("Browse"),
|
||||
App()->GetMainWindow(), QTStr("Browse"),
|
||||
item->text(),
|
||||
QFileDialog::ShowDirsOnly |
|
||||
QFileDialog::DontResolveSymlinks);
|
||||
|
@ -2060,9 +2047,10 @@ void WidgetInfo::EditListEdit()
|
|||
}
|
||||
|
||||
EditableItemDialog dialog(widget->window(), item->text(),
|
||||
type != OBS_EDITABLE_LIST_TYPE_STRINGS, filter);
|
||||
auto title = QTStr("Basic.PropertiesWindow.EditEditableListEntry").arg(
|
||||
QT_UTF8(desc));
|
||||
type != OBS_EDITABLE_LIST_TYPE_STRINGS,
|
||||
filter);
|
||||
auto title = QTStr("Basic.PropertiesWindow.EditEditableListEntry")
|
||||
.arg(QT_UTF8(desc));
|
||||
dialog.setWindowTitle(title);
|
||||
if (dialog.exec() == QDialog::Rejected)
|
||||
return;
|
||||
|
|
|
@ -10,8 +10,7 @@ class OBSPropertiesView;
|
|||
class QLabel;
|
||||
|
||||
typedef obs_properties_t *(*PropertiesReloadCallback)(void *obj);
|
||||
typedef void (*PropertiesUpdateCallback)(void *obj,
|
||||
obs_data_t *settings);
|
||||
typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t *settings);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -43,7 +42,8 @@ public:
|
|||
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
|
||||
QWidget *widget_)
|
||||
: view(view_), property(prop), widget(widget_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -99,7 +99,8 @@ private:
|
|||
void AddEditableList(obs_property_t *prop, QFormLayout *layout,
|
||||
QLabel *&label);
|
||||
QWidget *AddButton(obs_property_t *prop);
|
||||
void AddColor(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
|
||||
void AddColor(obs_property_t *prop, QFormLayout *layout,
|
||||
QLabel *&label);
|
||||
void AddFont(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
|
||||
void AddFrameRate(obs_property_t *prop, bool &warning,
|
||||
QFormLayout *layout, QLabel *&label);
|
||||
|
@ -126,8 +127,7 @@ signals:
|
|||
public:
|
||||
OBSPropertiesView(OBSData settings, void *obj,
|
||||
PropertiesReloadCallback reloadCallback,
|
||||
PropertiesUpdateCallback callback,
|
||||
int minSize = 0);
|
||||
PropertiesUpdateCallback callback, int minSize = 0);
|
||||
OBSPropertiesView(OBSData settings, const char *type,
|
||||
PropertiesReloadCallback reloadCallback,
|
||||
int minSize = 0);
|
||||
|
|
|
@ -8,23 +8,18 @@
|
|||
|
||||
static inline long long color_to_int(QColor color)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift) {
|
||||
return ((val & 0xff) << shift);
|
||||
};
|
||||
|
||||
return shift(color.red(), 0) |
|
||||
shift(color.green(), 8) |
|
||||
shift(color.blue(), 16) |
|
||||
shift(color.alpha(), 24);
|
||||
return shift(color.red(), 0) | shift(color.green(), 8) |
|
||||
shift(color.blue(), 16) | shift(color.alpha(), 24);
|
||||
}
|
||||
|
||||
static inline QColor rgba_to_color(uint32_t rgba)
|
||||
{
|
||||
return QColor::fromRgb(rgba & 0xFF,
|
||||
(rgba >> 8) & 0xFF,
|
||||
(rgba >> 16) & 0xFF,
|
||||
(rgba >> 24) & 0xFF);
|
||||
return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF,
|
||||
(rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
@ -37,8 +32,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
|
|||
setAttribute(Qt::WA_DontCreateNativeAncestors);
|
||||
setAttribute(Qt::WA_NativeWindow);
|
||||
|
||||
auto windowVisible = [this] (bool visible)
|
||||
{
|
||||
auto windowVisible = [this](bool visible) {
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
|
@ -46,12 +40,12 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
|
|||
CreateDisplay();
|
||||
} else {
|
||||
QSize size = GetPixelSize(this);
|
||||
obs_display_resize(display, size.width(), size.height());
|
||||
obs_display_resize(display, size.width(),
|
||||
size.height());
|
||||
}
|
||||
};
|
||||
|
||||
auto sizeChanged = [this] (QScreen*)
|
||||
{
|
||||
auto sizeChanged = [this](QScreen *) {
|
||||
CreateDisplay();
|
||||
|
||||
QSize size = GetPixelSize(this);
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
class OBSQTDisplay : public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor
|
||||
READ GetDisplayBackgroundColor
|
||||
WRITE SetDisplayBackgroundColor)
|
||||
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor READ
|
||||
GetDisplayBackgroundColor WRITE
|
||||
SetDisplayBackgroundColor)
|
||||
|
||||
OBSDisplay display;
|
||||
|
||||
|
|
|
@ -45,18 +45,15 @@ void OBSErrorBox(QWidget *parent, const char *msg, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton OBSMessageBox::question(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
QMessageBox::StandardButton
|
||||
OBSMessageBox::question(QWidget *parent, const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton)
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Question,
|
||||
title, text, buttons,
|
||||
parent);
|
||||
QMessageBox mb(QMessageBox::Question, title, text, buttons, parent);
|
||||
mb.setDefaultButton(defaultButton);
|
||||
if (buttons & QMessageBox::Ok) \
|
||||
if (buttons & QMessageBox::Ok)
|
||||
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
|
||||
#define translate_button(x) \
|
||||
if (buttons & QMessageBox::x) \
|
||||
|
@ -78,26 +75,19 @@ QMessageBox::StandardButton OBSMessageBox::question(
|
|||
return (QMessageBox::StandardButton)mb.exec();
|
||||
}
|
||||
|
||||
void OBSMessageBox::information(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
void OBSMessageBox::information(QWidget *parent, const QString &title,
|
||||
const QString &text)
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Information,
|
||||
title, text, QMessageBox::Ok,
|
||||
QMessageBox mb(QMessageBox::Information, title, text, QMessageBox::Ok,
|
||||
parent);
|
||||
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
|
||||
mb.exec();
|
||||
}
|
||||
|
||||
void OBSMessageBox::warning(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
bool enableRichText)
|
||||
void OBSMessageBox::warning(QWidget *parent, const QString &title,
|
||||
const QString &text, bool enableRichText)
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Warning,
|
||||
title, text, QMessageBox::Ok,
|
||||
QMessageBox mb(QMessageBox::Warning, title, text, QMessageBox::Ok,
|
||||
parent);
|
||||
if (enableRichText)
|
||||
mb.setTextFormat(Qt::RichText);
|
||||
|
@ -105,13 +95,10 @@ void OBSMessageBox::warning(
|
|||
mb.exec();
|
||||
}
|
||||
|
||||
void OBSMessageBox::critical(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
void OBSMessageBox::critical(QWidget *parent, const QString &title,
|
||||
const QString &text)
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Critical,
|
||||
title, text, QMessageBox::Ok,
|
||||
QMessageBox mb(QMessageBox::Critical, title, text, QMessageBox::Ok,
|
||||
parent);
|
||||
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
|
||||
mb.exec();
|
||||
|
@ -234,15 +221,12 @@ void DeleteLayout(QLayout *layout)
|
|||
|
||||
class QuickThread : public QThread {
|
||||
public:
|
||||
explicit inline QuickThread(std::function<void()> func_)
|
||||
: func(func_)
|
||||
{}
|
||||
explicit inline QuickThread(std::function<void()> func_) : func(func_)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void run() override
|
||||
{
|
||||
func();
|
||||
}
|
||||
virtual void run() override { func(); }
|
||||
|
||||
std::function<void()> func;
|
||||
};
|
||||
|
@ -258,8 +242,7 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
|
|||
{
|
||||
QEventLoop eventLoop;
|
||||
|
||||
auto wait = [&] ()
|
||||
{
|
||||
auto wait = [&]() {
|
||||
func();
|
||||
QMetaObject::invokeMethod(&eventLoop, "quit",
|
||||
Qt::QueuedConnection);
|
||||
|
@ -273,10 +256,8 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
|
|||
os_atomic_dec_long(&insideEventLoop);
|
||||
}
|
||||
|
||||
void ExecuteFuncSafeBlockMsgBox(
|
||||
std::function<void()> func,
|
||||
const QString &title,
|
||||
const QString &text)
|
||||
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
|
||||
const QString &title, const QString &text)
|
||||
{
|
||||
QMessageBox dlg;
|
||||
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowCloseButtonHint);
|
||||
|
@ -284,8 +265,7 @@ void ExecuteFuncSafeBlockMsgBox(
|
|||
dlg.setText(text);
|
||||
dlg.setStandardButtons(0);
|
||||
|
||||
auto wait = [&] ()
|
||||
{
|
||||
auto wait = [&]() {
|
||||
func();
|
||||
QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection);
|
||||
};
|
||||
|
@ -305,10 +285,8 @@ void EnableThreadedMessageBoxes(bool enable)
|
|||
enable_message_boxes = enable;
|
||||
}
|
||||
|
||||
void ExecThreadedWithoutBlocking(
|
||||
std::function<void()> func,
|
||||
const QString &title,
|
||||
const QString &text)
|
||||
void ExecThreadedWithoutBlocking(std::function<void()> func,
|
||||
const QString &title, const QString &text)
|
||||
{
|
||||
if (!enable_message_boxes)
|
||||
ExecuteFuncSafeBlock(func);
|
||||
|
|
|
@ -38,24 +38,18 @@ struct gs_window;
|
|||
|
||||
class OBSMessageBox {
|
||||
public:
|
||||
static QMessageBox::StandardButton question(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ),
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
static void information(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
static QMessageBox::StandardButton
|
||||
question(QWidget *parent, const QString &title, const QString &text,
|
||||
QMessageBox::StandardButtons buttons =
|
||||
QMessageBox::StandardButtons(QMessageBox::Yes |
|
||||
QMessageBox::No),
|
||||
QMessageBox::StandardButton defaultButton =
|
||||
QMessageBox::NoButton);
|
||||
static void information(QWidget *parent, const QString &title,
|
||||
const QString &text);
|
||||
static void warning(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
bool enableRichText = false);
|
||||
static void critical(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
static void warning(QWidget *parent, const QString &title,
|
||||
const QString &text, bool enableRichText = false);
|
||||
static void critical(QWidget *parent, const QString &title,
|
||||
const QString &text);
|
||||
};
|
||||
|
||||
|
@ -65,7 +59,8 @@ void QTToGSWindow(WId windowId, gs_window &gswindow);
|
|||
|
||||
uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods);
|
||||
|
||||
QDataStream &operator<<(QDataStream &out,
|
||||
QDataStream &
|
||||
operator<<(QDataStream &out,
|
||||
const std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
|
||||
QDataStream &operator>>(QDataStream &in,
|
||||
std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
|
||||
|
@ -77,18 +72,14 @@ QDataStream &operator>>(QDataStream &in, OBSSceneItem &si);
|
|||
QThread *CreateQThread(std::function<void()> func);
|
||||
|
||||
void ExecuteFuncSafeBlock(std::function<void()> func);
|
||||
void ExecuteFuncSafeBlockMsgBox(
|
||||
std::function<void()> func,
|
||||
const QString &title,
|
||||
const QString &text);
|
||||
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
|
||||
const QString &title, const QString &text);
|
||||
|
||||
/* allows executing without message boxes if starting up, otherwise with a
|
||||
* message box */
|
||||
void EnableThreadedMessageBoxes(bool enable);
|
||||
void ExecThreadedWithoutBlocking(
|
||||
std::function<void()> func,
|
||||
const QString &title,
|
||||
const QString &text);
|
||||
void ExecThreadedWithoutBlocking(std::function<void()> func,
|
||||
const QString &title, const QString &text);
|
||||
|
||||
class SignalBlocker {
|
||||
QWidget *widget;
|
||||
|
@ -100,10 +91,7 @@ public:
|
|||
blocked = widget->blockSignals(true);
|
||||
}
|
||||
|
||||
inline ~SignalBlocker()
|
||||
{
|
||||
widget->blockSignals(blocked);
|
||||
}
|
||||
inline ~SignalBlocker() { widget->blockSignals(blocked); }
|
||||
};
|
||||
|
||||
void DeleteLayout(QLayout *layout);
|
||||
|
|
|
@ -53,8 +53,7 @@ void RemoteTextThread::run()
|
|||
struct curl_slist *header = nullptr;
|
||||
string str;
|
||||
|
||||
header = curl_slist_append(header,
|
||||
versionString.c_str());
|
||||
header = curl_slist_append(header, versionString.c_str());
|
||||
|
||||
if (!contentTypeString.empty()) {
|
||||
header = curl_slist_append(header,
|
||||
|
@ -66,14 +65,11 @@ void RemoteTextThread::run()
|
|||
|
||||
curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
|
||||
header);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
|
||||
error);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
|
||||
string_write);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
|
||||
&str);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
|
||||
|
||||
if (timeoutSec)
|
||||
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
|
||||
|
@ -118,16 +114,10 @@ static size_t header_write(char *ptr, size_t size, size_t nmemb,
|
|||
return total;
|
||||
}
|
||||
|
||||
bool GetRemoteFile(
|
||||
const char *url,
|
||||
std::string &str,
|
||||
std::string &error,
|
||||
long *responseCode,
|
||||
const char *contentType,
|
||||
const char *postData,
|
||||
std::vector<std::string> extraHeaders,
|
||||
std::string *signature,
|
||||
int timeoutSec)
|
||||
bool GetRemoteFile(const char *url, std::string &str, std::string &error,
|
||||
long *responseCode, const char *contentType,
|
||||
const char *postData, std::vector<std::string> extraHeaders,
|
||||
std::string *signature, int timeoutSec)
|
||||
{
|
||||
vector<string> header_in_list;
|
||||
char error_in[CURL_ERROR_SIZE];
|
||||
|
@ -148,8 +138,7 @@ bool GetRemoteFile(
|
|||
if (curl) {
|
||||
struct curl_slist *header = nullptr;
|
||||
|
||||
header = curl_slist_append(header,
|
||||
versionString.c_str());
|
||||
header = curl_slist_append(header, versionString.c_str());
|
||||
|
||||
if (!contentTypeString.empty()) {
|
||||
header = curl_slist_append(header,
|
||||
|
@ -161,14 +150,11 @@ bool GetRemoteFile(
|
|||
|
||||
curl_easy_setopt(curl.get(), CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
|
||||
header);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
|
||||
error_in);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_in);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
|
||||
string_write);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
|
||||
&str);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
|
||||
if (signature) {
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
|
||||
header_write);
|
||||
|
|
|
@ -38,8 +38,7 @@ signals:
|
|||
void Result(const QString &text, const QString &error);
|
||||
|
||||
public:
|
||||
inline RemoteTextThread(
|
||||
std::string url_,
|
||||
inline RemoteTextThread(std::string url_,
|
||||
std::string contentType_ = std::string(),
|
||||
std::string postData_ = std::string(),
|
||||
int timeoutSec_ = 0)
|
||||
|
@ -47,10 +46,10 @@ public:
|
|||
contentType(contentType_),
|
||||
postData(postData_),
|
||||
timeoutSec(timeoutSec_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
inline RemoteTextThread(
|
||||
std::string url_,
|
||||
inline RemoteTextThread(std::string url_,
|
||||
std::vector<std::string> &&extraHeaders_,
|
||||
std::string contentType_ = std::string(),
|
||||
std::string postData_ = std::string(),
|
||||
|
@ -60,16 +59,13 @@ public:
|
|||
postData(postData_),
|
||||
extraHeaders(std::move(extraHeaders_)),
|
||||
timeoutSec(timeoutSec_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
bool GetRemoteFile(
|
||||
const char *url,
|
||||
std::string &str,
|
||||
std::string &error,
|
||||
long *responseCode = nullptr,
|
||||
const char *contentType = nullptr,
|
||||
const char *url, std::string &str, std::string &error,
|
||||
long *responseCode = nullptr, const char *contentType = nullptr,
|
||||
const char *postData = nullptr,
|
||||
std::vector<std::string> extraHeaders = std::vector<std::string>(),
|
||||
std::string *signature = nullptr,
|
||||
int timeoutSec = 0);
|
||||
std::string *signature = nullptr, int timeoutSec = 0);
|
||||
|
|
|
@ -10,7 +10,8 @@ SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle* baseStyle)
|
|||
}
|
||||
|
||||
int SliderAbsoluteSetStyle::styleHint(QStyle::StyleHint hint,
|
||||
const QStyleOption* option = 0, const QWidget* widget = 0,
|
||||
const QStyleOption *option = 0,
|
||||
const QWidget *widget = 0,
|
||||
QStyleHintReturn *returnData = 0) const
|
||||
{
|
||||
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
#include <QProxyStyle>
|
||||
|
||||
class SliderAbsoluteSetStyle : public QProxyStyle
|
||||
{
|
||||
class SliderAbsoluteSetStyle : public QProxyStyle {
|
||||
public:
|
||||
SliderAbsoluteSetStyle(const QString &baseStyle);
|
||||
SliderAbsoluteSetStyle(QStyle *baseStyle = Q_NULLPTR);
|
||||
int styleHint(QStyle::StyleHint hint, const QStyleOption *option,
|
||||
const QWidget* widget, QStyleHintReturn* returnData) const;
|
||||
const QWidget *widget,
|
||||
QStyleHintReturn *returnData) const;
|
||||
};
|
||||
|
|
|
@ -9,7 +9,8 @@ class SliderIgnoreScroll : public QSlider {
|
|||
|
||||
public:
|
||||
SliderIgnoreScroll(QWidget *parent = nullptr);
|
||||
SliderIgnoreScroll(Qt::Orientation orientation, QWidget *parent = nullptr);
|
||||
SliderIgnoreScroll(Qt::Orientation orientation,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
|
|
|
@ -38,7 +38,8 @@ public:
|
|||
destroyedSignal(obs_source_get_signal_handler(source),
|
||||
"destroy", &OBSSourceLabel::SourceDestroyed,
|
||||
this)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
static void SourceRenamed(void *data, calldata_t *params);
|
||||
|
|
|
@ -32,8 +32,7 @@ static inline OBSScene GetCurrentScene()
|
|||
/* ========================================================================= */
|
||||
|
||||
SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
|
||||
: tree (tree_),
|
||||
sceneitem (sceneitem_)
|
||||
: tree(tree_), sceneitem(sceneitem_)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setMouseTracking(true);
|
||||
|
@ -98,14 +97,12 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
|
|||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
auto setItemVisible = [this] (bool checked)
|
||||
{
|
||||
auto setItemVisible = [this](bool checked) {
|
||||
SignalBlocker sourcesSignalBlocker(this);
|
||||
obs_sceneitem_set_visible(sceneitem, checked);
|
||||
};
|
||||
|
||||
auto setItemLocked = [this] (bool checked)
|
||||
{
|
||||
auto setItemLocked = [this](bool checked) {
|
||||
SignalBlocker sourcesSignalBlocker(this);
|
||||
obs_sceneitem_set_locked(sceneitem, checked);
|
||||
};
|
||||
|
@ -150,15 +147,14 @@ void SourceTreeItem::ReconnectSignals()
|
|||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
auto removeItem = [] (void *data, calldata_t *cd)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto removeItem = [](void *data, calldata_t *cd) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(cd, "item");
|
||||
|
||||
if (curItem == this_->sceneitem) {
|
||||
QMetaObject::invokeMethod(this_->tree,
|
||||
"Remove",
|
||||
QMetaObject::invokeMethod(this_->tree, "Remove",
|
||||
Q_ARG(OBSSceneItem, curItem));
|
||||
curItem = nullptr;
|
||||
}
|
||||
|
@ -166,9 +162,9 @@ void SourceTreeItem::ReconnectSignals()
|
|||
QMetaObject::invokeMethod(this_, "Clear");
|
||||
};
|
||||
|
||||
auto itemVisible = [] (void *data, calldata_t *cd)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto itemVisible = [](void *data, calldata_t *cd) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(cd, "item");
|
||||
bool visible = calldata_bool(cd, "visible");
|
||||
|
@ -178,9 +174,9 @@ void SourceTreeItem::ReconnectSignals()
|
|||
Q_ARG(bool, visible));
|
||||
};
|
||||
|
||||
auto itemLocked = [] (void *data, calldata_t *cd)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto itemLocked = [](void *data, calldata_t *cd) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(cd, "item");
|
||||
bool locked = calldata_bool(cd, "locked");
|
||||
|
@ -190,9 +186,9 @@ void SourceTreeItem::ReconnectSignals()
|
|||
Q_ARG(bool, locked));
|
||||
};
|
||||
|
||||
auto itemDeselect = [] (void *data, calldata_t *cd)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto itemDeselect = [](void *data, calldata_t *cd) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(cd, "item");
|
||||
|
||||
|
@ -200,9 +196,9 @@ void SourceTreeItem::ReconnectSignals()
|
|||
QMetaObject::invokeMethod(this_, "Deselect");
|
||||
};
|
||||
|
||||
auto reorderGroup = [] (void *data, calldata_t*)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto reorderGroup = [](void *data, calldata_t *) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
QMetaObject::invokeMethod(this_->tree, "ReorderItems");
|
||||
};
|
||||
|
||||
|
@ -229,18 +225,18 @@ void SourceTreeItem::ReconnectSignals()
|
|||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
auto renamed = [] (void *data, calldata_t *cd)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto renamed = [](void *data, calldata_t *cd) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
const char *name = calldata_string(cd, "new_name");
|
||||
|
||||
QMetaObject::invokeMethod(this_, "Renamed",
|
||||
Q_ARG(QString, QT_UTF8(name)));
|
||||
};
|
||||
|
||||
auto removeSource = [] (void *data, calldata_t *)
|
||||
{
|
||||
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
|
||||
auto removeSource = [](void *data, calldata_t *) {
|
||||
SourceTreeItem *this_ =
|
||||
reinterpret_cast<SourceTreeItem *>(data);
|
||||
this_->DisconnectSignals();
|
||||
this_->sceneitem = nullptr;
|
||||
};
|
||||
|
@ -308,8 +304,7 @@ void SourceTreeItem::ExitEditMode(bool save)
|
|||
return;
|
||||
|
||||
if (newName.empty()) {
|
||||
OBSMessageBox::information(main,
|
||||
QTStr("NoNameEntered.Title"),
|
||||
OBSMessageBox::information(main, QTStr("NoNameEntered.Title"),
|
||||
QTStr("NoNameEntered.Text"));
|
||||
return;
|
||||
}
|
||||
|
@ -324,14 +319,12 @@ void SourceTreeItem::ExitEditMode(bool save)
|
|||
/* ----------------------------------------- */
|
||||
/* check for existing source */
|
||||
|
||||
obs_source_t *existingSource =
|
||||
obs_get_source_by_name(newName.c_str());
|
||||
obs_source_t *existingSource = obs_get_source_by_name(newName.c_str());
|
||||
obs_source_release(existingSource);
|
||||
bool exists = !!existingSource;
|
||||
|
||||
if (exists) {
|
||||
OBSMessageBox::information(main,
|
||||
QTStr("NameExists.Title"),
|
||||
OBSMessageBox::information(main, QTStr("NameExists.Title"),
|
||||
QTStr("NameExists.Text"));
|
||||
return;
|
||||
}
|
||||
|
@ -448,8 +441,7 @@ void SourceTreeItem::Update(bool force)
|
|||
|
||||
} else if (type == Type::Group) {
|
||||
expand = new SourceTreeSubItemCheckBox();
|
||||
expand->setSizePolicy(
|
||||
QSizePolicy::Maximum,
|
||||
expand->setSizePolicy(QSizePolicy::Maximum,
|
||||
QSizePolicy::Maximum);
|
||||
expand->setMaximumSize(10, 16);
|
||||
expand->setMinimumSize(10, 0);
|
||||
|
@ -458,14 +450,15 @@ void SourceTreeItem::Update(bool force)
|
|||
#endif
|
||||
boxLayout->insertWidget(0, expand);
|
||||
|
||||
obs_data_t *data = obs_sceneitem_get_private_settings(sceneitem);
|
||||
obs_data_t *data =
|
||||
obs_sceneitem_get_private_settings(sceneitem);
|
||||
expand->blockSignals(true);
|
||||
expand->setChecked(obs_data_get_bool(data, "collapsed"));
|
||||
expand->blockSignals(false);
|
||||
obs_data_release(data);
|
||||
|
||||
connect(expand, &QPushButton::toggled,
|
||||
this, &SourceTreeItem::ExpandClicked);
|
||||
connect(expand, &QPushButton::toggled, this,
|
||||
&SourceTreeItem::ExpandClicked);
|
||||
|
||||
} else {
|
||||
spacer = new QSpacerItem(3, 1);
|
||||
|
@ -556,14 +549,15 @@ void SourceTreeModel::SceneChanged()
|
|||
bool select = obs_sceneitem_selected(items[i]);
|
||||
QModelIndex index = createIndex(i, 0);
|
||||
|
||||
st->selectionModel()->select(index, select
|
||||
? QItemSelectionModel::Select
|
||||
st->selectionModel()->select(
|
||||
index, select ? QItemSelectionModel::Select
|
||||
: QItemSelectionModel::Deselect);
|
||||
}
|
||||
}
|
||||
|
||||
/* moves a scene item index (blame linux distros for using older Qt builds) */
|
||||
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx, int newIdx)
|
||||
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx,
|
||||
int newIdx)
|
||||
{
|
||||
OBSSceneItem item = items[oldIdx];
|
||||
items.remove(oldIdx);
|
||||
|
@ -709,8 +703,7 @@ OBSSceneItem SourceTreeModel::Get(int idx)
|
|||
}
|
||||
|
||||
SourceTreeModel::SourceTreeModel(SourceTree *st_)
|
||||
: QAbstractListModel (st_),
|
||||
st (st_)
|
||||
: QAbstractListModel(st_), st(st_)
|
||||
{
|
||||
obs_frontend_add_event_callback(OBSFrontendEvent, this);
|
||||
}
|
||||
|
@ -744,8 +737,7 @@ Qt::ItemFlags SourceTreeModel::flags(const QModelIndex &index) const
|
|||
obs_sceneitem_t *item = items[index.row()];
|
||||
bool is_group = obs_sceneitem_is_group(item);
|
||||
|
||||
return QAbstractListModel::flags(index) |
|
||||
Qt::ItemIsEditable |
|
||||
return QAbstractListModel::flags(index) | Qt::ItemIsEditable |
|
||||
Qt::ItemIsDragEnabled |
|
||||
(is_group ? Qt::ItemIsDropEnabled : Qt::NoItemFlags);
|
||||
}
|
||||
|
@ -775,8 +767,8 @@ QString SourceTreeModel::GetNewGroupName()
|
|||
void SourceTreeModel::AddGroup()
|
||||
{
|
||||
QString name = GetNewGroupName();
|
||||
obs_sceneitem_t *group = obs_scene_add_group(GetCurrentScene(),
|
||||
QT_TO_UTF8(name));
|
||||
obs_sceneitem_t *group =
|
||||
obs_scene_add_group(GetCurrentScene(), QT_TO_UTF8(name));
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
|
@ -807,8 +799,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
|
|||
}
|
||||
|
||||
obs_sceneitem_t *item = obs_scene_insert_group(
|
||||
scene, QT_TO_UTF8(name),
|
||||
item_order.data(), item_order.size());
|
||||
scene, QT_TO_UTF8(name), item_order.data(), item_order.size());
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
@ -929,20 +920,20 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_)
|
|||
SourceTreeModel *stm_ = new SourceTreeModel(this);
|
||||
setModel(stm_);
|
||||
setStyleSheet(QString(
|
||||
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" \
|
||||
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" \
|
||||
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" \
|
||||
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" \
|
||||
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" \
|
||||
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \
|
||||
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \
|
||||
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}"
|
||||
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}"
|
||||
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}"
|
||||
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}"
|
||||
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}"
|
||||
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}"
|
||||
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}"
|
||||
"*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}"));
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
UpdateNoSourcesMessage();
|
||||
connect(App(), &OBSApp::StyleChanged,
|
||||
this, &SourceTree::UpdateNoSourcesMessage);
|
||||
connect(App(), &OBSApp::StyleChanged, this,
|
||||
&SourceTree::UpdateNoSourcesMessage);
|
||||
}
|
||||
|
||||
void SourceTree::ResetWidgets()
|
||||
|
@ -994,8 +985,8 @@ void SourceTree::SelectItem(obs_sceneitem_t *sceneitem, bool select)
|
|||
|
||||
QModelIndex index = stm->createIndex(i, 0);
|
||||
if (index.isValid())
|
||||
selectionModel()->select(index, select
|
||||
? QItemSelectionModel::Select
|
||||
selectionModel()->select(
|
||||
index, select ? QItemSelectionModel::Select
|
||||
: QItemSelectionModel::Deselect);
|
||||
}
|
||||
|
||||
|
@ -1040,8 +1031,8 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
obs_sceneitem_t *dropItem = items[row]; /* item being dropped on */
|
||||
bool itemIsGroup = obs_sceneitem_is_group(dropItem);
|
||||
|
||||
obs_sceneitem_t *dropGroup = itemIsGroup
|
||||
? dropItem
|
||||
obs_sceneitem_t *dropGroup =
|
||||
itemIsGroup ? dropItem
|
||||
: obs_sceneitem_get_group(scene, dropItem);
|
||||
|
||||
/* not a group if moving above the group */
|
||||
|
@ -1056,7 +1047,8 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
|
||||
bool dropOnCollapsed = false;
|
||||
if (dropGroup) {
|
||||
obs_data_t *data = obs_sceneitem_get_private_settings(dropGroup);
|
||||
obs_data_t *data =
|
||||
obs_sceneitem_get_private_settings(dropGroup);
|
||||
dropOnCollapsed = obs_data_get_bool(data, "collapsed");
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
@ -1086,9 +1078,8 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
/* if dropping a group, detect if it's */
|
||||
/* below another group */
|
||||
|
||||
obs_sceneitem_t *itemBelow = row == stm->items.count()
|
||||
? nullptr
|
||||
: stm->items[row];
|
||||
obs_sceneitem_t *itemBelow =
|
||||
row == stm->items.count() ? nullptr : stm->items[row];
|
||||
if (hasGroups) {
|
||||
if (!itemBelow ||
|
||||
obs_sceneitem_get_group(scene, itemBelow) != dropGroup) {
|
||||
|
@ -1131,8 +1122,8 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
for (int j = items.size() - 1; j >= 0; j--) {
|
||||
obs_sceneitem_t *subitem = items[j];
|
||||
obs_sceneitem_t *subitemGroup =
|
||||
obs_sceneitem_get_group(scene,
|
||||
subitem);
|
||||
obs_sceneitem_get_group(
|
||||
scene, subitem);
|
||||
|
||||
if (subitemGroup == item) {
|
||||
QModelIndex idx =
|
||||
|
@ -1186,8 +1177,7 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
obs_sceneitem_t *lastGroup = nullptr;
|
||||
int insertCollapsedIdx = 0;
|
||||
|
||||
auto insertCollapsed = [&] (obs_sceneitem_t *item)
|
||||
{
|
||||
auto insertCollapsed = [&](obs_sceneitem_t *item) {
|
||||
struct obs_sceneitem_order_info info;
|
||||
info.group = lastGroup;
|
||||
info.item = item;
|
||||
|
@ -1198,22 +1188,20 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
using insertCollapsed_t = decltype(insertCollapsed);
|
||||
|
||||
auto preInsertCollapsed = [](obs_scene_t *, obs_sceneitem_t *item,
|
||||
void *param)
|
||||
{
|
||||
void *param) {
|
||||
(*reinterpret_cast<insertCollapsed_t *>(param))(item);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto insertLastGroup = [&] ()
|
||||
{
|
||||
obs_data_t *data = obs_sceneitem_get_private_settings(lastGroup);
|
||||
auto insertLastGroup = [&]() {
|
||||
obs_data_t *data =
|
||||
obs_sceneitem_get_private_settings(lastGroup);
|
||||
bool collapsed = obs_data_get_bool(data, "collapsed");
|
||||
obs_data_release(data);
|
||||
|
||||
if (collapsed) {
|
||||
insertCollapsedIdx = 0;
|
||||
obs_sceneitem_group_enum_items(
|
||||
lastGroup,
|
||||
obs_sceneitem_group_enum_items(lastGroup,
|
||||
preInsertCollapsed,
|
||||
&insertCollapsed);
|
||||
}
|
||||
|
@ -1224,8 +1212,7 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
orderList.insert(0, info);
|
||||
};
|
||||
|
||||
auto updateScene = [&] ()
|
||||
{
|
||||
auto updateScene = [&]() {
|
||||
struct obs_sceneitem_order_info info;
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
|
@ -1260,14 +1247,13 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
insertLastGroup();
|
||||
}
|
||||
|
||||
obs_scene_reorder_items2(scene,
|
||||
orderList.data(), orderList.size());
|
||||
obs_scene_reorder_items2(scene, orderList.data(),
|
||||
orderList.size());
|
||||
};
|
||||
|
||||
using updateScene_t = decltype(updateScene);
|
||||
|
||||
auto preUpdateScene = [] (void *data, obs_scene_t *)
|
||||
{
|
||||
auto preUpdateScene = [](void *data, obs_scene_t *) {
|
||||
(*reinterpret_cast<updateScene_t *>(data))();
|
||||
};
|
||||
|
||||
|
@ -1314,8 +1300,7 @@ void SourceTree::leaveEvent(QEvent *event)
|
|||
QListView::leaveEvent(event);
|
||||
}
|
||||
|
||||
void SourceTree::selectionChanged(
|
||||
const QItemSelection &selected,
|
||||
void SourceTree::selectionChanged(const QItemSelection &selected,
|
||||
const QItemSelection &deselected)
|
||||
{
|
||||
{
|
||||
|
@ -1465,8 +1450,7 @@ void SourceTree::UpdateNoSourcesMessage()
|
|||
|
||||
QColor color = palette().text().color();
|
||||
bool lightTheme = (color.redF() < 0.5);
|
||||
QString file = lightTheme
|
||||
? ":res/images/no_sources.svg"
|
||||
QString file = lightTheme ? ":res/images/no_sources.svg"
|
||||
: darkPath.c_str();
|
||||
iconNoSources.load(file);
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ public:
|
|||
~SourceTreeModel();
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
virtual QVariant data(const QModelIndex &index,
|
||||
int role) const override;
|
||||
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
|
@ -189,5 +190,7 @@ protected:
|
|||
virtual void leaveEvent(QEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
|
||||
virtual void
|
||||
selectionChanged(const QItemSelection &selected,
|
||||
const QItemSelection &deselected) override;
|
||||
};
|
||||
|
|
|
@ -8,8 +8,7 @@ class VScrollArea : public QScrollArea {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
inline VScrollArea(QWidget *parent = nullptr)
|
||||
: QScrollArea(parent)
|
||||
inline VScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
|
||||
{
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
|
|||
setLayout(itemLayout);
|
||||
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
|
||||
|
||||
connect(vis, SIGNAL(clicked(bool)),
|
||||
this, SLOT(VisibilityClicked(bool)));
|
||||
connect(vis, SIGNAL(clicked(bool)), this,
|
||||
SLOT(VisibilityClicked(bool)));
|
||||
}
|
||||
|
||||
VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
|
||||
|
@ -90,18 +90,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
|
|||
|
||||
signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
|
||||
signal_handler_connect(signal, "remove", OBSSceneRemove, this);
|
||||
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove,
|
||||
this);
|
||||
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, this);
|
||||
signal_handler_connect(signal, "item_visible", OBSSceneItemVisible,
|
||||
this);
|
||||
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked,
|
||||
this);
|
||||
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked, this);
|
||||
|
||||
connect(vis, SIGNAL(clicked(bool)),
|
||||
this, SLOT(VisibilityClicked(bool)));
|
||||
connect(vis, SIGNAL(clicked(bool)), this,
|
||||
SLOT(VisibilityClicked(bool)));
|
||||
|
||||
connect(lock, SIGNAL(clicked(bool)),
|
||||
this, SLOT(LockClicked(bool)));
|
||||
connect(lock, SIGNAL(clicked(bool)), this, SLOT(LockClicked(bool)));
|
||||
}
|
||||
|
||||
VisibilityItemWidget::~VisibilityItemWidget()
|
||||
|
@ -153,7 +150,8 @@ void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
|
|||
{
|
||||
VisibilityItemWidget *window =
|
||||
reinterpret_cast<VisibilityItemWidget *>(param);
|
||||
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
bool enabled = calldata_bool(data, "visible");
|
||||
|
||||
if (window->item == curItem)
|
||||
|
@ -165,7 +163,8 @@ void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data)
|
|||
{
|
||||
VisibilityItemWidget *window =
|
||||
reinterpret_cast<VisibilityItemWidget *>(param);
|
||||
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
|
||||
obs_sceneitem_t *curItem =
|
||||
(obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
bool locked = calldata_bool(data, "locked");
|
||||
|
||||
if (window->item == curItem)
|
||||
|
@ -225,8 +224,8 @@ void VisibilityItemWidget::SourceRenamed(QString name)
|
|||
label->setText(name);
|
||||
}
|
||||
|
||||
void VisibilityItemWidget::SetColor(const QColor &color,
|
||||
bool active_, bool selected_)
|
||||
void VisibilityItemWidget::SetColor(const QColor &color, bool active_,
|
||||
bool selected_)
|
||||
{
|
||||
/* Do not update unless the state has actually changed */
|
||||
if (active_ == active && selected_ == selected)
|
||||
|
@ -269,8 +268,8 @@ void VisibilityItemDelegate::paint(QPainter *painter,
|
|||
|
||||
QPalette palette = list->palette();
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
QPalette::ColorGroup group = active ?
|
||||
QPalette::Active : QPalette::Inactive;
|
||||
QPalette::ColorGroup group = active ? QPalette::Active
|
||||
: QPalette::Inactive;
|
||||
#else
|
||||
QPalette::ColorGroup group = QPalette::Active;
|
||||
#endif
|
||||
|
|
|
@ -48,8 +48,8 @@ void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata)
|
|||
void VolControl::VolumeChanged()
|
||||
{
|
||||
slider->blockSignals(true);
|
||||
slider->setValue((int) (obs_fader_get_deflection(obs_fader) *
|
||||
FADER_PRECISION));
|
||||
slider->setValue(
|
||||
(int)(obs_fader_get_deflection(obs_fader) * FADER_PRECISION));
|
||||
slider->blockSignals(false);
|
||||
|
||||
updateText();
|
||||
|
@ -79,8 +79,7 @@ void VolControl::updateText()
|
|||
volLabel->setText(db);
|
||||
|
||||
bool muted = obs_source_muted(source);
|
||||
const char *accTextLookup = muted
|
||||
? "VolControl.SliderMuted"
|
||||
const char *accTextLookup = muted ? "VolControl.SliderMuted"
|
||||
: "VolControl.SliderUnmuted";
|
||||
|
||||
QString sourceName = obs_source_get_name(source);
|
||||
|
@ -138,11 +137,11 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
|
|||
config->setMaximumSize(22, 22);
|
||||
config->setAutoDefault(false);
|
||||
|
||||
config->setAccessibleName(QTStr("VolControl.Properties")
|
||||
.arg(sourceName));
|
||||
config->setAccessibleName(
|
||||
QTStr("VolControl.Properties").arg(sourceName));
|
||||
|
||||
connect(config, &QAbstractButton::clicked,
|
||||
this, &VolControl::EmitConfigClicked);
|
||||
connect(config, &QAbstractButton::clicked, this,
|
||||
&VolControl::EmitConfigClicked);
|
||||
}
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
|
@ -244,13 +243,13 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
|
|||
obs_fader_add_callback(obs_fader, OBSVolumeChanged, this);
|
||||
obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this);
|
||||
|
||||
signal_handler_connect(obs_source_get_signal_handler(source),
|
||||
"mute", OBSVolumeMuted, this);
|
||||
signal_handler_connect(obs_source_get_signal_handler(source), "mute",
|
||||
OBSVolumeMuted, this);
|
||||
|
||||
QWidget::connect(slider, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(SliderChanged(int)));
|
||||
QWidget::connect(mute, SIGNAL(clicked(bool)),
|
||||
this, SLOT(SetMuted(bool)));
|
||||
QWidget::connect(slider, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(SliderChanged(int)));
|
||||
QWidget::connect(mute, SIGNAL(clicked(bool)), this,
|
||||
SLOT(SetMuted(bool)));
|
||||
|
||||
obs_fader_attach_source(obs_fader, source);
|
||||
obs_volmeter_attach_source(obs_volmeter, source);
|
||||
|
@ -276,8 +275,8 @@ VolControl::~VolControl()
|
|||
obs_fader_remove_callback(obs_fader, OBSVolumeChanged, this);
|
||||
obs_volmeter_remove_callback(obs_volmeter, OBSVolumeLevel, this);
|
||||
|
||||
signal_handler_disconnect(obs_source_get_signal_handler(source),
|
||||
"mute", OBSVolumeMuted, this);
|
||||
signal_handler_disconnect(obs_source_get_signal_handler(source), "mute",
|
||||
OBSVolumeMuted, this);
|
||||
|
||||
obs_fader_destroy(obs_fader);
|
||||
obs_volmeter_destroy(obs_volmeter);
|
||||
|
@ -518,8 +517,7 @@ void VolumeMeter::wheelEvent(QWheelEvent *event)
|
|||
|
||||
VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
|
||||
bool vertical)
|
||||
: QWidget(parent), obs_volmeter(obs_volmeter),
|
||||
vertical(vertical)
|
||||
: QWidget(parent), obs_volmeter(obs_volmeter), vertical(vertical)
|
||||
{
|
||||
// Use a font that can be rendered small.
|
||||
tickFont = QFont("Arial");
|
||||
|
@ -632,8 +630,9 @@ inline bool VolumeMeter::detectIdle(uint64_t ts)
|
|||
}
|
||||
}
|
||||
|
||||
inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
|
||||
uint64_t ts, qreal timeSinceLastRedraw)
|
||||
inline void
|
||||
VolumeMeter::calculateBallisticsForChannel(int channelNr, uint64_t ts,
|
||||
qreal timeSinceLastRedraw)
|
||||
{
|
||||
if (currentPeak[channelNr] >= displayPeak[channelNr] ||
|
||||
isnan(displayPeak[channelNr])) {
|
||||
|
@ -657,8 +656,10 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
|
|||
} else {
|
||||
// The peak and hold falls back to peak
|
||||
// after 20 seconds.
|
||||
qreal timeSinceLastPeak = (uint64_t)(ts -
|
||||
displayPeakHoldLastUpdateTime[channelNr]) * 0.000000001;
|
||||
qreal timeSinceLastPeak =
|
||||
(uint64_t)(ts -
|
||||
displayPeakHoldLastUpdateTime[channelNr]) *
|
||||
0.000000001;
|
||||
if (timeSinceLastPeak > peakHoldDuration) {
|
||||
displayPeakHold[channelNr] = currentPeak[channelNr];
|
||||
displayPeakHoldLastUpdateTime[channelNr] = ts;
|
||||
|
@ -673,14 +674,15 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
|
|||
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
|
||||
} else {
|
||||
// The peak and hold falls back to peak after 1 second.
|
||||
qreal timeSinceLastPeak = (uint64_t)(ts -
|
||||
qreal timeSinceLastPeak =
|
||||
(uint64_t)(
|
||||
ts -
|
||||
displayInputPeakHoldLastUpdateTime[channelNr]) *
|
||||
0.000000001;
|
||||
if (timeSinceLastPeak > inputPeakHoldDuration) {
|
||||
displayInputPeakHold[channelNr] =
|
||||
currentInputPeak[channelNr];
|
||||
displayInputPeakHoldLastUpdateTime[channelNr] =
|
||||
ts;
|
||||
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,12 +694,14 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
|
|||
// A VU meter will integrate to the new value to 99% in 300 ms.
|
||||
// The calculation here is very simplified and is more accurate
|
||||
// with higher frame-rate.
|
||||
float attack = float((currentMagnitude[channelNr] -
|
||||
float attack =
|
||||
float((currentMagnitude[channelNr] -
|
||||
displayMagnitude[channelNr]) *
|
||||
(timeSinceLastRedraw /
|
||||
magnitudeIntegrationTime) * 0.99);
|
||||
displayMagnitude[channelNr] = CLAMP(displayMagnitude[channelNr]
|
||||
+ attack, (float)minimumLevel, 0);
|
||||
(timeSinceLastRedraw / magnitudeIntegrationTime) *
|
||||
0.99);
|
||||
displayMagnitude[channelNr] =
|
||||
CLAMP(displayMagnitude[channelNr] + attack,
|
||||
(float)minimumLevel, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,7 +802,8 @@ void VolumeMeter::ClipEnding()
|
|||
}
|
||||
|
||||
void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float magnitude, float peak, float peakHold)
|
||||
int height, float magnitude, float peak,
|
||||
float peakHold)
|
||||
{
|
||||
qreal scale = width / minimumLevel;
|
||||
|
||||
|
@ -828,11 +833,12 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
|
|||
painter.fillRect(errorPosition, y, errorLength, height,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < warningPosition) {
|
||||
painter.fillRect(minimumPosition, y, peakPosition -
|
||||
minimumPosition, height,
|
||||
painter.fillRect(minimumPosition, y,
|
||||
peakPosition - minimumPosition, height,
|
||||
foregroundNominalColor);
|
||||
painter.fillRect(peakPosition, y, warningPosition -
|
||||
peakPosition, height, backgroundNominalColor);
|
||||
painter.fillRect(peakPosition, y,
|
||||
warningPosition - peakPosition, height,
|
||||
backgroundNominalColor);
|
||||
painter.fillRect(warningPosition, y, warningLength, height,
|
||||
backgroundWarningColor);
|
||||
painter.fillRect(errorPosition, y, errorLength, height,
|
||||
|
@ -843,8 +849,8 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
|
|||
painter.fillRect(warningPosition, y,
|
||||
peakPosition - warningPosition, height,
|
||||
foregroundWarningColor);
|
||||
painter.fillRect(peakPosition, y, errorPosition -
|
||||
peakPosition, height, backgroundWarningColor);
|
||||
painter.fillRect(peakPosition, y, errorPosition - peakPosition,
|
||||
height, backgroundWarningColor);
|
||||
painter.fillRect(errorPosition, y, errorLength, height,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < maximumPosition) {
|
||||
|
@ -887,7 +893,8 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
|
|||
}
|
||||
|
||||
void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float magnitude, float peak, float peakHold)
|
||||
int height, float magnitude, float peak,
|
||||
float peakHold)
|
||||
{
|
||||
qreal scale = height / minimumLevel;
|
||||
|
||||
|
@ -917,10 +924,12 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
|
|||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < warningPosition) {
|
||||
painter.fillRect(x, minimumPosition, width, peakPosition -
|
||||
minimumPosition, foregroundNominalColor);
|
||||
painter.fillRect(x, peakPosition, width, warningPosition -
|
||||
peakPosition, backgroundNominalColor);
|
||||
painter.fillRect(x, minimumPosition, width,
|
||||
peakPosition - minimumPosition,
|
||||
foregroundNominalColor);
|
||||
painter.fillRect(x, peakPosition, width,
|
||||
warningPosition - peakPosition,
|
||||
backgroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, warningLength,
|
||||
backgroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
|
@ -928,10 +937,12 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
|
|||
} else if (peakPosition < errorPosition) {
|
||||
painter.fillRect(x, minimumPosition, width, nominalLength,
|
||||
foregroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, peakPosition -
|
||||
warningPosition, foregroundWarningColor);
|
||||
painter.fillRect(x, peakPosition, width, errorPosition -
|
||||
peakPosition, backgroundWarningColor);
|
||||
painter.fillRect(x, warningPosition, width,
|
||||
peakPosition - warningPosition,
|
||||
foregroundWarningColor);
|
||||
painter.fillRect(x, peakPosition, width,
|
||||
errorPosition - peakPosition,
|
||||
backgroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, errorLength,
|
||||
backgroundErrorColor);
|
||||
} else if (peakPosition < maximumPosition) {
|
||||
|
@ -939,10 +950,12 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
|
|||
foregroundNominalColor);
|
||||
painter.fillRect(x, warningPosition, width, warningLength,
|
||||
foregroundWarningColor);
|
||||
painter.fillRect(x, errorPosition, width, peakPosition -
|
||||
errorPosition, foregroundErrorColor);
|
||||
painter.fillRect(x, peakPosition, width, maximumPosition -
|
||||
peakPosition, backgroundErrorColor);
|
||||
painter.fillRect(x, errorPosition, width,
|
||||
peakPosition - errorPosition,
|
||||
foregroundErrorColor);
|
||||
painter.fillRect(x, peakPosition, width,
|
||||
maximumPosition - peakPosition,
|
||||
backgroundErrorColor);
|
||||
} else {
|
||||
if (!clipping) {
|
||||
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
|
||||
|
@ -1028,8 +1041,8 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
|||
for (int channelNr = 0; channelNr < displayNrAudioChannels;
|
||||
channelNr++) {
|
||||
|
||||
int channelNrFixed = (displayNrAudioChannels == 1 &&
|
||||
channels > 2)
|
||||
int channelNrFixed =
|
||||
(displayNrAudioChannels == 1 && channels > 2)
|
||||
? 2
|
||||
: channelNr;
|
||||
|
||||
|
|
|
@ -11,73 +11,54 @@
|
|||
class QPushButton;
|
||||
class VolumeMeterTimer;
|
||||
|
||||
class VolumeMeter : public QWidget
|
||||
{
|
||||
class VolumeMeter : public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor backgroundNominalColor
|
||||
READ getBackgroundNominalColor
|
||||
Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor
|
||||
WRITE setBackgroundNominalColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor backgroundWarningColor
|
||||
READ getBackgroundWarningColor
|
||||
Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor
|
||||
WRITE setBackgroundWarningColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor backgroundErrorColor
|
||||
READ getBackgroundErrorColor
|
||||
Q_PROPERTY(QColor backgroundErrorColor READ getBackgroundErrorColor
|
||||
WRITE setBackgroundErrorColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor foregroundNominalColor
|
||||
READ getForegroundNominalColor
|
||||
Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor
|
||||
WRITE setForegroundNominalColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor foregroundWarningColor
|
||||
READ getForegroundWarningColor
|
||||
Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor
|
||||
WRITE setForegroundWarningColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor foregroundErrorColor
|
||||
READ getForegroundErrorColor
|
||||
Q_PROPERTY(QColor foregroundErrorColor READ getForegroundErrorColor
|
||||
WRITE setForegroundErrorColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor clipColor
|
||||
READ getClipColor
|
||||
WRITE setClipColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor magnitudeColor
|
||||
READ getMagnitudeColor
|
||||
WRITE setMagnitudeColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor majorTickColor
|
||||
READ getMajorTickColor
|
||||
WRITE setMajorTickColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor minorTickColor
|
||||
READ getMinorTickColor
|
||||
WRITE setMinorTickColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor
|
||||
DESIGNABLE true)
|
||||
Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE
|
||||
setMagnitudeColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE
|
||||
setMajorTickColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
|
||||
setMinorTickColor DESIGNABLE true)
|
||||
|
||||
// Levels are denoted in dBFS.
|
||||
Q_PROPERTY(qreal minimumLevel
|
||||
READ getMinimumLevel
|
||||
WRITE setMinimumLevel DESIGNABLE true)
|
||||
Q_PROPERTY(qreal warningLevel
|
||||
READ getWarningLevel
|
||||
WRITE setWarningLevel DESIGNABLE true)
|
||||
Q_PROPERTY(qreal errorLevel
|
||||
READ getErrorLevel
|
||||
WRITE setErrorLevel DESIGNABLE true)
|
||||
Q_PROPERTY(qreal clipLevel
|
||||
READ getClipLevel
|
||||
WRITE setClipLevel DESIGNABLE true)
|
||||
Q_PROPERTY(qreal minimumInputLevel
|
||||
READ getMinimumInputLevel
|
||||
WRITE setMinimumInputLevel DESIGNABLE true)
|
||||
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
|
||||
DESIGNABLE true)
|
||||
Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel
|
||||
DESIGNABLE true)
|
||||
Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel
|
||||
DESIGNABLE true)
|
||||
Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel
|
||||
DESIGNABLE true)
|
||||
Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE
|
||||
setMinimumInputLevel DESIGNABLE true)
|
||||
|
||||
// Rates are denoted in dB/second.
|
||||
Q_PROPERTY(qreal peakDecayRate
|
||||
READ getPeakDecayRate
|
||||
WRITE setPeakDecayRate DESIGNABLE true)
|
||||
Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE
|
||||
setPeakDecayRate DESIGNABLE true)
|
||||
|
||||
// Time in seconds for the VU meter to integrate over.
|
||||
Q_PROPERTY(qreal magnitudeIntegrationTime
|
||||
READ getMagnitudeIntegrationTime
|
||||
Q_PROPERTY(
|
||||
qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime
|
||||
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
|
||||
|
||||
// Duration is denoted in seconds.
|
||||
Q_PROPERTY(qreal peakHoldDuration
|
||||
READ getPeakHoldDuration
|
||||
WRITE setPeakHoldDuration DESIGNABLE true)
|
||||
Q_PROPERTY(qreal inputPeakHoldDuration
|
||||
READ getInputPeakHoldDuration
|
||||
Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE
|
||||
setPeakHoldDuration DESIGNABLE true)
|
||||
Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration
|
||||
WRITE setInputPeakHoldDuration DESIGNABLE true)
|
||||
|
||||
private slots:
|
||||
|
@ -93,8 +74,8 @@ private:
|
|||
inline bool detectIdle(uint64_t ts);
|
||||
inline void calculateBallistics(uint64_t ts,
|
||||
qreal timeSinceLastRedraw = 0.0);
|
||||
inline void calculateBallisticsForChannel(int channelNr,
|
||||
uint64_t ts, qreal timeSinceLastRedraw);
|
||||
inline void calculateBallisticsForChannel(int channelNr, uint64_t ts,
|
||||
qreal timeSinceLastRedraw);
|
||||
|
||||
void paintInputMeter(QPainter &painter, int x, int y, int width,
|
||||
int height, float peakHold);
|
||||
|
@ -154,8 +135,7 @@ public:
|
|||
bool vertical = false);
|
||||
~VolumeMeter();
|
||||
|
||||
void setLevels(
|
||||
const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
const float peak[MAX_AUDIO_CHANNELS],
|
||||
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#include "obs-app.hpp"
|
||||
|
||||
OBSUpdate::OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text)
|
||||
: QDialog (parent, Qt::WindowSystemMenuHint |
|
||||
Qt::WindowTitleHint |
|
||||
: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint |
|
||||
Qt::WindowCloseButtonHint),
|
||||
ui(new Ui_OBSUpdate)
|
||||
{
|
||||
|
|
|
@ -9,11 +9,7 @@ class OBSUpdate : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ReturnVal {
|
||||
No,
|
||||
Yes,
|
||||
Skip
|
||||
};
|
||||
enum ReturnVal { No, Yes, Skip };
|
||||
|
||||
OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text);
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ public:
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
|
||||
string &zipBuf, const uint8_t *buffer, DWORD outSize)
|
||||
string &zipBuf, const uint8_t *buffer,
|
||||
DWORD outSize)
|
||||
{
|
||||
strm->avail_in = outSize;
|
||||
strm->next_in = buffer;
|
||||
|
@ -85,11 +86,8 @@ static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HTTPPostData(const wchar_t *url,
|
||||
const BYTE * data,
|
||||
int dataLen,
|
||||
const wchar_t *extraHeaders,
|
||||
int * responseCode,
|
||||
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
|
||||
const wchar_t *extraHeaders, int *responseCode,
|
||||
string &responseBuf)
|
||||
{
|
||||
HttpHandle hSession;
|
||||
|
@ -129,8 +127,7 @@ bool HTTPPostData(const wchar_t *url,
|
|||
|
||||
hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
if (!hSession) {
|
||||
*responseCode = -1;
|
||||
|
@ -141,9 +138,9 @@ bool HTTPPostData(const wchar_t *url,
|
|||
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
|
||||
|
||||
hConnect = WinHttpConnect(hSession, hostName,
|
||||
secure
|
||||
? INTERNET_DEFAULT_HTTPS_PORT
|
||||
: INTERNET_DEFAULT_HTTP_PORT, 0);
|
||||
secure ? INTERNET_DEFAULT_HTTPS_PORT
|
||||
: INTERNET_DEFAULT_HTTP_PORT,
|
||||
0);
|
||||
if (!hConnect) {
|
||||
*responseCode = -2;
|
||||
return false;
|
||||
|
@ -152,14 +149,9 @@ bool HTTPPostData(const wchar_t *url,
|
|||
/* -------------------------------------- *
|
||||
* request data */
|
||||
|
||||
hRequest = WinHttpOpenRequest(hConnect,
|
||||
L"POST",
|
||||
path,
|
||||
nullptr,
|
||||
WINHTTP_NO_REFERER,
|
||||
acceptTypes,
|
||||
secure
|
||||
? WINHTTP_FLAG_SECURE |
|
||||
hRequest = WinHttpOpenRequest(hConnect, L"POST", path, nullptr,
|
||||
WINHTTP_NO_REFERER, acceptTypes,
|
||||
secure ? WINHTTP_FLAG_SECURE |
|
||||
WINHTTP_FLAG_REFRESH
|
||||
: WINHTTP_FLAG_REFRESH);
|
||||
if (!hRequest) {
|
||||
|
@ -191,12 +183,9 @@ bool HTTPPostData(const wchar_t *url,
|
|||
DWORD statusCodeLen;
|
||||
|
||||
statusCodeLen = sizeof(statusCode);
|
||||
if (!WinHttpQueryHeaders(hRequest,
|
||||
WINHTTP_QUERY_STATUS_CODE,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX,
|
||||
&statusCode,
|
||||
&statusCodeLen,
|
||||
WINHTTP_NO_HEADER_INDEX)) {
|
||||
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
|
||||
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
|
||||
*responseCode = -4;
|
||||
return false;
|
||||
} else {
|
||||
|
@ -204,12 +193,9 @@ bool HTTPPostData(const wchar_t *url,
|
|||
}
|
||||
|
||||
encodingLen = sizeof(encoding);
|
||||
if (!WinHttpQueryHeaders(hRequest,
|
||||
WINHTTP_QUERY_CONTENT_ENCODING,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX,
|
||||
encoding,
|
||||
&encodingLen,
|
||||
WINHTTP_NO_HEADER_INDEX)) {
|
||||
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
|
||||
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
|
||||
encoding[0] = 0;
|
||||
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
|
||||
*responseCode = -5;
|
||||
|
@ -311,8 +297,8 @@ bool HTTPPostData(const wchar_t *url,
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
|
||||
string &zipBuf, const uint8_t *buffer, DWORD outSize,
|
||||
int *responseCode)
|
||||
string &zipBuf, const uint8_t *buffer,
|
||||
DWORD outSize, int *responseCode)
|
||||
{
|
||||
strm->avail_in = outSize;
|
||||
strm->next_in = buffer;
|
||||
|
@ -326,10 +312,8 @@ static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
|
|||
return false;
|
||||
|
||||
DWORD written;
|
||||
if (!WriteFile(updateFile,
|
||||
zipBuf.data(),
|
||||
MAX_BUF_SIZE - strm->avail_out,
|
||||
&written,
|
||||
if (!WriteFile(updateFile, zipBuf.data(),
|
||||
MAX_BUF_SIZE - strm->avail_out, &written,
|
||||
nullptr)) {
|
||||
*responseCode = -10;
|
||||
return false;
|
||||
|
@ -363,10 +347,8 @@ static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HTTPGetFile(HINTERNET hConnect,
|
||||
const wchar_t *url,
|
||||
const wchar_t *outputPath,
|
||||
const wchar_t *extraHeaders,
|
||||
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
|
||||
const wchar_t *outputPath, const wchar_t *extraHeaders,
|
||||
int *responseCode)
|
||||
{
|
||||
HttpHandle hRequest;
|
||||
|
@ -399,14 +381,9 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
/* -------------------------------------- *
|
||||
* request data */
|
||||
|
||||
hRequest = WinHttpOpenRequest(hConnect,
|
||||
L"GET",
|
||||
path,
|
||||
nullptr,
|
||||
WINHTTP_NO_REFERER,
|
||||
acceptTypes,
|
||||
secure
|
||||
? WINHTTP_FLAG_SECURE |
|
||||
hRequest = WinHttpOpenRequest(hConnect, L"GET", path, nullptr,
|
||||
WINHTTP_NO_REFERER, acceptTypes,
|
||||
secure ? WINHTTP_FLAG_SECURE |
|
||||
WINHTTP_FLAG_REFRESH
|
||||
: WINHTTP_FLAG_REFRESH);
|
||||
if (!hRequest) {
|
||||
|
@ -415,7 +392,8 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
}
|
||||
|
||||
bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
|
||||
extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
|
||||
extraHeaders ? -1 : 0,
|
||||
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
|
||||
|
||||
/* -------------------------------------- *
|
||||
* end request */
|
||||
|
@ -437,12 +415,9 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
DWORD statusCodeLen;
|
||||
|
||||
statusCodeLen = sizeof(statusCode);
|
||||
if (!WinHttpQueryHeaders(hRequest,
|
||||
WINHTTP_QUERY_STATUS_CODE,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX,
|
||||
&statusCode,
|
||||
&statusCodeLen,
|
||||
WINHTTP_NO_HEADER_INDEX)) {
|
||||
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
|
||||
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
|
||||
*responseCode = -4;
|
||||
return false;
|
||||
} else {
|
||||
|
@ -450,12 +425,9 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
}
|
||||
|
||||
encodingLen = sizeof(encoding);
|
||||
if (!WinHttpQueryHeaders(hRequest,
|
||||
WINHTTP_QUERY_CONTENT_ENCODING,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX,
|
||||
encoding,
|
||||
&encodingLen,
|
||||
WINHTTP_NO_HEADER_INDEX)) {
|
||||
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
|
||||
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
|
||||
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
|
||||
encoding[0] = 0;
|
||||
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
|
||||
*responseCode = -5;
|
||||
|
@ -502,8 +474,8 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
DWORD dwSize, outSize;
|
||||
int lastPosition = 0;
|
||||
|
||||
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0,
|
||||
nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, nullptr,
|
||||
CREATE_ALWAYS, 0, nullptr);
|
||||
if (!updateFile.Valid()) {
|
||||
*responseCode = -7;
|
||||
return false;
|
||||
|
@ -529,17 +501,18 @@ bool HTTPGetFile(HINTERNET hConnect,
|
|||
|
||||
if (gzip) {
|
||||
if (!ReadHTTPZippedFile(strm, updateFile,
|
||||
zipBuf, buffer,
|
||||
outSize, responseCode))
|
||||
zipBuf, buffer, outSize,
|
||||
responseCode))
|
||||
return false;
|
||||
} else {
|
||||
if (!ReadHTTPFile(updateFile, buffer,
|
||||
outSize, responseCode))
|
||||
if (!ReadHTTPFile(updateFile, buffer, outSize,
|
||||
responseCode))
|
||||
return false;
|
||||
}
|
||||
|
||||
int position = (int)(((float)completedFileSize /
|
||||
(float)totalFileSize) * 100.0f);
|
||||
(float)totalFileSize) *
|
||||
100.0f);
|
||||
if (position > lastPosition) {
|
||||
lastPosition = position;
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
|
||||
|
|
|
@ -48,10 +48,7 @@ public:
|
|||
|
||||
inline bool init_decoder()
|
||||
{
|
||||
lzma_ret ret = lzma_stream_decoder(
|
||||
&strm,
|
||||
200 * 1024 * 1024,
|
||||
0);
|
||||
lzma_ret ret = lzma_stream_decoder(&strm, 200 * 1024 * 1024, 0);
|
||||
initialized = (ret == LZMA_OK);
|
||||
return initialized;
|
||||
}
|
||||
|
@ -225,8 +222,8 @@ try {
|
|||
/* --------------------------------- *
|
||||
* open patch and file to patch */
|
||||
|
||||
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr,
|
||||
OPEN_EXISTING, 0, nullptr);
|
||||
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr, OPEN_EXISTING,
|
||||
0, nullptr);
|
||||
if (!hPatch.Valid())
|
||||
throw int(GetLastError());
|
||||
|
||||
|
@ -311,8 +308,8 @@ try {
|
|||
|
||||
DWORD written;
|
||||
|
||||
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize,
|
||||
&written, nullptr);
|
||||
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize, &written,
|
||||
nullptr);
|
||||
if (!success || written != newsize)
|
||||
throw int(GetLastError());
|
||||
|
||||
|
|
|
@ -65,8 +65,7 @@ static inline bool HasVS2017Redist2()
|
|||
wchar_t path[MAX_PATH];
|
||||
WIN32_FIND_DATAW wfd;
|
||||
HANDLE handle;
|
||||
int folder = (is32bit && is_64bit_windows())
|
||||
? CSIDL_SYSTEMX86
|
||||
int folder = (is32bit && is_64bit_windows()) ? CSIDL_SYSTEMX86
|
||||
: CSIDL_SYSTEM;
|
||||
|
||||
SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, base);
|
||||
|
@ -97,7 +96,8 @@ static bool HasVS2017Redist()
|
|||
PVOID old = nullptr;
|
||||
bool redirect = !!Wow64DisableWow64FsRedirection(&old);
|
||||
bool success = HasVS2017Redist2();
|
||||
if (redirect) Wow64RevertWow64FsRedirection(old);
|
||||
if (redirect)
|
||||
Wow64RevertWow64FsRedirection(old);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -139,8 +139,8 @@ try {
|
|||
if (!hSrc.Valid())
|
||||
throw LastError();
|
||||
|
||||
hDest = CreateFile(dest, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
0, nullptr);
|
||||
hDest = CreateFile(dest, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0,
|
||||
nullptr);
|
||||
if (!hDest.Valid())
|
||||
throw LastError();
|
||||
|
||||
|
@ -182,10 +182,7 @@ static bool IsSafeFilename(const wchar_t *path)
|
|||
return false;
|
||||
|
||||
while (*p) {
|
||||
if (!isalnum(*p) &&
|
||||
*p != '.' &&
|
||||
*p != '/' &&
|
||||
*p != '_' &&
|
||||
if (!isalnum(*p) && *p != '.' && *p != '/' && *p != '_' &&
|
||||
*p != '-')
|
||||
return false;
|
||||
p++;
|
||||
|
@ -213,11 +210,7 @@ static string QuickReadFile(const wchar_t *path)
|
|||
data.resize((size_t)size.QuadPart);
|
||||
|
||||
DWORD read;
|
||||
if (!ReadFile(handle,
|
||||
&data[0],
|
||||
(DWORD)data.size(),
|
||||
&read,
|
||||
nullptr)) {
|
||||
if (!ReadFile(handle, &data[0], (DWORD)data.size(), &read, nullptr)) {
|
||||
return string();
|
||||
}
|
||||
if (read != size.QuadPart) {
|
||||
|
@ -293,8 +286,7 @@ struct update_t {
|
|||
|
||||
void CleanPartialUpdate()
|
||||
{
|
||||
if (state == STATE_INSTALL_FAILED ||
|
||||
state == STATE_INSTALLED) {
|
||||
if (state == STATE_INSTALL_FAILED || state == STATE_INSTALLED) {
|
||||
if (!previousFile.empty()) {
|
||||
DeleteFile(outputPath.c_str());
|
||||
MyCopyFile(previousFile.c_str(),
|
||||
|
@ -347,8 +339,7 @@ bool DownloadWorkerThread()
|
|||
HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!hSession) {
|
||||
downloadThreadFailure = true;
|
||||
Status(L"Update failed: Couldn't open obsproject.com");
|
||||
|
@ -358,7 +349,8 @@ bool DownloadWorkerThread()
|
|||
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
|
||||
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
|
||||
|
||||
HttpHandle hConnect = WinHttpConnect(hSession, L"cdn-fastly.obsproject.com",
|
||||
HttpHandle hConnect = WinHttpConnect(hSession,
|
||||
L"cdn-fastly.obsproject.com",
|
||||
INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hConnect) {
|
||||
downloadThreadFailure = true;
|
||||
|
@ -395,8 +387,7 @@ bool DownloadWorkerThread()
|
|||
|
||||
Status(L"Downloading %s", update.outputPath.c_str());
|
||||
|
||||
if (!HTTPGetFile(hConnect,
|
||||
update.sourceURL.c_str(),
|
||||
if (!HTTPGetFile(hConnect, update.sourceURL.c_str(),
|
||||
update.tempPath.c_str(),
|
||||
L"Accept-Encoding: gzip",
|
||||
&responseCode)) {
|
||||
|
@ -405,8 +396,7 @@ bool DownloadWorkerThread()
|
|||
DeleteFile(update.tempPath.c_str());
|
||||
Status(L"Update failed: Could not download "
|
||||
L"%s (error code %d)",
|
||||
update.outputPath.c_str(),
|
||||
responseCode);
|
||||
update.outputPath.c_str(), responseCode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -415,8 +405,7 @@ bool DownloadWorkerThread()
|
|||
DeleteFile(update.tempPath.c_str());
|
||||
Status(L"Update failed: Could not download "
|
||||
L"%s (error code %d)",
|
||||
update.outputPath.c_str(),
|
||||
responseCode);
|
||||
update.outputPath.c_str(), responseCode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -489,10 +478,8 @@ static inline DWORD WaitIfOBS(DWORD id, const wchar_t *expected)
|
|||
wchar_t *name;
|
||||
*path = 0;
|
||||
|
||||
WinHandle proc = OpenProcess(
|
||||
PROCESS_QUERY_INFORMATION |
|
||||
PROCESS_VM_READ |
|
||||
SYNCHRONIZE,
|
||||
WinHandle proc = OpenProcess(PROCESS_QUERY_INFORMATION |
|
||||
PROCESS_VM_READ | SYNCHRONIZE,
|
||||
false, id);
|
||||
if (!proc.Valid())
|
||||
return WAITIFOBS_WRONG_PROCESS;
|
||||
|
@ -578,13 +565,15 @@ static bool NonCorePackageInstalled(const char *name)
|
|||
{
|
||||
if (is32bit) {
|
||||
if (strcmp(name, "obs-browser") == 0) {
|
||||
return FileExists(L"obs-plugins\\32bit\\obs-browser.dll");
|
||||
return FileExists(
|
||||
L"obs-plugins\\32bit\\obs-browser.dll");
|
||||
} else if (strcmp(name, "realsense") == 0) {
|
||||
return FileExists(L"obs-plugins\\32bit\\win-ivcam.dll");
|
||||
}
|
||||
} else {
|
||||
if (strcmp(name, "obs-browser") == 0) {
|
||||
return FileExists(L"obs-plugins\\64bit\\obs-browser.dll");
|
||||
return FileExists(
|
||||
L"obs-plugins\\64bit\\obs-browser.dll");
|
||||
} else if (strcmp(name, "realsense") == 0) {
|
||||
return FileExists(L"obs-plugins\\64bit\\win-ivcam.dll");
|
||||
}
|
||||
|
@ -694,14 +683,15 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx,
|
|||
|
||||
if (!IsSafeFilename(updateFileName)) {
|
||||
Status(L"Update failed: Unsafe path '%s' found in "
|
||||
L"manifest", updateFileName);
|
||||
L"manifest",
|
||||
updateFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
StringCbPrintf(sourceURL, sizeof(sourceURL), L"%s/%s/%s",
|
||||
UPDATE_URL, wPackageName, updateFileName);
|
||||
StringCbPrintf(tempFilePath, sizeof(tempFilePath),
|
||||
L"%s\\%s", tempPath, updateHashStr);
|
||||
StringCbPrintf(tempFilePath, sizeof(tempFilePath), L"%s\\%s",
|
||||
tempPath, updateHashStr);
|
||||
|
||||
/* Check file hash */
|
||||
|
||||
|
@ -750,8 +740,7 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx,
|
|||
}
|
||||
|
||||
static void UpdateWithPatchIfAvailable(const char *name, const char *hash,
|
||||
const char *source,
|
||||
int size)
|
||||
const char *source, int size)
|
||||
{
|
||||
wchar_t widePatchableFilename[MAX_PATH];
|
||||
wchar_t widePatchHash[MAX_PATH];
|
||||
|
@ -825,11 +814,9 @@ static bool UpdateFile(update_t &file)
|
|||
curFileName = baseName;
|
||||
|
||||
/* Backup the existing file in case a rollback is needed */
|
||||
StringCbCopy(oldFileRenamedPath,
|
||||
sizeof(oldFileRenamedPath),
|
||||
StringCbCopy(oldFileRenamedPath, sizeof(oldFileRenamedPath),
|
||||
file.outputPath.c_str());
|
||||
StringCbCat(oldFileRenamedPath,
|
||||
sizeof(oldFileRenamedPath),
|
||||
StringCbCat(oldFileRenamedPath, sizeof(oldFileRenamedPath),
|
||||
L".old");
|
||||
|
||||
if (!MyCopyFile(file.outputPath.c_str(), oldFileRenamedPath)) {
|
||||
|
@ -853,8 +840,7 @@ static bool UpdateFile(update_t &file)
|
|||
bool installed_ok;
|
||||
|
||||
if (file.patchable) {
|
||||
error_code = ApplyPatch(
|
||||
file.tempPath.c_str(),
|
||||
error_code = ApplyPatch(file.tempPath.c_str(),
|
||||
file.outputPath.c_str());
|
||||
installed_ok = (error_code == 0);
|
||||
|
||||
|
@ -882,8 +868,7 @@ static bool UpdateFile(update_t &file)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
installed_ok = MyCopyFile(
|
||||
file.tempPath.c_str(),
|
||||
installed_ok = MyCopyFile(file.tempPath.c_str(),
|
||||
file.outputPath.c_str());
|
||||
error_code = GetLastError();
|
||||
}
|
||||
|
@ -900,8 +885,7 @@ static bool UpdateFile(update_t &file)
|
|||
else
|
||||
Status(L"Update failed: Couldn't update %s "
|
||||
L"(error %d)",
|
||||
curFileName,
|
||||
GetLastError());
|
||||
curFileName, GetLastError());
|
||||
|
||||
file.state = STATE_INSTALL_FAILED;
|
||||
return false;
|
||||
|
@ -923,13 +907,11 @@ static bool UpdateFile(update_t &file)
|
|||
|
||||
file.previousFile = L"";
|
||||
|
||||
bool success = !!MyCopyFile(
|
||||
file.tempPath.c_str(),
|
||||
bool success = !!MyCopyFile(file.tempPath.c_str(),
|
||||
file.outputPath.c_str());
|
||||
if (!success) {
|
||||
Status(L"Update failed: Couldn't install %s (error %d)",
|
||||
file.outputPath.c_str(),
|
||||
GetLastError());
|
||||
file.outputPath.c_str(), GetLastError());
|
||||
file.state = STATE_INSTALL_FAILED;
|
||||
return false;
|
||||
}
|
||||
|
@ -944,8 +926,7 @@ static wchar_t tempPath[MAX_PATH] = {};
|
|||
|
||||
#define PATCH_MANIFEST_URL \
|
||||
L"https://obsproject.com/update_studio/getpatchmanifest"
|
||||
#define HASH_NULL \
|
||||
L"0000000000000000000000000000000000000000"
|
||||
#define HASH_NULL L"0000000000000000000000000000000000000000"
|
||||
|
||||
static bool UpdateVS2017Redists(json_t *root)
|
||||
{
|
||||
|
@ -957,8 +938,7 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!hSession) {
|
||||
Status(L"Update failed: Couldn't open obsproject.com");
|
||||
return false;
|
||||
|
@ -967,7 +947,8 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
|
||||
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
|
||||
|
||||
HttpHandle hConnect = WinHttpConnect(hSession, L"cdn-fastly.obsproject.com",
|
||||
HttpHandle hConnect = WinHttpConnect(hSession,
|
||||
L"cdn-fastly.obsproject.com",
|
||||
INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hConnect) {
|
||||
Status(L"Update failed: Couldn't connect to cdn-fastly.obsproject.com");
|
||||
|
@ -986,8 +967,7 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
|
||||
Status(L"Downloading %s", L"Visual C++ 2017 Redistributable");
|
||||
|
||||
const wchar_t *file = (is32bit)
|
||||
? L"vc2017redist_x86.exe"
|
||||
const wchar_t *file = (is32bit) ? L"vc2017redist_x86.exe"
|
||||
: L"vc2017redist_x64.exe";
|
||||
|
||||
wstring sourceURL;
|
||||
|
@ -999,26 +979,21 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
destPath += L"\\";
|
||||
destPath += file;
|
||||
|
||||
if (!HTTPGetFile(hConnect,
|
||||
sourceURL.c_str(),
|
||||
destPath.c_str(),
|
||||
L"Accept-Encoding: gzip",
|
||||
&responseCode)) {
|
||||
if (!HTTPGetFile(hConnect, sourceURL.c_str(), destPath.c_str(),
|
||||
L"Accept-Encoding: gzip", &responseCode)) {
|
||||
|
||||
DeleteFile(destPath.c_str());
|
||||
Status(L"Update failed: Could not download "
|
||||
L"%s (error code %d)",
|
||||
L"Visual C++ 2017 Redistributable",
|
||||
responseCode);
|
||||
L"Visual C++ 2017 Redistributable", responseCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* Get expected hash */
|
||||
|
||||
json_t *redistJson = json_object_get(root, is32bit
|
||||
? "vc2017_redist_x86"
|
||||
: "vc2017_redist_x64");
|
||||
json_t *redistJson = json_object_get(
|
||||
root, is32bit ? "vc2017_redist_x86" : "vc2017_redist_x64");
|
||||
if (!redistJson) {
|
||||
Status(L"Update failed: Could not parse VC2017 redist json");
|
||||
return false;
|
||||
|
@ -1071,8 +1046,8 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
STARTUPINFO si = {};
|
||||
si.cb = sizeof(si);
|
||||
|
||||
bool success = !!CreateProcessW(destPath.c_str(), commandline,
|
||||
nullptr, nullptr, false, CREATE_NO_WINDOW,
|
||||
bool success = !!CreateProcessW(destPath.c_str(), commandline, nullptr,
|
||||
nullptr, false, CREATE_NO_WINDOW,
|
||||
nullptr, nullptr, &si, &pi);
|
||||
if (success) {
|
||||
Status(L"Installing %s...", L"Visual C++ 2017 Redistributable");
|
||||
|
@ -1083,8 +1058,7 @@ static bool UpdateVS2017Redists(json_t *root)
|
|||
} else {
|
||||
Status(L"Update failed: Could not execute "
|
||||
L"%s (error code %d)",
|
||||
L"Visual C++ 2017 Redistributable",
|
||||
(int)GetLastError());
|
||||
L"Visual C++ 2017 Redistributable", (int)GetLastError());
|
||||
}
|
||||
|
||||
DeleteFile(destPath.c_str());
|
||||
|
@ -1102,8 +1076,8 @@ static bool Update(wchar_t *cmdLine)
|
|||
/* ------------------------------------- *
|
||||
* Check to make sure OBS isn't running */
|
||||
|
||||
HANDLE hObsUpdateMutex = OpenMutexW(SYNCHRONIZE, false,
|
||||
L"OBSStudioUpdateMutex");
|
||||
HANDLE hObsUpdateMutex =
|
||||
OpenMutexW(SYNCHRONIZE, false, L"OBSStudioUpdateMutex");
|
||||
if (hObsUpdateMutex) {
|
||||
HANDLE hWait[2];
|
||||
hWait[0] = hObsUpdateMutex;
|
||||
|
@ -1179,7 +1153,8 @@ static bool Update(wchar_t *cmdLine)
|
|||
} else {
|
||||
CoTaskMemPtr<wchar_t> pOut;
|
||||
HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData,
|
||||
KF_FLAG_DEFAULT, nullptr, &pOut);
|
||||
KF_FLAG_DEFAULT, nullptr,
|
||||
&pOut);
|
||||
if (hr != S_OK) {
|
||||
Status(L"Update failed: Could not determine AppData "
|
||||
L"location");
|
||||
|
@ -1189,8 +1164,7 @@ static bool Update(wchar_t *cmdLine)
|
|||
StringCbCopy(lpAppDataPath, sizeof(lpAppDataPath), pOut);
|
||||
}
|
||||
|
||||
StringCbCat(lpAppDataPath, sizeof(lpAppDataPath),
|
||||
L"\\obs-studio");
|
||||
StringCbCat(lpAppDataPath, sizeof(lpAppDataPath), L"\\obs-studio");
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Get download path */
|
||||
|
@ -1233,7 +1207,8 @@ static bool Update(wchar_t *cmdLine)
|
|||
|
||||
if (!root) {
|
||||
Status(L"Update failed: Couldn't parse update "
|
||||
L"manifest: %S", error.text);
|
||||
L"manifest: %S",
|
||||
error.text);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1327,15 +1302,14 @@ static bool Update(wchar_t *cmdLine)
|
|||
|
||||
compressedJson.resize(compressSize);
|
||||
compress2((Bytef *)&compressedJson[0], &compressSize,
|
||||
(const Bytef*)post_body, len,
|
||||
Z_BEST_COMPRESSION);
|
||||
(const Bytef *)post_body, len, Z_BEST_COMPRESSION);
|
||||
compressedJson.resize(compressSize);
|
||||
|
||||
bool success = !!HTTPPostData(PATCH_MANIFEST_URL,
|
||||
(BYTE *)&compressedJson[0],
|
||||
(int)compressedJson.size(),
|
||||
L"Accept-Encoding: gzip", &responseCode,
|
||||
newManifest);
|
||||
L"Accept-Encoding: gzip",
|
||||
&responseCode, newManifest);
|
||||
free(post_body);
|
||||
|
||||
if (!success)
|
||||
|
@ -1416,8 +1390,7 @@ static bool Update(wchar_t *cmdLine)
|
|||
int updatesInstalled = 0;
|
||||
int lastPosition = 0;
|
||||
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
|
||||
PBM_SETPOS, 0, 0);
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETPOS, 0, 0);
|
||||
|
||||
for (update_t &update : updates) {
|
||||
if (!UpdateFile(update)) {
|
||||
|
@ -1425,7 +1398,8 @@ static bool Update(wchar_t *cmdLine)
|
|||
} else {
|
||||
updatesInstalled++;
|
||||
int position = (int)(((float)updatesInstalled /
|
||||
(float)completedUpdates) * 100.0f);
|
||||
(float)completedUpdates) *
|
||||
100.0f);
|
||||
if (position > lastPosition) {
|
||||
lastPosition = position;
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
|
||||
|
@ -1445,8 +1419,7 @@ static bool Update(wchar_t *cmdLine)
|
|||
DeleteFile(update.tempPath.c_str());
|
||||
}
|
||||
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
|
||||
PBM_SETPOS, 100, 0);
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETPOS, 100, 0);
|
||||
|
||||
Status(L"Update complete.");
|
||||
SetDlgItemText(hwndMain, IDC_BUTTON, L"Launch OBS");
|
||||
|
@ -1508,15 +1481,13 @@ static void LaunchOBS()
|
|||
GetCurrentDirectory(_countof(cwd) - 1, cwd);
|
||||
|
||||
StringCbCopy(obsPath, sizeof(obsPath), cwd);
|
||||
StringCbCat(obsPath, sizeof(obsPath), is32bit
|
||||
? L"\\bin\\32bit"
|
||||
: L"\\bin\\64bit");
|
||||
StringCbCat(obsPath, sizeof(obsPath),
|
||||
is32bit ? L"\\bin\\32bit" : L"\\bin\\64bit");
|
||||
SetCurrentDirectory(obsPath);
|
||||
StringCbCopy(newCwd, sizeof(newCwd), obsPath);
|
||||
|
||||
StringCbCat(obsPath, sizeof(obsPath), is32bit
|
||||
? L"\\obs32.exe"
|
||||
: L"\\obs64.exe");
|
||||
StringCbCat(obsPath, sizeof(obsPath),
|
||||
is32bit ? L"\\obs32.exe" : L"\\obs64.exe");
|
||||
|
||||
if (!FileExists(obsPath)) {
|
||||
StringCbCopy(obsPath, sizeof(obsPath), cwd);
|
||||
|
@ -1544,13 +1515,13 @@ static void LaunchOBS()
|
|||
ShellExecuteEx(&execInfo);
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG: {
|
||||
static HICON hMainIcon = LoadIcon(hinstMain,
|
||||
MAKEINTRESOURCE(IDI_ICON1));
|
||||
static HICON hMainIcon =
|
||||
LoadIcon(hinstMain, MAKEINTRESOURCE(IDI_ICON1));
|
||||
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hMainIcon);
|
||||
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hMainIcon);
|
||||
return true;
|
||||
|
@ -1559,8 +1530,8 @@ static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message,
|
|||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == IDC_BUTTON) {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
DWORD result = WaitForSingleObject(
|
||||
updateThread, 0);
|
||||
DWORD result =
|
||||
WaitForSingleObject(updateThread, 0);
|
||||
if (result == WAIT_OBJECT_0) {
|
||||
if (updateFailed)
|
||||
PostQuitMessage(0);
|
||||
|
@ -1627,7 +1598,8 @@ static bool HasElevation()
|
|||
BOOL success;
|
||||
|
||||
success = AllocateAndInitializeSid(&sia, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid);
|
||||
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
|
||||
0, 0, &sid);
|
||||
if (success && sid) {
|
||||
CheckTokenMembership(nullptr, sid, &elevated);
|
||||
FreeSid(sid);
|
||||
|
@ -1641,8 +1613,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
|||
INITCOMMONCONTROLSEX icce;
|
||||
|
||||
if (!HasElevation()) {
|
||||
HANDLE hLowMutex = CreateMutexW(nullptr, true,
|
||||
L"OBSUpdaterRunningAsNonAdminUser");
|
||||
HANDLE hLowMutex = CreateMutexW(
|
||||
nullptr, true, L"OBSUpdaterRunningAsNonAdminUser");
|
||||
|
||||
RestartAsAdmin(lpCmdLine);
|
||||
|
||||
|
@ -1674,8 +1646,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
|||
InitCommonControlsEx(&icce);
|
||||
|
||||
hwndMain = CreateDialog(hInstance,
|
||||
MAKEINTRESOURCE(IDD_UPDATEDIALOG), nullptr,
|
||||
UpdateDialogProc);
|
||||
MAKEINTRESOURCE(IDD_UPDATEDIALOG),
|
||||
nullptr, UpdateDialogProc);
|
||||
if (!hwndMain) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1684,8 +1656,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
|||
SetForegroundWindow(hwndMain);
|
||||
|
||||
cancelRequested = CreateEvent(nullptr, true, false, nullptr);
|
||||
updateThread = CreateThread(nullptr, 0, UpdateThread,
|
||||
lpCmdLine, 0, nullptr);
|
||||
updateThread = CreateThread(nullptr, 0, UpdateThread, lpCmdLine,
|
||||
0, nullptr);
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, nullptr, 0, 0)) {
|
||||
|
@ -1697,8 +1669,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
|||
|
||||
/* there is no non-elevated process waiting for us if UAC is
|
||||
* disabled */
|
||||
WinHandle hMutex = OpenMutex(SYNCHRONIZE, false,
|
||||
L"OBSUpdaterRunningAsNonAdminUser");
|
||||
WinHandle hMutex = OpenMutex(
|
||||
SYNCHRONIZE, false, L"OBSUpdaterRunningAsNonAdminUser");
|
||||
if (msg.wParam == 1 && !hMutex) {
|
||||
LaunchOBS();
|
||||
}
|
||||
|
|
|
@ -45,32 +45,28 @@
|
|||
#define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1)
|
||||
|
||||
#if defined _M_IX86
|
||||
#pragma comment(linker, \
|
||||
"/manifestdependency:\"type='win32' " \
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
|
||||
"name='Microsoft.Windows.Common-Controls' " \
|
||||
"version='6.0.0.0' " \
|
||||
"processorArchitecture='x86' " \
|
||||
"publicKeyToken='6595b64144ccf1df' " \
|
||||
"language='*'\"")
|
||||
#elif defined _M_IA64
|
||||
#pragma comment(linker, \
|
||||
"/manifestdependency:\"type='win32' " \
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
|
||||
"name='Microsoft.Windows.Common-Controls' " \
|
||||
"version='6.0.0.0' " \
|
||||
"processorArchitecture='ia64' " \
|
||||
"publicKeyToken='6595b64144ccf1df' " \
|
||||
"language='*'\"")
|
||||
#elif defined _M_X64
|
||||
#pragma comment(linker, \
|
||||
"/manifestdependency:\"type='win32' " \
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
|
||||
"name='Microsoft.Windows.Common-Controls' " \
|
||||
"version='6.0.0.0' " \
|
||||
"processorArchitecture='amd64' " \
|
||||
"publicKeyToken='6595b64144ccf1df' " \
|
||||
"language='*'\"")
|
||||
#else
|
||||
#pragma comment(linker, \
|
||||
"/manifestdependency:\"type='win32' " \
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
|
||||
"name='Microsoft.Windows.Common-Controls' " \
|
||||
"version='6.0.0.0' processorArchitecture='*' " \
|
||||
"publicKeyToken='6595b64144ccf1df' " \
|
||||
|
@ -81,16 +77,11 @@
|
|||
#include <jansson.h>
|
||||
#include "resource.h"
|
||||
|
||||
bool HTTPGetFile(HINTERNET hConnect,
|
||||
const wchar_t *url,
|
||||
const wchar_t *outputPath,
|
||||
const wchar_t *extraHeaders,
|
||||
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
|
||||
const wchar_t *outputPath, const wchar_t *extraHeaders,
|
||||
int *responseCode);
|
||||
bool HTTPPostData(const wchar_t *url,
|
||||
const BYTE * data,
|
||||
int dataLen,
|
||||
const wchar_t *extraHeaders,
|
||||
int * responseCode,
|
||||
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
|
||||
const wchar_t *extraHeaders, int *responseCode,
|
||||
std::string &response);
|
||||
|
||||
void HashToString(const BYTE *in, wchar_t *out);
|
||||
|
|
|
@ -78,7 +78,8 @@ public:
|
|||
inline Json(const Json &from) : json(json_incref(from.json)) {}
|
||||
inline Json(Json &&from) : json(from.json) { from.json = nullptr; }
|
||||
|
||||
inline ~Json() {
|
||||
inline ~Json()
|
||||
{
|
||||
if (json)
|
||||
json_decref(json);
|
||||
}
|
||||
|
|
|
@ -120,8 +120,7 @@ static const unsigned char obs_pub[] = {
|
|||
0x42, 0x61, 0x35, 0x66, 0x37, 0x4c, 0x6f, 0x4b, 0x38, 0x43, 0x41, 0x77,
|
||||
0x45, 0x41, 0x41, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b,
|
||||
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
|
||||
};
|
||||
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a};
|
||||
static const unsigned int obs_pub_len = 800;
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -132,23 +131,18 @@ try {
|
|||
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
|
||||
return false;
|
||||
|
||||
WinHandle handle = CreateFileW(
|
||||
w_file,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
nullptr,
|
||||
CREATE_ALWAYS,
|
||||
FILE_FLAG_WRITE_THROUGH,
|
||||
WinHandle handle = CreateFileW(w_file, GENERIC_WRITE, 0, nullptr,
|
||||
CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,
|
||||
nullptr);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
throw strprintf("Failed to open file '%s': %lu",
|
||||
file, GetLastError());
|
||||
throw strprintf("Failed to open file '%s': %lu", file,
|
||||
GetLastError());
|
||||
|
||||
DWORD written;
|
||||
if (!WriteFile(handle, data, (DWORD)size, &written, nullptr))
|
||||
throw strprintf("Failed to write file '%s': %lu",
|
||||
file, GetLastError());
|
||||
throw strprintf("Failed to write file '%s': %lu", file,
|
||||
GetLastError());
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -163,26 +157,20 @@ try {
|
|||
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
|
||||
return false;
|
||||
|
||||
WinHandle handle = CreateFileW(
|
||||
w_file,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
nullptr);
|
||||
WinHandle handle = CreateFileW(w_file, GENERIC_READ, FILE_SHARE_READ,
|
||||
nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
throw strprintf("Failed to open file '%s': %lu",
|
||||
file, GetLastError());
|
||||
throw strprintf("Failed to open file '%s': %lu", file,
|
||||
GetLastError());
|
||||
|
||||
DWORD size = GetFileSize(handle, nullptr);
|
||||
data.resize(size);
|
||||
|
||||
DWORD read;
|
||||
if (!ReadFile(handle, &data[0], size, &read, nullptr))
|
||||
throw strprintf("Failed to write file '%s': %lu",
|
||||
file, GetLastError());
|
||||
throw strprintf("Failed to write file '%s': %lu", file,
|
||||
GetLastError());
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -216,8 +204,8 @@ try {
|
|||
WinHandle handle = CreateFileW(w_path, GENERIC_READ, FILE_SHARE_READ,
|
||||
nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
throw strprintf("Failed to open file '%s': %lu",
|
||||
path, GetLastError());
|
||||
throw strprintf("Failed to open file '%s': %lu", path,
|
||||
GetLastError());
|
||||
|
||||
vector<BYTE> buf;
|
||||
buf.resize(65536);
|
||||
|
@ -226,8 +214,8 @@ try {
|
|||
DWORD read = 0;
|
||||
if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
|
||||
nullptr))
|
||||
throw strprintf("Failed to read file '%s': %lu",
|
||||
path, GetLastError());
|
||||
throw strprintf("Failed to read file '%s': %lu", path,
|
||||
GetLastError());
|
||||
|
||||
if (!read)
|
||||
break;
|
||||
|
@ -272,41 +260,26 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
|
|||
/* Signature in little-endian format */
|
||||
vector<BYTE> reversedSig;
|
||||
|
||||
if (!CryptStringToBinaryA((LPCSTR)obs_pub,
|
||||
obs_pub_len,
|
||||
CRYPT_STRING_BASE64HEADER,
|
||||
binaryKey,
|
||||
&binaryKeyLen,
|
||||
nullptr,
|
||||
nullptr))
|
||||
if (!CryptStringToBinaryA((LPCSTR)obs_pub, obs_pub_len,
|
||||
CRYPT_STRING_BASE64HEADER, binaryKey,
|
||||
&binaryKeyLen, nullptr, nullptr))
|
||||
return false;
|
||||
|
||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
|
||||
X509_PUBLIC_KEY_INFO,
|
||||
binaryKey,
|
||||
binaryKeyLen,
|
||||
CRYPT_ENCODE_ALLOC_FLAG,
|
||||
nullptr,
|
||||
&publicPBLOB,
|
||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
|
||||
binaryKey, binaryKeyLen,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, nullptr, &publicPBLOB,
|
||||
&iPBLOBSize))
|
||||
return false;
|
||||
|
||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
|
||||
RSA_CSP_PUBLICKEYBLOB,
|
||||
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
|
||||
publicPBLOB->PublicKey.pbData,
|
||||
publicPBLOB->PublicKey.cbData,
|
||||
CRYPT_ENCODE_ALLOC_FLAG,
|
||||
nullptr,
|
||||
&rsaPublicBLOB,
|
||||
&rsaPublicBLOBSize))
|
||||
CRYPT_ENCODE_ALLOC_FLAG, nullptr,
|
||||
&rsaPublicBLOB, &rsaPublicBLOBSize))
|
||||
return false;
|
||||
|
||||
if (!CryptImportKey(provider,
|
||||
(const BYTE *)rsaPublicBLOB.get(),
|
||||
rsaPublicBLOBSize,
|
||||
0,
|
||||
0,
|
||||
&keyOut))
|
||||
if (!CryptImportKey(provider, (const BYTE *)rsaPublicBLOB.get(),
|
||||
rsaPublicBLOBSize, 0, 0, &keyOut))
|
||||
return false;
|
||||
|
||||
if (!CryptCreateHash(provider, CALG_SHA_512, 0, 0, &hash))
|
||||
|
@ -321,12 +294,8 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
|
|||
for (size_t i = 0; i < sigLen; i++)
|
||||
reversedSig[i] = sig[sigLen - i - 1];
|
||||
|
||||
if (!CryptVerifySignature(hash,
|
||||
reversedSig.data(),
|
||||
(DWORD)sigLen,
|
||||
keyOut,
|
||||
nullptr,
|
||||
0))
|
||||
if (!CryptVerifySignature(hash, reversedSig.data(), (DWORD)sigLen,
|
||||
keyOut, nullptr, 0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -357,10 +326,8 @@ try {
|
|||
signature.reserve(sigLen);
|
||||
HexToByteArray(hexSig, sigLen, signature);
|
||||
|
||||
if (!VerifyDigitalSignature((uint8_t*)data.data(),
|
||||
data.size(),
|
||||
signature.data(),
|
||||
signature.size()))
|
||||
if (!VerifyDigitalSignature((uint8_t *)data.data(), data.size(),
|
||||
signature.data(), signature.size()))
|
||||
throw strprintf("Signature check failed for %s", name);
|
||||
|
||||
return true;
|
||||
|
@ -378,8 +345,8 @@ try {
|
|||
uint8_t updateFileHash[BLAKE2_HASH_LENGTH];
|
||||
vector<string> extraHeaders;
|
||||
|
||||
BPtr<char> updateFilePath = GetConfigPathPtr(
|
||||
"obs-studio\\updates\\updater.exe");
|
||||
BPtr<char> updateFilePath =
|
||||
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
|
||||
|
||||
if (CalculateFileHash(updateFilePath, updateFileHash)) {
|
||||
char hashString[BLAKE2_HASH_STR_LENGTH];
|
||||
|
@ -394,8 +361,8 @@ try {
|
|||
string error;
|
||||
string data;
|
||||
|
||||
bool success = GetRemoteFile(url, data, error, &responseCode,
|
||||
nullptr, nullptr, extraHeaders, &signature);
|
||||
bool success = GetRemoteFile(url, data, error, &responseCode, nullptr,
|
||||
nullptr, extraHeaders, &signature);
|
||||
|
||||
if (!success || (responseCode != 200 && responseCode != 304)) {
|
||||
if (responseCode == 404)
|
||||
|
@ -442,10 +409,8 @@ try {
|
|||
int patch = root.GetInt("version_patch");
|
||||
|
||||
if (major == 0)
|
||||
throw strprintf("Invalid version number: %d.%d.%d",
|
||||
major,
|
||||
minor,
|
||||
patch);
|
||||
throw strprintf("Invalid version number: %d.%d.%d", major,
|
||||
minor, patch);
|
||||
|
||||
json_t *notes = json_object_get(root, "notes");
|
||||
if (!json_is_string(notes))
|
||||
|
@ -491,8 +456,8 @@ string GetProgramGUID()
|
|||
/* NOTE: this is an arbitrary random number that we use to count the
|
||||
* number of unique OBS installations and is not associated with any
|
||||
* kind of identifiable information */
|
||||
const char *pguid = config_get_string(GetGlobalConfig(),
|
||||
"General", "InstallGUID");
|
||||
const char *pguid =
|
||||
config_get_string(GetGlobalConfig(), "General", "InstallGUID");
|
||||
string guid;
|
||||
if (pguid)
|
||||
guid = pguid;
|
||||
|
@ -501,9 +466,8 @@ string GetProgramGUID()
|
|||
GenerateGUID(guid);
|
||||
|
||||
if (!guid.empty())
|
||||
config_set_string(GetGlobalConfig(),
|
||||
"General", "InstallGUID",
|
||||
guid.c_str());
|
||||
config_set_string(GetGlobalConfig(), "General",
|
||||
"InstallGUID", guid.c_str());
|
||||
}
|
||||
|
||||
return guid;
|
||||
|
@ -516,13 +480,12 @@ void AutoUpdateThread::infoMsg(const QString &title, const QString &text)
|
|||
|
||||
void AutoUpdateThread::info(const QString &title, const QString &text)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "infoMsg",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QString, title),
|
||||
Q_ARG(QString, text));
|
||||
QMetaObject::invokeMethod(this, "infoMsg", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QString, title), Q_ARG(QString, text));
|
||||
}
|
||||
|
||||
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, const QString &text)
|
||||
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate,
|
||||
const QString &text)
|
||||
{
|
||||
OBSUpdate updateDlg(App()->GetMainWindow(), localManualUpdate, text);
|
||||
return updateDlg.exec();
|
||||
|
@ -557,8 +520,7 @@ static bool IsFileInUse(const wstring &file)
|
|||
static bool IsGameCaptureInUse()
|
||||
{
|
||||
wstring path = L"..\\..\\data\\obs-plugins\\win-capture\\graphics-hook";
|
||||
return IsFileInUse(path + L"32.dll") ||
|
||||
IsFileInUse(path + L"64.dll");
|
||||
return IsFileInUse(path + L"32.dll") || IsFileInUse(path + L"64.dll");
|
||||
}
|
||||
|
||||
void AutoUpdateThread::run()
|
||||
|
@ -581,11 +543,10 @@ try {
|
|||
}
|
||||
} finishedTrigger;
|
||||
|
||||
BPtr<char> manifestPath = GetConfigPathPtr(
|
||||
"obs-studio\\updates\\manifest.json");
|
||||
BPtr<char> manifestPath =
|
||||
GetConfigPathPtr("obs-studio\\updates\\manifest.json");
|
||||
|
||||
auto ActiveOrGameCaptureLocked = [this] ()
|
||||
{
|
||||
auto ActiveOrGameCaptureLocked = [this]() {
|
||||
if (obs_video_active()) {
|
||||
if (manualUpdate)
|
||||
info(QTStr("Updater.Running.Title"),
|
||||
|
@ -611,11 +572,8 @@ try {
|
|||
/* ----------------------------------- *
|
||||
* create signature provider */
|
||||
|
||||
if (!CryptAcquireContext(&localProvider,
|
||||
nullptr,
|
||||
MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
|
||||
throw strprintf("CryptAcquireContext failed: %lu",
|
||||
GetLastError());
|
||||
|
||||
|
@ -653,7 +611,8 @@ try {
|
|||
if (responseCode == 404)
|
||||
return;
|
||||
|
||||
throw strprintf("Failed to fetch manifest file: %s", error.c_str());
|
||||
throw strprintf("Failed to fetch manifest file: %s",
|
||||
error.c_str());
|
||||
}
|
||||
|
||||
/* ----------------------------------- *
|
||||
|
@ -661,8 +620,8 @@ try {
|
|||
|
||||
/* a new file must be digitally signed */
|
||||
if (responseCode == 200) {
|
||||
success = CheckDataSignature(text, "manifest",
|
||||
signature.data(), signature.size());
|
||||
success = CheckDataSignature(text, "manifest", signature.data(),
|
||||
signature.size());
|
||||
if (!success)
|
||||
throw string("Invalid manifest signature");
|
||||
}
|
||||
|
@ -749,8 +708,8 @@ try {
|
|||
/* ----------------------------------- *
|
||||
* execute updater */
|
||||
|
||||
BPtr<char> updateFilePath = GetConfigPathPtr(
|
||||
"obs-studio\\updates\\updater.exe");
|
||||
BPtr<char> updateFilePath =
|
||||
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
|
||||
BPtr<wchar_t> wUpdateFilePath;
|
||||
|
||||
size_t size = os_utf8_to_wcs_ptr(updateFilePath, 0, &wUpdateFilePath);
|
||||
|
@ -808,17 +767,14 @@ try {
|
|||
BYTE whatsnewHash[BLAKE2_HASH_LENGTH];
|
||||
bool success;
|
||||
|
||||
BPtr<char> whatsnewPath = GetConfigPathPtr(
|
||||
"obs-studio\\updates\\whatsnew.json");
|
||||
BPtr<char> whatsnewPath =
|
||||
GetConfigPathPtr("obs-studio\\updates\\whatsnew.json");
|
||||
|
||||
/* ----------------------------------- *
|
||||
* create signature provider */
|
||||
|
||||
if (!CryptAcquireContext(&localProvider,
|
||||
nullptr,
|
||||
MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
|
||||
throw strprintf("CryptAcquireContext failed: %lu",
|
||||
GetLastError());
|
||||
|
||||
|
@ -865,8 +821,8 @@ try {
|
|||
* verify file signature */
|
||||
|
||||
if (responseCode == 200) {
|
||||
success = CheckDataSignature(text, "whatsnew",
|
||||
signature.data(), signature.size());
|
||||
success = CheckDataSignature(text, "whatsnew", signature.data(),
|
||||
signature.size());
|
||||
if (!success)
|
||||
throw string("Invalid whatsnew signature");
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
|
||||
using namespace json11;
|
||||
|
||||
OBSAbout::OBSAbout(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::OBSAbout)
|
||||
OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -28,20 +26,21 @@ OBSAbout::OBSAbout(QWidget *parent)
|
|||
#ifdef HAVE_OBSCONFIG_H
|
||||
ver += OBS_VERSION;
|
||||
#else
|
||||
ver += LIBOBS_API_MAJOR_VER + "." +
|
||||
LIBOBS_API_MINOR_VER + "." +
|
||||
ver += LIBOBS_API_MAJOR_VER + "." + LIBOBS_API_MINOR_VER + "." +
|
||||
LIBOBS_API_PATCH_VER;
|
||||
#endif
|
||||
|
||||
ui->version->setText(ver + bitness);
|
||||
|
||||
ui->contribute->setText(QTStr("About.Contribute"));
|
||||
ui->donate->setText(" <a href='https://obsproject.com/donate'>" +
|
||||
ui->donate->setText(
|
||||
" <a href='https://obsproject.com/donate'>" +
|
||||
QTStr("About.Donate") + "</a>");
|
||||
ui->donate->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
ui->donate->setOpenExternalLinks(true);
|
||||
|
||||
ui->getInvolved->setText(" <a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
|
||||
ui->getInvolved->setText(
|
||||
" <a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
|
||||
QTStr("About.GetInvolved") + "</a>");
|
||||
ui->getInvolved->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
ui->getInvolved->setOpenExternalLinks(true);
|
||||
|
@ -68,10 +67,12 @@ OBSAbout::OBSAbout(QWidget *parent)
|
|||
RemoteTextThread *thread = new RemoteTextThread(
|
||||
"https://obsproject.com/patreon/about-box.json",
|
||||
"application/json");
|
||||
QObject::connect(thread, &RemoteTextThread::Result,
|
||||
main, &OBSBasic::UpdatePatronJson);
|
||||
QObject::connect(thread, SIGNAL(Result(const QString &, const QString &)),
|
||||
this, SLOT(ShowAbout()));
|
||||
QObject::connect(thread, &RemoteTextThread::Result, main,
|
||||
&OBSBasic::UpdatePatronJson);
|
||||
QObject::connect(
|
||||
thread,
|
||||
SIGNAL(Result(const QString &, const QString &)), this,
|
||||
SLOT(ShowAbout()));
|
||||
main->patronJsonThread.reset(thread);
|
||||
thread->start();
|
||||
} else {
|
||||
|
|
|
@ -31,17 +31,14 @@ class TestMode {
|
|||
gs_eparam_t *randomvals[3] = {
|
||||
gs_effect_get_param_by_name(solid, "randomvals1"),
|
||||
gs_effect_get_param_by_name(solid, "randomvals2"),
|
||||
gs_effect_get_param_by_name(solid, "randomvals3")
|
||||
};
|
||||
gs_effect_get_param_by_name(solid, "randomvals3")};
|
||||
|
||||
struct vec4 r;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
vec4_set(&r,
|
||||
vec4_set(&r, rand_float(true) * 100.0f,
|
||||
rand_float(true) * 100.0f,
|
||||
rand_float(true) * 100.0f,
|
||||
rand_float(true) * 50000.0f + 10000.0f,
|
||||
0.0f);
|
||||
rand_float(true) * 50000.0f + 10000.0f, 0.0f);
|
||||
gs_effect_set_vec4(randomvals[i], &r);
|
||||
}
|
||||
|
||||
|
@ -181,16 +178,15 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
/* -----------------------------------*/
|
||||
/* create obs objects */
|
||||
|
||||
const char *serverType = wiz->customServer
|
||||
? "rtmp_custom"
|
||||
const char *serverType = wiz->customServer ? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
|
||||
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
|
||||
"test_x264", nullptr, nullptr);
|
||||
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
|
||||
"test_aac", nullptr, 0, nullptr);
|
||||
OBSService service = obs_service_create(serverType,
|
||||
"test_service", nullptr, nullptr);
|
||||
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
|
||||
nullptr, nullptr);
|
||||
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
|
||||
nullptr, 0, nullptr);
|
||||
OBSService service = obs_service_create(serverType, "test_service",
|
||||
nullptr, nullptr);
|
||||
obs_encoder_release(vencoder);
|
||||
obs_encoder_release(aencoder);
|
||||
obs_service_release(service);
|
||||
|
@ -218,8 +214,8 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
if (wiz->service == AutoConfig::Service::Twitch) {
|
||||
string_depad_key(key);
|
||||
key += "?bandwidthtest";
|
||||
}
|
||||
else if(wiz->serviceName == "Restream.io" || wiz->serviceName == "Restream.io - RTMP") {
|
||||
} else if (wiz->serviceName == "Restream.io" ||
|
||||
wiz->serviceName == "Restream.io - RTMP") {
|
||||
string_depad_key(key);
|
||||
key += "?test=true";
|
||||
}
|
||||
|
@ -236,8 +232,8 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
obs_data_set_int(aencoder_settings, "bitrate", 32);
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
const char *bind_ip = config_get_string(main->Config(), "Output",
|
||||
"BindIP");
|
||||
const char *bind_ip =
|
||||
config_get_string(main->Config(), "Output", "BindIP");
|
||||
obs_data_set_string(output_settings, "bind_ip", bind_ip);
|
||||
|
||||
/* -----------------------------------*/
|
||||
|
@ -267,8 +263,8 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
/* apply service settings */
|
||||
|
||||
obs_service_update(service, service_settings);
|
||||
obs_service_apply_encoder_settings(service,
|
||||
vencoder_settings, aencoder_settings);
|
||||
obs_service_apply_encoder_settings(service, vencoder_settings,
|
||||
aencoder_settings);
|
||||
|
||||
/* -----------------------------------*/
|
||||
/* create output */
|
||||
|
@ -277,18 +273,17 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
if (!output_type)
|
||||
output_type = "rtmp_output";
|
||||
|
||||
OBSOutput output = obs_output_create(output_type,
|
||||
"test_stream", nullptr, nullptr);
|
||||
OBSOutput output =
|
||||
obs_output_create(output_type, "test_stream", nullptr, nullptr);
|
||||
obs_output_release(output);
|
||||
obs_output_update(output, output_settings);
|
||||
|
||||
const char *audio_codec =
|
||||
obs_output_get_supported_audio_codecs(output);
|
||||
const char *audio_codec = obs_output_get_supported_audio_codecs(output);
|
||||
|
||||
if (strcmp(audio_codec, "aac") != 0) {
|
||||
const char *id = FindAudioEncoderFromCodec(audio_codec);
|
||||
aencoder = obs_audio_encoder_create(id,
|
||||
"test_audio", nullptr, 0, nullptr);
|
||||
aencoder = obs_audio_encoder_create(id, "test_audio", nullptr,
|
||||
0, nullptr);
|
||||
obs_encoder_release(aencoder);
|
||||
}
|
||||
|
||||
|
@ -308,16 +303,14 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
/* -----------------------------------*/
|
||||
/* connect signals */
|
||||
|
||||
auto on_started = [&] ()
|
||||
{
|
||||
auto on_started = [&]() {
|
||||
unique_lock<mutex> lock(m);
|
||||
connected = true;
|
||||
stopped = false;
|
||||
cv.notify_one();
|
||||
};
|
||||
|
||||
auto on_stopped = [&] ()
|
||||
{
|
||||
auto on_stopped = [&]() {
|
||||
unique_lock<mutex> lock(m);
|
||||
connected = false;
|
||||
stopped = true;
|
||||
|
@ -327,15 +320,13 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
using on_started_t = decltype(on_started);
|
||||
using on_stopped_t = decltype(on_stopped);
|
||||
|
||||
auto pre_on_started = [] (void *data, calldata_t *)
|
||||
{
|
||||
auto pre_on_started = [](void *data, calldata_t *) {
|
||||
on_started_t &on_started =
|
||||
*reinterpret_cast<on_started_t *>(data);
|
||||
on_started();
|
||||
};
|
||||
|
||||
auto pre_on_stopped = [] (void *data, calldata_t *)
|
||||
{
|
||||
auto pre_on_stopped = [](void *data, calldata_t *) {
|
||||
on_stopped_t &on_stopped =
|
||||
*reinterpret_cast<on_stopped_t *>(data);
|
||||
on_stopped();
|
||||
|
@ -358,7 +349,8 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
|
||||
int per = int((i + 1) * 100 / servers.size());
|
||||
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
|
||||
QMetaObject::invokeMethod(this, "UpdateMessage",
|
||||
QMetaObject::invokeMethod(
|
||||
this, "UpdateMessage",
|
||||
Q_ARG(QString, QTStr(TEST_BW_CONNECTING)
|
||||
.arg(server.name.c_str())));
|
||||
|
||||
|
@ -385,9 +377,10 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
if (!connected)
|
||||
continue;
|
||||
|
||||
QMetaObject::invokeMethod(this, "UpdateMessage",
|
||||
Q_ARG(QString, QTStr(TEST_BW_SERVER)
|
||||
.arg(server.name.c_str())));
|
||||
QMetaObject::invokeMethod(
|
||||
this, "UpdateMessage",
|
||||
Q_ARG(QString,
|
||||
QTStr(TEST_BW_SERVER).arg(server.name.c_str())));
|
||||
|
||||
/* ignore first 2.5 seconds due to possible buffering skewing
|
||||
* the result */
|
||||
|
@ -418,10 +411,10 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
|
||||
uint64_t total_time = os_gettime_ns() - t_start;
|
||||
|
||||
int total_bytes = (int)obs_output_get_total_bytes(output) -
|
||||
start_bytes;
|
||||
uint64_t bitrate = (uint64_t)total_bytes * 8
|
||||
* 1000000000 / total_time / 1000;
|
||||
int total_bytes =
|
||||
(int)obs_output_get_total_bytes(output) - start_bytes;
|
||||
uint64_t bitrate = (uint64_t)total_bytes * 8 * 1000000000 /
|
||||
total_time / 1000;
|
||||
|
||||
if (obs_output_get_frames_dropped(output) ||
|
||||
(int)bitrate < (wiz->startingBitrate * 75 / 100)) {
|
||||
|
@ -436,7 +429,8 @@ void AutoConfigTestPage::TestBandwidthThread()
|
|||
|
||||
if (!success) {
|
||||
QMetaObject::invokeMethod(this, "Failure",
|
||||
Q_ARG(QString, QTStr(TEST_BW_CONNECT_FAIL)));
|
||||
Q_ARG(QString,
|
||||
QTStr(TEST_BW_CONNECT_FAIL)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -480,7 +474,8 @@ static long double EstimateMinBitrate(int cx, int cy, int fps_num, int fps_den)
|
|||
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
|
||||
}
|
||||
|
||||
static long double EstimateUpperBitrate(int cx, int cy, int fps_num, int fps_den)
|
||||
static long double EstimateUpperBitrate(int cx, int cy, int fps_num,
|
||||
int fps_den)
|
||||
{
|
||||
long double val = EstimateBitrateVal(1280, 720, 30, 1) / 3000.0l;
|
||||
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
|
||||
|
@ -525,12 +520,12 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
/* -----------------------------------*/
|
||||
/* create obs objects */
|
||||
|
||||
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
|
||||
"test_x264", nullptr, nullptr);
|
||||
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
|
||||
"test_aac", nullptr, 0, nullptr);
|
||||
OBSOutput output = obs_output_create("null_output",
|
||||
"null", nullptr, nullptr);
|
||||
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
|
||||
nullptr, nullptr);
|
||||
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
|
||||
nullptr, 0, nullptr);
|
||||
OBSOutput output =
|
||||
obs_output_create("null_output", "null", nullptr, nullptr);
|
||||
obs_output_release(output);
|
||||
obs_encoder_release(vencoder);
|
||||
obs_encoder_release(aencoder);
|
||||
|
@ -573,16 +568,14 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
/* -----------------------------------*/
|
||||
/* connect signals */
|
||||
|
||||
auto on_stopped = [&] ()
|
||||
{
|
||||
auto on_stopped = [&]() {
|
||||
unique_lock<mutex> lock(m);
|
||||
cv.notify_one();
|
||||
};
|
||||
|
||||
using on_stopped_t = decltype(on_stopped);
|
||||
|
||||
auto pre_on_stopped = [] (void *data, calldata_t *)
|
||||
{
|
||||
auto pre_on_stopped = [](void *data, calldata_t *) {
|
||||
on_stopped_t &on_stopped =
|
||||
*reinterpret_cast<on_stopped_t *>(data);
|
||||
on_stopped();
|
||||
|
@ -629,8 +622,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
int count = 1;
|
||||
|
||||
auto testRes = [&](long double div, int fps_num, int fps_den,
|
||||
bool force)
|
||||
{
|
||||
bool force) {
|
||||
int per = ++i * 100 / count;
|
||||
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
|
||||
|
||||
|
@ -669,13 +661,13 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
QString cxStr = QString::number(cx);
|
||||
QString cyStr = QString::number(cy);
|
||||
|
||||
QString fpsStr = (fps_den > 1)
|
||||
? QString::number(fps, 'f', 2)
|
||||
QString fpsStr = (fps_den > 1) ? QString::number(fps, 'f', 2)
|
||||
: QString::number(fps, 'g', 2);
|
||||
|
||||
QMetaObject::invokeMethod(this, "UpdateMessage",
|
||||
Q_ARG(QString, QTStr(TEST_RES_VAL)
|
||||
.arg(cxStr, cyStr, fpsStr)));
|
||||
QMetaObject::invokeMethod(
|
||||
this, "UpdateMessage",
|
||||
Q_ARG(QString,
|
||||
QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr)));
|
||||
|
||||
unique_lock<mutex> ul(m);
|
||||
if (cancel)
|
||||
|
@ -683,7 +675,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
|
||||
if (!obs_output_start(output)) {
|
||||
QMetaObject::invokeMethod(this, "Failure",
|
||||
Q_ARG(QString, QTStr(TEST_RES_FAIL)));
|
||||
Q_ARG(QString,
|
||||
QTStr(TEST_RES_FAIL)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -692,8 +685,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
obs_output_stop(output);
|
||||
cv.wait(ul);
|
||||
|
||||
int skipped = (int)video_output_get_skipped_frames(
|
||||
obs_get_video());
|
||||
int skipped =
|
||||
(int)video_output_get_skipped_frames(obs_get_video());
|
||||
if (force || skipped <= 10)
|
||||
results.emplace_back(cx, cy, fps_num, fps_den);
|
||||
|
||||
|
@ -702,23 +695,38 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
|
|||
|
||||
if (wiz->specificFPSNum && wiz->specificFPSDen) {
|
||||
count = 5;
|
||||
if (!testRes(1.0, 0, 0, false)) return false;
|
||||
if (!testRes(1.5, 0, 0, false)) return false;
|
||||
if (!testRes(1.0 / 0.6, 0, 0, false)) return false;
|
||||
if (!testRes(2.0, 0, 0, false)) return false;
|
||||
if (!testRes(2.25, 0, 0, true)) return false;
|
||||
if (!testRes(1.0, 0, 0, false))
|
||||
return false;
|
||||
if (!testRes(1.5, 0, 0, false))
|
||||
return false;
|
||||
if (!testRes(1.0 / 0.6, 0, 0, false))
|
||||
return false;
|
||||
if (!testRes(2.0, 0, 0, false))
|
||||
return false;
|
||||
if (!testRes(2.25, 0, 0, true))
|
||||
return false;
|
||||
} else {
|
||||
count = 10;
|
||||
if (!testRes(1.0, 60, 1, false)) return false;
|
||||
if (!testRes(1.0, 30, 1, false)) return false;
|
||||
if (!testRes(1.5, 60, 1, false)) return false;
|
||||
if (!testRes(1.5, 30, 1, false)) return false;
|
||||
if (!testRes(1.0 / 0.6, 60, 1, false)) return false;
|
||||
if (!testRes(1.0 / 0.6, 30, 1, false)) return false;
|
||||
if (!testRes(2.0, 60, 1, false)) return false;
|
||||
if (!testRes(2.0, 30, 1, false)) return false;
|
||||
if (!testRes(2.25, 60, 1, false)) return false;
|
||||
if (!testRes(2.25, 30, 1, true)) return false;
|
||||
if (!testRes(1.0, 60, 1, false))
|
||||
return false;
|
||||
if (!testRes(1.0, 30, 1, false))
|
||||
return false;
|
||||
if (!testRes(1.5, 60, 1, false))
|
||||
return false;
|
||||
if (!testRes(1.5, 30, 1, false))
|
||||
return false;
|
||||
if (!testRes(1.0 / 0.6, 60, 1, false))
|
||||
return false;
|
||||
if (!testRes(1.0 / 0.6, 30, 1, false))
|
||||
return false;
|
||||
if (!testRes(2.0, 60, 1, false))
|
||||
return false;
|
||||
if (!testRes(2.0, 30, 1, false))
|
||||
return false;
|
||||
if (!testRes(2.25, 60, 1, false))
|
||||
return false;
|
||||
if (!testRes(2.25, 30, 1, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -----------------------------------*/
|
||||
|
@ -777,8 +785,7 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
|
|||
}
|
||||
|
||||
auto testRes = [&](long double div, int fps_num, int fps_den,
|
||||
bool force)
|
||||
{
|
||||
bool force) {
|
||||
if (results.size() >= 3)
|
||||
return;
|
||||
|
||||
|
@ -805,7 +812,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
|
|||
* ratio, so increase the minimum bitrate estimate for them.
|
||||
* NVENC currently is the exception because of the improvements
|
||||
* its made to its quality in recent generations. */
|
||||
if (!nvenc) minBitrate = minBitrate * 114 / 100;
|
||||
if (!nvenc)
|
||||
minBitrate = minBitrate * 114 / 100;
|
||||
|
||||
if (wiz->type == AutoConfig::Type::Recording)
|
||||
force = true;
|
||||
|
@ -933,8 +941,7 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
|
||||
QFormLayout *form = results;
|
||||
|
||||
auto encName = [] (AutoConfig::Encoder enc) -> QString
|
||||
{
|
||||
auto encName = [](AutoConfig::Encoder enc) -> QString {
|
||||
switch (enc) {
|
||||
case AutoConfig::Encoder::x264:
|
||||
return QTStr(ENCODER_SOFTWARE);
|
||||
|
@ -951,18 +958,16 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
return QTStr(ENCODER_SOFTWARE);
|
||||
};
|
||||
|
||||
auto newLabel = [this] (const char *str) -> QLabel *
|
||||
{
|
||||
auto newLabel = [this](const char *str) -> QLabel * {
|
||||
return new QLabel(QTStr(str), this);
|
||||
};
|
||||
|
||||
if (wiz->type != AutoConfig::Type::Recording) {
|
||||
const char *serverType = wiz->customServer
|
||||
? "rtmp_custom"
|
||||
const char *serverType = wiz->customServer ? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
|
||||
OBSService service = obs_service_create(serverType,
|
||||
"temp_service", nullptr, nullptr);
|
||||
OBSService service = obs_service_create(
|
||||
serverType, "temp_service", nullptr, nullptr);
|
||||
obs_service_release(service);
|
||||
|
||||
OBSData service_settings = obs_data_create();
|
||||
|
@ -976,11 +981,11 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
obs_data_set_string(service_settings, "service",
|
||||
wiz->serviceName.c_str());
|
||||
obs_service_update(service, service_settings);
|
||||
obs_service_apply_encoder_settings(service,
|
||||
vencoder_settings, nullptr);
|
||||
obs_service_apply_encoder_settings(service, vencoder_settings,
|
||||
nullptr);
|
||||
|
||||
wiz->idealBitrate = (int)obs_data_get_int(vencoder_settings,
|
||||
"bitrate");
|
||||
wiz->idealBitrate =
|
||||
(int)obs_data_get_int(vencoder_settings, "bitrate");
|
||||
|
||||
if (!wiz->customServer)
|
||||
form->addRow(
|
||||
|
@ -988,7 +993,8 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
new QLabel(wiz->serviceName.c_str(),
|
||||
ui->finishPage));
|
||||
form->addRow(newLabel("Basic.AutoConfig.StreamPage.Server"),
|
||||
new QLabel(wiz->serverName.c_str(), ui->finishPage));
|
||||
new QLabel(wiz->serverName.c_str(),
|
||||
ui->finishPage));
|
||||
form->addRow(newLabel("Basic.Settings.Output.VideoBitrate"),
|
||||
new QLabel(QString::number(wiz->idealBitrate),
|
||||
ui->finishPage));
|
||||
|
@ -997,11 +1003,11 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
ui->finishPage));
|
||||
}
|
||||
|
||||
QString baseRes = QString("%1x%2").arg(
|
||||
QString::number(wiz->baseResolutionCX),
|
||||
QString baseRes =
|
||||
QString("%1x%2").arg(QString::number(wiz->baseResolutionCX),
|
||||
QString::number(wiz->baseResolutionCY));
|
||||
QString scaleRes = QString("%1x%2").arg(
|
||||
QString::number(wiz->idealResolutionCX),
|
||||
QString scaleRes =
|
||||
QString("%1x%2").arg(QString::number(wiz->idealResolutionCX),
|
||||
QString::number(wiz->idealResolutionCY));
|
||||
|
||||
if (wiz->recordingEncoder != AutoConfig::Encoder::Stream ||
|
||||
|
@ -1027,8 +1033,7 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
long double fps =
|
||||
(long double)wiz->idealFPSNum / (long double)wiz->idealFPSDen;
|
||||
|
||||
QString fpsStr = (wiz->idealFPSDen > 1)
|
||||
? QString::number(fps, 'f', 2)
|
||||
QString fpsStr = (wiz->idealFPSDen > 1) ? QString::number(fps, 'f', 2)
|
||||
: QString::number(fps, 'g', 2);
|
||||
|
||||
form->addRow(newLabel("Basic.Settings.Video.BaseResolution"),
|
||||
|
@ -1103,8 +1108,7 @@ void AutoConfigTestPage::Progress(int percentage)
|
|||
}
|
||||
|
||||
AutoConfigTestPage::AutoConfigTestPage(QWidget *parent)
|
||||
: QWizardPage (parent),
|
||||
ui (new Ui_AutoConfigTestPage)
|
||||
: QWizardPage(parent), ui(new Ui_AutoConfigTestPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setTitle(QTStr("Basic.AutoConfig.TestPage"));
|
||||
|
|
|
@ -37,8 +37,8 @@ static OBSData OpenServiceSettings(std::string &type)
|
|||
if (ret <= 0)
|
||||
return OBSData();
|
||||
|
||||
OBSData data = obs_data_create_from_json_file_safe(serviceJsonPath,
|
||||
"bak");
|
||||
OBSData data =
|
||||
obs_data_create_from_json_file_safe(serviceJsonPath, "bak");
|
||||
obs_data_release(data);
|
||||
|
||||
obs_data_set_default_string(data, "type", "rtmp_common");
|
||||
|
@ -63,8 +63,7 @@ static void GetServiceInfo(std::string &type, std::string &service,
|
|||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
AutoConfigStartPage::AutoConfigStartPage(QWidget *parent)
|
||||
: QWizardPage (parent),
|
||||
ui (new Ui_AutoConfigStartPage)
|
||||
: QWizardPage(parent), ui(new Ui_AutoConfigStartPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setTitle(QTStr("Basic.AutoConfig.StartPage"));
|
||||
|
@ -101,8 +100,7 @@ void AutoConfigStartPage::on_prioritizeRecording_clicked()
|
|||
#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes")
|
||||
|
||||
AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
|
||||
: QWizardPage (parent),
|
||||
ui (new Ui_AutoConfigVideoPage)
|
||||
: QWizardPage(parent), ui(new Ui_AutoConfigVideoPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -115,8 +113,7 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
|
|||
long double fpsVal =
|
||||
(long double)ovi.fps_num / (long double)ovi.fps_den;
|
||||
|
||||
QString fpsStr = (ovi.fps_den > 1)
|
||||
? QString::number(fpsVal, 'f', 2)
|
||||
QString fpsStr = (ovi.fps_den > 1) ? QString::number(fpsVal, 'f', 2)
|
||||
: QString::number(fpsVal, 'g', 2);
|
||||
|
||||
ui->fps->addItem(QTStr(FPS_PREFER_HIGH_FPS),
|
||||
|
@ -151,11 +148,9 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
|
|||
ui->canvasRes->addItem(str, encRes);
|
||||
}
|
||||
|
||||
auto addRes = [&] (int cx, int cy)
|
||||
{
|
||||
auto addRes = [&](int cx, int cy) {
|
||||
encRes = (cx << 16) | cy;
|
||||
QString str = QString("%1x%2").arg(
|
||||
QString::number(cx),
|
||||
QString str = QString("%1x%2").arg(QString::number(cx),
|
||||
QString::number(cy));
|
||||
ui->canvasRes->addItem(str, encRes);
|
||||
};
|
||||
|
@ -223,12 +218,11 @@ bool AutoConfigVideoPage::validatePage()
|
|||
|
||||
enum class ListOpt : int {
|
||||
ShowAll = 1,
|
||||
Custom
|
||||
Custom,
|
||||
};
|
||||
|
||||
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
|
||||
: QWizardPage (parent),
|
||||
ui (new Ui_AutoConfigStreamPage)
|
||||
: QWizardPage(parent), ui(new Ui_AutoConfigStreamPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->bitrateLabel->setVisible(false);
|
||||
|
@ -255,29 +249,29 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
|
|||
|
||||
LoadServices(false);
|
||||
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(ServiceChanged()));
|
||||
connect(ui->customServer, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(ServiceChanged()));
|
||||
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)),
|
||||
this, SLOT(ServiceChanged()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ServiceChanged()));
|
||||
connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
|
||||
SLOT(ServiceChanged()));
|
||||
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this,
|
||||
SLOT(ServiceChanged()));
|
||||
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(UpdateServerList()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(UpdateServerList()));
|
||||
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(UpdateKeyLink()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(UpdateKeyLink()));
|
||||
|
||||
connect(ui->key, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(UpdateCompleted()));
|
||||
connect(ui->regionUS, SIGNAL(toggled(bool)),
|
||||
this, SLOT(UpdateCompleted()));
|
||||
connect(ui->regionEU, SIGNAL(toggled(bool)),
|
||||
this, SLOT(UpdateCompleted()));
|
||||
connect(ui->regionAsia, SIGNAL(toggled(bool)),
|
||||
this, SLOT(UpdateCompleted()));
|
||||
connect(ui->regionOther, SIGNAL(toggled(bool)),
|
||||
this, SLOT(UpdateCompleted()));
|
||||
connect(ui->key, SIGNAL(textChanged(const QString &)), this,
|
||||
SLOT(UpdateCompleted()));
|
||||
connect(ui->regionUS, SIGNAL(toggled(bool)), this,
|
||||
SLOT(UpdateCompleted()));
|
||||
connect(ui->regionEU, SIGNAL(toggled(bool)), this,
|
||||
SLOT(UpdateCompleted()));
|
||||
connect(ui->regionAsia, SIGNAL(toggled(bool)), this,
|
||||
SLOT(UpdateCompleted()));
|
||||
connect(ui->regionOther, SIGNAL(toggled(bool)), this,
|
||||
SLOT(UpdateCompleted()));
|
||||
}
|
||||
|
||||
AutoConfigStreamPage::~AutoConfigStreamPage()
|
||||
|
@ -307,8 +301,7 @@ bool AutoConfigStreamPage::validatePage()
|
|||
|
||||
wiz->customServer = IsCustom();
|
||||
|
||||
const char *serverType = wiz->customServer
|
||||
? "rtmp_custom"
|
||||
const char *serverType = wiz->customServer ? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
|
||||
if (!wiz->customServer) {
|
||||
|
@ -365,8 +358,7 @@ bool AutoConfigStreamPage::validatePage()
|
|||
if (wiz->service != AutoConfig::Service::Twitch && wiz->bandwidthTest) {
|
||||
QMessageBox::StandardButton button;
|
||||
#define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x)
|
||||
button = OBSMessageBox::question(this,
|
||||
WARNING_TEXT("Title"),
|
||||
button = OBSMessageBox::question(this, WARNING_TEXT("Title"),
|
||||
WARNING_TEXT("Text"));
|
||||
#undef WARNING_TEXT
|
||||
|
||||
|
@ -440,8 +432,7 @@ void AutoConfigStreamPage::on_disconnectAccount_clicked()
|
|||
{
|
||||
QMessageBox::StandardButton button;
|
||||
|
||||
button = OBSMessageBox::question(this,
|
||||
QTStr(DISCONNECT_COMFIRM_TITLE),
|
||||
button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE),
|
||||
QTStr(DISCONNECT_COMFIRM_TEXT));
|
||||
|
||||
if (button == QMessageBox::No) {
|
||||
|
@ -479,14 +470,13 @@ static inline bool is_auth_service(const std::string &service)
|
|||
|
||||
void AutoConfigStreamPage::ServiceChanged()
|
||||
{
|
||||
bool showMore =
|
||||
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
|
||||
bool showMore = ui->service->currentData().toInt() ==
|
||||
(int)ListOpt::ShowAll;
|
||||
if (showMore)
|
||||
return;
|
||||
|
||||
std::string service = QT_TO_UTF8(ui->service->currentText());
|
||||
bool regionBased = service == "Twitch" ||
|
||||
service == "Smashcast";
|
||||
bool regionBased = service == "Twitch" || service == "Smashcast";
|
||||
bool testBandwidth = ui->doBandwidthTest->isChecked();
|
||||
bool custom = IsCustom();
|
||||
|
||||
|
@ -496,8 +486,7 @@ void AutoConfigStreamPage::ServiceChanged()
|
|||
if (cef) {
|
||||
if (lastService != service.c_str()) {
|
||||
bool can_auth = is_auth_service(service);
|
||||
int page = can_auth
|
||||
? (int)Section::Connect
|
||||
int page = can_auth ? (int)Section::Connect
|
||||
: (int)Section::StreamKey;
|
||||
|
||||
ui->stackedWidget->setCurrentIndex(page);
|
||||
|
@ -533,8 +522,8 @@ void AutoConfigStreamPage::ServiceChanged()
|
|||
ui->serverLabel->setVisible(true);
|
||||
} else {
|
||||
if (!testBandwidth)
|
||||
ui->streamkeyPageLayout->insertRow(2, ui->serverLabel,
|
||||
ui->serverStackedWidget);
|
||||
ui->streamkeyPageLayout->insertRow(
|
||||
2, ui->serverLabel, ui->serverStackedWidget);
|
||||
|
||||
ui->region->setVisible(regionBased && testBandwidth);
|
||||
ui->serverStackedWidget->setCurrentIndex(0);
|
||||
|
@ -574,13 +563,15 @@ void AutoConfigStreamPage::UpdateKeyLink()
|
|||
text += " <a href=\"https://";
|
||||
text += "www.twitch.tv/broadcast/dashboard/streamkey";
|
||||
text += "\">";
|
||||
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += QTStr(
|
||||
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += "</a>";
|
||||
} else if (serviceName == "YouTube / YouTube Gaming") {
|
||||
text += " <a href=\"https://";
|
||||
text += "www.youtube.com/live_dashboard";
|
||||
text += "\">";
|
||||
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += QTStr(
|
||||
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += "</a>";
|
||||
|
||||
isYoutube = true;
|
||||
|
@ -632,8 +623,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
|
|||
QVariant((int)ListOpt::ShowAll));
|
||||
}
|
||||
|
||||
ui->service->insertItem(0,
|
||||
QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
|
||||
ui->service->insertItem(
|
||||
0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
|
||||
QVariant((int)ListOpt::Custom));
|
||||
|
||||
if (!lastService.isEmpty()) {
|
||||
|
@ -650,8 +641,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
|
|||
void AutoConfigStreamPage::UpdateServerList()
|
||||
{
|
||||
QString serviceName = ui->service->currentText();
|
||||
bool showMore =
|
||||
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
|
||||
bool showMore = ui->service->currentData().toInt() ==
|
||||
(int)ListOpt::ShowAll;
|
||||
|
||||
if (showMore) {
|
||||
LoadServices(true);
|
||||
|
@ -706,8 +697,7 @@ void AutoConfigStreamPage::UpdateCompleted()
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
AutoConfig::AutoConfig(QWidget *parent)
|
||||
: QWizard(parent)
|
||||
AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
|
||||
{
|
||||
EnableThreadedMessageBoxes(true);
|
||||
|
||||
|
@ -812,7 +802,8 @@ AutoConfig::AutoConfig(QWidget *parent)
|
|||
if (!key.empty())
|
||||
streamPage->ui->key->setText(key.c_str());
|
||||
|
||||
int bitrate = config_get_int(main->Config(), "SimpleOutput", "VBitrate");
|
||||
int bitrate =
|
||||
config_get_int(main->Config(), "SimpleOutput", "VBitrate");
|
||||
streamPage->ui->bitrate->setValue(bitrate);
|
||||
streamPage->ServiceChanged();
|
||||
|
||||
|
@ -929,9 +920,7 @@ void AutoConfig::SaveStreamSettings()
|
|||
/* ---------------------------------- */
|
||||
/* save service */
|
||||
|
||||
const char *service_id = customServer
|
||||
? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
|
||||
|
||||
obs_service_t *oldService = main->GetService();
|
||||
OBSData hotkeyData = obs_hotkeys_save_service(oldService);
|
||||
|
@ -945,8 +934,8 @@ void AutoConfig::SaveStreamSettings()
|
|||
obs_data_set_string(settings, "server", server.c_str());
|
||||
obs_data_set_string(settings, "key", key.c_str());
|
||||
|
||||
OBSService newService = obs_service_create(service_id,
|
||||
"default_service", settings, hotkeyData);
|
||||
OBSService newService = obs_service_create(
|
||||
service_id, "default_service", settings, hotkeyData);
|
||||
obs_service_release(newService);
|
||||
|
||||
if (!newService)
|
||||
|
@ -976,12 +965,12 @@ void AutoConfig::SaveSettings()
|
|||
config_set_string(main->Config(), "SimpleOutput", "RecEncoder",
|
||||
GetEncoderId(recordingEncoder));
|
||||
|
||||
const char *quality = recordingQuality == Quality::High
|
||||
? "Small"
|
||||
const char *quality = recordingQuality == Quality::High ? "Small"
|
||||
: "Stream";
|
||||
|
||||
config_set_string(main->Config(), "Output", "Mode", "Simple");
|
||||
config_set_string(main->Config(), "SimpleOutput", "RecQuality", quality);
|
||||
config_set_string(main->Config(), "SimpleOutput", "RecQuality",
|
||||
quality);
|
||||
config_set_int(main->Config(), "Video", "BaseCX", baseResolutionCX);
|
||||
config_set_int(main->Config(), "Video", "BaseCY", baseResolutionCY);
|
||||
config_set_int(main->Config(), "Video", "OutputCX", idealResolutionCX);
|
||||
|
|
|
@ -32,13 +32,13 @@ class AutoConfig : public QWizard {
|
|||
enum class Type {
|
||||
Invalid,
|
||||
Streaming,
|
||||
Recording
|
||||
Recording,
|
||||
};
|
||||
|
||||
enum class Service {
|
||||
Twitch,
|
||||
Smashcast,
|
||||
Other
|
||||
Other,
|
||||
};
|
||||
|
||||
enum class Encoder {
|
||||
|
@ -46,12 +46,12 @@ class AutoConfig : public QWizard {
|
|||
NVENC,
|
||||
QSV,
|
||||
AMD,
|
||||
Stream
|
||||
Stream,
|
||||
};
|
||||
|
||||
enum class Quality {
|
||||
Stream,
|
||||
High
|
||||
High,
|
||||
};
|
||||
|
||||
enum class FPSType : int {
|
||||
|
@ -59,7 +59,7 @@ class AutoConfig : public QWizard {
|
|||
PreferHighRes,
|
||||
UseCurrent,
|
||||
fps30,
|
||||
fps60
|
||||
fps60,
|
||||
};
|
||||
|
||||
static inline const char *GetEncoderId(Encoder enc);
|
||||
|
@ -119,7 +119,7 @@ public:
|
|||
StartPage,
|
||||
VideoPage,
|
||||
StreamPage,
|
||||
TestPage
|
||||
TestPage,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -216,7 +216,7 @@ class AutoConfigTestPage : public QWizardPage {
|
|||
BandwidthTest,
|
||||
StreamEncoder,
|
||||
RecordingEncoder,
|
||||
Finished
|
||||
Finished,
|
||||
};
|
||||
|
||||
Stage stage = Stage::Starting;
|
||||
|
|
|
@ -39,23 +39,16 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
|
|||
: QDialog(parent),
|
||||
ui(new Ui::OBSBasicFilters),
|
||||
source(source_),
|
||||
addSignal (obs_source_get_signal_handler(source),
|
||||
"filter_add",
|
||||
OBSBasicFilters::OBSSourceFilterAdded,
|
||||
this),
|
||||
removeSignal (obs_source_get_signal_handler(source),
|
||||
"filter_remove",
|
||||
OBSBasicFilters::OBSSourceFilterRemoved,
|
||||
this),
|
||||
addSignal(obs_source_get_signal_handler(source), "filter_add",
|
||||
OBSBasicFilters::OBSSourceFilterAdded, this),
|
||||
removeSignal(obs_source_get_signal_handler(source), "filter_remove",
|
||||
OBSBasicFilters::OBSSourceFilterRemoved, this),
|
||||
reorderSignal(obs_source_get_signal_handler(source),
|
||||
"reorder_filters",
|
||||
OBSBasicFilters::OBSSourceReordered,
|
||||
"reorder_filters", OBSBasicFilters::OBSSourceReordered,
|
||||
this),
|
||||
removeSourceSignal (obs_source_get_signal_handler(source),
|
||||
"remove",
|
||||
removeSourceSignal(obs_source_get_signal_handler(source), "remove",
|
||||
OBSBasicFilters::SourceRemoved, this),
|
||||
renameSourceSignal (obs_source_get_signal_handler(source),
|
||||
"rename",
|
||||
renameSourceSignal(obs_source_get_signal_handler(source), "rename",
|
||||
OBSBasicFilters::SourceRenamed, this),
|
||||
noPreviewMargin(13)
|
||||
{
|
||||
|
@ -74,7 +67,8 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
|
|||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
#ifndef QT_NO_SHORTCUT
|
||||
ui->actionRemoveFilter->setShortcut(QApplication::translate("OBSBasicFilters", "Del", nullptr));
|
||||
ui->actionRemoveFilter->setShortcut(
|
||||
QApplication::translate("OBSBasicFilters", "Del", nullptr));
|
||||
#endif // QT_NO_SHORTCUT
|
||||
|
||||
addAction(ui->actionRemoveFilter);
|
||||
|
@ -87,22 +81,22 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
|
|||
SIGNAL(closeEditor(QWidget *,
|
||||
QAbstractItemDelegate::EndEditHint)),
|
||||
this,
|
||||
SLOT(AsyncFilterNameEdited(QWidget*,
|
||||
QAbstractItemDelegate::EndEditHint)));
|
||||
SLOT(AsyncFilterNameEdited(
|
||||
QWidget *, QAbstractItemDelegate::EndEditHint)));
|
||||
|
||||
connect(ui->effectFilters->itemDelegate(),
|
||||
SIGNAL(closeEditor(QWidget *,
|
||||
QAbstractItemDelegate::EndEditHint)),
|
||||
this,
|
||||
SLOT(EffectFilterNameEdited(QWidget*,
|
||||
QAbstractItemDelegate::EndEditHint)));
|
||||
SLOT(EffectFilterNameEdited(
|
||||
QWidget *, QAbstractItemDelegate::EndEditHint)));
|
||||
|
||||
QPushButton *close = ui->buttonBox->button(QDialogButtonBox::Close);
|
||||
connect(close, SIGNAL(clicked()), this, SLOT(close()));
|
||||
close->setDefault(true);
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->setText(
|
||||
QTStr("Defaults"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)
|
||||
->setText(QTStr("Defaults"));
|
||||
|
||||
connect(ui->buttonBox->button(QDialogButtonBox::Reset),
|
||||
SIGNAL(clicked()), this, SLOT(ResetFilters()));
|
||||
|
@ -124,10 +118,10 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
|
|||
if (audioOnly || (audio && !async))
|
||||
ui->asyncLabel->setText(QTStr("Basic.Filters.AudioFilters"));
|
||||
|
||||
auto addDrawCallback = [this] ()
|
||||
{
|
||||
auto addDrawCallback = [this]() {
|
||||
obs_display_add_draw_callback(ui->preview->GetDisplay(),
|
||||
OBSBasicFilters::DrawPreview, this);
|
||||
OBSBasicFilters::DrawPreview,
|
||||
this);
|
||||
};
|
||||
|
||||
enum obs_source_type type = obs_source_get_type(source);
|
||||
|
@ -187,14 +181,14 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
|
|||
|
||||
obs_data_t *settings = obs_source_get_settings(filter);
|
||||
|
||||
view = new OBSPropertiesView(settings, filter,
|
||||
view = new OBSPropertiesView(
|
||||
settings, filter,
|
||||
(PropertiesReloadCallback)obs_source_properties,
|
||||
(PropertiesUpdateCallback)obs_source_update);
|
||||
|
||||
updatePropertiesSignal.Connect(obs_source_get_signal_handler(filter),
|
||||
"update_properties",
|
||||
OBSBasicFilters::UpdateProperties,
|
||||
this);
|
||||
OBSBasicFilters::UpdateProperties, this);
|
||||
|
||||
obs_data_release(settings);
|
||||
|
||||
|
@ -265,8 +259,8 @@ struct FilterOrderInfo {
|
|||
inline FilterOrderInfo(OBSBasicFilters *window_) : window(window_) {}
|
||||
};
|
||||
|
||||
void OBSBasicFilters::ReorderFilter(QListWidget *list,
|
||||
obs_source_t *filter, size_t idx)
|
||||
void OBSBasicFilters::ReorderFilter(QListWidget *list, obs_source_t *filter,
|
||||
size_t idx)
|
||||
{
|
||||
int count = list->count();
|
||||
|
||||
|
@ -282,8 +276,8 @@ void OBSBasicFilters::ReorderFilter(QListWidget *list,
|
|||
listItem = TakeListItem(list, i);
|
||||
if (listItem) {
|
||||
list->insertItem((int)idx, listItem);
|
||||
SetupVisibilityItem(list,
|
||||
listItem, filterItem);
|
||||
SetupVisibilityItem(list, listItem,
|
||||
filterItem);
|
||||
|
||||
if (sel)
|
||||
list->setCurrentRow((int)idx);
|
||||
|
@ -299,9 +293,9 @@ void OBSBasicFilters::ReorderFilters()
|
|||
{
|
||||
FilterOrderInfo info(this);
|
||||
|
||||
obs_source_enum_filters(source,
|
||||
[] (obs_source_t*, obs_source_t *filter, void *p)
|
||||
{
|
||||
obs_source_enum_filters(
|
||||
source,
|
||||
[](obs_source_t *, obs_source_t *filter, void *p) {
|
||||
FilterOrderInfo *info =
|
||||
reinterpret_cast<FilterOrderInfo *>(p);
|
||||
uint32_t flags;
|
||||
|
@ -312,14 +306,15 @@ void OBSBasicFilters::ReorderFilters()
|
|||
|
||||
if (async) {
|
||||
info->window->ReorderFilter(
|
||||
info->window->ui->asyncFilters,
|
||||
filter, info->asyncIdx++);
|
||||
info->window->ui->asyncFilters, filter,
|
||||
info->asyncIdx++);
|
||||
} else {
|
||||
info->window->ReorderFilter(
|
||||
info->window->ui->effectFilters,
|
||||
filter, info->effectIdx++);
|
||||
info->window->ui->effectFilters, filter,
|
||||
info->effectIdx++);
|
||||
}
|
||||
}, &info);
|
||||
},
|
||||
&info);
|
||||
}
|
||||
|
||||
void OBSBasicFilters::UpdateFilters()
|
||||
|
@ -330,14 +325,15 @@ void OBSBasicFilters::UpdateFilters()
|
|||
ClearListItems(ui->effectFilters);
|
||||
ClearListItems(ui->asyncFilters);
|
||||
|
||||
obs_source_enum_filters(source,
|
||||
[] (obs_source_t*, obs_source_t *filter, void *p)
|
||||
{
|
||||
obs_source_enum_filters(
|
||||
source,
|
||||
[](obs_source_t *, obs_source_t *filter, void *p) {
|
||||
OBSBasicFilters *window =
|
||||
reinterpret_cast<OBSBasicFilters *>(p);
|
||||
|
||||
window->AddFilter(filter);
|
||||
}, this);
|
||||
},
|
||||
this);
|
||||
|
||||
main->SaveProject();
|
||||
}
|
||||
|
@ -372,7 +368,8 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
|
|||
|
||||
inline FilterInfo(const char *type_, const char *name_)
|
||||
: type(type_), name(name_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
vector<FilterInfo> types;
|
||||
|
@ -396,17 +393,17 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
|
|||
|
||||
QMenu *popup = new QMenu(QTStr("Add"), this);
|
||||
for (FilterInfo &type : types) {
|
||||
uint32_t filterFlags = obs_get_source_output_flags(
|
||||
type.type.c_str());
|
||||
uint32_t filterFlags =
|
||||
obs_get_source_output_flags(type.type.c_str());
|
||||
|
||||
if (!filter_compatible(async, sourceFlags, filterFlags))
|
||||
continue;
|
||||
|
||||
QAction *popupItem = new QAction(QT_UTF8(type.name.c_str()),
|
||||
this);
|
||||
QAction *popupItem =
|
||||
new QAction(QT_UTF8(type.name.c_str()), this);
|
||||
popupItem->setData(QT_UTF8(type.type.c_str()));
|
||||
connect(popupItem, SIGNAL(triggered(bool)),
|
||||
this, SLOT(AddFilterFromAction()));
|
||||
connect(popupItem, SIGNAL(triggered(bool)), this,
|
||||
SLOT(AddFilterFromAction()));
|
||||
popup->addAction(popupItem);
|
||||
|
||||
foundValues = true;
|
||||
|
@ -426,8 +423,8 @@ void OBSBasicFilters::AddNewFilter(const char *id)
|
|||
obs_source_t *existing_filter;
|
||||
string name = obs_source_get_display_name(id);
|
||||
|
||||
bool success = NameDialog::AskForName(this,
|
||||
QTStr("Basic.Filters.AddFilter.Title"),
|
||||
bool success = NameDialog::AskForName(
|
||||
this, QTStr("Basic.Filters.AddFilter.Title"),
|
||||
QTStr("Basic.FIlters.AddFilter.Text"), name,
|
||||
QT_UTF8(name.c_str()));
|
||||
if (!success)
|
||||
|
@ -441,23 +438,23 @@ void OBSBasicFilters::AddNewFilter(const char *id)
|
|||
return;
|
||||
}
|
||||
|
||||
existing_filter = obs_source_get_filter_by_name(source,
|
||||
name.c_str());
|
||||
existing_filter =
|
||||
obs_source_get_filter_by_name(source, name.c_str());
|
||||
if (existing_filter) {
|
||||
OBSMessageBox::warning(this,
|
||||
QTStr("NameExists.Title"),
|
||||
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
|
||||
QTStr("NameExists.Text"));
|
||||
obs_source_release(existing_filter);
|
||||
AddNewFilter(id);
|
||||
return;
|
||||
}
|
||||
|
||||
obs_source_t *filter = obs_source_create(id, name.c_str(),
|
||||
nullptr, nullptr);
|
||||
obs_source_t *filter =
|
||||
obs_source_create(id, name.c_str(), nullptr, nullptr);
|
||||
if (filter) {
|
||||
const char *sourceName = obs_source_get_name(source);
|
||||
|
||||
blog(LOG_INFO, "User added filter '%s' (%s) "
|
||||
blog(LOG_INFO,
|
||||
"User added filter '%s' (%s) "
|
||||
"to source '%s'",
|
||||
name.c_str(), id, sourceName);
|
||||
|
||||
|
@ -574,8 +571,8 @@ static bool QueryRemove(QWidget *parent, obs_source_t *source)
|
|||
|
||||
QMessageBox remove_source(parent);
|
||||
remove_source.setText(text);
|
||||
QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"),
|
||||
QMessageBox::YesRole);
|
||||
QAbstractButton *Yes =
|
||||
remove_source.addButton(QTStr("Yes"), QMessageBox::YesRole);
|
||||
remove_source.addButton(QTStr("No"), QMessageBox::NoRole);
|
||||
remove_source.setIcon(QMessageBox::Question);
|
||||
remove_source.setWindowTitle(QTStr("ConfirmRemove.Title"));
|
||||
|
@ -704,11 +701,11 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
|
|||
popup.addMenu(addMenu);
|
||||
|
||||
if (item) {
|
||||
const char *renameSlot = async ?
|
||||
SLOT(RenameAsyncFilter()) : SLOT(RenameEffectFilter());
|
||||
const char *removeSlot = async ?
|
||||
SLOT(on_removeAsyncFilter_clicked()) :
|
||||
SLOT(on_removeEffectFilter_clicked());
|
||||
const char *renameSlot = async ? SLOT(RenameAsyncFilter())
|
||||
: SLOT(RenameEffectFilter());
|
||||
const char *removeSlot =
|
||||
async ? SLOT(on_removeAsyncFilter_clicked())
|
||||
: SLOT(on_removeEffectFilter_clicked());
|
||||
|
||||
popup.addSeparator();
|
||||
popup.addAction(QTStr("Rename"), this, renameSlot);
|
||||
|
@ -766,8 +763,8 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
|
|||
obs_source_t *foundFilter = nullptr;
|
||||
|
||||
if (!sameName)
|
||||
foundFilter = obs_source_get_filter_by_name(source,
|
||||
name.c_str());
|
||||
foundFilter =
|
||||
obs_source_get_filter_by_name(source, name.c_str());
|
||||
|
||||
if (foundFilter || name.empty() || sameName) {
|
||||
listItem->setText(QT_UTF8(prevName));
|
||||
|
@ -786,7 +783,8 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
|
|||
} else {
|
||||
const char *sourceName = obs_source_get_name(source);
|
||||
|
||||
blog(LOG_INFO, "User renamed filter '%s' on source '%s' to '%s'",
|
||||
blog(LOG_INFO,
|
||||
"User renamed filter '%s' on source '%s' to '%s'",
|
||||
prevName, sourceName, name.c_str());
|
||||
|
||||
listItem->setText(QT_UTF8(name.c_str()));
|
||||
|
@ -797,15 +795,15 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
|
|||
SetupVisibilityItem(list, listItem, filter);
|
||||
}
|
||||
|
||||
void OBSBasicFilters::AsyncFilterNameEdited(QWidget *editor,
|
||||
QAbstractItemDelegate::EndEditHint endHint)
|
||||
void OBSBasicFilters::AsyncFilterNameEdited(
|
||||
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
|
||||
{
|
||||
FilterNameEdited(editor, ui->asyncFilters);
|
||||
UNUSED_PARAMETER(endHint);
|
||||
}
|
||||
|
||||
void OBSBasicFilters::EffectFilterNameEdited(QWidget *editor,
|
||||
QAbstractItemDelegate::EndEditHint endHint)
|
||||
void OBSBasicFilters::EffectFilterNameEdited(
|
||||
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
|
||||
{
|
||||
FilterNameEdited(editor, ui->effectFilters);
|
||||
UNUSED_PARAMETER(endHint);
|
||||
|
|
|
@ -59,10 +59,10 @@ OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_)
|
|||
const char *name = obs_source_get_name(source);
|
||||
setWindowTitle(QTStr("Basic.InteractionWindow").arg(QT_UTF8(name)));
|
||||
|
||||
auto addDrawCallback = [this] ()
|
||||
{
|
||||
auto addDrawCallback = [this]() {
|
||||
obs_display_add_draw_callback(ui->preview->GetDisplay(),
|
||||
OBSBasicInteraction::DrawPreview, this);
|
||||
OBSBasicInteraction::DrawPreview,
|
||||
this);
|
||||
};
|
||||
|
||||
connect(ui->preview, &OBSQTDisplay::DisplayCreated, addDrawCallback);
|
||||
|
@ -77,9 +77,7 @@ OBSBasicInteraction::~OBSBasicInteraction()
|
|||
|
||||
OBSEventFilter *OBSBasicInteraction::BuildEventFilter()
|
||||
{
|
||||
return new OBSEventFilter(
|
||||
[this](QObject *obj, QEvent *event)
|
||||
{
|
||||
return new OBSEventFilter([this](QObject *obj, QEvent *event) {
|
||||
UNUSED_PARAMETER(obj);
|
||||
|
||||
switch (event->type()) {
|
||||
|
@ -149,8 +147,7 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
gs_viewport_push();
|
||||
gs_projection_push();
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
|
||||
-100.0f, 100.0f);
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
|
||||
gs_set_viewport(x, y, newCX, newCY);
|
||||
obs_source_video_render(window->source);
|
||||
|
||||
|
@ -170,10 +167,13 @@ void OBSBasicInteraction::closeEvent(QCloseEvent *event)
|
|||
height());
|
||||
|
||||
obs_display_remove_draw_callback(ui->preview->GetDisplay(),
|
||||
OBSBasicInteraction::DrawPreview, this);
|
||||
OBSBasicInteraction::DrawPreview,
|
||||
this);
|
||||
}
|
||||
|
||||
static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent) {
|
||||
static int TranslateQtKeyboardEventModifiers(QInputEvent *event,
|
||||
bool mouseEvent)
|
||||
{
|
||||
int obsModifiers = INTERACT_NONE;
|
||||
|
||||
if (event->modifiers().testFlag(Qt::ShiftModifier))
|
||||
|
@ -200,8 +200,7 @@ static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent
|
|||
return obsModifiers;
|
||||
}
|
||||
|
||||
static int TranslateQtMouseEventModifiers(
|
||||
QMouseEvent *event)
|
||||
static int TranslateQtMouseEventModifiers(QMouseEvent *event)
|
||||
{
|
||||
int modifiers = TranslateQtKeyboardEventModifiers(event, true);
|
||||
|
||||
|
@ -215,8 +214,8 @@ static int TranslateQtMouseEventModifiers(
|
|||
return modifiers;
|
||||
}
|
||||
|
||||
bool OBSBasicInteraction::GetSourceRelativeXY(
|
||||
int mouseX, int mouseY, int &relX, int &relY)
|
||||
bool OBSBasicInteraction::GetSourceRelativeXY(int mouseX, int mouseY, int &relX,
|
||||
int &relY)
|
||||
{
|
||||
QSize size = GetPixelSize(ui->preview);
|
||||
|
||||
|
@ -226,8 +225,8 @@ bool OBSBasicInteraction::GetSourceRelativeXY(
|
|||
int x, y;
|
||||
float scale;
|
||||
|
||||
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(),
|
||||
x, y, scale);
|
||||
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(), x,
|
||||
y, scale);
|
||||
|
||||
if (x > 0) {
|
||||
relX = int(float(mouseX - x) / scale);
|
||||
|
@ -246,8 +245,7 @@ bool OBSBasicInteraction::GetSourceRelativeXY(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OBSBasicInteraction::HandleMouseClickEvent(
|
||||
QMouseEvent *event)
|
||||
bool OBSBasicInteraction::HandleMouseClickEvent(QMouseEvent *event)
|
||||
{
|
||||
bool mouseUp = event->type() == QEvent::MouseButtonRelease;
|
||||
int clickCount = 1;
|
||||
|
@ -271,8 +269,7 @@ bool OBSBasicInteraction::HandleMouseClickEvent(
|
|||
button = MOUSE_RIGHT;
|
||||
break;
|
||||
default:
|
||||
blog(LOG_WARNING, "unknown button type %d",
|
||||
event->button());
|
||||
blog(LOG_WARNING, "unknown button type %d", event->button());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,13 +69,10 @@ protected:
|
|||
|
||||
typedef std::function<bool(QObject *, QEvent *)> EventFilterFunc;
|
||||
|
||||
class OBSEventFilter : public QObject
|
||||
{
|
||||
class OBSEventFilter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OBSEventFilter(EventFilterFunc filter_)
|
||||
: filter(filter_)
|
||||
{}
|
||||
OBSEventFilter(EventFilterFunc filter_) : filter(filter_) {}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event)
|
||||
|
|
|
@ -52,7 +52,8 @@ void CheckExistingCookieId()
|
|||
if (config_has_user_value(main->Config(), "Panels", "CookieId"))
|
||||
return;
|
||||
|
||||
config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str());
|
||||
config_set_string(main->Config(), "Panels", "CookieId",
|
||||
GenId().c_str());
|
||||
}
|
||||
|
||||
#ifdef BROWSER_AVAILABLE
|
||||
|
@ -66,8 +67,8 @@ static void InitPanelCookieManager()
|
|||
CheckExistingCookieId();
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
const char *cookie_id = config_get_string(main->Config(),
|
||||
"Panels", "CookieId");
|
||||
const char *cookie_id =
|
||||
config_get_string(main->Config(), "Panels", "CookieId");
|
||||
|
||||
std::string sub_path;
|
||||
sub_path += "obs_profile_cookies/";
|
||||
|
@ -102,8 +103,8 @@ void DuplicateCurrentCookieProfile(ConfigFile &config)
|
|||
#ifdef BROWSER_AVAILABLE
|
||||
if (cef) {
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
std::string cookie_id = config_get_string(main->Config(),
|
||||
"Panels", "CookieId");
|
||||
std::string cookie_id =
|
||||
config_get_string(main->Config(), "Panels", "CookieId");
|
||||
|
||||
std::string src_path;
|
||||
src_path += "obs_profile_cookies/";
|
||||
|
@ -155,8 +156,7 @@ void OBSBasic::InitBrowserPanelSafeBlock()
|
|||
return;
|
||||
}
|
||||
|
||||
ExecThreadedWithoutBlocking(
|
||||
[] {cef->wait_for_browser_init();},
|
||||
ExecThreadedWithoutBlocking([] { cef->wait_for_browser_init(); },
|
||||
QTStr("BrowserPanelInit.Title"),
|
||||
QTStr("BrowserPanelInit.Text"));
|
||||
InitPanelCookieManager();
|
||||
|
|
|
@ -11,34 +11,29 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
static const char *textExtensions[] = {
|
||||
"txt", "log", nullptr
|
||||
};
|
||||
static const char *textExtensions[] = {"txt", "log", nullptr};
|
||||
|
||||
static const char *imageExtensions[] = {
|
||||
"bmp", "tga", "png", "jpg", "jpeg", "gif", nullptr
|
||||
};
|
||||
static const char *imageExtensions[] = {"bmp", "tga", "png", "jpg",
|
||||
"jpeg", "gif", nullptr};
|
||||
|
||||
static const char *htmlExtensions[] = {
|
||||
"htm", "html", nullptr
|
||||
};
|
||||
static const char *htmlExtensions[] = {"htm", "html", nullptr};
|
||||
|
||||
static const char *mediaExtensions[] = {
|
||||
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif", "aifc",
|
||||
"aiff", "amb", "amr", "aob", "ape", "au", "awb", "caf", "dts",
|
||||
"flac", "it", "kar", "m4a", "m4b", "m4p", "m5p", "mid", "mka",
|
||||
"mlp", "mod", "mpa", "mp1", "mp2", "mp3", "mpc", "mpga", "mus",
|
||||
"oga", "ogg", "oma", "opus", "qcp", "ra", "rmi", "s3m", "sid",
|
||||
"spx", "tak", "thd", "tta", "voc", "vqf", "w64", "wav", "wma",
|
||||
"wv", "xa", "xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
|
||||
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv", "gvi",
|
||||
"gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v", "mkv", "mov",
|
||||
"mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg", "mpeg1", "mpeg2",
|
||||
"mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf", "mxg", "nsv", "nuv",
|
||||
"ogg", "ogm", "ogv", "ogx", "ps", "rec", "rm", "rmvb", "rpl", "thp",
|
||||
"tod", "ts", "tts", "txd", "vob", "vro", "webm", "wm", "wmv", "wtv",
|
||||
nullptr
|
||||
};
|
||||
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif",
|
||||
"aifc", "aiff", "amb", "amr", "aob", "ape", "au", "awb",
|
||||
"caf", "dts", "flac", "it", "kar", "m4a", "m4b", "m4p",
|
||||
"m5p", "mid", "mka", "mlp", "mod", "mpa", "mp1", "mp2",
|
||||
"mp3", "mpc", "mpga", "mus", "oga", "ogg", "oma", "opus",
|
||||
"qcp", "ra", "rmi", "s3m", "sid", "spx", "tak", "thd",
|
||||
"tta", "voc", "vqf", "w64", "wav", "wma", "wv", "xa",
|
||||
"xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
|
||||
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv",
|
||||
"gvi", "gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v",
|
||||
"mkv", "mov", "mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg",
|
||||
"mpeg1", "mpeg2", "mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf",
|
||||
"mxg", "nsv", "nuv", "ogg", "ogm", "ogv", "ogx", "ps",
|
||||
"rec", "rm", "rmvb", "rpl", "thp", "tod", "ts", "tts",
|
||||
"txd", "vob", "vro", "webm", "wm", "wmv", "wtv", nullptr};
|
||||
|
||||
static string GenerateSourceName(const char *base)
|
||||
{
|
||||
|
@ -188,4 +183,3 @@ if (found) \
|
|||
AddDropSource(QT_TO_UTF8(mimeData->text()), DropType_RawText);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ static void OBSStreamStarting(void *data, calldata_t *params)
|
|||
return;
|
||||
|
||||
output->delayActive = true;
|
||||
QMetaObject::invokeMethod(output->main,
|
||||
"StreamDelayStarting", Q_ARG(int, sec));
|
||||
QMetaObject::invokeMethod(output->main, "StreamDelayStarting",
|
||||
Q_ARG(int, sec));
|
||||
}
|
||||
|
||||
static void OBSStreamStopping(void *data, calldata_t *params)
|
||||
|
@ -37,8 +37,8 @@ static void OBSStreamStopping(void *data, calldata_t *params)
|
|||
if (sec == 0)
|
||||
QMetaObject::invokeMethod(output->main, "StreamStopping");
|
||||
else
|
||||
QMetaObject::invokeMethod(output->main,
|
||||
"StreamDelayStopping", Q_ARG(int, sec));
|
||||
QMetaObject::invokeMethod(output->main, "StreamDelayStopping",
|
||||
Q_ARG(int, sec));
|
||||
}
|
||||
|
||||
static void OBSStartStreaming(void *data, calldata_t *params)
|
||||
|
@ -62,8 +62,8 @@ static void OBSStopStreaming(void *data, calldata_t *params)
|
|||
output->streamingActive = false;
|
||||
output->delayActive = false;
|
||||
os_atomic_set_bool(&streaming_active, false);
|
||||
QMetaObject::invokeMethod(output->main,
|
||||
"StreamingStop", Q_ARG(int, code),
|
||||
QMetaObject::invokeMethod(output->main, "StreamingStop",
|
||||
Q_ARG(int, code),
|
||||
Q_ARG(QString, arg_last_error));
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,8 @@ static void OBSStopRecording(void *data, calldata_t *params)
|
|||
|
||||
output->recordingActive = false;
|
||||
os_atomic_set_bool(&recording_active, false);
|
||||
QMetaObject::invokeMethod(output->main,
|
||||
"RecordingStop", Q_ARG(int, code),
|
||||
QMetaObject::invokeMethod(output->main, "RecordingStop",
|
||||
Q_ARG(int, code),
|
||||
Q_ARG(QString, arg_last_error));
|
||||
|
||||
UNUSED_PARAMETER(params);
|
||||
|
@ -121,8 +121,8 @@ static void OBSStopReplayBuffer(void *data, calldata_t *params)
|
|||
|
||||
output->replayBufferActive = false;
|
||||
os_atomic_set_bool(&replaybuf_active, false);
|
||||
QMetaObject::invokeMethod(output->main,
|
||||
"ReplayBufferStop", Q_ARG(int, code));
|
||||
QMetaObject::invokeMethod(output->main, "ReplayBufferStop",
|
||||
Q_ARG(int, code));
|
||||
|
||||
UNUSED_PARAMETER(params);
|
||||
}
|
||||
|
@ -247,8 +247,8 @@ struct SimpleOutput : BasicOutputHandler {
|
|||
|
||||
void SimpleOutput::LoadRecordingPreset_Lossless()
|
||||
{
|
||||
fileOutput = obs_output_create("ffmpeg_output",
|
||||
"simple_ffmpeg_output", nullptr, nullptr);
|
||||
fileOutput = obs_output_create("ffmpeg_output", "simple_ffmpeg_output",
|
||||
nullptr, nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording FFmpeg output "
|
||||
"(simple output)";
|
||||
|
@ -267,8 +267,8 @@ void SimpleOutput::LoadRecordingPreset_Lossless()
|
|||
|
||||
void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId)
|
||||
{
|
||||
h264Recording = obs_video_encoder_create(encoderId,
|
||||
"simple_h264_recording", nullptr, nullptr);
|
||||
h264Recording = obs_video_encoder_create(
|
||||
encoderId, "simple_h264_recording", nullptr, nullptr);
|
||||
if (!h264Recording)
|
||||
throw "Failed to create h264 recording encoder (simple output)";
|
||||
obs_encoder_release(h264Recording);
|
||||
|
@ -276,8 +276,8 @@ void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId)
|
|||
|
||||
void SimpleOutput::LoadStreamingPreset_h264(const char *encoderId)
|
||||
{
|
||||
h264Streaming = obs_video_encoder_create(encoderId,
|
||||
"simple_h264_stream", nullptr, nullptr);
|
||||
h264Streaming = obs_video_encoder_create(
|
||||
encoderId, "simple_h264_stream", nullptr, nullptr);
|
||||
if (!h264Streaming)
|
||||
throw "Failed to create h264 streaming encoder (simple output)";
|
||||
obs_encoder_release(h264Streaming);
|
||||
|
@ -285,10 +285,10 @@ void SimpleOutput::LoadStreamingPreset_h264(const char *encoderId)
|
|||
|
||||
void SimpleOutput::LoadRecordingPreset()
|
||||
{
|
||||
const char *quality = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecQuality");
|
||||
const char *encoder = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecEncoder");
|
||||
const char *quality =
|
||||
config_get_string(main->Config(), "SimpleOutput", "RecQuality");
|
||||
const char *encoder =
|
||||
config_get_string(main->Config(), "SimpleOutput", "RecEncoder");
|
||||
|
||||
videoEncoder = encoder;
|
||||
videoQuality = quality;
|
||||
|
@ -345,8 +345,7 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
LoadStreamingPreset_h264("amd_amf_h264");
|
||||
|
||||
} else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) {
|
||||
const char *id = EncoderAvailable("jim_nvenc")
|
||||
? "jim_nvenc"
|
||||
const char *id = EncoderAvailable("jim_nvenc") ? "jim_nvenc"
|
||||
: "ffmpeg_nvenc";
|
||||
LoadStreamingPreset_h264(id);
|
||||
|
||||
|
@ -364,11 +363,12 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
bool useReplayBuffer = config_get_bool(main->Config(),
|
||||
"SimpleOutput", "RecRB");
|
||||
if (useReplayBuffer) {
|
||||
const char *str = config_get_string(main->Config(),
|
||||
"Hotkeys", "ReplayBuffer");
|
||||
const char *str = config_get_string(
|
||||
main->Config(), "Hotkeys", "ReplayBuffer");
|
||||
obs_data_t *hotkey = obs_data_create_from_json(str);
|
||||
replayBuffer = obs_output_create("replay_buffer",
|
||||
Str("ReplayBuffer"), nullptr, hotkey);
|
||||
Str("ReplayBuffer"),
|
||||
nullptr, hotkey);
|
||||
|
||||
obs_data_release(hotkey);
|
||||
if (!replayBuffer)
|
||||
|
@ -384,11 +384,12 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
stopReplayBuffer.Connect(signal, "stop",
|
||||
OBSStopReplayBuffer, this);
|
||||
replayBufferStopping.Connect(signal, "stopping",
|
||||
OBSReplayBufferStopping, this);
|
||||
OBSReplayBufferStopping,
|
||||
this);
|
||||
}
|
||||
|
||||
fileOutput = obs_output_create("ffmpeg_muxer",
|
||||
"simple_file_output", nullptr, nullptr);
|
||||
fileOutput = obs_output_create(
|
||||
"ffmpeg_muxer", "simple_file_output", nullptr, nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording output "
|
||||
"(simple output)";
|
||||
|
@ -397,8 +398,8 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
|
||||
startRecording.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"start", OBSStartRecording, this);
|
||||
stopRecording.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"stop", OBSStopRecording, this);
|
||||
stopRecording.Connect(obs_output_get_signal_handler(fileOutput), "stop",
|
||||
OBSStopRecording, this);
|
||||
recordStopping.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"stopping", OBSRecordStopping, this);
|
||||
}
|
||||
|
@ -416,15 +417,15 @@ void SimpleOutput::Update()
|
|||
obs_data_t *h264Settings = obs_data_create();
|
||||
obs_data_t *aacSettings = obs_data_create();
|
||||
|
||||
int videoBitrate = config_get_uint(main->Config(), "SimpleOutput",
|
||||
"VBitrate");
|
||||
int videoBitrate =
|
||||
config_get_uint(main->Config(), "SimpleOutput", "VBitrate");
|
||||
int audioBitrate = GetAudioBitrate();
|
||||
bool advanced = config_get_bool(main->Config(), "SimpleOutput",
|
||||
"UseAdvanced");
|
||||
bool advanced =
|
||||
config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced");
|
||||
bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput",
|
||||
"EnforceBitrate");
|
||||
const char *custom = config_get_string(main->Config(),
|
||||
"SimpleOutput", "x264Settings");
|
||||
const char *custom = config_get_string(main->Config(), "SimpleOutput",
|
||||
"x264Settings");
|
||||
const char *encoder = config_get_string(main->Config(), "SimpleOutput",
|
||||
"StreamEncoder");
|
||||
const char *presetType;
|
||||
|
@ -457,8 +458,8 @@ void SimpleOutput::Update()
|
|||
obs_data_set_string(aacSettings, "rate_control", "CBR");
|
||||
obs_data_set_int(aacSettings, "bitrate", audioBitrate);
|
||||
|
||||
obs_service_apply_encoder_settings(main->GetService(),
|
||||
h264Settings, aacSettings);
|
||||
obs_service_apply_encoder_settings(main->GetService(), h264Settings,
|
||||
aacSettings);
|
||||
|
||||
if (advanced && !enforceBitrate) {
|
||||
obs_data_set_int(h264Settings, "bitrate", videoBitrate);
|
||||
|
@ -696,31 +697,33 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
|
|||
startStreaming.Disconnect();
|
||||
stopStreaming.Disconnect();
|
||||
|
||||
streamOutput = obs_output_create(type, "simple_stream",
|
||||
nullptr, nullptr);
|
||||
streamOutput = obs_output_create(type, "simple_stream", nullptr,
|
||||
nullptr);
|
||||
if (!streamOutput) {
|
||||
blog(LOG_WARNING, "Creation of stream output type '%s' "
|
||||
"failed!", type);
|
||||
blog(LOG_WARNING,
|
||||
"Creation of stream output type '%s' "
|
||||
"failed!",
|
||||
type);
|
||||
return false;
|
||||
}
|
||||
obs_output_release(streamOutput);
|
||||
|
||||
streamDelayStarting.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"starting", OBSStreamStarting, this);
|
||||
obs_output_get_signal_handler(streamOutput), "starting",
|
||||
OBSStreamStarting, this);
|
||||
streamStopping.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"stopping", OBSStreamStopping, this);
|
||||
obs_output_get_signal_handler(streamOutput), "stopping",
|
||||
OBSStreamStopping, this);
|
||||
|
||||
startStreaming.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"start", OBSStartStreaming, this);
|
||||
obs_output_get_signal_handler(streamOutput), "start",
|
||||
OBSStartStreaming, this);
|
||||
stopStreaming.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"stop", OBSStopStreaming, this);
|
||||
obs_output_get_signal_handler(streamOutput), "stop",
|
||||
OBSStopStreaming, this);
|
||||
|
||||
bool isEncoded = obs_output_get_flags(streamOutput)
|
||||
& OBS_OUTPUT_ENCODED;
|
||||
bool isEncoded = obs_output_get_flags(streamOutput) &
|
||||
OBS_OUTPUT_ENCODED;
|
||||
|
||||
if (isEncoded) {
|
||||
const char *codec =
|
||||
|
@ -732,15 +735,15 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
|
|||
}
|
||||
|
||||
if (strcmp(codec, "aac") != 0) {
|
||||
const char *id = FindAudioEncoderFromCodec(
|
||||
codec);
|
||||
const char *id =
|
||||
FindAudioEncoderFromCodec(codec);
|
||||
int audioBitrate = GetAudioBitrate();
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_int(settings, "bitrate",
|
||||
audioBitrate);
|
||||
|
||||
aacStreaming = obs_audio_encoder_create(id,
|
||||
"alt_audio_enc", nullptr, 0,
|
||||
aacStreaming = obs_audio_encoder_create(
|
||||
id, "alt_audio_enc", nullptr, 0,
|
||||
nullptr);
|
||||
obs_encoder_release(aacStreaming);
|
||||
if (!aacStreaming)
|
||||
|
@ -763,24 +766,22 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
|
|||
|
||||
/* --------------------- */
|
||||
|
||||
bool reconnect = config_get_bool(main->Config(), "Output",
|
||||
"Reconnect");
|
||||
int retryDelay = config_get_uint(main->Config(), "Output",
|
||||
"RetryDelay");
|
||||
int maxRetries = config_get_uint(main->Config(), "Output",
|
||||
"MaxRetries");
|
||||
bool useDelay = config_get_bool(main->Config(), "Output",
|
||||
"DelayEnable");
|
||||
int delaySec = config_get_int(main->Config(), "Output",
|
||||
"DelaySec");
|
||||
bool preserveDelay = config_get_bool(main->Config(), "Output",
|
||||
"DelayPreserve");
|
||||
const char *bindIP = config_get_string(main->Config(), "Output",
|
||||
"BindIP");
|
||||
bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect");
|
||||
int retryDelay =
|
||||
config_get_uint(main->Config(), "Output", "RetryDelay");
|
||||
int maxRetries =
|
||||
config_get_uint(main->Config(), "Output", "MaxRetries");
|
||||
bool useDelay =
|
||||
config_get_bool(main->Config(), "Output", "DelayEnable");
|
||||
int delaySec = config_get_int(main->Config(), "Output", "DelaySec");
|
||||
bool preserveDelay =
|
||||
config_get_bool(main->Config(), "Output", "DelayPreserve");
|
||||
const char *bindIP =
|
||||
config_get_string(main->Config(), "Output", "BindIP");
|
||||
bool enableNewSocketLoop = config_get_bool(main->Config(), "Output",
|
||||
"NewSocketLoopEnable");
|
||||
bool enableLowLatencyMode = config_get_bool(main->Config(), "Output",
|
||||
"LowLatencyEnable");
|
||||
bool enableLowLatencyMode =
|
||||
config_get_bool(main->Config(), "Output", "LowLatencyEnable");
|
||||
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_string(settings, "bind_ip", bindIP);
|
||||
|
@ -797,8 +798,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
|
|||
obs_output_set_delay(streamOutput, useDelay ? delaySec : 0,
|
||||
preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0);
|
||||
|
||||
obs_output_set_reconnect_settings(streamOutput, maxRetries,
|
||||
retryDelay);
|
||||
obs_output_set_reconnect_settings(streamOutput, maxRetries, retryDelay);
|
||||
|
||||
if (obs_output_start(streamOutput)) {
|
||||
return true;
|
||||
|
@ -812,8 +812,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
|
|||
lastError = string();
|
||||
|
||||
blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type,
|
||||
hasLastError ? " Last Error: " : "",
|
||||
hasLastError ? error : "");
|
||||
hasLastError ? " Last Error: " : "", hasLastError ? error : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -871,26 +870,26 @@ void SimpleOutput::UpdateRecording()
|
|||
|
||||
bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
|
||||
{
|
||||
const char *path = config_get_string(main->Config(),
|
||||
"SimpleOutput", "FilePath");
|
||||
const char *format = config_get_string(main->Config(),
|
||||
"SimpleOutput", "RecFormat");
|
||||
const char *path =
|
||||
config_get_string(main->Config(), "SimpleOutput", "FilePath");
|
||||
const char *format =
|
||||
config_get_string(main->Config(), "SimpleOutput", "RecFormat");
|
||||
const char *mux = config_get_string(main->Config(), "SimpleOutput",
|
||||
"MuxerCustom");
|
||||
bool noSpace = config_get_bool(main->Config(), "SimpleOutput",
|
||||
"FileNameWithoutSpace");
|
||||
const char *filenameFormat = config_get_string(main->Config(), "Output",
|
||||
"FilenameFormatting");
|
||||
bool overwriteIfExists = config_get_bool(main->Config(), "Output",
|
||||
"OverwriteIfExists");
|
||||
bool overwriteIfExists =
|
||||
config_get_bool(main->Config(), "Output", "OverwriteIfExists");
|
||||
const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecRBPrefix");
|
||||
const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecRBSuffix");
|
||||
int rbTime = config_get_int(main->Config(), "SimpleOutput",
|
||||
"RecRBTime");
|
||||
int rbSize = config_get_int(main->Config(), "SimpleOutput",
|
||||
"RecRBSize");
|
||||
int rbTime =
|
||||
config_get_int(main->Config(), "SimpleOutput", "RecRBTime");
|
||||
int rbSize =
|
||||
config_get_int(main->Config(), "SimpleOutput", "RecRBSize");
|
||||
|
||||
os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr;
|
||||
|
||||
|
@ -990,8 +989,7 @@ bool SimpleOutput::StartReplayBuffer()
|
|||
if (!ConfigureRecording(true))
|
||||
return false;
|
||||
if (!obs_output_start(replayBuffer)) {
|
||||
QMessageBox::critical(main,
|
||||
QTStr("Output.StartReplayFailed"),
|
||||
QMessageBox::critical(main, QTStr("Output.StartReplayFailed"),
|
||||
QTStr("Output.StartFailedGeneric"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1111,15 +1109,16 @@ static void ApplyEncoderDefaults(OBSData &settings,
|
|||
|
||||
AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
||||
{
|
||||
const char *recType = config_get_string(main->Config(), "AdvOut",
|
||||
"RecType");
|
||||
const char *streamEncoder = config_get_string(main->Config(), "AdvOut",
|
||||
"Encoder");
|
||||
const char *recordEncoder = config_get_string(main->Config(), "AdvOut",
|
||||
"RecEncoder");
|
||||
const char *recType =
|
||||
config_get_string(main->Config(), "AdvOut", "RecType");
|
||||
const char *streamEncoder =
|
||||
config_get_string(main->Config(), "AdvOut", "Encoder");
|
||||
const char *recordEncoder =
|
||||
config_get_string(main->Config(), "AdvOut", "RecEncoder");
|
||||
|
||||
ffmpegOutput = astrcmpi(recType, "FFmpeg") == 0;
|
||||
ffmpegRecording = ffmpegOutput &&
|
||||
ffmpegRecording =
|
||||
ffmpegOutput &&
|
||||
config_get_bool(main->Config(), "AdvOut", "FFOutputToFile");
|
||||
useStreamEncoder = astrcmpi(recordEncoder, "none") == 0;
|
||||
|
||||
|
@ -1136,21 +1135,22 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
astrcmpi(rate_control, "ABR") == 0;
|
||||
|
||||
if (ffmpegOutput) {
|
||||
fileOutput = obs_output_create("ffmpeg_output",
|
||||
"adv_ffmpeg_output", nullptr, nullptr);
|
||||
fileOutput = obs_output_create(
|
||||
"ffmpeg_output", "adv_ffmpeg_output", nullptr, nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording FFmpeg output "
|
||||
"(advanced output)";
|
||||
obs_output_release(fileOutput);
|
||||
} else {
|
||||
bool useReplayBuffer = config_get_bool(main->Config(),
|
||||
"AdvOut", "RecRB");
|
||||
bool useReplayBuffer =
|
||||
config_get_bool(main->Config(), "AdvOut", "RecRB");
|
||||
if (useReplayBuffer) {
|
||||
const char *str = config_get_string(main->Config(),
|
||||
"Hotkeys", "ReplayBuffer");
|
||||
const char *str = config_get_string(
|
||||
main->Config(), "Hotkeys", "ReplayBuffer");
|
||||
obs_data_t *hotkey = obs_data_create_from_json(str);
|
||||
replayBuffer = obs_output_create("replay_buffer",
|
||||
Str("ReplayBuffer"), nullptr, hotkey);
|
||||
Str("ReplayBuffer"),
|
||||
nullptr, hotkey);
|
||||
|
||||
obs_data_release(hotkey);
|
||||
if (!replayBuffer)
|
||||
|
@ -1159,28 +1159,28 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
obs_output_release(replayBuffer);
|
||||
|
||||
signal_handler_t *signal =
|
||||
obs_output_get_signal_handler(
|
||||
replayBuffer);
|
||||
obs_output_get_signal_handler(replayBuffer);
|
||||
|
||||
startReplayBuffer.Connect(signal, "start",
|
||||
OBSStartReplayBuffer, this);
|
||||
stopReplayBuffer.Connect(signal, "stop",
|
||||
OBSStopReplayBuffer, this);
|
||||
replayBufferStopping.Connect(signal, "stopping",
|
||||
OBSReplayBufferStopping, this);
|
||||
OBSReplayBufferStopping,
|
||||
this);
|
||||
}
|
||||
|
||||
fileOutput = obs_output_create("ffmpeg_muxer",
|
||||
"adv_file_output", nullptr, nullptr);
|
||||
fileOutput = obs_output_create(
|
||||
"ffmpeg_muxer", "adv_file_output", nullptr, nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording output "
|
||||
"(advanced output)";
|
||||
obs_output_release(fileOutput);
|
||||
|
||||
if (!useStreamEncoder) {
|
||||
h264Recording = obs_video_encoder_create(recordEncoder,
|
||||
"recording_h264", recordEncSettings,
|
||||
nullptr);
|
||||
h264Recording = obs_video_encoder_create(
|
||||
recordEncoder, "recording_h264",
|
||||
recordEncSettings, nullptr);
|
||||
if (!h264Recording)
|
||||
throw "Failed to create recording h264 "
|
||||
"encoder (advanced output)";
|
||||
|
@ -1188,8 +1188,8 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
}
|
||||
}
|
||||
|
||||
h264Streaming = obs_video_encoder_create(streamEncoder,
|
||||
"streaming_h264", streamEncSettings, nullptr);
|
||||
h264Streaming = obs_video_encoder_create(
|
||||
streamEncoder, "streaming_h264", streamEncSettings, nullptr);
|
||||
if (!h264Streaming)
|
||||
throw "Failed to create streaming h264 encoder "
|
||||
"(advanced output)";
|
||||
|
@ -1207,8 +1207,8 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
|||
|
||||
startRecording.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"start", OBSStartRecording, this);
|
||||
stopRecording.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"stop", OBSStopRecording, this);
|
||||
stopRecording.Connect(obs_output_get_signal_handler(fileOutput), "stop",
|
||||
OBSStopRecording, this);
|
||||
recordStopping.Connect(obs_output_get_signal_handler(fileOutput),
|
||||
"stopping", OBSRecordStopping, this);
|
||||
}
|
||||
|
@ -1222,8 +1222,8 @@ void AdvancedOutput::UpdateStreamSettings()
|
|||
ApplyEncoderDefaults(settings, h264Streaming);
|
||||
|
||||
if (applyServiceSettings)
|
||||
obs_service_apply_encoder_settings(main->GetService(),
|
||||
settings, nullptr);
|
||||
obs_service_apply_encoder_settings(main->GetService(), settings,
|
||||
nullptr);
|
||||
|
||||
video_t *video = obs_get_video();
|
||||
enum video_format format = video_output_get_format(video);
|
||||
|
@ -1251,10 +1251,9 @@ void AdvancedOutput::Update()
|
|||
|
||||
inline void AdvancedOutput::SetupStreaming()
|
||||
{
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut",
|
||||
"Rescale");
|
||||
const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
|
||||
"RescaleRes");
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut", "Rescale");
|
||||
const char *rescaleRes =
|
||||
config_get_string(main->Config(), "AdvOut", "RescaleRes");
|
||||
uint32_t caps = obs_encoder_get_caps(h264Streaming);
|
||||
unsigned int cx = 0;
|
||||
unsigned int cy = 0;
|
||||
|
@ -1276,14 +1275,13 @@ inline void AdvancedOutput::SetupStreaming()
|
|||
|
||||
inline void AdvancedOutput::SetupRecording()
|
||||
{
|
||||
const char *path = config_get_string(main->Config(), "AdvOut",
|
||||
"RecFilePath");
|
||||
const char *mux = config_get_string(main->Config(), "AdvOut",
|
||||
"RecMuxerCustom");
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut",
|
||||
"RecRescale");
|
||||
const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
|
||||
"RecRescaleRes");
|
||||
const char *path =
|
||||
config_get_string(main->Config(), "AdvOut", "RecFilePath");
|
||||
const char *mux =
|
||||
config_get_string(main->Config(), "AdvOut", "RecMuxerCustom");
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut", "RecRescale");
|
||||
const char *rescaleRes =
|
||||
config_get_string(main->Config(), "AdvOut", "RecRescaleRes");
|
||||
int tracks = config_get_int(main->Config(), "AdvOut", "RecTracks");
|
||||
obs_data_t *settings = obs_data_create();
|
||||
unsigned int cx = 0;
|
||||
|
@ -1341,36 +1339,31 @@ inline void AdvancedOutput::SetupRecording()
|
|||
inline void AdvancedOutput::SetupFFmpeg()
|
||||
{
|
||||
const char *url = config_get_string(main->Config(), "AdvOut", "FFURL");
|
||||
int vBitrate = config_get_int(main->Config(), "AdvOut",
|
||||
"FFVBitrate");
|
||||
int gopSize = config_get_int(main->Config(), "AdvOut",
|
||||
"FFVGOPSize");
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut",
|
||||
"FFRescale");
|
||||
const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
|
||||
"FFRescaleRes");
|
||||
const char *formatName = config_get_string(main->Config(), "AdvOut",
|
||||
"FFFormat");
|
||||
const char *mimeType = config_get_string(main->Config(), "AdvOut",
|
||||
"FFFormatMimeType");
|
||||
const char *muxCustom = config_get_string(main->Config(), "AdvOut",
|
||||
"FFMCustom");
|
||||
const char *vEncoder = config_get_string(main->Config(), "AdvOut",
|
||||
"FFVEncoder");
|
||||
int vEncoderId = config_get_int(main->Config(), "AdvOut",
|
||||
"FFVEncoderId");
|
||||
const char *vEncCustom = config_get_string(main->Config(), "AdvOut",
|
||||
"FFVCustom");
|
||||
int aBitrate = config_get_int(main->Config(), "AdvOut",
|
||||
"FFABitrate");
|
||||
int aMixes = config_get_int(main->Config(), "AdvOut",
|
||||
"FFAudioMixes");
|
||||
const char *aEncoder = config_get_string(main->Config(), "AdvOut",
|
||||
"FFAEncoder");
|
||||
int aEncoderId = config_get_int(main->Config(), "AdvOut",
|
||||
"FFAEncoderId");
|
||||
const char *aEncCustom = config_get_string(main->Config(), "AdvOut",
|
||||
"FFACustom");
|
||||
int vBitrate = config_get_int(main->Config(), "AdvOut", "FFVBitrate");
|
||||
int gopSize = config_get_int(main->Config(), "AdvOut", "FFVGOPSize");
|
||||
bool rescale = config_get_bool(main->Config(), "AdvOut", "FFRescale");
|
||||
const char *rescaleRes =
|
||||
config_get_string(main->Config(), "AdvOut", "FFRescaleRes");
|
||||
const char *formatName =
|
||||
config_get_string(main->Config(), "AdvOut", "FFFormat");
|
||||
const char *mimeType =
|
||||
config_get_string(main->Config(), "AdvOut", "FFFormatMimeType");
|
||||
const char *muxCustom =
|
||||
config_get_string(main->Config(), "AdvOut", "FFMCustom");
|
||||
const char *vEncoder =
|
||||
config_get_string(main->Config(), "AdvOut", "FFVEncoder");
|
||||
int vEncoderId =
|
||||
config_get_int(main->Config(), "AdvOut", "FFVEncoderId");
|
||||
const char *vEncCustom =
|
||||
config_get_string(main->Config(), "AdvOut", "FFVCustom");
|
||||
int aBitrate = config_get_int(main->Config(), "AdvOut", "FFABitrate");
|
||||
int aMixes = config_get_int(main->Config(), "AdvOut", "FFAudioMixes");
|
||||
const char *aEncoder =
|
||||
config_get_string(main->Config(), "AdvOut", "FFAEncoder");
|
||||
int aEncoderId =
|
||||
config_get_int(main->Config(), "AdvOut", "FFAEncoderId");
|
||||
const char *aEncCustom =
|
||||
config_get_string(main->Config(), "AdvOut", "FFACustom");
|
||||
obs_data_t *settings = obs_data_create();
|
||||
|
||||
obs_data_set_string(settings, "url", url);
|
||||
|
@ -1415,8 +1408,8 @@ inline void AdvancedOutput::UpdateAudioSettings()
|
|||
{
|
||||
bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
|
||||
"ApplyServiceSettings");
|
||||
int streamTrackIndex = config_get_int(main->Config(), "AdvOut",
|
||||
"TrackIndex");
|
||||
int streamTrackIndex =
|
||||
config_get_int(main->Config(), "AdvOut", "TrackIndex");
|
||||
obs_data_t *settings[MAX_AUDIO_MIXES];
|
||||
|
||||
for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
|
||||
|
@ -1438,8 +1431,8 @@ inline void AdvancedOutput::UpdateAudioSettings()
|
|||
|
||||
for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
|
||||
if (applyServiceSettings && (int)(i + 1) == streamTrackIndex)
|
||||
obs_service_apply_encoder_settings(main->GetService(),
|
||||
nullptr, settings[i]);
|
||||
obs_service_apply_encoder_settings(
|
||||
main->GetService(), nullptr, settings[i]);
|
||||
|
||||
obs_encoder_update(aacTrack[i], settings[i]);
|
||||
obs_data_release(settings[i]);
|
||||
|
@ -1465,9 +1458,8 @@ void AdvancedOutput::SetupOutputs()
|
|||
int AdvancedOutput::GetAudioBitrate(size_t i) const
|
||||
{
|
||||
static const char *names[] = {
|
||||
"Track1Bitrate", "Track2Bitrate",
|
||||
"Track3Bitrate", "Track4Bitrate",
|
||||
"Track5Bitrate", "Track6Bitrate",
|
||||
"Track1Bitrate", "Track2Bitrate", "Track3Bitrate",
|
||||
"Track4Bitrate", "Track5Bitrate", "Track6Bitrate",
|
||||
};
|
||||
int bitrate = (int)config_get_uint(main->Config(), "AdvOut", names[i]);
|
||||
return FindClosestAvailableAACBitrate(bitrate);
|
||||
|
@ -1491,8 +1483,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
|
||||
/* --------------------- */
|
||||
|
||||
int trackIndex = config_get_int(main->Config(), "AdvOut",
|
||||
"TrackIndex");
|
||||
int trackIndex = config_get_int(main->Config(), "AdvOut", "TrackIndex");
|
||||
|
||||
const char *type = obs_service_get_output_type(service);
|
||||
if (!type)
|
||||
|
@ -1505,31 +1496,33 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
startStreaming.Disconnect();
|
||||
stopStreaming.Disconnect();
|
||||
|
||||
streamOutput = obs_output_create(type, "adv_stream",
|
||||
nullptr, nullptr);
|
||||
streamOutput =
|
||||
obs_output_create(type, "adv_stream", nullptr, nullptr);
|
||||
if (!streamOutput) {
|
||||
blog(LOG_WARNING, "Creation of stream output type '%s' "
|
||||
"failed!", type);
|
||||
blog(LOG_WARNING,
|
||||
"Creation of stream output type '%s' "
|
||||
"failed!",
|
||||
type);
|
||||
return false;
|
||||
}
|
||||
obs_output_release(streamOutput);
|
||||
|
||||
streamDelayStarting.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"starting", OBSStreamStarting, this);
|
||||
obs_output_get_signal_handler(streamOutput), "starting",
|
||||
OBSStreamStarting, this);
|
||||
streamStopping.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"stopping", OBSStreamStopping, this);
|
||||
obs_output_get_signal_handler(streamOutput), "stopping",
|
||||
OBSStreamStopping, this);
|
||||
|
||||
startStreaming.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"start", OBSStartStreaming, this);
|
||||
obs_output_get_signal_handler(streamOutput), "start",
|
||||
OBSStartStreaming, this);
|
||||
stopStreaming.Connect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"stop", OBSStopStreaming, this);
|
||||
obs_output_get_signal_handler(streamOutput), "stop",
|
||||
OBSStopStreaming, this);
|
||||
|
||||
bool isEncoded = obs_output_get_flags(streamOutput)
|
||||
& OBS_OUTPUT_ENCODED;
|
||||
bool isEncoded = obs_output_get_flags(streamOutput) &
|
||||
OBS_OUTPUT_ENCODED;
|
||||
|
||||
if (isEncoded) {
|
||||
const char *codec =
|
||||
|
@ -1551,8 +1544,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
|
||||
obs_data_set_int(settings, "bitrate",
|
||||
audioBitrate);
|
||||
streamAudioEnc = obs_audio_encoder_create(id,
|
||||
"alt_audio_enc", nullptr,
|
||||
streamAudioEnc = obs_audio_encoder_create(
|
||||
id, "alt_audio_enc", nullptr,
|
||||
trackIndex - 1, nullptr);
|
||||
|
||||
if (!streamAudioEnc)
|
||||
|
@ -1579,18 +1572,17 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect");
|
||||
int retryDelay = config_get_int(main->Config(), "Output", "RetryDelay");
|
||||
int maxRetries = config_get_int(main->Config(), "Output", "MaxRetries");
|
||||
bool useDelay = config_get_bool(main->Config(), "Output",
|
||||
"DelayEnable");
|
||||
int delaySec = config_get_int(main->Config(), "Output",
|
||||
"DelaySec");
|
||||
bool preserveDelay = config_get_bool(main->Config(), "Output",
|
||||
"DelayPreserve");
|
||||
const char *bindIP = config_get_string(main->Config(), "Output",
|
||||
"BindIP");
|
||||
bool useDelay =
|
||||
config_get_bool(main->Config(), "Output", "DelayEnable");
|
||||
int delaySec = config_get_int(main->Config(), "Output", "DelaySec");
|
||||
bool preserveDelay =
|
||||
config_get_bool(main->Config(), "Output", "DelayPreserve");
|
||||
const char *bindIP =
|
||||
config_get_string(main->Config(), "Output", "BindIP");
|
||||
bool enableNewSocketLoop = config_get_bool(main->Config(), "Output",
|
||||
"NewSocketLoopEnable");
|
||||
bool enableLowLatencyMode = config_get_bool(main->Config(), "Output",
|
||||
"LowLatencyEnable");
|
||||
bool enableLowLatencyMode =
|
||||
config_get_bool(main->Config(), "Output", "LowLatencyEnable");
|
||||
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_string(settings, "bind_ip", bindIP);
|
||||
|
@ -1607,8 +1599,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
obs_output_set_delay(streamOutput, useDelay ? delaySec : 0,
|
||||
preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0);
|
||||
|
||||
obs_output_set_reconnect_settings(streamOutput, maxRetries,
|
||||
retryDelay);
|
||||
obs_output_set_reconnect_settings(streamOutput, maxRetries, retryDelay);
|
||||
|
||||
if (obs_output_start(streamOutput)) {
|
||||
return true;
|
||||
|
@ -1622,8 +1613,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
|
|||
lastError = string();
|
||||
|
||||
blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type,
|
||||
hasLastError ? " Last Error: " : "",
|
||||
hasLastError ? error : "");
|
||||
hasLastError ? " Last Error: " : "", hasLastError ? error : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1650,27 +1640,30 @@ bool AdvancedOutput::StartRecording()
|
|||
|
||||
if (!ffmpegOutput || ffmpegRecording) {
|
||||
path = config_get_string(main->Config(), "AdvOut",
|
||||
ffmpegRecording ? "FFFilePath" : "RecFilePath");
|
||||
ffmpegRecording ? "FFFilePath"
|
||||
: "RecFilePath");
|
||||
recFormat = config_get_string(main->Config(), "AdvOut",
|
||||
ffmpegRecording ? "FFExtension" : "RecFormat");
|
||||
ffmpegRecording ? "FFExtension"
|
||||
: "RecFormat");
|
||||
filenameFormat = config_get_string(main->Config(), "Output",
|
||||
"FilenameFormatting");
|
||||
overwriteIfExists = config_get_bool(main->Config(), "Output",
|
||||
"OverwriteIfExists");
|
||||
noSpace = config_get_bool(main->Config(), "AdvOut",
|
||||
ffmpegRecording ?
|
||||
"FFFileNameWithoutSpace" :
|
||||
"RecFileNameWithoutSpace");
|
||||
ffmpegRecording
|
||||
? "FFFileNameWithoutSpace"
|
||||
: "RecFileNameWithoutSpace");
|
||||
|
||||
os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr;
|
||||
|
||||
if (!dir) {
|
||||
if (main->isVisible())
|
||||
OBSMessageBox::warning(main,
|
||||
QTStr("Output.BadPath.Title"),
|
||||
OBSMessageBox::warning(
|
||||
main, QTStr("Output.BadPath.Title"),
|
||||
QTStr("Output.BadPath.Text"));
|
||||
else
|
||||
main->SysTrayNotify(QTStr("Output.BadPath.Text"),
|
||||
main->SysTrayNotify(
|
||||
QTStr("Output.BadPath.Text"),
|
||||
QSystemTrayIcon::Warning);
|
||||
return false;
|
||||
}
|
||||
|
@ -1691,8 +1684,7 @@ bool AdvancedOutput::StartRecording()
|
|||
FindBestFilename(strPath, noSpace);
|
||||
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_string(settings,
|
||||
ffmpegRecording ? "url" : "path",
|
||||
obs_data_set_string(settings, ffmpegRecording ? "url" : "path",
|
||||
strPath.c_str());
|
||||
|
||||
obs_output_update(fileOutput, settings);
|
||||
|
@ -1742,35 +1734,36 @@ bool AdvancedOutput::StartReplayBuffer()
|
|||
|
||||
if (!ffmpegOutput || ffmpegRecording) {
|
||||
path = config_get_string(main->Config(), "AdvOut",
|
||||
ffmpegRecording ? "FFFilePath" : "RecFilePath");
|
||||
ffmpegRecording ? "FFFilePath"
|
||||
: "RecFilePath");
|
||||
recFormat = config_get_string(main->Config(), "AdvOut",
|
||||
ffmpegRecording ? "FFExtension" : "RecFormat");
|
||||
ffmpegRecording ? "FFExtension"
|
||||
: "RecFormat");
|
||||
filenameFormat = config_get_string(main->Config(), "Output",
|
||||
"FilenameFormatting");
|
||||
overwriteIfExists = config_get_bool(main->Config(), "Output",
|
||||
"OverwriteIfExists");
|
||||
noSpace = config_get_bool(main->Config(), "AdvOut",
|
||||
ffmpegRecording ?
|
||||
"FFFileNameWithoutSpace" :
|
||||
"RecFileNameWithoutSpace");
|
||||
ffmpegRecording
|
||||
? "FFFileNameWithoutSpace"
|
||||
: "RecFileNameWithoutSpace");
|
||||
rbPrefix = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecRBPrefix");
|
||||
rbSuffix = config_get_string(main->Config(), "SimpleOutput",
|
||||
"RecRBSuffix");
|
||||
rbTime = config_get_int(main->Config(), "AdvOut",
|
||||
"RecRBTime");
|
||||
rbSize = config_get_int(main->Config(), "AdvOut",
|
||||
"RecRBSize");
|
||||
rbTime = config_get_int(main->Config(), "AdvOut", "RecRBTime");
|
||||
rbSize = config_get_int(main->Config(), "AdvOut", "RecRBSize");
|
||||
|
||||
os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr;
|
||||
|
||||
if (!dir) {
|
||||
if (main->isVisible())
|
||||
OBSMessageBox::warning(main,
|
||||
QTStr("Output.BadPath.Title"),
|
||||
OBSMessageBox::warning(
|
||||
main, QTStr("Output.BadPath.Title"),
|
||||
QTStr("Output.BadPath.Text"));
|
||||
else
|
||||
main->SysTrayNotify(QTStr("Output.BadPath.Text"),
|
||||
main->SysTrayNotify(
|
||||
QTStr("Output.BadPath.Text"),
|
||||
QSystemTrayIcon::Warning);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -54,8 +54,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
|
|||
if (!glob->gl_pathv[i].directory)
|
||||
continue;
|
||||
|
||||
if (strcmp(dirName, ".") == 0 ||
|
||||
strcmp(dirName, "..") == 0)
|
||||
if (strcmp(dirName, ".") == 0 || strcmp(dirName, "..") == 0)
|
||||
continue;
|
||||
|
||||
std::string file = filePath;
|
||||
|
@ -80,8 +79,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
|
|||
static bool ProfileExists(const char *findName)
|
||||
{
|
||||
bool found = false;
|
||||
auto func = [&](const char *name, const char*)
|
||||
{
|
||||
auto func = [&](const char *name, const char *) {
|
||||
if (strcmp(name, findName) == 0) {
|
||||
found = true;
|
||||
return false;
|
||||
|
@ -94,15 +92,15 @@ static bool ProfileExists(const char *findName)
|
|||
}
|
||||
|
||||
static bool GetProfileName(QWidget *parent, std::string &name,
|
||||
std::string &file, const char *title, const char *text,
|
||||
const char *oldName = nullptr)
|
||||
std::string &file, const char *title,
|
||||
const char *text, const char *oldName = nullptr)
|
||||
{
|
||||
char path[512];
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
bool success = NameDialog::AskForName(parent, title, text,
|
||||
name, QT_UTF8(oldName));
|
||||
bool success = NameDialog::AskForName(parent, title, text, name,
|
||||
QT_UTF8(oldName));
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
@ -170,11 +168,12 @@ static bool CopyProfile(const char *fromPartial, const char *to)
|
|||
if (glob->gl_pathv[i].directory)
|
||||
continue;
|
||||
|
||||
ret = snprintf(path, sizeof(path), "%s/%s",
|
||||
to, strrchr(filePath, '/') + 1);
|
||||
ret = snprintf(path, sizeof(path), "%s/%s", to,
|
||||
strrchr(filePath, '/') + 1);
|
||||
if (ret > 0) {
|
||||
if (os_copyfile(filePath, path) != 0) {
|
||||
blog(LOG_WARNING, "CopyProfile: Failed to "
|
||||
blog(LOG_WARNING,
|
||||
"CopyProfile: Failed to "
|
||||
"copy file %s to %s",
|
||||
filePath, path);
|
||||
}
|
||||
|
@ -197,8 +196,8 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
|
|||
if (!GetProfileName(this, newName, newDir, title, text, init_text))
|
||||
return false;
|
||||
|
||||
std::string curDir = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "ProfileDir");
|
||||
std::string curDir =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
|
||||
|
||||
char baseDir[512];
|
||||
int ret = GetConfigPath(baseDir, sizeof(baseDir),
|
||||
|
@ -312,8 +311,7 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
|
|||
os_rmdir(profilePath);
|
||||
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
blog(LOG_INFO, "Removed profile '%s' (%s)",
|
||||
profileName, profileDir);
|
||||
blog(LOG_INFO, "Removed profile '%s' (%s)", profileName, profileDir);
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
}
|
||||
|
||||
|
@ -328,17 +326,16 @@ void OBSBasic::RefreshProfiles()
|
|||
delete menuActions[i];
|
||||
}
|
||||
|
||||
const char *curName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "Profile");
|
||||
const char *curName =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
|
||||
|
||||
auto addProfile = [&](const char *name, const char *path)
|
||||
{
|
||||
auto addProfile = [&](const char *name, const char *path) {
|
||||
std::string file = strrchr(path, '/') + 1;
|
||||
|
||||
QAction *action = new QAction(QT_UTF8(name), this);
|
||||
action->setProperty("file_name", QT_UTF8(path));
|
||||
connect(action, &QAction::triggered,
|
||||
this, &OBSBasic::ChangeProfile);
|
||||
connect(action, &QAction::triggered, this,
|
||||
&OBSBasic::ChangeProfile);
|
||||
action->setCheckable(true);
|
||||
|
||||
action->setChecked(strcmp(name, curName) == 0);
|
||||
|
@ -364,10 +361,10 @@ void OBSBasic::ResetProfileData()
|
|||
|
||||
/* load audio monitoring */
|
||||
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
|
||||
const char *device_name = config_get_string(basicConfig, "Audio",
|
||||
"MonitoringDeviceName");
|
||||
const char *device_id = config_get_string(basicConfig, "Audio",
|
||||
"MonitoringDeviceId");
|
||||
const char *device_name =
|
||||
config_get_string(basicConfig, "Audio", "MonitoringDeviceName");
|
||||
const char *device_id =
|
||||
config_get_string(basicConfig, "Audio", "MonitoringDeviceId");
|
||||
|
||||
obs_set_audio_monitoring_device(device_name, device_id);
|
||||
|
||||
|
@ -388,14 +385,15 @@ void OBSBasic::on_actionDupProfile_triggered()
|
|||
|
||||
void OBSBasic::on_actionRenameProfile_triggered()
|
||||
{
|
||||
std::string curDir = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "ProfileDir");
|
||||
std::string curName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "Profile");
|
||||
std::string curDir =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
|
||||
std::string curName =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
|
||||
|
||||
/* Duplicate and delete in case there are any issues in the process */
|
||||
bool success = AddProfile(false, Str("RenameProfile.Title"),
|
||||
Str("AddProfile.Text"), curName.c_str(), true);
|
||||
Str("AddProfile.Text"), curName.c_str(),
|
||||
true);
|
||||
if (success) {
|
||||
DeleteProfile(curName.c_str(), curDir.c_str());
|
||||
RefreshProfiles();
|
||||
|
@ -413,13 +411,12 @@ void OBSBasic::on_actionRemoveProfile_triggered()
|
|||
std::string newPath;
|
||||
ConfigFile config;
|
||||
|
||||
std::string oldDir = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "ProfileDir");
|
||||
std::string oldName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "Profile");
|
||||
std::string oldDir =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
|
||||
std::string oldName =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
|
||||
|
||||
auto cb = [&](const char *name, const char *filePath)
|
||||
{
|
||||
auto cb = [&](const char *name, const char *filePath) {
|
||||
if (strcmp(oldName.c_str(), name) != 0) {
|
||||
newName = name;
|
||||
newPath = filePath;
|
||||
|
@ -438,8 +435,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
|
|||
QString text = QTStr("ConfirmRemove.Text");
|
||||
text.replace("$1", QT_UTF8(oldName.c_str()));
|
||||
|
||||
QMessageBox::StandardButton button = OBSMessageBox::question(this,
|
||||
QTStr("ConfirmRemove.Title"), text);
|
||||
QMessageBox::StandardButton button = OBSMessageBox::question(
|
||||
this, QTStr("ConfirmRemove.Title"), text);
|
||||
if (button == QMessageBox::No)
|
||||
return;
|
||||
|
||||
|
@ -458,8 +455,7 @@ void OBSBasic::on_actionRemoveProfile_triggered()
|
|||
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "Profile",
|
||||
newName.c_str());
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
|
||||
newDir);
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
|
||||
|
||||
Auth::Save();
|
||||
auth.reset();
|
||||
|
@ -474,8 +470,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
|
|||
RefreshProfiles();
|
||||
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
|
||||
|
||||
blog(LOG_INFO, "Switched to profile '%s' (%s)",
|
||||
newName.c_str(), newDir);
|
||||
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName.c_str(),
|
||||
newDir);
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
|
||||
UpdateTitleBar();
|
||||
|
@ -501,11 +497,8 @@ void OBSBasic::on_actionImportProfile_triggered()
|
|||
}
|
||||
|
||||
QString dir = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
QTStr("Basic.MainMenu.Profile.Import"),
|
||||
home,
|
||||
QFileDialog::ShowDirsOnly |
|
||||
QFileDialog::DontResolveSymlinks);
|
||||
this, QTStr("Basic.MainMenu.Profile.Import"), home,
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
if (!dir.isEmpty() && !dir.isNull()) {
|
||||
QString inputPath = QString::fromUtf8(path);
|
||||
|
@ -526,8 +519,8 @@ void OBSBasic::on_actionImportProfile_triggered()
|
|||
profileDir + "/recordEncoder.json");
|
||||
RefreshProfiles();
|
||||
} else {
|
||||
OBSMessageBox::warning(this,
|
||||
QTStr("Basic.MainMenu.Profile.Import"),
|
||||
OBSMessageBox::warning(
|
||||
this, QTStr("Basic.MainMenu.Profile.Import"),
|
||||
QTStr("Basic.MainMenu.Profile.Exists"));
|
||||
}
|
||||
}
|
||||
|
@ -539,9 +532,8 @@ void OBSBasic::on_actionExportProfile_triggered()
|
|||
|
||||
QString home = QDir::homePath();
|
||||
|
||||
QString currentProfile =
|
||||
QString::fromUtf8(config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "ProfileDir"));
|
||||
QString currentProfile = QString::fromUtf8(config_get_string(
|
||||
App()->GlobalConfig(), "Basic", "ProfileDir"));
|
||||
|
||||
int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
|
||||
if (ret <= 0) {
|
||||
|
@ -550,11 +542,8 @@ void OBSBasic::on_actionExportProfile_triggered()
|
|||
}
|
||||
|
||||
QString dir = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
QTStr("Basic.MainMenu.Profile.Export"),
|
||||
home,
|
||||
QFileDialog::ShowDirsOnly |
|
||||
QFileDialog::DontResolveSymlinks);
|
||||
this, QTStr("Basic.MainMenu.Profile.Export"), home,
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
if (!dir.isEmpty() && !dir.isNull()) {
|
||||
QString outputDir = dir + "/" + currentProfile;
|
||||
|
@ -571,10 +560,12 @@ void OBSBasic::on_actionExportProfile_triggered()
|
|||
QFile::remove(outputDir + "/service.json");
|
||||
|
||||
if (QFile::exists(outputDir + "/streamEncoder.json"))
|
||||
QFile::remove(outputDir + "/streamEncoder.json");
|
||||
QFile::remove(outputDir +
|
||||
"/streamEncoder.json");
|
||||
|
||||
if (QFile::exists(outputDir + "/recordEncoder.json"))
|
||||
QFile::remove(outputDir + "/recordEncoder.json");
|
||||
QFile::remove(outputDir +
|
||||
"/recordEncoder.json");
|
||||
}
|
||||
|
||||
QFile::copy(inputPath + currentProfile + "/basic.ini",
|
||||
|
@ -601,8 +592,8 @@ void OBSBasic::ChangeProfile()
|
|||
if (path.empty())
|
||||
return;
|
||||
|
||||
const char *oldName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "Profile");
|
||||
const char *oldName =
|
||||
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
|
||||
if (action->text().compare(QT_UTF8(oldName)) == 0) {
|
||||
action->setChecked(true);
|
||||
return;
|
||||
|
@ -623,8 +614,7 @@ void OBSBasic::ChangeProfile()
|
|||
const char *newDir = strrchr(path.c_str(), '/') + 1;
|
||||
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "Profile", newName);
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
|
||||
newDir);
|
||||
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
|
||||
|
||||
Auth::Save();
|
||||
auth.reset();
|
||||
|
@ -642,8 +632,7 @@ void OBSBasic::ChangeProfile()
|
|||
|
||||
CheckForSimpleModeX264Fallback();
|
||||
|
||||
blog(LOG_INFO, "Switched to profile '%s' (%s)",
|
||||
newName, newDir);
|
||||
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName, newDir);
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
|
||||
if (api)
|
||||
|
@ -652,10 +641,10 @@ void OBSBasic::ChangeProfile()
|
|||
|
||||
void OBSBasic::CheckForSimpleModeX264Fallback()
|
||||
{
|
||||
const char *curStreamEncoder = config_get_string(basicConfig,
|
||||
"SimpleOutput", "StreamEncoder");
|
||||
const char *curRecEncoder = config_get_string(basicConfig,
|
||||
"SimpleOutput", "RecEncoder");
|
||||
const char *curStreamEncoder =
|
||||
config_get_string(basicConfig, "SimpleOutput", "StreamEncoder");
|
||||
const char *curRecEncoder =
|
||||
config_get_string(basicConfig, "SimpleOutput", "RecEncoder");
|
||||
bool qsv_supported = false;
|
||||
bool amd_supported = false;
|
||||
bool nve_supported = false;
|
||||
|
@ -672,8 +661,7 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
|
|||
nve_supported = true;
|
||||
}
|
||||
|
||||
auto CheckEncoder = [&] (const char *&name)
|
||||
{
|
||||
auto CheckEncoder = [&](const char *&name) {
|
||||
if (strcmp(name, SIMPLE_ENCODER_QSV) == 0) {
|
||||
if (!qsv_supported) {
|
||||
changed = true;
|
||||
|
@ -698,12 +686,10 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
|
|||
};
|
||||
|
||||
if (!CheckEncoder(curStreamEncoder))
|
||||
config_set_string(basicConfig,
|
||||
"SimpleOutput", "StreamEncoder",
|
||||
config_set_string(basicConfig, "SimpleOutput", "StreamEncoder",
|
||||
curStreamEncoder);
|
||||
if (!CheckEncoder(curRecEncoder))
|
||||
config_set_string(basicConfig,
|
||||
"SimpleOutput", "RecEncoder",
|
||||
config_set_string(basicConfig, "SimpleOutput", "RecEncoder",
|
||||
curRecEncoder);
|
||||
if (changed)
|
||||
config_save_safe(basicConfig, "tmp", nullptr);
|
||||
|
|
|
@ -52,8 +52,8 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
|
|||
if (glob->gl_pathv[i].directory)
|
||||
continue;
|
||||
|
||||
obs_data_t *data = obs_data_create_from_json_file_safe(filePath,
|
||||
"bak");
|
||||
obs_data_t *data =
|
||||
obs_data_create_from_json_file_safe(filePath, "bak");
|
||||
std::string name = obs_data_get_string(data, "name");
|
||||
|
||||
/* if no name found, use the file name as the name
|
||||
|
@ -75,8 +75,7 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
|
|||
static bool SceneCollectionExists(const char *findName)
|
||||
{
|
||||
bool found = false;
|
||||
auto func = [&](const char *name, const char*)
|
||||
{
|
||||
auto func = [&](const char *name, const char *) {
|
||||
if (strcmp(name, findName) == 0) {
|
||||
found = true;
|
||||
return false;
|
||||
|
@ -90,7 +89,8 @@ static bool SceneCollectionExists(const char *findName)
|
|||
}
|
||||
|
||||
static bool GetSceneCollectionName(QWidget *parent, std::string &name,
|
||||
std::string &file, const char *oldName = nullptr)
|
||||
std::string &file,
|
||||
const char *oldName = nullptr)
|
||||
{
|
||||
bool rename = oldName != nullptr;
|
||||
const char *title;
|
||||
|
@ -108,8 +108,8 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
bool success = NameDialog::AskForName(parent, title, text,
|
||||
name, QT_UTF8(oldName));
|
||||
bool success = NameDialog::AskForName(parent, title, text, name,
|
||||
QT_UTF8(oldName));
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
@ -181,8 +181,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
|
|||
RefreshSceneCollections();
|
||||
|
||||
blog(LOG_INFO, "Added scene collection '%s' (%s, %s.json)",
|
||||
name.c_str(), create_new ? "clean" : "duplicate",
|
||||
file.c_str());
|
||||
name.c_str(), create_new ? "clean" : "duplicate", file.c_str());
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
|
||||
UpdateTitleBar();
|
||||
|
@ -206,18 +205,17 @@ void OBSBasic::RefreshSceneCollections()
|
|||
delete menuActions[i];
|
||||
}
|
||||
|
||||
const char *cur_name = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
const char *cur_name = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollection");
|
||||
|
||||
auto addCollection = [&](const char *name, const char *path)
|
||||
{
|
||||
auto addCollection = [&](const char *name, const char *path) {
|
||||
std::string file = strrchr(path, '/') + 1;
|
||||
file.erase(file.size() - 5, 5);
|
||||
|
||||
QAction *action = new QAction(QT_UTF8(name), this);
|
||||
action->setProperty("file_name", QT_UTF8(path));
|
||||
connect(action, &QAction::triggered,
|
||||
this, &OBSBasic::ChangeSceneCollection);
|
||||
connect(action, &QAction::triggered, this,
|
||||
&OBSBasic::ChangeSceneCollection);
|
||||
action->setCheckable(true);
|
||||
|
||||
action->setChecked(strcmp(name, cur_name) == 0);
|
||||
|
@ -265,10 +263,10 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
|
|||
std::string name;
|
||||
std::string file;
|
||||
|
||||
std::string oldFile = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollectionFile");
|
||||
const char *oldName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollectionFile");
|
||||
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollection");
|
||||
|
||||
bool success = GetSceneCollectionName(this, name, file, oldName);
|
||||
if (!success)
|
||||
|
@ -312,13 +310,12 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
|
|||
std::string newName;
|
||||
std::string newPath;
|
||||
|
||||
std::string oldFile = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollectionFile");
|
||||
std::string oldName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollectionFile");
|
||||
std::string oldName = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollection");
|
||||
|
||||
auto cb = [&](const char *name, const char *filePath)
|
||||
{
|
||||
auto cb = [&](const char *name, const char *filePath) {
|
||||
if (strcmp(oldName.c_str(), name) != 0) {
|
||||
newName = name;
|
||||
newPath = filePath;
|
||||
|
@ -337,8 +334,8 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
|
|||
QString text = QTStr("ConfirmRemove.Text");
|
||||
text.replace("$1", QT_UTF8(oldName.c_str()));
|
||||
|
||||
QMessageBox::StandardButton button = OBSMessageBox::question(this,
|
||||
QTStr("ConfirmRemove.Title"), text);
|
||||
QMessageBox::StandardButton button = OBSMessageBox::question(
|
||||
this, QTStr("ConfirmRemove.Title"), text);
|
||||
if (button == QMessageBox::No)
|
||||
return;
|
||||
|
||||
|
@ -358,13 +355,13 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
|
|||
Load(newPath.c_str());
|
||||
RefreshSceneCollections();
|
||||
|
||||
const char *newFile = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollectionFile");
|
||||
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollectionFile");
|
||||
|
||||
blog(LOG_INFO, "Removed scene collection '%s' (%s.json), "
|
||||
blog(LOG_INFO,
|
||||
"Removed scene collection '%s' (%s.json), "
|
||||
"switched to '%s' (%s.json)",
|
||||
oldName.c_str(), oldFile.c_str(),
|
||||
newName.c_str(), newFile);
|
||||
oldName.c_str(), oldFile.c_str(), newName.c_str(), newFile);
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
|
||||
UpdateTitleBar();
|
||||
|
@ -388,9 +385,7 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
|
|||
}
|
||||
|
||||
QString qfilePath = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
QTStr("Basic.MainMenu.SceneCollection.Import"),
|
||||
qhome,
|
||||
this, QTStr("Basic.MainMenu.SceneCollection.Import"), qhome,
|
||||
"JSON Files (*.json)");
|
||||
|
||||
QFileInfo finfo(qfilePath);
|
||||
|
@ -416,7 +411,8 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
|
|||
obs_data_set_string(scenedata, "name", name.c_str());
|
||||
|
||||
if (!GetFileSafeName(name.c_str(), file)) {
|
||||
blog(LOG_WARNING, "Failed to create "
|
||||
blog(LOG_WARNING,
|
||||
"Failed to create "
|
||||
"safe file name for '%s'",
|
||||
name.c_str());
|
||||
return;
|
||||
|
@ -425,14 +421,15 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
|
|||
string filePath = path + file;
|
||||
|
||||
if (!GetClosestUnusedFileName(filePath, "json")) {
|
||||
blog(LOG_WARNING, "Failed to get "
|
||||
blog(LOG_WARNING,
|
||||
"Failed to get "
|
||||
"closest file name for %s",
|
||||
file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
obs_data_save_json_safe(scenedata, filePath.c_str(),
|
||||
"tmp", "bak");
|
||||
obs_data_save_json_safe(scenedata, filePath.c_str(), "tmp",
|
||||
"bak");
|
||||
RefreshSceneCollections();
|
||||
}
|
||||
}
|
||||
|
@ -445,8 +442,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
|
|||
|
||||
QString home = QDir::homePath();
|
||||
|
||||
QString currentFile = QT_UTF8(config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollectionFile"));
|
||||
QString currentFile = QT_UTF8(config_get_string(
|
||||
App()->GlobalConfig(), "Basic", "SceneCollectionFile"));
|
||||
|
||||
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
|
||||
if (ret <= 0) {
|
||||
|
@ -455,10 +452,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
|
|||
}
|
||||
|
||||
QString exportFile = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
QTStr("Basic.MainMenu.SceneCollection.Export"),
|
||||
home + "/" + currentFile,
|
||||
"JSON Files (*.json)");
|
||||
this, QTStr("Basic.MainMenu.SceneCollection.Export"),
|
||||
home + "/" + currentFile, "JSON Files (*.json)");
|
||||
|
||||
string file = QT_TO_UTF8(exportFile);
|
||||
|
||||
|
@ -482,8 +477,8 @@ void OBSBasic::ChangeSceneCollection()
|
|||
if (fileName.empty())
|
||||
return;
|
||||
|
||||
const char *oldName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollection");
|
||||
if (action->text().compare(QT_UTF8(oldName)) == 0) {
|
||||
action->setChecked(true);
|
||||
return;
|
||||
|
@ -494,13 +489,13 @@ void OBSBasic::ChangeSceneCollection()
|
|||
Load(fileName.c_str());
|
||||
RefreshSceneCollections();
|
||||
|
||||
const char *newName = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollection");
|
||||
const char *newFile = config_get_string(App()->GlobalConfig(),
|
||||
"Basic", "SceneCollectionFile");
|
||||
const char *newName = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollection");
|
||||
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
|
||||
"SceneCollectionFile");
|
||||
|
||||
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)",
|
||||
newName, newFile);
|
||||
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)", newName,
|
||||
newFile);
|
||||
blog(LOG_INFO, "------------------------------------------------");
|
||||
|
||||
UpdateTitleBar();
|
||||
|
|
|
@ -54,8 +54,8 @@ void OBSBasic::InitDefaultTransitions()
|
|||
if (!obs_is_source_configurable(id)) {
|
||||
const char *name = obs_source_get_display_name(id);
|
||||
|
||||
obs_source_t *tr = obs_source_create_private(
|
||||
id, name, NULL);
|
||||
obs_source_t *tr =
|
||||
obs_source_create_private(id, name, NULL);
|
||||
InitTransition(tr);
|
||||
transitions.emplace_back(tr);
|
||||
|
||||
|
@ -82,8 +82,7 @@ void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt)
|
|||
.arg(MakeQuickTransitionText(qt));
|
||||
|
||||
auto quickTransition = [](void *data, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
bool pressed) {
|
||||
int id = (int)(uintptr_t)data;
|
||||
OBSBasic *main =
|
||||
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
@ -96,7 +95,8 @@ void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt)
|
|||
};
|
||||
|
||||
qt->hotkey = obs_hotkey_register_frontend(hotkeyId->array,
|
||||
QT_TO_UTF8(hotkeyName), quickTransition,
|
||||
QT_TO_UTF8(hotkeyName),
|
||||
quickTransition,
|
||||
(void *)(uintptr_t)qt->id);
|
||||
}
|
||||
|
||||
|
@ -150,8 +150,8 @@ void OBSBasic::InitTransition(obs_source_t *transition)
|
|||
signal_handler_t *handler = obs_source_get_signal_handler(transition);
|
||||
signal_handler_connect(handler, "transition_video_stop",
|
||||
onTransitionStop, this);
|
||||
signal_handler_connect(handler, "transition_stop",
|
||||
onTransitionFullStop, this);
|
||||
signal_handler_connect(handler, "transition_stop", onTransitionFullStop,
|
||||
this);
|
||||
}
|
||||
|
||||
static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx)
|
||||
|
@ -163,11 +163,11 @@ void OBSBasic::CreateDefaultQuickTransitions()
|
|||
{
|
||||
/* non-configurable transitions are always available, so add them
|
||||
* to the "default quick transitions" list */
|
||||
quickTransitions.emplace_back(
|
||||
GetTransitionComboItem(ui->transitions, 0),
|
||||
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
|
||||
0),
|
||||
300, quickTransitionIdCounter++);
|
||||
quickTransitions.emplace_back(
|
||||
GetTransitionComboItem(ui->transitions, 1),
|
||||
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
|
||||
1),
|
||||
300, quickTransitionIdCounter++);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,8 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
|
|||
quickTransitionIdCounter = id + 1;
|
||||
|
||||
int idx = (int)quickTransitions.size() - 1;
|
||||
AddQuickTransitionHotkey(&quickTransitions[idx]);
|
||||
AddQuickTransitionHotkey(
|
||||
&quickTransitions[idx]);
|
||||
obs_hotkey_load(quickTransitions[idx].hotkey,
|
||||
hotkeys);
|
||||
}
|
||||
|
@ -231,8 +232,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
|
|||
obs_source_t *OBSBasic::FindTransition(const char *name)
|
||||
{
|
||||
for (int i = 0; i < ui->transitions->count(); i++) {
|
||||
OBSSource tr = ui->transitions->itemData(i)
|
||||
.value<OBSSource>();
|
||||
OBSSource tr = ui->transitions->itemData(i).value<OBSSource>();
|
||||
|
||||
const char *trName = obs_source_get_name(tr);
|
||||
if (strcmp(trName, name) == 0)
|
||||
|
@ -317,10 +317,10 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
|
|||
}
|
||||
|
||||
if (usingPreviewProgram && sceneDuplicationMode) {
|
||||
scene = obs_scene_duplicate(scene, NULL,
|
||||
editPropertiesMode ?
|
||||
OBS_SCENE_DUP_PRIVATE_COPY :
|
||||
OBS_SCENE_DUP_PRIVATE_REFS);
|
||||
scene = obs_scene_duplicate(
|
||||
scene, NULL,
|
||||
editPropertiesMode ? OBS_SCENE_DUP_PRIVATE_COPY
|
||||
: OBS_SCENE_DUP_PRIVATE_REFS);
|
||||
source = obs_scene_get_source(scene);
|
||||
}
|
||||
|
||||
|
@ -342,8 +342,8 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
|
|||
OBSData data = obs_source_get_private_settings(source);
|
||||
obs_data_release(data);
|
||||
|
||||
const char *trOverrideName = obs_data_get_string(data,
|
||||
"transition");
|
||||
const char *trOverrideName =
|
||||
obs_data_get_string(data, "transition");
|
||||
int duration = ui->transitionDuration->value();
|
||||
|
||||
if (trOverrideName && *trOverrideName && !quickTransition) {
|
||||
|
@ -351,18 +351,18 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
|
|||
if (trOverride) {
|
||||
transition = trOverride;
|
||||
|
||||
obs_data_set_default_int(data,
|
||||
"transition_duration", 300);
|
||||
obs_data_set_default_int(
|
||||
data, "transition_duration", 300);
|
||||
|
||||
duration = (int)obs_data_get_int(data,
|
||||
"transition_duration");
|
||||
duration = (int)obs_data_get_int(
|
||||
data, "transition_duration");
|
||||
OverrideTransition(trOverride);
|
||||
overridingTransition = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool success = obs_transition_start(transition,
|
||||
OBS_TRANSITION_MODE_AUTO, duration, source);
|
||||
bool success = obs_transition_start(
|
||||
transition, OBS_TRANSITION_MODE_AUTO, duration, source);
|
||||
if (!success)
|
||||
TransitionFullyStopped();
|
||||
}
|
||||
|
@ -436,8 +436,8 @@ void OBSBasic::AddTransition()
|
|||
QString idStr = action->property("id").toString();
|
||||
|
||||
string name;
|
||||
QString placeHolderText = QT_UTF8(
|
||||
obs_source_get_display_name(QT_TO_UTF8(idStr)));
|
||||
QString placeHolderText =
|
||||
QT_UTF8(obs_source_get_display_name(QT_TO_UTF8(idStr)));
|
||||
QString format = placeHolderText + " (%1)";
|
||||
obs_source_t *source = nullptr;
|
||||
int i = 1;
|
||||
|
@ -462,8 +462,7 @@ void OBSBasic::AddTransition()
|
|||
|
||||
source = FindTransition(name.c_str());
|
||||
if (source) {
|
||||
OBSMessageBox::warning(this,
|
||||
QTStr("NameExists.Title"),
|
||||
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
|
||||
QTStr("NameExists.Text"));
|
||||
|
||||
AddTransition();
|
||||
|
@ -473,14 +472,16 @@ void OBSBasic::AddTransition()
|
|||
source = obs_source_create_private(QT_TO_UTF8(idStr),
|
||||
name.c_str(), NULL);
|
||||
InitTransition(source);
|
||||
ui->transitions->addItem(QT_UTF8(name.c_str()),
|
||||
ui->transitions->addItem(
|
||||
QT_UTF8(name.c_str()),
|
||||
QVariant::fromValue(OBSSource(source)));
|
||||
ui->transitions->setCurrentIndex(ui->transitions->count() - 1);
|
||||
CreatePropertiesWindow(source);
|
||||
obs_source_release(source);
|
||||
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
|
||||
api->on_event(
|
||||
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
|
||||
|
||||
ClearQuickTransitionWidgets();
|
||||
RefreshQuickTransitions();
|
||||
|
@ -500,8 +501,8 @@ void OBSBasic::on_transitionAdd_clicked()
|
|||
QAction *action = new QAction(name, this);
|
||||
action->setProperty("id", id);
|
||||
|
||||
connect(action, SIGNAL(triggered()),
|
||||
this, SLOT(AddTransition()));
|
||||
connect(action, SIGNAL(triggered()), this,
|
||||
SLOT(AddTransition()));
|
||||
|
||||
menu.addAction(action);
|
||||
foundConfigurableTransitions = true;
|
||||
|
@ -529,7 +530,8 @@ void OBSBasic::on_transitionRemove_clicked()
|
|||
if (qt.button)
|
||||
qt.button->deleteLater();
|
||||
RemoveQuickTransitionHotkey(&qt);
|
||||
quickTransitions.erase(quickTransitions.begin() + i - 1);
|
||||
quickTransitions.erase(quickTransitions.begin() + i -
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,8 +570,7 @@ void OBSBasic::RenameTransition()
|
|||
|
||||
source = FindTransition(name.c_str());
|
||||
if (source) {
|
||||
OBSMessageBox::warning(this,
|
||||
QTStr("NameExists.Title"),
|
||||
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
|
||||
QTStr("NameExists.Text"));
|
||||
|
||||
RenameTransition();
|
||||
|
@ -579,10 +580,12 @@ void OBSBasic::RenameTransition()
|
|||
obs_source_set_name(transition, name.c_str());
|
||||
int idx = ui->transitions->findData(variant);
|
||||
if (idx != -1) {
|
||||
ui->transitions->setItemText(idx, QT_UTF8(name.c_str()));
|
||||
ui->transitions->setItemText(idx,
|
||||
QT_UTF8(name.c_str()));
|
||||
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
|
||||
api->on_event(
|
||||
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
|
||||
|
||||
ClearQuickTransitionWidgets();
|
||||
RefreshQuickTransitions();
|
||||
|
@ -597,9 +600,7 @@ void OBSBasic::on_transitionProps_clicked()
|
|||
if (!obs_source_configurable(source))
|
||||
return;
|
||||
|
||||
auto properties = [&] () {
|
||||
CreatePropertiesWindow(source);
|
||||
};
|
||||
auto properties = [&]() { CreatePropertiesWindow(source); };
|
||||
|
||||
QMenu menu(this);
|
||||
|
||||
|
@ -643,8 +644,7 @@ void OBSBasic::SetCurrentScene(obs_scene_t *scene, bool force, bool direct)
|
|||
SetCurrentScene(source, force, direct);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T GetOBSRef(QListWidgetItem *item)
|
||||
template<typename T> static T GetOBSRef(QListWidgetItem *item)
|
||||
{
|
||||
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
|
||||
}
|
||||
|
@ -679,7 +679,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct)
|
|||
ui->scenes->setCurrentItem(item);
|
||||
ui->scenes->blockSignals(false);
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
|
||||
api->on_event(
|
||||
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -698,8 +699,8 @@ void OBSBasic::CreateProgramDisplay()
|
|||
program = new OBSQTDisplay();
|
||||
|
||||
program->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(program.data(), &QWidget::customContextMenuRequested,
|
||||
this, &OBSBasic::on_program_customContextMenuRequested);
|
||||
connect(program.data(), &QWidget::customContextMenuRequested, this,
|
||||
&OBSBasic::on_program_customContextMenuRequested);
|
||||
|
||||
auto displayResize = [this]() {
|
||||
struct obs_video_info ovi;
|
||||
|
@ -708,11 +709,9 @@ void OBSBasic::CreateProgramDisplay()
|
|||
ResizeProgram(ovi.base_width, ovi.base_height);
|
||||
};
|
||||
|
||||
connect(program.data(), &OBSQTDisplay::DisplayResized,
|
||||
displayResize);
|
||||
connect(program.data(), &OBSQTDisplay::DisplayResized, displayResize);
|
||||
|
||||
auto addDisplay = [this] (OBSQTDisplay *window)
|
||||
{
|
||||
auto addDisplay = [this](OBSQTDisplay *window) {
|
||||
obs_display_add_draw_callback(window->GetDisplay(),
|
||||
OBSBasic::RenderProgram, this);
|
||||
|
||||
|
@ -723,8 +722,7 @@ void OBSBasic::CreateProgramDisplay()
|
|||
|
||||
connect(program.data(), &OBSQTDisplay::DisplayCreated, addDisplay);
|
||||
|
||||
program->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
program->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
}
|
||||
|
||||
void OBSBasic::TransitionClicked()
|
||||
|
@ -806,14 +804,16 @@ void OBSBasic::CreateProgramOptions()
|
|||
&menu, menu.actionGeometry(act));
|
||||
};
|
||||
|
||||
action = menu.addAction(QTStr("QuickTransitions.DuplicateScene"));
|
||||
action = menu.addAction(
|
||||
QTStr("QuickTransitions.DuplicateScene"));
|
||||
action->setToolTip(QTStr("QuickTransitions.DuplicateSceneTT"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(sceneDuplicationMode);
|
||||
connect(action, &QAction::triggered, toggleSceneDuplication);
|
||||
connect(action, &QAction::hovered, showToolTip);
|
||||
|
||||
action = menu.addAction(QTStr("QuickTransitions.EditProperties"));
|
||||
action = menu.addAction(
|
||||
QTStr("QuickTransitions.EditProperties"));
|
||||
action->setToolTip(QTStr("QuickTransitions.EditPropertiesTT"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(editPropertiesMode);
|
||||
|
@ -831,8 +831,8 @@ void OBSBasic::CreateProgramOptions()
|
|||
menu.exec(QCursor::pos());
|
||||
};
|
||||
|
||||
connect(transitionButton.data(), &QAbstractButton::clicked,
|
||||
this, &OBSBasic::TransitionClicked);
|
||||
connect(transitionButton.data(), &QAbstractButton::clicked, this,
|
||||
&OBSBasic::TransitionClicked);
|
||||
connect(addQuickTransition, &QAbstractButton::clicked, onAdd);
|
||||
connect(configTransitions, &QAbstractButton::clicked, onConfig);
|
||||
}
|
||||
|
@ -868,8 +868,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
|
|||
duration->setSingleStep(50);
|
||||
duration->setValue(curDuration);
|
||||
|
||||
auto setTransition = [this] (QAction *action)
|
||||
{
|
||||
auto setTransition = [this](QAction *action) {
|
||||
int idx = action->property("transition_index").toInt();
|
||||
OBSSource scene = GetCurrentSceneSource();
|
||||
OBSData data = obs_source_get_private_settings(scene);
|
||||
|
@ -886,8 +885,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
|
|||
obs_data_set_string(data, "transition", name);
|
||||
};
|
||||
|
||||
auto setDuration = [this] (int duration)
|
||||
{
|
||||
auto setDuration = [this](int duration) {
|
||||
OBSSource scene = GetCurrentSceneSource();
|
||||
OBSData data = obs_source_get_private_settings(scene);
|
||||
obs_data_release(data);
|
||||
|
@ -937,8 +935,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
|
|||
if (qt) {
|
||||
action = menu->addAction(QTStr("Remove"));
|
||||
action->setProperty("id", qt->id);
|
||||
connect(action, &QAction::triggered,
|
||||
this, &OBSBasic::QuickTransitionRemoveClicked);
|
||||
connect(action, &QAction::triggered, this,
|
||||
&OBSBasic::QuickTransitionRemoveClicked);
|
||||
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
@ -953,7 +951,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
|
|||
duration->setValue(qt ? qt->duration : 300);
|
||||
|
||||
if (qt) {
|
||||
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
|
||||
connect(duration,
|
||||
(void (QSpinBox::*)(int)) & QSpinBox::valueChanged,
|
||||
this, &OBSBasic::QuickTransitionChangeDuration);
|
||||
}
|
||||
|
||||
|
@ -968,7 +967,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
|
|||
connect(action, &QAction::triggered, this,
|
||||
&OBSBasic::QuickTransitionChange);
|
||||
} else {
|
||||
action->setProperty("duration",
|
||||
action->setProperty(
|
||||
"duration",
|
||||
QVariant::fromValue<QWidget *>(duration));
|
||||
connect(action, &QAction::triggered, this,
|
||||
&OBSBasic::AddQuickTransition);
|
||||
|
@ -1004,8 +1004,8 @@ void OBSBasic::AddQuickTransitionId(int id)
|
|||
/* --------------------------------- */
|
||||
|
||||
button->setMenu(buttonMenu);
|
||||
connect(button, &QAbstractButton::clicked,
|
||||
this, &OBSBasic::QuickTransitionClicked);
|
||||
connect(button, &QAbstractButton::clicked, this,
|
||||
&OBSBasic::QuickTransitionClicked);
|
||||
|
||||
QVBoxLayout *programLayout =
|
||||
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
|
||||
|
@ -1209,10 +1209,11 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
|
|||
|
||||
obs_scene_t *dup;
|
||||
if (sceneDuplicationMode) {
|
||||
dup = obs_scene_duplicate(curScene, nullptr,
|
||||
editPropertiesMode ?
|
||||
OBS_SCENE_DUP_PRIVATE_COPY :
|
||||
OBS_SCENE_DUP_PRIVATE_REFS);
|
||||
dup = obs_scene_duplicate(
|
||||
curScene, nullptr,
|
||||
editPropertiesMode
|
||||
? OBS_SCENE_DUP_PRIVATE_COPY
|
||||
: OBS_SCENE_DUP_PRIVATE_REFS);
|
||||
} else {
|
||||
dup = curScene;
|
||||
obs_scene_addref(dup);
|
||||
|
@ -1248,8 +1249,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
|
|||
programLayout->addWidget(programLabel);
|
||||
programLayout->addWidget(program);
|
||||
|
||||
bool labels = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "StudioModeLabels");
|
||||
bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"StudioModeLabels");
|
||||
|
||||
programLabel->setHidden(!labels);
|
||||
|
||||
|
@ -1257,7 +1258,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
|
|||
|
||||
ui->previewLayout->addWidget(programOptions);
|
||||
ui->previewLayout->addWidget(programWidget);
|
||||
ui->previewLayout->setAlignment(programOptions, Qt::AlignCenter);
|
||||
ui->previewLayout->setAlignment(programOptions,
|
||||
Qt::AlignCenter);
|
||||
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED);
|
||||
|
@ -1325,8 +1327,8 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height),
|
||||
-100.0f, 100.0f);
|
||||
gs_set_viewport(window->programX, window->programY,
|
||||
window->programCX, window->programCY);
|
||||
gs_set_viewport(window->programX, window->programY, window->programCX,
|
||||
window->programCY);
|
||||
|
||||
window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height));
|
||||
|
||||
|
@ -1371,7 +1373,8 @@ obs_data_array_t *OBSBasic::SaveTransitions()
|
|||
obs_data_t *sourceData = obs_data_create();
|
||||
obs_data_t *settings = obs_source_get_settings(tr);
|
||||
|
||||
obs_data_set_string(sourceData, "name", obs_source_get_name(tr));
|
||||
obs_data_set_string(sourceData, "name",
|
||||
obs_source_get_name(tr));
|
||||
obs_data_set_string(sourceData, "id", obs_obj_get_id(tr));
|
||||
obs_data_set_obj(sourceData, "settings", settings);
|
||||
|
||||
|
@ -1394,11 +1397,12 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions)
|
|||
const char *id = obs_data_get_string(item, "id");
|
||||
obs_data_t *settings = obs_data_get_obj(item, "settings");
|
||||
|
||||
obs_source_t *source = obs_source_create_private(id, name,
|
||||
settings);
|
||||
obs_source_t *source =
|
||||
obs_source_create_private(id, name, settings);
|
||||
if (!obs_obj_invalid(source)) {
|
||||
InitTransition(source);
|
||||
ui->transitions->addItem(QT_UTF8(name),
|
||||
ui->transitions->addItem(
|
||||
QT_UTF8(name),
|
||||
QVariant::fromValue(OBSSource(source)));
|
||||
ui->transitions->setCurrentIndex(
|
||||
ui->transitions->count() - 1);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -93,9 +93,10 @@ struct QuickTransition {
|
|||
duration(duration_),
|
||||
id(id_),
|
||||
renamedSignal(std::make_shared<OBSSignal>(
|
||||
obs_source_get_signal_handler(source),
|
||||
"rename", SourceRenamed, this))
|
||||
{}
|
||||
obs_source_get_signal_handler(source), "rename",
|
||||
SourceRenamed, this))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
static void SourceRenamed(void *param, calldata_t *data);
|
||||
|
@ -124,19 +125,14 @@ class OBSBasic : public OBSMainWindow {
|
|||
friend class AutoConfigStreamPage;
|
||||
friend struct OBSStudioAPI;
|
||||
|
||||
enum class MoveDir {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
enum class MoveDir { Up, Down, Left, Right };
|
||||
|
||||
enum DropType {
|
||||
DropType_RawText,
|
||||
DropType_Text,
|
||||
DropType_Image,
|
||||
DropType_Media,
|
||||
DropType_Html
|
||||
DropType_Html,
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -293,8 +289,8 @@ private:
|
|||
void ChangeSceneIndex(bool relative, int idx, int invalidIdx);
|
||||
|
||||
void TempFileOutput(const char *path, int vBitrate, int aBitrate);
|
||||
void TempStreamOutput(const char *url, const char *key,
|
||||
int vBitrate, int aBitrate);
|
||||
void TempStreamOutput(const char *url, const char *key, int vBitrate,
|
||||
int aBitrate);
|
||||
|
||||
void CloseDialogs();
|
||||
void ClearSceneData();
|
||||
|
@ -327,8 +323,8 @@ private:
|
|||
|
||||
int GetTopSelectedSourceItem();
|
||||
|
||||
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys,
|
||||
replayBufHotkeys, togglePreviewHotkeys;
|
||||
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, replayBufHotkeys,
|
||||
togglePreviewHotkeys;
|
||||
obs_hotkey_id forceStreamingStopHotkey;
|
||||
|
||||
void InitDefaultTransitions();
|
||||
|
@ -459,12 +455,12 @@ public slots:
|
|||
void TransitionToScene(OBSScene scene, bool force = false,
|
||||
bool direct = false);
|
||||
void TransitionToScene(OBSSource scene, bool force = false,
|
||||
bool direct = false, bool quickTransition = false);
|
||||
bool direct = false,
|
||||
bool quickTransition = false);
|
||||
void SetCurrentScene(OBSSource scene, bool force = false,
|
||||
bool direct = false);
|
||||
|
||||
bool AddSceneCollection(
|
||||
bool create_new,
|
||||
bool AddSceneCollection(bool create_new,
|
||||
const QString &name = QString());
|
||||
|
||||
void UpdatePatronJson(const QString &text, const QString &error);
|
||||
|
@ -607,10 +603,7 @@ public:
|
|||
cy = previewCY;
|
||||
}
|
||||
|
||||
inline bool SavingDisabled() const
|
||||
{
|
||||
return disableSaving;
|
||||
}
|
||||
inline bool SavingDisabled() const { return disableSaving; }
|
||||
|
||||
inline double GetCPUUsage() const
|
||||
{
|
||||
|
@ -635,7 +628,8 @@ public:
|
|||
QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source);
|
||||
QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item);
|
||||
QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction,
|
||||
ColorSelect *select, obs_sceneitem_t *item);
|
||||
ColorSelect *select,
|
||||
obs_sceneitem_t *item);
|
||||
void CreateSourcePopupMenu(int idx, bool preview);
|
||||
|
||||
void UpdateTitleBar();
|
||||
|
@ -728,8 +722,8 @@ private slots:
|
|||
|
||||
void on_preview_customContextMenuRequested(const QPoint &pos);
|
||||
void on_program_customContextMenuRequested(const QPoint &pos);
|
||||
void on_previewDisabledLabel_customContextMenuRequested(
|
||||
const QPoint &pos);
|
||||
void
|
||||
on_previewDisabledLabel_customContextMenuRequested(const QPoint &pos);
|
||||
|
||||
void on_actionNewSceneCollection_triggered();
|
||||
void on_actionDupSceneCollection_triggered();
|
||||
|
@ -825,8 +819,8 @@ public:
|
|||
|
||||
virtual config_t *Config() const override;
|
||||
|
||||
virtual int GetProfilePath(char *path, size_t size, const char *file)
|
||||
const override;
|
||||
virtual int GetProfilePath(char *path, size_t size,
|
||||
const char *file) const override;
|
||||
|
||||
static void InitBrowserPanelSafeBlock();
|
||||
|
||||
|
@ -839,8 +833,8 @@ class SceneRenameDelegate : public QStyledItemDelegate {
|
|||
|
||||
public:
|
||||
SceneRenameDelegate(QObject *parent);
|
||||
virtual void setEditorData(QWidget *editor, const QModelIndex &index)
|
||||
const override;
|
||||
virtual void setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *editor, QEvent *event) override;
|
||||
|
|
|
@ -65,9 +65,9 @@ struct SceneFindData {
|
|||
SceneFindData &operator=(SceneFindData &&) = delete;
|
||||
|
||||
inline SceneFindData(const vec2 &pos_, bool selectBelow_)
|
||||
: pos (pos_),
|
||||
selectBelow (selectBelow_)
|
||||
{}
|
||||
: pos(pos_), selectBelow(selectBelow_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static bool SceneItemHasVideo(obs_sceneitem_t *item)
|
||||
|
@ -153,48 +153,44 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
|
|||
|
||||
vec3_zero(&clampOffset);
|
||||
|
||||
const bool snap = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "SnappingEnabled");
|
||||
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"SnappingEnabled");
|
||||
if (snap == false)
|
||||
return clampOffset;
|
||||
|
||||
const bool screenSnap = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "ScreenSnapping");
|
||||
const bool centerSnap = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "CenterSnapping");
|
||||
const bool screenSnap = config_get_bool(
|
||||
GetGlobalConfig(), "BasicWindow", "ScreenSnapping");
|
||||
const bool centerSnap = config_get_bool(
|
||||
GetGlobalConfig(), "BasicWindow", "CenterSnapping");
|
||||
|
||||
const float clampDist = config_get_double(GetGlobalConfig(),
|
||||
"BasicWindow", "SnapDistance") / main->previewScale;
|
||||
"BasicWindow",
|
||||
"SnapDistance") /
|
||||
main->previewScale;
|
||||
const float centerX = br.x - (br.x - tl.x) / 2.0f;
|
||||
const float centerY = br.y - (br.y - tl.y) / 2.0f;
|
||||
|
||||
// Left screen edge.
|
||||
if (screenSnap &&
|
||||
fabsf(tl.x) < clampDist)
|
||||
if (screenSnap && fabsf(tl.x) < clampDist)
|
||||
clampOffset.x = -tl.x;
|
||||
// Right screen edge.
|
||||
if (screenSnap &&
|
||||
fabsf(clampOffset.x) < EPSILON &&
|
||||
if (screenSnap && fabsf(clampOffset.x) < EPSILON &&
|
||||
fabsf(screenSize.x - br.x) < clampDist)
|
||||
clampOffset.x = screenSize.x - br.x;
|
||||
// Horizontal center.
|
||||
if (centerSnap &&
|
||||
fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
|
||||
if (centerSnap && fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
|
||||
fabsf(screenSize.x / 2.0f - centerX) < clampDist)
|
||||
clampOffset.x = screenSize.x / 2.0f - centerX;
|
||||
|
||||
// Top screen edge.
|
||||
if (screenSnap &&
|
||||
fabsf(tl.y) < clampDist)
|
||||
if (screenSnap && fabsf(tl.y) < clampDist)
|
||||
clampOffset.y = -tl.y;
|
||||
// Bottom screen edge.
|
||||
if (screenSnap &&
|
||||
fabsf(clampOffset.y) < EPSILON &&
|
||||
if (screenSnap && fabsf(clampOffset.y) < EPSILON &&
|
||||
fabsf(screenSize.y - br.y) < clampDist)
|
||||
clampOffset.y = screenSize.y - br.y;
|
||||
// Vertical center.
|
||||
if (centerSnap &&
|
||||
fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
|
||||
if (centerSnap && fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
|
||||
fabsf(screenSize.y / 2.0f - centerY) < clampDist)
|
||||
clampOffset.y = screenSize.y / 2.0f - centerY;
|
||||
|
||||
|
@ -240,7 +236,8 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
|
|||
|
||||
if (data->group) {
|
||||
matrix4 parent_transform;
|
||||
obs_sceneitem_get_draw_transform(data->group, &parent_transform);
|
||||
obs_sceneitem_get_draw_transform(data->group,
|
||||
&parent_transform);
|
||||
matrix4_mul(&transform, &transform, &parent_transform);
|
||||
}
|
||||
|
||||
|
@ -286,8 +283,7 @@ struct HandleFindData {
|
|||
HandleFindData &operator=(HandleFindData &&) = delete;
|
||||
|
||||
inline HandleFindData(const vec2 &pos_, float scale)
|
||||
: pos (pos_),
|
||||
radius (HANDLE_SEL_RADIUS / scale)
|
||||
: pos(pos_), radius(HANDLE_SEL_RADIUS / scale)
|
||||
{
|
||||
matrix4_identity(&parent_xform);
|
||||
}
|
||||
|
@ -328,8 +324,7 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
|
|||
|
||||
obs_sceneitem_get_box_transform(item, &transform);
|
||||
|
||||
auto TestHandle = [&] (float x, float y, ItemHandle handle)
|
||||
{
|
||||
auto TestHandle = [&](float x, float y, ItemHandle handle) {
|
||||
vec3 handlePos = GetTransformedPos(x, y, transform);
|
||||
vec3_transform(&handlePos, &handlePos, &data.parent_xform);
|
||||
|
||||
|
@ -370,10 +365,12 @@ static vec2 GetItemSize(obs_sceneitem_t *item)
|
|||
|
||||
obs_sceneitem_get_scale(item, &scale);
|
||||
obs_sceneitem_get_crop(item, &crop);
|
||||
size.x = float(obs_source_get_width(source) -
|
||||
crop.left - crop.right) * scale.x;
|
||||
size.y = float(obs_source_get_height(source) -
|
||||
crop.top - crop.bottom) * scale.y;
|
||||
size.x = float(obs_source_get_width(source) - crop.left -
|
||||
crop.right) *
|
||||
scale.x;
|
||||
size.y = float(obs_source_get_height(source) - crop.top -
|
||||
crop.bottom) *
|
||||
scale.y;
|
||||
}
|
||||
|
||||
return size;
|
||||
|
@ -413,16 +410,16 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
|
|||
|
||||
/* build the item space conversion matrices */
|
||||
matrix4_identity(&itemToScreen);
|
||||
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen,
|
||||
0.0f, 0.0f, 1.0f, RAD(itemRot));
|
||||
matrix4_translate3f(&itemToScreen, &itemToScreen,
|
||||
itemUL.x, itemUL.y, 0.0f);
|
||||
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, 0.0f, 0.0f,
|
||||
1.0f, RAD(itemRot));
|
||||
matrix4_translate3f(&itemToScreen, &itemToScreen, itemUL.x,
|
||||
itemUL.y, 0.0f);
|
||||
|
||||
matrix4_identity(&screenToItem);
|
||||
matrix4_translate3f(&screenToItem, &screenToItem,
|
||||
-itemUL.x, -itemUL.y, 0.0f);
|
||||
matrix4_rotate_aa4f(&screenToItem, &screenToItem,
|
||||
0.0f, 0.0f, 1.0f, RAD(-itemRot));
|
||||
matrix4_translate3f(&screenToItem, &screenToItem, -itemUL.x,
|
||||
-itemUL.y, 0.0f);
|
||||
matrix4_rotate_aa4f(&screenToItem, &screenToItem, 0.0f, 0.0f,
|
||||
1.0f, RAD(-itemRot));
|
||||
|
||||
obs_sceneitem_get_crop(stretchItem, &startCrop);
|
||||
obs_sceneitem_get_pos(stretchItem, &startItemPos);
|
||||
|
@ -437,8 +434,7 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
|
|||
if (stretchGroup) {
|
||||
obs_sceneitem_get_draw_transform(stretchGroup,
|
||||
&invGroupTransform);
|
||||
matrix4_inv(&invGroupTransform,
|
||||
&invGroupTransform);
|
||||
matrix4_inv(&invGroupTransform, &invGroupTransform);
|
||||
obs_sceneitem_defer_group_resize_begin(stretchGroup);
|
||||
}
|
||||
}
|
||||
|
@ -480,8 +476,8 @@ void OBSBasicPreview::keyReleaseEvent(QKeyEvent *event)
|
|||
|
||||
void OBSBasicPreview::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (scrollMode && IsFixedScaling()
|
||||
&& event->orientation() == Qt::Vertical) {
|
||||
if (scrollMode && IsFixedScaling() &&
|
||||
event->orientation() == Qt::Vertical) {
|
||||
if (event->delta() > 0)
|
||||
SetScalingLevel(scalingLevel + 1);
|
||||
else if (event->delta() < 0)
|
||||
|
@ -628,11 +624,11 @@ struct SelectedItemBounds {
|
|||
static bool AddItemBounds(obs_scene_t *scene, obs_sceneitem_t *item,
|
||||
void *param)
|
||||
{
|
||||
SelectedItemBounds *data = reinterpret_cast<SelectedItemBounds*>(param);
|
||||
SelectedItemBounds *data =
|
||||
reinterpret_cast<SelectedItemBounds *>(param);
|
||||
vec3 t[4];
|
||||
|
||||
auto add_bounds = [data, &t] ()
|
||||
{
|
||||
auto add_bounds = [data, &t]() {
|
||||
for (const vec3 &v : t) {
|
||||
if (data->first) {
|
||||
vec3_copy(&data->tl, &v);
|
||||
|
@ -696,12 +692,10 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
|
|||
matrix4 boxTransform;
|
||||
obs_sceneitem_get_box_transform(item, &boxTransform);
|
||||
|
||||
vec3 t[4] = {
|
||||
GetTransformedPos(0.0f, 0.0f, boxTransform),
|
||||
vec3 t[4] = {GetTransformedPos(0.0f, 0.0f, boxTransform),
|
||||
GetTransformedPos(1.0f, 0.0f, boxTransform),
|
||||
GetTransformedPos(0.0f, 1.0f, boxTransform),
|
||||
GetTransformedPos(1.0f, 1.0f, boxTransform)
|
||||
};
|
||||
GetTransformedPos(1.0f, 1.0f, boxTransform)};
|
||||
|
||||
bool first = true;
|
||||
vec3 tl, br;
|
||||
|
@ -723,10 +717,10 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
|
|||
do { \
|
||||
double dist = fabsf(l.x - data->r.x); \
|
||||
if (dist < data->clampDist && \
|
||||
fabsf(data->offset.x) < EPSILON && \
|
||||
data->tl.y < br.y && \
|
||||
fabsf(data->offset.x) < EPSILON && data->tl.y < br.y && \
|
||||
data->br.y > tl.y && \
|
||||
(fabsf(data->offset.x) > dist || data->offset.x < EPSILON)) \
|
||||
(fabsf(data->offset.x) > dist || \
|
||||
data->offset.x < EPSILON)) \
|
||||
data->offset.x = l.x - data->r.x; \
|
||||
} while (false)
|
||||
|
||||
|
@ -755,10 +749,10 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
|
|||
|
||||
vec3 snapOffset = GetSnapOffset(data.tl, data.br);
|
||||
|
||||
const bool snap = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "SnappingEnabled");
|
||||
const bool sourcesSnap = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "SourceSnapping");
|
||||
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"SnappingEnabled");
|
||||
const bool sourcesSnap = config_get_bool(
|
||||
GetGlobalConfig(), "BasicWindow", "SourceSnapping");
|
||||
if (snap == false)
|
||||
return;
|
||||
if (sourcesSnap == false) {
|
||||
|
@ -768,7 +762,9 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
|
|||
}
|
||||
|
||||
const float clampDist = config_get_double(GetGlobalConfig(),
|
||||
"BasicWindow", "SnapDistance") / main->previewScale;
|
||||
"BasicWindow",
|
||||
"SnapDistance") /
|
||||
main->previewScale;
|
||||
|
||||
OffsetData offsetData;
|
||||
offsetData.clampDist = clampDist;
|
||||
|
@ -984,11 +980,9 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
|
|||
vec2 max_tl;
|
||||
vec2 max_br;
|
||||
|
||||
vec2_set(&max_tl,
|
||||
float(-crop.left) * scale.x,
|
||||
vec2_set(&max_tl, float(-crop.left) * scale.x,
|
||||
float(-crop.top) * scale.y);
|
||||
vec2_set(&max_br,
|
||||
stretchItemSize.x + crop.right * scale.x,
|
||||
vec2_set(&max_br, stretchItemSize.x + crop.right * scale.x,
|
||||
stretchItemSize.y + crop.bottom * scale.y);
|
||||
|
||||
typedef std::function<float(float, float)> minmax_func_t;
|
||||
|
@ -1049,12 +1043,14 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
|
|||
if (stretchFlags & ITEM_LEFT)
|
||||
crop.left += int(std::round(tl.x / scale.x));
|
||||
else if (stretchFlags & ITEM_RIGHT)
|
||||
crop.right += int(std::round((stretchItemSize.x - br.x) / scale.x));
|
||||
crop.right +=
|
||||
int(std::round((stretchItemSize.x - br.x) / scale.x));
|
||||
|
||||
if (stretchFlags & ITEM_TOP)
|
||||
crop.top += int(std::round(tl.y / scale.y));
|
||||
else if (stretchFlags & ITEM_BOTTOM)
|
||||
crop.bottom += int(std::round((stretchItemSize.y - br.y) / scale.y));
|
||||
crop.bottom +=
|
||||
int(std::round((stretchItemSize.y - br.y) / scale.y));
|
||||
|
||||
vec3_transform(&newPos, &newPos, &itemToScreen);
|
||||
newPos.x = std::round(newPos.x);
|
||||
|
@ -1109,8 +1105,7 @@ void OBSBasicPreview::StretchItem(const vec2 &pos)
|
|||
obs_source_t *source = obs_sceneitem_get_source(stretchItem);
|
||||
|
||||
vec2 baseSize;
|
||||
vec2_set(&baseSize,
|
||||
float(obs_source_get_width(source)),
|
||||
vec2_set(&baseSize, float(obs_source_get_width(source)),
|
||||
float(obs_source_get_height(source)));
|
||||
|
||||
vec2 size;
|
||||
|
@ -1120,8 +1115,10 @@ void OBSBasicPreview::StretchItem(const vec2 &pos)
|
|||
if (shiftDown)
|
||||
ClampAspect(tl, br, size, baseSize);
|
||||
|
||||
if (tl.x > br.x) std::swap(tl.x, br.x);
|
||||
if (tl.y > br.y) std::swap(tl.y, br.y);
|
||||
if (tl.x > br.x)
|
||||
std::swap(tl.x, br.x);
|
||||
if (tl.y > br.y)
|
||||
std::swap(tl.y, br.y);
|
||||
|
||||
vec2_abs(&size, &size);
|
||||
|
||||
|
@ -1180,8 +1177,8 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
|
|||
OBSBasic *main = reinterpret_cast<OBSBasic *>(
|
||||
App()->GetMainWindow());
|
||||
OBSScene scene = main->GetCurrentScene();
|
||||
obs_sceneitem_t *group = obs_sceneitem_get_group(
|
||||
scene, stretchItem);
|
||||
obs_sceneitem_t *group =
|
||||
obs_sceneitem_get_group(scene, stretchItem);
|
||||
if (group) {
|
||||
vec3 group_pos;
|
||||
vec3_set(&group_pos, pos.x, pos.y, 0.0f);
|
||||
|
@ -1292,9 +1289,7 @@ static void DrawRect(float thickness, vec2 scale)
|
|||
|
||||
static inline bool crop_enabled(const obs_sceneitem_crop *crop)
|
||||
{
|
||||
return crop->left > 0 ||
|
||||
crop->top > 0 ||
|
||||
crop->right > 0 ||
|
||||
return crop->left > 0 || crop->top > 0 || crop->right > 0 ||
|
||||
crop->bottom > 0;
|
||||
}
|
||||
|
||||
|
@ -1319,7 +1314,8 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
|
|||
|
||||
gs_matrix_push();
|
||||
gs_matrix_mul(&mat);
|
||||
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param);
|
||||
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow,
|
||||
param);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
|
@ -1343,9 +1339,8 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
|
|||
{{{1.f, 1.f, 0.f}}},
|
||||
};
|
||||
|
||||
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
|
||||
[&](const vec3 &b)
|
||||
{
|
||||
bool visible = std::all_of(
|
||||
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
|
||||
vec3 pos;
|
||||
vec3_transform(&pos, &b, &boxTransform);
|
||||
vec3_transform(&pos, &pos, &invBoxTransform);
|
||||
|
@ -1437,9 +1432,8 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
|||
vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f);
|
||||
|
||||
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
|
||||
[&](const vec3 &b)
|
||||
{
|
||||
bool visible = std::all_of(
|
||||
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
|
||||
vec3 pos;
|
||||
vec3_transform(&pos, &b, &boxTransform);
|
||||
vec3_transform(&pos, &pos, &invBoxTransform);
|
||||
|
@ -1592,13 +1586,16 @@ void OBSBasicPreview::ResetScrollingOffset()
|
|||
vec2_zero(&scrollingOffset);
|
||||
}
|
||||
|
||||
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal) {
|
||||
float newScalingAmountVal = pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
|
||||
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal)
|
||||
{
|
||||
float newScalingAmountVal =
|
||||
pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
|
||||
scalingLevel = newScalingLevelVal;
|
||||
SetScalingAmount(newScalingAmountVal);
|
||||
}
|
||||
|
||||
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) {
|
||||
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal)
|
||||
{
|
||||
scrollingOffset.x *= newScalingAmountVal / scalingAmount;
|
||||
scrollingOffset.y *= newScalingAmountVal / scalingAmount;
|
||||
scalingAmount = newScalingAmountVal;
|
||||
|
|
|
@ -25,7 +25,7 @@ enum class ItemHandle : uint32_t {
|
|||
CenterRight = ITEM_RIGHT,
|
||||
BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
|
||||
BottomCenter = ITEM_BOTTOM,
|
||||
BottomRight = ITEM_BOTTOM | ITEM_RIGHT
|
||||
BottomRight = ITEM_BOTTOM | ITEM_RIGHT,
|
||||
};
|
||||
|
||||
class OBSBasicPreview : public OBSQTDisplay {
|
||||
|
@ -114,7 +114,10 @@ public:
|
|||
inline void ToggleLocked() { locked = !locked; }
|
||||
inline bool Locked() const { return locked; }
|
||||
|
||||
inline void SetFixedScaling(bool newFixedScalingVal) { fixedScaling = newFixedScalingVal; }
|
||||
inline void SetFixedScaling(bool newFixedScalingVal)
|
||||
{
|
||||
fixedScaling = newFixedScalingVal;
|
||||
}
|
||||
inline bool IsFixedScaling() const { return fixedScaling; }
|
||||
|
||||
void SetScalingLevel(int32_t newScalingLevelVal);
|
||||
|
@ -123,7 +126,10 @@ public:
|
|||
inline float GetScalingAmount() const { return scalingAmount; }
|
||||
|
||||
void ResetScrollingOffset();
|
||||
inline void SetScrollingOffset(float x, float y) {vec2_set(&scrollingOffset, x, y);}
|
||||
inline void SetScrollingOffset(float x, float y)
|
||||
{
|
||||
vec2_set(&scrollingOffset, x, y);
|
||||
}
|
||||
inline float GetScrollX() const { return scrollingOffset.x; }
|
||||
inline float GetScrollY() const { return scrollingOffset.y; }
|
||||
|
||||
|
|
|
@ -37,12 +37,10 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
main(qobject_cast<OBSBasic *>(parent)),
|
||||
acceptClicked(false),
|
||||
source(source_),
|
||||
removedSignal (obs_source_get_signal_handler(source),
|
||||
"remove", OBSBasicProperties::SourceRemoved,
|
||||
this),
|
||||
renamedSignal (obs_source_get_signal_handler(source),
|
||||
"rename", OBSBasicProperties::SourceRenamed,
|
||||
this),
|
||||
removedSignal(obs_source_get_signal_handler(source), "remove",
|
||||
OBSBasicProperties::SourceRemoved, this),
|
||||
renamedSignal(obs_source_get_signal_handler(source), "rename",
|
||||
OBSBasicProperties::SourceRenamed, this),
|
||||
oldSettings(obs_data_create()),
|
||||
buttonBox(new QDialogButtonBox(this))
|
||||
{
|
||||
|
@ -60,8 +58,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
|
||||
buttonBox->button(QDialogButtonBox::Ok)->setText(QTStr("OK"));
|
||||
buttonBox->button(QDialogButtonBox::Cancel)->setText(QTStr("Cancel"));
|
||||
buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setText(QTStr("Defaults"));
|
||||
buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setText(QTStr("Defaults"));
|
||||
|
||||
if (cx > 400 && cy > 400)
|
||||
resize(cx, cy);
|
||||
|
@ -79,14 +77,15 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
obs_data_apply(oldSettings, settings);
|
||||
obs_data_release(settings);
|
||||
|
||||
view = new OBSPropertiesView(settings, source,
|
||||
view = new OBSPropertiesView(
|
||||
settings, source,
|
||||
(PropertiesReloadCallback)obs_source_properties,
|
||||
(PropertiesUpdateCallback)obs_source_update);
|
||||
view->setMinimumHeight(150);
|
||||
|
||||
preview->setMinimumSize(20, 150);
|
||||
preview->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding));
|
||||
preview->setSizePolicy(
|
||||
QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
// Create a QSplitter to keep a unified workflow here.
|
||||
windowSplitter = new QSplitter(Qt::Orientation::Vertical, this);
|
||||
|
@ -102,8 +101,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
|
||||
if (type == OBS_SOURCE_TYPE_TRANSITION) {
|
||||
AddPreviewButton();
|
||||
connect(view, SIGNAL(PropertiesRefreshed()),
|
||||
this, SLOT(AddPreviewButton()));
|
||||
connect(view, SIGNAL(PropertiesRefreshed()), this,
|
||||
SLOT(AddPreviewButton()));
|
||||
}
|
||||
|
||||
layout()->addWidget(buttonBox);
|
||||
|
@ -122,14 +121,14 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
OBSBasicProperties::UpdateProperties,
|
||||
this);
|
||||
|
||||
auto addDrawCallback = [this] ()
|
||||
{
|
||||
auto addDrawCallback = [this]() {
|
||||
obs_display_add_draw_callback(preview->GetDisplay(),
|
||||
OBSBasicProperties::DrawPreview, this);
|
||||
OBSBasicProperties::DrawPreview,
|
||||
this);
|
||||
};
|
||||
auto addTransitionDrawCallback = [this] ()
|
||||
{
|
||||
obs_display_add_draw_callback(preview->GetDisplay(),
|
||||
auto addTransitionDrawCallback = [this]() {
|
||||
obs_display_add_draw_callback(
|
||||
preview->GetDisplay(),
|
||||
OBSBasicProperties::DrawTransitionPreview, this);
|
||||
};
|
||||
uint32_t caps = obs_source_get_output_flags(source);
|
||||
|
@ -143,10 +142,10 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
addDrawCallback);
|
||||
|
||||
} else if (type == OBS_SOURCE_TYPE_TRANSITION) {
|
||||
sourceA = obs_source_create_private("scene", "sourceA",
|
||||
nullptr);
|
||||
sourceB = obs_source_create_private("scene", "sourceB",
|
||||
nullptr);
|
||||
sourceA =
|
||||
obs_source_create_private("scene", "sourceA", nullptr);
|
||||
sourceB =
|
||||
obs_source_create_private("scene", "sourceB", nullptr);
|
||||
|
||||
obs_source_release(sourceA);
|
||||
obs_source_release(sourceB);
|
||||
|
@ -174,8 +173,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
|
|||
|
||||
obs_data_release(settings);
|
||||
|
||||
auto updateCallback = [=]()
|
||||
{
|
||||
auto updateCallback = [=]() {
|
||||
obs_data_t *settings = obs_source_get_settings(source);
|
||||
obs_source_update(sourceClone, settings);
|
||||
|
||||
|
@ -210,15 +208,14 @@ OBSBasicProperties::~OBSBasicProperties()
|
|||
|
||||
void OBSBasicProperties::AddPreviewButton()
|
||||
{
|
||||
QPushButton *playButton = new QPushButton(
|
||||
QTStr("PreviewTransition"), this);
|
||||
QPushButton *playButton =
|
||||
new QPushButton(QTStr("PreviewTransition"), this);
|
||||
VScrollArea *area = view;
|
||||
area->widget()->layout()->addWidget(playButton);
|
||||
|
||||
playButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
auto play = [=] ()
|
||||
{
|
||||
auto play = [=]() {
|
||||
OBSSource start;
|
||||
OBSSource end;
|
||||
|
||||
|
@ -231,8 +228,7 @@ void OBSBasicProperties::AddPreviewButton()
|
|||
}
|
||||
|
||||
obs_transition_set(sourceClone, start);
|
||||
obs_transition_start(sourceClone,
|
||||
OBS_TRANSITION_MODE_AUTO,
|
||||
obs_transition_start(sourceClone, OBS_TRANSITION_MODE_AUTO,
|
||||
main->GetTransitionDuration(), end);
|
||||
direction = !direction;
|
||||
|
||||
|
@ -273,8 +269,8 @@ static obs_source_t *CreateLabel(const char *name, size_t h)
|
|||
const char *text_source_id = "text_ft2_source";
|
||||
#endif
|
||||
|
||||
obs_source_t *txtSource = obs_source_create_private(text_source_id,
|
||||
name, settings);
|
||||
obs_source_t *txtSource =
|
||||
obs_source_create_private(text_source_id, name, settings);
|
||||
|
||||
obs_data_release(font);
|
||||
obs_data_release(settings);
|
||||
|
@ -289,14 +285,14 @@ static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color)
|
|||
obs_data_set_int(settings, "height", obs_source_get_height(scene));
|
||||
obs_data_set_int(settings, "color", color);
|
||||
|
||||
obs_source_t *colorBG = obs_source_create_private("color_source",
|
||||
"background", settings);
|
||||
obs_source_t *colorBG = obs_source_create_private(
|
||||
"color_source", "background", settings);
|
||||
|
||||
obs_scene_add(obs_scene_from_source(scene), colorBG);
|
||||
|
||||
obs_source_t *label = CreateLabel(text, obs_source_get_height(scene));
|
||||
obs_sceneitem_t *item = obs_scene_add(obs_scene_from_source(scene),
|
||||
label);
|
||||
obs_sceneitem_t *item =
|
||||
obs_scene_add(obs_scene_from_source(scene), label);
|
||||
|
||||
vec2 size;
|
||||
vec2_set(&size, obs_source_get_width(scene),
|
||||
|
@ -393,8 +389,7 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
gs_viewport_push();
|
||||
gs_projection_push();
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
|
||||
-100.0f, 100.0f);
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
|
||||
gs_set_viewport(x, y, newCX, newCY);
|
||||
|
||||
obs_source_video_render(window->source);
|
||||
|
@ -425,8 +420,7 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx,
|
|||
|
||||
gs_viewport_push();
|
||||
gs_projection_push();
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
|
||||
-100.0f, 100.0f);
|
||||
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
|
||||
gs_set_viewport(x, y, newCX, newCY);
|
||||
|
||||
obs_source_video_render(window->sourceClone);
|
||||
|
@ -444,7 +438,8 @@ void OBSBasicProperties::Cleanup()
|
|||
|
||||
obs_display_remove_draw_callback(preview->GetDisplay(),
|
||||
OBSBasicProperties::DrawPreview, this);
|
||||
obs_display_remove_draw_callback(preview->GetDisplay(),
|
||||
obs_display_remove_draw_callback(
|
||||
preview->GetDisplay(),
|
||||
OBSBasicProperties::DrawTransitionPreview, this);
|
||||
}
|
||||
|
||||
|
@ -497,11 +492,10 @@ bool OBSBasicProperties::ConfirmQuit()
|
|||
{
|
||||
QMessageBox::StandardButton button;
|
||||
|
||||
button = OBSMessageBox::question(this,
|
||||
QTStr("Basic.PropertiesWindow.ConfirmTitle"),
|
||||
button = OBSMessageBox::question(
|
||||
this, QTStr("Basic.PropertiesWindow.ConfirmTitle"),
|
||||
QTStr("Basic.PropertiesWindow.Confirm"),
|
||||
QMessageBox::Save | QMessageBox::Discard |
|
||||
QMessageBox::Cancel);
|
||||
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
|
||||
switch (button) {
|
||||
case QMessageBox::Save:
|
||||
|
|
|
@ -54,8 +54,7 @@ private:
|
|||
static void SourceRenamed(void *data, calldata_t *params);
|
||||
static void UpdateProperties(void *data, calldata_t *params);
|
||||
static void DrawPreview(void *data, uint32_t cx, uint32_t cy);
|
||||
static void DrawTransitionPreview(void *data, uint32_t cx,
|
||||
uint32_t cy);
|
||||
static void DrawTransitionPreview(void *data, uint32_t cx, uint32_t cy);
|
||||
void UpdateCallback(void *obj, obs_data_t *settings);
|
||||
bool ConfirmQuit();
|
||||
int CheckSettings();
|
||||
|
|
|
@ -54,10 +54,10 @@ void OBSBasicSettings::InitStreamPage()
|
|||
|
||||
LoadServices(false);
|
||||
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(UpdateServerList()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(UpdateKeyLink()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(UpdateServerList()));
|
||||
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(UpdateKeyLink()));
|
||||
}
|
||||
|
||||
void OBSBasicSettings::LoadStream1Settings()
|
||||
|
@ -78,8 +78,10 @@ void OBSBasicSettings::LoadStream1Settings()
|
|||
ui->customServer->setText(server);
|
||||
|
||||
bool use_auth = obs_data_get_bool(settings, "use_auth");
|
||||
const char *username = obs_data_get_string(settings, "username");
|
||||
const char *password = obs_data_get_string(settings, "password");
|
||||
const char *username =
|
||||
obs_data_get_string(settings, "username");
|
||||
const char *password =
|
||||
obs_data_get_string(settings, "password");
|
||||
ui->authUsername->setText(QT_UTF8(username));
|
||||
ui->authPw->setText(QT_UTF8(password));
|
||||
ui->useAuth->setChecked(use_auth);
|
||||
|
@ -126,9 +128,7 @@ void OBSBasicSettings::LoadStream1Settings()
|
|||
void OBSBasicSettings::SaveStream1Settings()
|
||||
{
|
||||
bool customServer = IsCustomService();
|
||||
const char *service_id = customServer
|
||||
? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
|
||||
|
||||
obs_service_t *oldService = main->GetService();
|
||||
OBSData hotkeyData = obs_hotkeys_save_service(oldService);
|
||||
|
@ -140,7 +140,8 @@ void OBSBasicSettings::SaveStream1Settings()
|
|||
if (!customServer) {
|
||||
obs_data_set_string(settings, "service",
|
||||
QT_TO_UTF8(ui->service->currentText()));
|
||||
obs_data_set_string(settings, "server",
|
||||
obs_data_set_string(
|
||||
settings, "server",
|
||||
QT_TO_UTF8(ui->server->currentData().toString()));
|
||||
} else {
|
||||
obs_data_set_string(settings, "server",
|
||||
|
@ -148,18 +149,20 @@ void OBSBasicSettings::SaveStream1Settings()
|
|||
obs_data_set_bool(settings, "use_auth",
|
||||
ui->useAuth->isChecked());
|
||||
if (ui->useAuth->isChecked()) {
|
||||
obs_data_set_string(settings, "username",
|
||||
obs_data_set_string(
|
||||
settings, "username",
|
||||
QT_TO_UTF8(ui->authUsername->text()));
|
||||
obs_data_set_string(settings, "password",
|
||||
QT_TO_UTF8(ui->authPw->text()));
|
||||
}
|
||||
}
|
||||
|
||||
obs_data_set_bool(settings, "bwtest", ui->bandwidthTestEnable->isChecked());
|
||||
obs_data_set_bool(settings, "bwtest",
|
||||
ui->bandwidthTestEnable->isChecked());
|
||||
obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
|
||||
|
||||
OBSService newService = obs_service_create(service_id,
|
||||
"default_service", settings, hotkeyData);
|
||||
OBSService newService = obs_service_create(
|
||||
service_id, "default_service", settings, hotkeyData);
|
||||
obs_service_release(newService);
|
||||
|
||||
if (!newService)
|
||||
|
@ -185,13 +188,15 @@ void OBSBasicSettings::UpdateKeyLink()
|
|||
text += " <a href=\"https://";
|
||||
text += "www.twitch.tv/broadcast/dashboard/streamkey";
|
||||
text += "\">";
|
||||
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += QTStr(
|
||||
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += "</a>";
|
||||
} else if (serviceName == "YouTube / YouTube Gaming") {
|
||||
text += " <a href=\"https://";
|
||||
text += "www.youtube.com/live_dashboard";
|
||||
text += "\">";
|
||||
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += QTStr(
|
||||
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
|
||||
text += "</a>";
|
||||
}
|
||||
|
||||
|
@ -234,8 +239,8 @@ void OBSBasicSettings::LoadServices(bool showAll)
|
|||
QVariant((int)ListOpt::ShowAll));
|
||||
}
|
||||
|
||||
ui->service->insertItem(0,
|
||||
QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
|
||||
ui->service->insertItem(
|
||||
0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
|
||||
QVariant((int)ListOpt::Custom));
|
||||
|
||||
if (!lastService.isEmpty()) {
|
||||
|
@ -256,8 +261,8 @@ static inline bool is_auth_service(const std::string &service)
|
|||
|
||||
void OBSBasicSettings::on_service_currentIndexChanged(int)
|
||||
{
|
||||
bool showMore =
|
||||
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
|
||||
bool showMore = ui->service->currentData().toInt() ==
|
||||
(int)ListOpt::ShowAll;
|
||||
if (showMore)
|
||||
return;
|
||||
|
||||
|
@ -320,8 +325,8 @@ void OBSBasicSettings::on_service_currentIndexChanged(int)
|
|||
void OBSBasicSettings::UpdateServerList()
|
||||
{
|
||||
QString serviceName = ui->service->currentText();
|
||||
bool showMore =
|
||||
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
|
||||
bool showMore = ui->service->currentData().toInt() ==
|
||||
(int)ListOpt::ShowAll;
|
||||
|
||||
if (showMore) {
|
||||
LoadServices(true);
|
||||
|
@ -387,7 +392,8 @@ OBSService OBSBasicSettings::SpawnTempService()
|
|||
if (!custom) {
|
||||
obs_data_set_string(settings, "service",
|
||||
QT_TO_UTF8(ui->service->currentText()));
|
||||
obs_data_set_string(settings, "server",
|
||||
obs_data_set_string(
|
||||
settings, "server",
|
||||
QT_TO_UTF8(ui->server->currentData().toString()));
|
||||
} else {
|
||||
obs_data_set_string(settings, "server",
|
||||
|
@ -395,8 +401,8 @@ OBSService OBSBasicSettings::SpawnTempService()
|
|||
}
|
||||
obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
|
||||
|
||||
OBSService newService = obs_service_create(service_id,
|
||||
"temp_service", settings, nullptr);
|
||||
OBSService newService = obs_service_create(service_id, "temp_service",
|
||||
settings, nullptr);
|
||||
obs_service_release(newService);
|
||||
|
||||
return newService;
|
||||
|
@ -461,8 +467,7 @@ void OBSBasicSettings::on_disconnectAccount_clicked()
|
|||
{
|
||||
QMessageBox::StandardButton button;
|
||||
|
||||
button = OBSMessageBox::question(this,
|
||||
QTStr(DISCONNECT_COMFIRM_TITLE),
|
||||
button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE),
|
||||
QTStr(DISCONNECT_COMFIRM_TEXT));
|
||||
|
||||
if (button == QMessageBox::No) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -68,8 +68,7 @@ public slots:
|
|||
}
|
||||
};
|
||||
|
||||
class OBSFFDeleter
|
||||
{
|
||||
class OBSFFDeleter {
|
||||
public:
|
||||
void operator()(const ff_format_desc *format)
|
||||
{
|
||||
|
@ -80,27 +79,19 @@ public:
|
|||
ff_codec_desc_free(codec);
|
||||
}
|
||||
};
|
||||
using OBSFFCodecDesc = std::unique_ptr<const ff_codec_desc,
|
||||
OBSFFDeleter>;
|
||||
using OBSFFFormatDesc = std::unique_ptr<const ff_format_desc,
|
||||
OBSFFDeleter>;
|
||||
using OBSFFCodecDesc = std::unique_ptr<const ff_codec_desc, OBSFFDeleter>;
|
||||
using OBSFFFormatDesc = std::unique_ptr<const ff_format_desc, OBSFFDeleter>;
|
||||
|
||||
class OBSBasicSettings : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QIcon generalIcon WRITE SetGeneralIcon
|
||||
NOTIFY SetGeneralIcon)
|
||||
Q_PROPERTY(QIcon streamIcon WRITE SetStreamIcon
|
||||
NOTIFY SetStreamIcon)
|
||||
Q_PROPERTY(QIcon outputIcon WRITE SetOutputIcon
|
||||
NOTIFY SetOutputIcon)
|
||||
Q_PROPERTY(QIcon audioIcon WRITE SetAudioIcon
|
||||
NOTIFY SetAudioIcon)
|
||||
Q_PROPERTY(QIcon videoIcon WRITE SetVideoIcon
|
||||
NOTIFY SetVideoIcon)
|
||||
Q_PROPERTY(QIcon hotkeysIcon WRITE SetHotkeysIcon
|
||||
NOTIFY SetHotkeysIcon)
|
||||
Q_PROPERTY(QIcon advancedIcon WRITE SetAdvancedIcon
|
||||
NOTIFY SetAdvancedIcon)
|
||||
Q_PROPERTY(QIcon generalIcon WRITE SetGeneralIcon NOTIFY SetGeneralIcon)
|
||||
Q_PROPERTY(QIcon streamIcon WRITE SetStreamIcon NOTIFY SetStreamIcon)
|
||||
Q_PROPERTY(QIcon outputIcon WRITE SetOutputIcon NOTIFY SetOutputIcon)
|
||||
Q_PROPERTY(QIcon audioIcon WRITE SetAudioIcon NOTIFY SetAudioIcon)
|
||||
Q_PROPERTY(QIcon videoIcon WRITE SetVideoIcon NOTIFY SetVideoIcon)
|
||||
Q_PROPERTY(QIcon hotkeysIcon WRITE SetHotkeysIcon NOTIFY SetHotkeysIcon)
|
||||
Q_PROPERTY(
|
||||
QIcon advancedIcon WRITE SetAdvancedIcon NOTIFY SetAdvancedIcon)
|
||||
|
||||
private:
|
||||
OBSBasic *main;
|
||||
|
@ -141,9 +132,9 @@ private:
|
|||
QString curAdvRecordEncoder;
|
||||
|
||||
using AudioSource_t =
|
||||
std::tuple<OBSWeakSource,
|
||||
QPointer<QCheckBox>, QPointer<QSpinBox>,
|
||||
QPointer<QCheckBox>, QPointer<QSpinBox>>;
|
||||
std::tuple<OBSWeakSource, QPointer<QCheckBox>,
|
||||
QPointer<QSpinBox>, QPointer<QCheckBox>,
|
||||
QPointer<QSpinBox>>;
|
||||
std::vector<AudioSource_t> audioSources;
|
||||
std::vector<OBSSignal> audioSourceSignals;
|
||||
OBSSignal sourceCreated;
|
||||
|
@ -214,12 +205,14 @@ private:
|
|||
void LoadOutputSettings();
|
||||
void LoadAudioSettings();
|
||||
void LoadVideoSettings();
|
||||
void LoadHotkeySettings(obs_hotkey_id ignoreKey=OBS_INVALID_HOTKEY_ID);
|
||||
void
|
||||
LoadHotkeySettings(obs_hotkey_id ignoreKey = OBS_INVALID_HOTKEY_ID);
|
||||
void LoadAdvancedSettings();
|
||||
void LoadSettings(bool changedOnly);
|
||||
|
||||
OBSPropertiesView *CreateEncoderPropertyView(const char *encoder,
|
||||
const char *path, bool changed = false);
|
||||
const char *path,
|
||||
bool changed = false);
|
||||
|
||||
/* general */
|
||||
void LoadLanguageList();
|
||||
|
@ -241,8 +234,8 @@ private slots:
|
|||
void on_disconnectAccount_clicked();
|
||||
void on_useStreamKey_clicked();
|
||||
void on_useAuth_toggled();
|
||||
private:
|
||||
|
||||
private:
|
||||
/* output */
|
||||
void LoadSimpleOutputSettings();
|
||||
void LoadAdvOutputStreamingSettings();
|
||||
|
@ -251,8 +244,8 @@ private:
|
|||
void LoadAdvOutputRecordingEncoderProperties();
|
||||
void LoadAdvOutputFFmpegSettings();
|
||||
void LoadAdvOutputAudioSettings();
|
||||
void SetAdvOutputFFmpegEnablement(
|
||||
ff_codec_type encoderType, bool enabled,
|
||||
void SetAdvOutputFFmpegEnablement(ff_codec_type encoderType,
|
||||
bool enabled,
|
||||
bool enableEncode = false);
|
||||
|
||||
/* audio */
|
||||
|
|
|
@ -28,7 +28,8 @@ struct AddSourceData {
|
|||
|
||||
bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source)
|
||||
{
|
||||
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
||||
OBSBasicSourceSelect *window =
|
||||
static_cast<OBSBasicSourceSelect *>(data);
|
||||
const char *name = obs_source_get_name(source);
|
||||
const char *id = obs_source_get_id(source);
|
||||
|
||||
|
@ -40,13 +41,14 @@ bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source)
|
|||
|
||||
bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source)
|
||||
{
|
||||
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
||||
OBSBasicSourceSelect *window =
|
||||
static_cast<OBSBasicSourceSelect *>(data);
|
||||
const char *name = obs_source_get_name(source);
|
||||
const char *id = obs_source_get_id(source);
|
||||
|
||||
if (strcmp(id, window->id) == 0) {
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(
|
||||
App()->GetMainWindow());
|
||||
OBSBasic *main =
|
||||
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
OBSScene scene = main->GetCurrentScene();
|
||||
|
||||
obs_sceneitem_t *existing = obs_scene_get_group(scene, name);
|
||||
|
@ -59,7 +61,8 @@ bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source)
|
|||
|
||||
void OBSBasicSourceSelect::OBSSourceAdded(void *data, calldata_t *calldata)
|
||||
{
|
||||
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
||||
OBSBasicSourceSelect *window =
|
||||
static_cast<OBSBasicSourceSelect *>(data);
|
||||
obs_source_t *source = (obs_source_t *)calldata_ptr(calldata, "source");
|
||||
|
||||
QMetaObject::invokeMethod(window, "SourceAdded",
|
||||
|
@ -68,7 +71,8 @@ void OBSBasicSourceSelect::OBSSourceAdded(void *data, calldata_t *calldata)
|
|||
|
||||
void OBSBasicSourceSelect::OBSSourceRemoved(void *data, calldata_t *calldata)
|
||||
{
|
||||
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
||||
OBSBasicSourceSelect *window =
|
||||
static_cast<OBSBasicSourceSelect *>(data);
|
||||
obs_source_t *source = (obs_source_t *)calldata_ptr(calldata, "source");
|
||||
|
||||
QMetaObject::invokeMethod(window, "SourceRemoved",
|
||||
|
@ -120,8 +124,8 @@ static char *get_new_source_name(const char *name)
|
|||
dstr_copy(&new_name, name);
|
||||
|
||||
for (;;) {
|
||||
obs_source_t *existing_source = obs_get_source_by_name(
|
||||
new_name.array);
|
||||
obs_source_t *existing_source =
|
||||
obs_get_source_by_name(new_name.array);
|
||||
if (!existing_source)
|
||||
break;
|
||||
|
||||
|
@ -176,8 +180,7 @@ bool AddNew(QWidget *parent, const char *id, const char *name,
|
|||
|
||||
obs_source_t *source = obs_get_source_by_name(name);
|
||||
if (source) {
|
||||
OBSMessageBox::information(parent,
|
||||
QTStr("NameExists.Title"),
|
||||
OBSMessageBox::information(parent, QTStr("NameExists.Title"),
|
||||
QTStr("NameExists.Text"));
|
||||
|
||||
} else {
|
||||
|
@ -243,16 +246,13 @@ static inline const char *GetSourceDisplayName(const char *id)
|
|||
|
||||
Q_DECLARE_METATYPE(OBSScene);
|
||||
|
||||
template <typename T>
|
||||
static inline T GetOBSRef(QListWidgetItem *item)
|
||||
template<typename T> static inline T GetOBSRef(QListWidgetItem *item)
|
||||
{
|
||||
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
|
||||
}
|
||||
|
||||
OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
|
||||
: QDialog (parent),
|
||||
ui (new Ui::OBSBasicSourceSelect),
|
||||
id (id_)
|
||||
: QDialog(parent), ui(new Ui::OBSBasicSourceSelect), id(id_)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
|
@ -277,8 +277,8 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
|
|||
installEventFilter(CreateShortcutFilter());
|
||||
|
||||
if (strcmp(id_, "scene") == 0) {
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(
|
||||
App()->GetMainWindow());
|
||||
OBSBasic *main =
|
||||
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
OBSSource curSceneSource = main->GetCurrentSceneSource();
|
||||
|
||||
ui->selectExisting->setChecked(true);
|
||||
|
|
|
@ -58,15 +58,13 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
|
|||
|
||||
int row = 0;
|
||||
|
||||
auto newStatBare = [&] (QString name, QWidget *label, int col)
|
||||
{
|
||||
auto newStatBare = [&](QString name, QWidget *label, int col) {
|
||||
QLabel *typeLabel = new QLabel(name, this);
|
||||
topLayout->addWidget(typeLabel, row, col);
|
||||
topLayout->addWidget(label, row++, col + 1);
|
||||
};
|
||||
|
||||
auto newStat = [&] (const char *strLoc, QWidget *label, int col)
|
||||
{
|
||||
auto newStat = [&](const char *strLoc, QWidget *label, int col) {
|
||||
std::string str = "Basic.Stats.";
|
||||
str += strLoc;
|
||||
newStatBare(QTStr(str.c_str()), label, col);
|
||||
|
@ -109,8 +107,7 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
|
|||
/* --------------------------------------------- */
|
||||
|
||||
int col = 0;
|
||||
auto addOutputCol = [&] (const char *loc)
|
||||
{
|
||||
auto addOutputCol = [&](const char *loc) {
|
||||
QLabel *label = new QLabel(QTStr(loc), this);
|
||||
label->setStyleSheet("font-weight: bold");
|
||||
outputLayout->addWidget(label, 0, col++);
|
||||
|
@ -165,7 +162,8 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
|
|||
setWindowModality(Qt::NonModal);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
QObject::connect(&timer, &QTimer::timeout, this, &OBSBasicStats::Update);
|
||||
QObject::connect(&timer, &QTimer::timeout, this,
|
||||
&OBSBasicStats::Update);
|
||||
timer.setInterval(TIMER_INTERVAL);
|
||||
|
||||
if (isVisible())
|
||||
|
@ -179,20 +177,19 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
|
|||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
|
||||
const char *geometry = config_get_string(main->Config(),
|
||||
"Stats", "geometry");
|
||||
const char *geometry =
|
||||
config_get_string(main->Config(), "Stats", "geometry");
|
||||
if (geometry != NULL) {
|
||||
QByteArray byteArray = QByteArray::fromBase64(
|
||||
QByteArray(geometry));
|
||||
QByteArray byteArray =
|
||||
QByteArray::fromBase64(QByteArray(geometry));
|
||||
restoreGeometry(byteArray);
|
||||
|
||||
QRect windowGeometry = normalGeometry();
|
||||
if (!WindowPositionValid(windowGeometry)) {
|
||||
QRect rect = App()->desktop()->geometry();
|
||||
setGeometry(QStyle::alignedRect(
|
||||
Qt::LeftToRight,
|
||||
Qt::AlignCenter,
|
||||
size(), rect));
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight,
|
||||
Qt::AlignCenter, size(),
|
||||
rect));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,8 +200,7 @@ void OBSBasicStats::closeEvent(QCloseEvent *event)
|
|||
{
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
if (isVisible()) {
|
||||
config_set_string(main->Config(),
|
||||
"Stats", "geometry",
|
||||
config_set_string(main->Config(), "Stats", "geometry",
|
||||
saveGeometry().toBase64().constData());
|
||||
config_save_safe(main->Config(), "tmp", nullptr);
|
||||
}
|
||||
|
@ -302,9 +298,12 @@ void OBSBasicStats::Update()
|
|||
/* ------------------ */
|
||||
|
||||
const char *mode = config_get_string(main->Config(), "Output", "Mode");
|
||||
const char *path = strcmp(mode, "Advanced") ?
|
||||
config_get_string(main->Config(), "SimpleOutput", "FilePath") :
|
||||
config_get_string(main->Config(), "AdvOut", "RecFilePath");
|
||||
const char *path = strcmp(mode, "Advanced")
|
||||
? config_get_string(main->Config(),
|
||||
"SimpleOutput",
|
||||
"FilePath")
|
||||
: config_get_string(main->Config(), "AdvOut",
|
||||
"RecFilePath");
|
||||
|
||||
#define MBYTE (1024ULL * 1024ULL)
|
||||
#define GBYTE (1024ULL * 1024ULL * 1024ULL)
|
||||
|
@ -374,8 +373,8 @@ void OBSBasicStats::Update()
|
|||
: 0.0l;
|
||||
num *= 100.0l;
|
||||
|
||||
str = QString("%1 / %2 (%3%)").arg(
|
||||
QString::number(total_skipped),
|
||||
str = QString("%1 / %2 (%3%)")
|
||||
.arg(QString::number(total_skipped),
|
||||
QString::number(total_encoded),
|
||||
QString::number(num, 'f', 1));
|
||||
skippedFrames->setText(str);
|
||||
|
@ -404,8 +403,8 @@ void OBSBasicStats::Update()
|
|||
: 0.0l;
|
||||
num *= 100.0l;
|
||||
|
||||
str = QString("%1 / %2 (%3%)").arg(
|
||||
QString::number(total_lagged),
|
||||
str = QString("%1 / %2 (%3%)")
|
||||
.arg(QString::number(total_lagged),
|
||||
QString::number(total_rendered),
|
||||
QString::number(num, 'f', 1));
|
||||
missedFrames->setText(str);
|
||||
|
@ -444,8 +443,8 @@ void OBSBasicStats::ResetRecTimeLeft()
|
|||
|
||||
void OBSBasicStats::RecordingTimeLeft()
|
||||
{
|
||||
long double averageBitrate = accumulate(bitrates.begin(),
|
||||
bitrates.end(), 0.0) /
|
||||
long double averageBitrate =
|
||||
accumulate(bitrates.begin(), bitrates.end(), 0.0) /
|
||||
(long double)bitrates.size();
|
||||
long double bytesPerSec = (averageBitrate / 8.0l) * 1000.0l;
|
||||
long double secondsUntilFull = (long double)num_bytes / bytesPerSec;
|
||||
|
@ -457,8 +456,8 @@ void OBSBasicStats::RecordingTimeLeft()
|
|||
int hours = totalMinutes / 60;
|
||||
|
||||
QString text;
|
||||
text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")),
|
||||
minutes, QT_TO_UTF8(QTStr("Minutes")));
|
||||
text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")), minutes,
|
||||
QT_TO_UTF8(QTStr("Minutes")));
|
||||
recordTimeLeft->setText(text);
|
||||
recordTimeLeft->setMinimumWidth(recordTimeLeft->width());
|
||||
}
|
||||
|
@ -494,8 +493,8 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
|
|||
lastBytesSent = 0;
|
||||
|
||||
uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
|
||||
long double timePassed = (long double)(curTime - lastBytesSentTime) /
|
||||
1000000000.0l;
|
||||
long double timePassed =
|
||||
(long double)(curTime - lastBytesSentTime) / 1000000000.0l;
|
||||
kbps = (long double)bitsBetween / timePassed / 1000.0l;
|
||||
|
||||
if (timePassed < 0.01l)
|
||||
|
@ -509,8 +508,8 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
|
|||
str = QTStr("Basic.Stats.Status.Recording");
|
||||
} else {
|
||||
if (active) {
|
||||
bool reconnecting = output
|
||||
? obs_output_reconnecting(output)
|
||||
bool reconnecting =
|
||||
output ? obs_output_reconnecting(output)
|
||||
: false;
|
||||
|
||||
if (reconnecting) {
|
||||
|
@ -530,12 +529,12 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
|
|||
|
||||
megabytesSent->setText(
|
||||
QString("%1 MB").arg(QString::number(num, 'f', 1)));
|
||||
bitrate->setText(
|
||||
QString("%1 kb/s").arg(QString::number(kbps, 'f', 0)));
|
||||
bitrate->setText(QString("%1 kb/s").arg(QString::number(kbps, 'f', 0)));
|
||||
|
||||
if (!rec) {
|
||||
int total = output ? obs_output_get_total_frames(output) : 0;
|
||||
int dropped = output ? obs_output_get_frames_dropped(output) : 0;
|
||||
int dropped = output ? obs_output_get_frames_dropped(output)
|
||||
: 0;
|
||||
|
||||
if (total < first_total || dropped < first_dropped) {
|
||||
first_total = 0;
|
||||
|
@ -545,12 +544,11 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
|
|||
total -= first_total;
|
||||
dropped -= first_dropped;
|
||||
|
||||
num = total
|
||||
? (long double)dropped / (long double)total * 100.0l
|
||||
num = total ? (long double)dropped / (long double)total * 100.0l
|
||||
: 0.0l;
|
||||
|
||||
str = QString("%1 / %2 (%3%)").arg(
|
||||
QString::number(dropped),
|
||||
str = QString("%1 / %2 (%3%)")
|
||||
.arg(QString::number(dropped),
|
||||
QString::number(total),
|
||||
QString::number(num, 'f', 1));
|
||||
droppedFrames->setText(str);
|
||||
|
|
|
@ -74,8 +74,8 @@ void OBSBasicStatusBar::Activate()
|
|||
{
|
||||
if (!active) {
|
||||
refreshTimer = new QTimer(this);
|
||||
connect(refreshTimer, SIGNAL(timeout()),
|
||||
this, SLOT(UpdateStatusBar()));
|
||||
connect(refreshTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateStatusBar()));
|
||||
|
||||
int skipped = video_output_get_skipped_frames(obs_get_video());
|
||||
int total = video_output_get_total_frames(obs_get_video());
|
||||
|
@ -175,14 +175,13 @@ void OBSBasicStatusBar::UpdateBandwidth()
|
|||
|
||||
uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
|
||||
|
||||
double timePassed = double(bytesSentTime - lastBytesSentTime) /
|
||||
1000000000.0;
|
||||
double timePassed =
|
||||
double(bytesSentTime - lastBytesSentTime) / 1000000000.0;
|
||||
|
||||
double kbitsPerSec = double(bitsBetween) / timePassed / 1000.0;
|
||||
|
||||
QString text;
|
||||
text += QString("kb/s: ") +
|
||||
QString::number(kbitsPerSec, 'f', 0);
|
||||
text += QString("kb/s: ") + QString::number(kbitsPerSec, 'f', 0);
|
||||
|
||||
kbps->setText(text);
|
||||
kbps->setMinimumWidth(kbps->width());
|
||||
|
@ -293,11 +292,13 @@ void OBSBasicStatusBar::UpdateDroppedFrames()
|
|||
QPixmap pixmap(20, 20);
|
||||
|
||||
float red = avgCongestion * 2.0f;
|
||||
if (red > 1.0f) red = 1.0f;
|
||||
if (red > 1.0f)
|
||||
red = 1.0f;
|
||||
red *= 255.0;
|
||||
|
||||
float green = (1.0f - avgCongestion) * 2.0f;
|
||||
if (green > 1.0f) green = 1.0f;
|
||||
if (green > 1.0f)
|
||||
green = 1.0f;
|
||||
green *= 255.0;
|
||||
|
||||
pixmap.fill(QColor(int(red), int(green), 0));
|
||||
|
@ -317,7 +318,8 @@ void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t *params)
|
|||
UNUSED_PARAMETER(params);
|
||||
}
|
||||
|
||||
void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *params)
|
||||
void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data,
|
||||
calldata_t *params)
|
||||
{
|
||||
OBSBasicStatusBar *statusBar =
|
||||
reinterpret_cast<OBSBasicStatusBar *>(data);
|
||||
|
@ -432,7 +434,8 @@ void OBSBasicStatusBar::StreamStarted(obs_output_t *output)
|
|||
signal_handler_connect(obs_output_get_signal_handler(streamOutput),
|
||||
"reconnect", OBSOutputReconnect, this);
|
||||
signal_handler_connect(obs_output_get_signal_handler(streamOutput),
|
||||
"reconnect_success", OBSOutputReconnectSuccess, this);
|
||||
"reconnect_success", OBSOutputReconnectSuccess,
|
||||
this);
|
||||
|
||||
retries = 0;
|
||||
lastBytesSent = 0;
|
||||
|
@ -448,8 +451,7 @@ void OBSBasicStatusBar::StreamStopped()
|
|||
"reconnect", OBSOutputReconnect, this);
|
||||
signal_handler_disconnect(
|
||||
obs_output_get_signal_handler(streamOutput),
|
||||
"reconnect_success", OBSOutputReconnectSuccess,
|
||||
this);
|
||||
"reconnect_success", OBSOutputReconnectSuccess, this);
|
||||
|
||||
ReconnectClear();
|
||||
streamOutput = nullptr;
|
||||
|
|
|
@ -40,9 +40,7 @@ void OBSBasicTransform::HookWidget(QWidget *widget, const char *signal,
|
|||
#define DSCROLL_CHANGED SIGNAL(valueChanged(double))
|
||||
|
||||
OBSBasicTransform::OBSBasicTransform(OBSBasic *parent)
|
||||
: QDialog (parent),
|
||||
ui (new Ui::OBSBasicTransform),
|
||||
main (parent)
|
||||
: QDialog(parent), ui(new Ui::OBSBasicTransform), main(parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -88,14 +86,15 @@ void OBSBasicTransform::SetScene(OBSScene scene)
|
|||
|
||||
if (scene) {
|
||||
OBSSource source = obs_scene_get_source(scene);
|
||||
signal_handler_t *signal = obs_source_get_signal_handler(source);
|
||||
signal_handler_t *signal =
|
||||
obs_source_get_signal_handler(source);
|
||||
|
||||
transformSignal.Connect(signal, "item_transform",
|
||||
OBSSceneItemTransform, this);
|
||||
removeSignal.Connect(signal, "item_remove",
|
||||
OBSSceneItemRemoved, this);
|
||||
selectSignal.Connect(signal, "item_select",
|
||||
OBSSceneItemSelect, this);
|
||||
removeSignal.Connect(signal, "item_remove", OBSSceneItemRemoved,
|
||||
this);
|
||||
selectSignal.Connect(signal, "item_select", OBSSceneItemSelect,
|
||||
this);
|
||||
deselectSignal.Connect(signal, "item_deselect",
|
||||
OBSSceneItemDeselect, this);
|
||||
}
|
||||
|
@ -118,7 +117,8 @@ void OBSBasicTransform::SetItemQt(OBSSceneItem newItem)
|
|||
|
||||
void OBSBasicTransform::OBSChannelChanged(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSBasicTransform *window =
|
||||
reinterpret_cast<OBSBasicTransform *>(param);
|
||||
uint32_t channel = (uint32_t)calldata_int(data, "channel");
|
||||
OBSSource source = (obs_source_t *)calldata_ptr(data, "source");
|
||||
|
||||
|
@ -135,7 +135,8 @@ void OBSBasicTransform::OBSChannelChanged(void *param, calldata_t *data)
|
|||
|
||||
void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSBasicTransform *window =
|
||||
reinterpret_cast<OBSBasicTransform *>(param);
|
||||
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
|
||||
if (item == window->item && !window->ignoreTransformSignal)
|
||||
|
@ -144,7 +145,8 @@ void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data)
|
|||
|
||||
void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSBasicTransform *window =
|
||||
reinterpret_cast<OBSBasicTransform *>(param);
|
||||
OBSScene scene = (obs_scene_t *)calldata_ptr(data, "scene");
|
||||
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
|
||||
|
@ -154,7 +156,8 @@ void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data)
|
|||
|
||||
void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSBasicTransform *window =
|
||||
reinterpret_cast<OBSBasicTransform *>(param);
|
||||
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
|
||||
if (item != window->item)
|
||||
|
@ -163,7 +166,8 @@ void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data)
|
|||
|
||||
void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data)
|
||||
{
|
||||
OBSBasicTransform *window = reinterpret_cast<OBSBasicTransform*>(param);
|
||||
OBSBasicTransform *window =
|
||||
reinterpret_cast<OBSBasicTransform *>(param);
|
||||
OBSScene scene = (obs_scene_t *)calldata_ptr(data, "scene");
|
||||
OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item");
|
||||
|
||||
|
@ -171,8 +175,7 @@ void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data)
|
|||
window->SetItem(FindASelectedItem(scene));
|
||||
}
|
||||
|
||||
static const uint32_t listToAlign[] = {
|
||||
OBS_ALIGN_TOP | OBS_ALIGN_LEFT,
|
||||
static const uint32_t listToAlign[] = {OBS_ALIGN_TOP | OBS_ALIGN_LEFT,
|
||||
OBS_ALIGN_TOP,
|
||||
OBS_ALIGN_TOP | OBS_ALIGN_RIGHT,
|
||||
OBS_ALIGN_LEFT,
|
||||
|
@ -180,8 +183,7 @@ static const uint32_t listToAlign[] = {
|
|||
OBS_ALIGN_RIGHT,
|
||||
OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT,
|
||||
OBS_ALIGN_BOTTOM,
|
||||
OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT
|
||||
};
|
||||
OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT};
|
||||
|
||||
static int AlignToList(uint32_t align)
|
||||
{
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
|
||||
void OBSDock::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
auto msgBox = [] ()
|
||||
{
|
||||
auto msgBox = []() {
|
||||
QMessageBox msgbox(App()->GetMainWindow());
|
||||
msgbox.setWindowTitle(QTStr("DockCloseWarning.Title"));
|
||||
msgbox.setText(QTStr("DockCloseWarning.Text"));
|
||||
|
@ -29,8 +28,7 @@ void OBSDock::closeEvent(QCloseEvent *event)
|
|||
bool warned = config_get_bool(App()->GlobalConfig(), "General",
|
||||
"WarnedAboutClosingDocks");
|
||||
if (!warned) {
|
||||
QMetaObject::invokeMethod(App(), "Exec",
|
||||
Qt::QueuedConnection,
|
||||
QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection,
|
||||
Q_ARG(VoidFunc, msgBox));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
#include "obs-app.hpp"
|
||||
|
||||
OBSLogReply::OBSLogReply(QWidget *parent, const QString &url)
|
||||
: QDialog (parent),
|
||||
ui (new Ui::OBSLogReply)
|
||||
: QDialog(parent), ui(new Ui::OBSLogReply)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->urlEdit->setText(url);
|
||||
|
|
|
@ -13,6 +13,6 @@ public:
|
|||
virtual config_t *Config() const = 0;
|
||||
virtual void OBSInit() = 0;
|
||||
|
||||
virtual int GetProfilePath(char *path, size_t size, const char *file)
|
||||
const=0;
|
||||
virtual int GetProfilePath(char *path, size_t size,
|
||||
const char *file) const = 0;
|
||||
};
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
using namespace std;
|
||||
|
||||
NameDialog::NameDialog(QWidget *parent)
|
||||
: QDialog (parent),
|
||||
ui (new Ui::NameDialog)
|
||||
: QDialog(parent), ui(new Ui::NameDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -37,15 +36,16 @@ static bool IsWhitespace(char ch)
|
|||
}
|
||||
|
||||
bool NameDialog::AskForName(QWidget *parent, const QString &title,
|
||||
const QString &text, string &str, const QString &placeHolder,
|
||||
int maxSize)
|
||||
const QString &text, string &str,
|
||||
const QString &placeHolder, int maxSize)
|
||||
{
|
||||
if (maxSize <= 0 || maxSize > 32767)
|
||||
maxSize = 256;
|
||||
|
||||
NameDialog dialog(parent);
|
||||
dialog.setWindowTitle(title);
|
||||
dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
dialog.setWindowFlags(dialog.windowFlags() &
|
||||
~Qt::WindowContextHelpButtonHint);
|
||||
dialog.ui->label->setText(text);
|
||||
dialog.ui->userText->setMaxLength(maxSize);
|
||||
dialog.ui->userText->setText(placeHolder);
|
||||
|
|
|
@ -18,11 +18,10 @@ static size_t maxSrcs, numSrcs;
|
|||
|
||||
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
||||
QString title, ProjectorType type_)
|
||||
: OBSQTDisplay (widget,
|
||||
Qt::Window),
|
||||
: OBSQTDisplay(widget, Qt::Window),
|
||||
source(source_),
|
||||
removedSignal (obs_source_get_signal_handler(source),
|
||||
"remove", OBSSourceRemoved, this)
|
||||
removedSignal(obs_source_get_signal_handler(source), "remove",
|
||||
OBSSourceRemoved, this)
|
||||
{
|
||||
projectorTitle = std::move(title);
|
||||
savedMonitor = monitor;
|
||||
|
@ -30,8 +29,8 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
|||
type = type_;
|
||||
|
||||
if (isWindow) {
|
||||
setWindowIcon(QIcon::fromTheme("obs",
|
||||
QIcon(":/res/images/obs.png")));
|
||||
setWindowIcon(
|
||||
QIcon::fromTheme("obs", QIcon(":/res/images/obs.png")));
|
||||
|
||||
UpdateProjectorTitle(projectorTitle);
|
||||
windowedProjectors.push_back(this);
|
||||
|
@ -51,8 +50,8 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
|||
SLOT(EscapeTriggered()));
|
||||
}
|
||||
|
||||
SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "ProjectorAlwaysOnTop"));
|
||||
SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"ProjectorAlwaysOnTop"));
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
|
@ -61,19 +60,18 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
|||
|
||||
installEventFilter(CreateShortcutFilter());
|
||||
|
||||
auto addDrawCallback = [this] ()
|
||||
{
|
||||
auto addDrawCallback = [this]() {
|
||||
bool isMultiview = type == ProjectorType::Multiview;
|
||||
obs_display_add_draw_callback(GetDisplay(),
|
||||
isMultiview ? OBSRenderMultiview : OBSRender,
|
||||
this);
|
||||
obs_display_add_draw_callback(
|
||||
GetDisplay(),
|
||||
isMultiview ? OBSRenderMultiview : OBSRender, this);
|
||||
obs_display_set_background_color(GetDisplay(), 0x000000);
|
||||
};
|
||||
|
||||
connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
|
||||
|
||||
bool hideCursor = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "HideProjectorCursor");
|
||||
bool hideCursor = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"HideProjectorCursor");
|
||||
if (hideCursor && !isWindow && type != ProjectorType::Multiview) {
|
||||
QPixmap empty(16, 16);
|
||||
empty.fill(Qt::transparent);
|
||||
|
@ -107,8 +105,8 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
|||
gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage);
|
||||
gs_vertex2f(1 - fourByThreeSafePercentage,
|
||||
graphicsSafePercentage);
|
||||
gs_vertex2f(1 - fourByThreeSafePercentage, 1 -
|
||||
graphicsSafePercentage);
|
||||
gs_vertex2f(1 - fourByThreeSafePercentage,
|
||||
1 - graphicsSafePercentage);
|
||||
gs_vertex2f(fourByThreeSafePercentage,
|
||||
1 - graphicsSafePercentage);
|
||||
gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage);
|
||||
|
@ -155,8 +153,9 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
|||
OBSProjector::~OBSProjector()
|
||||
{
|
||||
bool isMultiview = type == ProjectorType::Multiview;
|
||||
obs_display_remove_draw_callback(GetDisplay(),
|
||||
isMultiview ? OBSRenderMultiview : OBSRender, this);
|
||||
obs_display_remove_draw_callback(
|
||||
GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender,
|
||||
this);
|
||||
|
||||
if (source)
|
||||
obs_source_dec_showing(source);
|
||||
|
@ -217,8 +216,8 @@ static OBSSource CreateLabel(const char *name, size_t h)
|
|||
const char *text_source_id = "text_ft2_source";
|
||||
#endif
|
||||
|
||||
OBSSource txtSource = obs_source_create_private(text_source_id, name,
|
||||
settings);
|
||||
OBSSource txtSource =
|
||||
obs_source_create_private(text_source_id, name, settings);
|
||||
obs_source_release(txtSource);
|
||||
|
||||
obs_data_release(font);
|
||||
|
@ -282,8 +281,7 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
bool studioMode = main->IsPreviewProgramMode();
|
||||
|
||||
auto renderVB = [&](gs_vertbuffer_t *vb, int cx, int cy,
|
||||
uint32_t colorVal)
|
||||
{
|
||||
uint32_t colorVal) {
|
||||
if (!vb)
|
||||
return;
|
||||
|
||||
|
@ -304,16 +302,13 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
gs_matrix_pop();
|
||||
};
|
||||
|
||||
auto drawBox = [&](float cx, float cy, uint32_t colorVal)
|
||||
{
|
||||
auto drawBox = [&](float cx, float cy, uint32_t colorVal) {
|
||||
gs_effect_set_color(window->color, colorVal);
|
||||
while (gs_effect_loop(window->solid, "Solid"))
|
||||
gs_draw_sprite(nullptr, 0, (uint32_t)cx, (uint32_t)cy);
|
||||
};
|
||||
|
||||
auto setRegion = [&](float bx, float by, float cx,
|
||||
float cy)
|
||||
{
|
||||
auto setRegion = [&](float bx, float by, float cx, float cy) {
|
||||
float vX = int(x + bx * scale);
|
||||
float vY = int(y + by * scale);
|
||||
float vCX = int(cx * scale);
|
||||
|
@ -327,13 +322,12 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
startRegion(vX, vY, vCX, vCY, oL, oR, oT, oB);
|
||||
};
|
||||
|
||||
auto calcBaseSource = [&](size_t i)
|
||||
{
|
||||
auto calcBaseSource = [&](size_t i) {
|
||||
switch (multiviewLayout) {
|
||||
case MultiviewLayout::HORIZONTAL_TOP_24_SCENES:
|
||||
window->sourceX = (i % 6) * window->scenesCX;
|
||||
window->sourceY = window->pvwprgCY +
|
||||
(i / 6) * window->scenesCY;
|
||||
window->sourceY =
|
||||
window->pvwprgCY + (i / 6) * window->scenesCY;
|
||||
break;
|
||||
case MultiviewLayout::VERTICAL_LEFT_8_SCENES:
|
||||
window->sourceX = window->pvwprgCX;
|
||||
|
@ -352,8 +346,8 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
window->sourceX = (float(i) * window->scenesCX);
|
||||
window->sourceY = 0;
|
||||
} else {
|
||||
window->sourceX = (float(i - 4) *
|
||||
window->scenesCX);
|
||||
window->sourceX =
|
||||
(float(i - 4) * window->scenesCX);
|
||||
window->sourceY = window->scenesCY;
|
||||
}
|
||||
break;
|
||||
|
@ -362,22 +356,21 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
window->sourceX = (float(i) * window->scenesCX);
|
||||
window->sourceY = window->pvwprgCY;
|
||||
} else {
|
||||
window->sourceX = (float(i - 4) *
|
||||
window->scenesCX);
|
||||
window->sourceY = window->pvwprgCY +
|
||||
window->scenesCY;
|
||||
window->sourceX =
|
||||
(float(i - 4) * window->scenesCX);
|
||||
window->sourceY =
|
||||
window->pvwprgCY + window->scenesCY;
|
||||
}
|
||||
}
|
||||
window->siX = window->sourceX + window->thickness;
|
||||
window->siY = window->sourceY + window->thickness;
|
||||
};
|
||||
|
||||
auto calcPreviewProgram = [&](bool program)
|
||||
{
|
||||
auto calcPreviewProgram = [&](bool program) {
|
||||
switch (multiviewLayout) {
|
||||
case MultiviewLayout::HORIZONTAL_TOP_24_SCENES:
|
||||
window->sourceX = window->thickness +
|
||||
window->pvwprgCX / 2;
|
||||
window->sourceX =
|
||||
window->thickness + window->pvwprgCX / 2;
|
||||
window->sourceY = window->thickness;
|
||||
window->labelX = window->offset + window->pvwprgCX / 2;
|
||||
window->labelY = window->pvwprgCY * 0.85f;
|
||||
|
@ -429,8 +422,7 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
};
|
||||
|
||||
auto paintAreaWithColor = [&](float tx, float ty, float cx, float cy,
|
||||
uint32_t color)
|
||||
{
|
||||
uint32_t color) {
|
||||
gs_matrix_push();
|
||||
gs_matrix_translate3f(tx, ty, 0.0f);
|
||||
drawBox(cx, cy, color);
|
||||
|
@ -473,7 +465,8 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
// Paint the background
|
||||
paintAreaWithColor(window->sourceX, window->sourceY,
|
||||
window->scenesCX, window->scenesCY, colorVal);
|
||||
window->scenesCX, window->scenesCY,
|
||||
colorVal);
|
||||
paintAreaWithColor(window->siX, window->siY, window->siCX,
|
||||
window->siCY, backgroundColor);
|
||||
|
||||
|
@ -501,13 +494,14 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
window->offset = labelOffset(label, window->scenesCX);
|
||||
|
||||
gs_matrix_push();
|
||||
gs_matrix_translate3f(window->sourceX + window->offset,
|
||||
(window->scenesCY * 0.85f) + window->sourceY,
|
||||
0.0f);
|
||||
gs_matrix_translate3f(
|
||||
window->sourceX + window->offset,
|
||||
(window->scenesCY * 0.85f) + window->sourceY, 0.0f);
|
||||
gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f);
|
||||
drawBox(obs_source_get_width(label),
|
||||
obs_source_get_height(label) +
|
||||
int(window->sourceY * 0.015f), labelColor);
|
||||
int(window->sourceY * 0.015f),
|
||||
labelColor);
|
||||
obs_source_video_render(label);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
@ -556,7 +550,8 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f);
|
||||
drawBox(obs_source_get_width(previewLabel),
|
||||
obs_source_get_height(previewLabel) +
|
||||
int(window->pvwprgCX * 0.015f), labelColor);
|
||||
int(window->pvwprgCX * 0.015f),
|
||||
labelColor);
|
||||
obs_source_video_render(previewLabel);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
@ -590,7 +585,8 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f);
|
||||
drawBox(obs_source_get_width(programLabel),
|
||||
obs_source_get_height(programLabel) +
|
||||
int(window->pvwprgCX * 0.015f), labelColor);
|
||||
int(window->pvwprgCX * 0.015f),
|
||||
labelColor);
|
||||
obs_source_video_render(programLabel);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
@ -599,10 +595,12 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
|
|||
if (multiviewLayout == MultiviewLayout::HORIZONTAL_TOP_24_SCENES) {
|
||||
// Just paint the background for now
|
||||
paintAreaWithColor(window->thickness, window->thickness,
|
||||
window->siCX, window->siCY * 2 +
|
||||
window->thicknessx2, backgroundColor);
|
||||
paintAreaWithColor(window->thickness + 2.5 * (
|
||||
window->thicknessx2 + window->ppiCX),
|
||||
window->siCX,
|
||||
window->siCY * 2 + window->thicknessx2,
|
||||
backgroundColor);
|
||||
paintAreaWithColor(
|
||||
window->thickness +
|
||||
2.5 * (window->thicknessx2 + window->ppiCX),
|
||||
window->thickness, window->siCX,
|
||||
window->siCY * 2 + window->thicknessx2,
|
||||
backgroundColor);
|
||||
|
@ -863,16 +861,16 @@ void OBSProjector::UpdateMultiview()
|
|||
struct obs_frontend_source_list scenes = {};
|
||||
obs_frontend_get_scenes(&scenes);
|
||||
|
||||
multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Preview"),
|
||||
h / 2));
|
||||
multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Program"),
|
||||
h / 2));
|
||||
multiviewLabels.emplace_back(
|
||||
CreateLabel(Str("StudioMode.Preview"), h / 2));
|
||||
multiviewLabels.emplace_back(
|
||||
CreateLabel(Str("StudioMode.Program"), h / 2));
|
||||
|
||||
multiviewLayout = static_cast<MultiviewLayout>(config_get_int(
|
||||
GetGlobalConfig(), "BasicWindow", "MultiviewLayout"));
|
||||
|
||||
drawLabel = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "MultiviewDrawNames");
|
||||
drawLabel = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"MultiviewDrawNames");
|
||||
|
||||
drawSafeArea = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"MultiviewDrawAreas");
|
||||
|
@ -880,8 +878,8 @@ void OBSProjector::UpdateMultiview()
|
|||
mouseSwitching = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"MultiviewMouseSwitch");
|
||||
|
||||
transitionOnDoubleClick = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "TransitionOnDoubleClick");
|
||||
transitionOnDoubleClick = config_get_bool(
|
||||
GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick");
|
||||
|
||||
switch (multiviewLayout) {
|
||||
case MultiviewLayout::HORIZONTAL_TOP_24_SCENES:
|
||||
|
|
|
@ -8,7 +8,7 @@ enum class ProjectorType {
|
|||
Scene,
|
||||
Preview,
|
||||
StudioProgram,
|
||||
Multiview
|
||||
Multiview,
|
||||
};
|
||||
|
||||
class QMouseEvent;
|
||||
|
@ -18,7 +18,7 @@ enum class MultiviewLayout : uint8_t {
|
|||
HORIZONTAL_BOTTOM_8_SCENES = 1,
|
||||
VERTICAL_LEFT_8_SCENES = 2,
|
||||
VERTICAL_RIGHT_8_SCENES = 3,
|
||||
HORIZONTAL_TOP_24_SCENES = 4
|
||||
HORIZONTAL_TOP_24_SCENES = 4,
|
||||
};
|
||||
|
||||
class OBSProjector : public OBSQTDisplay {
|
||||
|
@ -51,10 +51,10 @@ private:
|
|||
gs_eparam_t *color = nullptr;
|
||||
// Multiview position helpers
|
||||
float thickness = 4;
|
||||
float offset, thicknessx2 = thickness * 2, pvwprgCX,
|
||||
pvwprgCY, sourceX, sourceY, labelX, labelY, scenesCX, scenesCY,
|
||||
ppiCX, ppiCY, siX, siY, siCX, siCY, ppiScaleX, ppiScaleY,
|
||||
siScaleX, siScaleY, fw, fh, ratio;
|
||||
float offset, thicknessx2 = thickness * 2, pvwprgCX, pvwprgCY, sourceX,
|
||||
sourceY, labelX, labelY, scenesCX, scenesCY, ppiCX, ppiCY,
|
||||
siX, siY, siCX, siCY, ppiScaleX, ppiScaleY, siScaleX,
|
||||
siScaleY, fw, fh, ratio;
|
||||
|
||||
float lineLength = 0.1f;
|
||||
// Rec. ITU-R BT.1848-1 / EBU R 95
|
||||
|
|
|
@ -48,28 +48,24 @@ enum RemuxEntryColumn {
|
|||
Count
|
||||
};
|
||||
|
||||
enum RemuxEntryRole {
|
||||
EntryStateRole = Qt::UserRole,
|
||||
NewPathsToProcessRole
|
||||
};
|
||||
enum RemuxEntryRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole };
|
||||
|
||||
/**********************************************************
|
||||
Delegate - Presents cells in the grid.
|
||||
**********************************************************/
|
||||
|
||||
RemuxEntryPathItemDelegate::RemuxEntryPathItemDelegate(bool isOutput,
|
||||
const QString &defaultPath)
|
||||
: QStyledItemDelegate(),
|
||||
isOutput(isOutput),
|
||||
defaultPath(defaultPath)
|
||||
RemuxEntryPathItemDelegate::RemuxEntryPathItemDelegate(
|
||||
bool isOutput, const QString &defaultPath)
|
||||
: QStyledItemDelegate(), isOutput(isOutput), defaultPath(defaultPath)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem & /* option */,
|
||||
QWidget *RemuxEntryPathItemDelegate::createEditor(
|
||||
QWidget *parent, const QStyleOptionViewItem & /* option */,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
RemuxEntryState state = index.model()
|
||||
RemuxEntryState state =
|
||||
index.model()
|
||||
->index(index.row(), RemuxEntryColumn::State)
|
||||
.data(RemuxEntryRole::EntryStateRole)
|
||||
.value<RemuxEntryState>();
|
||||
|
@ -94,14 +90,12 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent,
|
|||
|
||||
QWidget *container = new QWidget(parent);
|
||||
|
||||
auto browseCallback = [this, container]()
|
||||
{
|
||||
auto browseCallback = [this, container]() {
|
||||
const_cast<RemuxEntryPathItemDelegate *>(this)
|
||||
->handleBrowse(container);
|
||||
};
|
||||
|
||||
auto clearCallback = [this, container]()
|
||||
{
|
||||
auto clearCallback = [this, container]() {
|
||||
const_cast<RemuxEntryPathItemDelegate *>(this)
|
||||
->handleClear(container);
|
||||
};
|
||||
|
@ -112,8 +106,8 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent,
|
|||
|
||||
QLineEdit *text = new QLineEdit();
|
||||
text->setObjectName(QStringLiteral("text"));
|
||||
text->setSizePolicy(QSizePolicy(
|
||||
QSizePolicy::Policy::Expanding,
|
||||
text->setSizePolicy(
|
||||
QSizePolicy(QSizePolicy::Policy::Expanding,
|
||||
QSizePolicy::Policy::Expanding,
|
||||
QSizePolicy::ControlType::LineEdit));
|
||||
layout->addWidget(text);
|
||||
|
@ -134,8 +128,7 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent,
|
|||
clearButton->setSizePolicy(buttonSizePolicy);
|
||||
layout->addWidget(clearButton);
|
||||
|
||||
container->connect(clearButton,
|
||||
&QToolButton::clicked,
|
||||
container->connect(clearButton, &QToolButton::clicked,
|
||||
clearCallback);
|
||||
}
|
||||
|
||||
|
@ -150,7 +143,8 @@ void RemuxEntryPathItemDelegate::setEditorData(QWidget *editor,
|
|||
{
|
||||
QLineEdit *text = editor->findChild<QLineEdit *>();
|
||||
text->setText(index.data().toString());
|
||||
QObject::connect(text, SIGNAL(textEdited(QString)), this, SLOT(updateText()));
|
||||
QObject::connect(text, SIGNAL(textEdited(QString)), this,
|
||||
SLOT(updateText()));
|
||||
editor->setProperty(PATH_LIST_PROP, QVariant());
|
||||
}
|
||||
|
||||
|
@ -167,8 +161,8 @@ void RemuxEntryPathItemDelegate::setModelData(QWidget *editor,
|
|||
// as normal text data in the default role.
|
||||
QVariant pathListProp = editor->property(PATH_LIST_PROP);
|
||||
if (pathListProp.isValid()) {
|
||||
QStringList list = editor->property(PATH_LIST_PROP)
|
||||
.toStringList();
|
||||
QStringList list =
|
||||
editor->property(PATH_LIST_PROP).toStringList();
|
||||
if (isOutput) {
|
||||
if (list.size() > 0)
|
||||
model->setData(index, list);
|
||||
|
@ -185,7 +179,8 @@ void RemuxEntryPathItemDelegate::paint(QPainter *painter,
|
|||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
RemuxEntryState state = index.model()
|
||||
RemuxEntryState state =
|
||||
index.model()
|
||||
->index(index.row(), RemuxEntryColumn::State)
|
||||
.data(RemuxEntryRole::EntryStateRole)
|
||||
.value<RemuxEntryState>();
|
||||
|
@ -195,8 +190,8 @@ void RemuxEntryPathItemDelegate::paint(QPainter *painter,
|
|||
|
||||
if (isOutput) {
|
||||
if (state != Ready) {
|
||||
QColor background = localOption.palette
|
||||
.color(QPalette::ColorGroup::Disabled,
|
||||
QColor background = localOption.palette.color(
|
||||
QPalette::ColorGroup::Disabled,
|
||||
QPalette::ColorRole::Background);
|
||||
|
||||
localOption.backgroundBrush = QBrush(background);
|
||||
|
@ -209,10 +204,8 @@ void RemuxEntryPathItemDelegate::paint(QPainter *painter,
|
|||
|
||||
void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container)
|
||||
{
|
||||
QString OutputPattern =
|
||||
"(*.mp4 *.flv *.mov *.mkv *.ts *.m3u8)";
|
||||
QString InputPattern =
|
||||
"(*.flv *.mov *.mkv *.ts *.m3u8)";
|
||||
QString OutputPattern = "(*.mp4 *.flv *.mov *.mkv *.ts *.m3u8)";
|
||||
QString InputPattern = "(*.flv *.mov *.mkv *.ts *.m3u8)";
|
||||
|
||||
QLineEdit *text = container->findChild<QLineEdit *>();
|
||||
|
||||
|
@ -223,8 +216,8 @@ void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container)
|
|||
bool isSet = false;
|
||||
if (isOutput) {
|
||||
QString newPath = QFileDialog::getSaveFileName(
|
||||
container, QTStr("Remux.SelectTarget"),
|
||||
currentPath, OutputPattern);
|
||||
container, QTStr("Remux.SelectTarget"), currentPath,
|
||||
OutputPattern);
|
||||
|
||||
if (!newPath.isEmpty()) {
|
||||
container->setProperty(PATH_LIST_PROP,
|
||||
|
@ -233,11 +226,9 @@ void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container)
|
|||
}
|
||||
} else {
|
||||
QStringList paths = QFileDialog::getOpenFileNames(
|
||||
container,
|
||||
QTStr("Remux.SelectRecording"),
|
||||
currentPath,
|
||||
QTStr("Remux.OBSRecording")
|
||||
+ QString(" ") + InputPattern);
|
||||
container, QTStr("Remux.SelectRecording"), currentPath,
|
||||
QTStr("Remux.OBSRecording") + QString(" ") +
|
||||
InputPattern);
|
||||
|
||||
if (!paths.empty()) {
|
||||
container->setProperty(PATH_LIST_PROP, paths);
|
||||
|
@ -258,7 +249,8 @@ void RemuxEntryPathItemDelegate::handleClear(QWidget *container)
|
|||
emit commitData(container);
|
||||
}
|
||||
|
||||
void RemuxEntryPathItemDelegate::updateText() {
|
||||
void RemuxEntryPathItemDelegate::updateText()
|
||||
{
|
||||
QLineEdit *lineEdit = dynamic_cast<QLineEdit *>(sender());
|
||||
QWidget *editor = lineEdit->parentWidget();
|
||||
emit commitData(editor);
|
||||
|
@ -356,7 +348,8 @@ bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value,
|
|||
endRemoveRows();
|
||||
}
|
||||
} else {
|
||||
if (pathList.size() > 1 && index.row() < queue.length()) {
|
||||
if (pathList.size() > 1 &&
|
||||
index.row() < queue.length()) {
|
||||
queue[index.row()].sourcePath = pathList[0];
|
||||
checkInputPath(index.row());
|
||||
|
||||
|
@ -414,12 +407,14 @@ bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value,
|
|||
} else {
|
||||
switch (index.column()) {
|
||||
case RemuxEntryColumn::InputPath:
|
||||
queue[index.row()].sourcePath = value.toString();
|
||||
queue[index.row()].sourcePath =
|
||||
value.toString();
|
||||
checkInputPath(index.row());
|
||||
success = true;
|
||||
break;
|
||||
case RemuxEntryColumn::OutputPath:
|
||||
queue[index.row()].targetPath = value.toString();
|
||||
queue[index.row()].targetPath =
|
||||
value.toString();
|
||||
emit dataChanged(index, index);
|
||||
success = true;
|
||||
break;
|
||||
|
@ -437,23 +432,19 @@ QVariant RemuxQueueModel::getIcon(RemuxEntryState state)
|
|||
|
||||
switch (state) {
|
||||
case RemuxEntryState::Complete:
|
||||
icon = style->standardIcon(
|
||||
QStyle::SP_DialogApplyButton);
|
||||
icon = style->standardIcon(QStyle::SP_DialogApplyButton);
|
||||
break;
|
||||
|
||||
case RemuxEntryState::InProgress:
|
||||
icon = style->standardIcon(
|
||||
QStyle::SP_ArrowRight);
|
||||
icon = style->standardIcon(QStyle::SP_ArrowRight);
|
||||
break;
|
||||
|
||||
case RemuxEntryState::Error:
|
||||
icon = style->standardIcon(
|
||||
QStyle::SP_DialogCancelButton);
|
||||
icon = style->standardIcon(QStyle::SP_DialogCancelButton);
|
||||
break;
|
||||
|
||||
case RemuxEntryState::InvalidPath:
|
||||
icon = style->standardIcon(
|
||||
QStyle::SP_MessageBoxWarning);
|
||||
icon = style->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -477,8 +468,8 @@ void RemuxQueueModel::checkInputPath(int row)
|
|||
entry.state = RemuxEntryState::InvalidPath;
|
||||
|
||||
if (entry.state == RemuxEntryState::Ready)
|
||||
entry.targetPath = fileInfo.path() + QDir::separator()
|
||||
+ fileInfo.completeBaseName() + ".mp4";
|
||||
entry.targetPath = fileInfo.path() + QDir::separator() +
|
||||
fileInfo.completeBaseName() + ".mp4";
|
||||
}
|
||||
|
||||
if (entry.state == RemuxEntryState::Ready && isProcessing)
|
||||
|
@ -600,8 +591,8 @@ bool RemuxQueueModel::beginNextEntry(QString &inputPath, QString &outputPath)
|
|||
inputPath = entry.sourcePath;
|
||||
outputPath = entry.targetPath;
|
||||
|
||||
QModelIndex index = this->index(row,
|
||||
RemuxEntryColumn::State);
|
||||
QModelIndex index =
|
||||
this->index(row, RemuxEntryColumn::State);
|
||||
emit dataChanged(index, index);
|
||||
|
||||
anyStarted = true;
|
||||
|
@ -622,8 +613,8 @@ void RemuxQueueModel::finishEntry(bool success)
|
|||
else
|
||||
entry.state = RemuxEntryState::Error;
|
||||
|
||||
QModelIndex index = this->index(row,
|
||||
RemuxEntryColumn::State);
|
||||
QModelIndex index =
|
||||
this->index(row, RemuxEntryColumn::State);
|
||||
emit dataChanged(index, index);
|
||||
|
||||
break;
|
||||
|
@ -650,10 +641,9 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_)
|
|||
ui->setupUi(this);
|
||||
|
||||
ui->progressBar->setVisible(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setEnabled(false);
|
||||
|
||||
if (autoRemux) {
|
||||
resize(280, 40);
|
||||
|
@ -667,31 +657,31 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_)
|
|||
ui->progressBar->setValue(0);
|
||||
|
||||
ui->tableView->setModel(queueModel);
|
||||
ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::InputPath,
|
||||
ui->tableView->setItemDelegateForColumn(
|
||||
RemuxEntryColumn::InputPath,
|
||||
new RemuxEntryPathItemDelegate(false, recPath));
|
||||
ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::OutputPath,
|
||||
ui->tableView->setItemDelegateForColumn(
|
||||
RemuxEntryColumn::OutputPath,
|
||||
new RemuxEntryPathItemDelegate(true, recPath));
|
||||
ui->tableView->horizontalHeader()->setSectionResizeMode(
|
||||
QHeaderView::ResizeMode::Stretch);
|
||||
ui->tableView->horizontalHeader()->setSectionResizeMode(
|
||||
RemuxEntryColumn::State,
|
||||
QHeaderView::ResizeMode::Fixed);
|
||||
RemuxEntryColumn::State, QHeaderView::ResizeMode::Fixed);
|
||||
ui->tableView->setEditTriggers(
|
||||
QAbstractItemView::EditTrigger::CurrentChanged);
|
||||
|
||||
installEventFilter(CreateShortcutFilter());
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setText(QTStr("Remux.Remux"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->
|
||||
setText(QTStr("Remux.ClearFinished"));
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setText(QTStr("Remux.ClearAll"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->
|
||||
setDisabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setText(QTStr("Remux.Remux"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)
|
||||
->setText(QTStr("Remux.ClearFinished"));
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setText(QTStr("Remux.ClearAll"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->setDisabled(true);
|
||||
|
||||
connect(ui->buttonBox->button(QDialogButtonBox::Ok),
|
||||
SIGNAL(clicked()), this, SLOT(beginRemux()));
|
||||
connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
|
||||
this, SLOT(beginRemux()));
|
||||
connect(ui->buttonBox->button(QDialogButtonBox::Reset),
|
||||
SIGNAL(clicked()), this, SLOT(clearFinished()));
|
||||
connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults),
|
||||
|
@ -704,28 +694,25 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_)
|
|||
|
||||
//gcc-4.8 can't use QPointer<RemuxWorker> below
|
||||
RemuxWorker *worker_ = worker;
|
||||
connect(worker_, &RemuxWorker::updateProgress,
|
||||
this, &OBSRemux::updateProgress);
|
||||
connect(worker_, &RemuxWorker::updateProgress, this,
|
||||
&OBSRemux::updateProgress);
|
||||
connect(&remuxer, &QThread::finished, worker_, &QObject::deleteLater);
|
||||
connect(worker_, &RemuxWorker::remuxFinished,
|
||||
this, &OBSRemux::remuxFinished);
|
||||
connect(worker_, &RemuxWorker::remuxFinished, this,
|
||||
&OBSRemux::remuxFinished);
|
||||
connect(this, &OBSRemux::remux, worker_, &RemuxWorker::remux);
|
||||
|
||||
// Guessing the GCC bug mentioned above would also affect
|
||||
// QPointer<RemuxQueueModel>? Unsure.
|
||||
RemuxQueueModel *queueModel_ = queueModel;
|
||||
connect(queueModel_,
|
||||
SIGNAL(rowsInserted(const QModelIndex &, int, int)),
|
||||
this,
|
||||
SLOT(rowCountChanged(const QModelIndex &, int, int)));
|
||||
connect(queueModel_,
|
||||
SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
|
||||
this,
|
||||
SIGNAL(rowsInserted(const QModelIndex &, int, int)), this,
|
||||
SLOT(rowCountChanged(const QModelIndex &, int, int)));
|
||||
connect(queueModel_, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
|
||||
this, SLOT(rowCountChanged(const QModelIndex &, int, int)));
|
||||
|
||||
QModelIndex index = queueModel->createIndex(0, 1);
|
||||
QMetaObject::invokeMethod(ui->tableView,
|
||||
"setCurrentIndex", Qt::QueuedConnection,
|
||||
QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QModelIndex &, index));
|
||||
}
|
||||
|
||||
|
@ -741,12 +728,10 @@ bool OBSRemux::stopRemux()
|
|||
|
||||
bool exit = false;
|
||||
|
||||
if (QMessageBox::critical(nullptr,
|
||||
QTStr("Remux.ExitUnfinishedTitle"),
|
||||
if (QMessageBox::critical(nullptr, QTStr("Remux.ExitUnfinishedTitle"),
|
||||
QTStr("Remux.ExitUnfinished"),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No) ==
|
||||
QMessageBox::Yes) {
|
||||
QMessageBox::No) == QMessageBox::Yes) {
|
||||
exit = true;
|
||||
}
|
||||
|
||||
|
@ -774,19 +759,17 @@ void OBSRemux::rowCountChanged(const QModelIndex &, int, int)
|
|||
// There must be more than one row, since there will always be
|
||||
// at least one row for the empty insertion point.
|
||||
if (queueModel->rowCount() > 1) {
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->
|
||||
setEnabled(queueModel->canClearFinished());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)
|
||||
->setEnabled(queueModel->canClearFinished());
|
||||
} else {
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->
|
||||
setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setEnabled(false);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)
|
||||
->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,13 +782,12 @@ void OBSRemux::dropEvent(QDropEvent *ev)
|
|||
|
||||
if (fileInfo.isDir()) {
|
||||
QStringList directoryFilter;
|
||||
directoryFilter <<
|
||||
"*.flv" <<
|
||||
"*.mp4" <<
|
||||
"*.mov" <<
|
||||
"*.mkv" <<
|
||||
"*.ts" <<
|
||||
"*.m3u8";
|
||||
directoryFilter << "*.flv"
|
||||
<< "*.mp4"
|
||||
<< "*.mov"
|
||||
<< "*.mkv"
|
||||
<< "*.ts"
|
||||
<< "*.m3u8";
|
||||
|
||||
QDirIterator dirIter(fileInfo.absoluteFilePath(),
|
||||
directoryFilter, QDir::Files,
|
||||
|
@ -822,10 +804,11 @@ void OBSRemux::dropEvent(QDropEvent *ev)
|
|||
if (urlList.empty()) {
|
||||
QMessageBox::information(nullptr,
|
||||
QTStr("Remux.NoFilesAddedTitle"),
|
||||
QTStr("Remux.NoFilesAdded"), QMessageBox::Ok);
|
||||
QTStr("Remux.NoFilesAdded"),
|
||||
QMessageBox::Ok);
|
||||
} else if (!autoRemux) {
|
||||
QModelIndex insertIndex = queueModel->index(
|
||||
queueModel->rowCount() - 1,
|
||||
QModelIndex insertIndex =
|
||||
queueModel->index(queueModel->rowCount() - 1,
|
||||
RemuxEntryColumn::InputPath);
|
||||
queueModel->setData(insertIndex, urlList,
|
||||
RemuxEntryRole::NewPathsToProcessRole);
|
||||
|
@ -856,8 +839,8 @@ void OBSRemux::beginRemux()
|
|||
message += fileInfo.canonicalFilePath() + "\n";
|
||||
|
||||
if (OBSMessageBox::question(this,
|
||||
QTStr("Remux.FileExistsTitle"), message)
|
||||
!= QMessageBox::Yes)
|
||||
QTStr("Remux.FileExistsTitle"),
|
||||
message) != QMessageBox::Yes)
|
||||
proceedWithRemux = false;
|
||||
}
|
||||
|
||||
|
@ -868,8 +851,8 @@ void OBSRemux::beginRemux()
|
|||
queueModel->beginProcessing();
|
||||
|
||||
ui->progressBar->setVisible(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setText(QTStr("Remux.Stop"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setText(QTStr("Remux.Stop"));
|
||||
setAcceptDrops(false);
|
||||
|
||||
remuxNextEntry();
|
||||
|
@ -895,20 +878,20 @@ void OBSRemux::remuxNextEntry()
|
|||
queueModel->endProcessing();
|
||||
|
||||
if (!autoRemux) {
|
||||
OBSMessageBox::information(this,
|
||||
QTStr("Remux.FinishedTitle"),
|
||||
OBSMessageBox::information(
|
||||
this, QTStr("Remux.FinishedTitle"),
|
||||
queueModel->checkForErrors()
|
||||
? QTStr("Remux.FinishedError")
|
||||
: QTStr("Remux.Finished"));
|
||||
}
|
||||
|
||||
ui->progressBar->setVisible(autoRemux);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setText(QTStr("Remux.Remux"));
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->
|
||||
setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->
|
||||
setEnabled(queueModel->canClearFinished());
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setText(QTStr("Remux.Remux"));
|
||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)
|
||||
->setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)
|
||||
->setEnabled(queueModel->canClearFinished());
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
}
|
||||
|
@ -936,8 +919,7 @@ void OBSRemux::updateProgress(float percent)
|
|||
|
||||
void OBSRemux::remuxFinished(bool success)
|
||||
{
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->
|
||||
setEnabled(true);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
|
||||
queueModel->finishEntry(success);
|
||||
|
||||
|
@ -976,8 +958,7 @@ void RemuxWorker::remux(const QString &source, const QString &target)
|
|||
{
|
||||
isWorking = true;
|
||||
|
||||
auto callback = [](void *data, float percent)
|
||||
{
|
||||
auto callback = [](void *data, float percent) {
|
||||
RemuxWorker *rw = static_cast<RemuxWorker *>(data);
|
||||
|
||||
QMutexLocker lock(&rw->updateMutex);
|
||||
|
@ -991,12 +972,10 @@ void RemuxWorker::remux(const QString &source, const QString &target)
|
|||
bool success = false;
|
||||
|
||||
media_remux_job_t mr_job = nullptr;
|
||||
if (media_remux_job_create(&mr_job,
|
||||
QT_TO_UTF8(source),
|
||||
if (media_remux_job_create(&mr_job, QT_TO_UTF8(source),
|
||||
QT_TO_UTF8(target))) {
|
||||
|
||||
success = media_remux_job_process(mr_job, callback,
|
||||
this);
|
||||
success = media_remux_job_process(mr_job, callback, this);
|
||||
|
||||
media_remux_job_destroy(mr_job);
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
class RemuxQueueModel;
|
||||
class RemuxWorker;
|
||||
|
||||
enum RemuxEntryState
|
||||
{
|
||||
enum RemuxEntryState {
|
||||
Empty,
|
||||
Ready,
|
||||
Pending,
|
||||
|
@ -97,8 +96,9 @@ class RemuxQueueModel : public QAbstractTableModel {
|
|||
|
||||
public:
|
||||
RemuxQueueModel(QObject *parent = 0)
|
||||
: QAbstractTableModel(parent)
|
||||
, isProcessing(false) {}
|
||||
: QAbstractTableModel(parent), isProcessing(false)
|
||||
{
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
@ -106,8 +106,7 @@ public:
|
|||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role);
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
QFileInfoList checkForOverwrites() const;
|
||||
bool checkForErrors() const;
|
||||
|
@ -122,8 +121,7 @@ public:
|
|||
bool autoRemux = false;
|
||||
|
||||
private:
|
||||
struct RemuxQueueEntry
|
||||
{
|
||||
struct RemuxQueueEntry {
|
||||
RemuxEntryState state;
|
||||
|
||||
QString sourcePath;
|
||||
|
@ -148,8 +146,7 @@ class RemuxWorker : public QObject {
|
|||
float lastProgress;
|
||||
void UpdateProgress(float percent);
|
||||
|
||||
explicit RemuxWorker()
|
||||
: isWorking(false) { }
|
||||
explicit RemuxWorker() : isWorking(false) {}
|
||||
virtual ~RemuxWorker(){};
|
||||
|
||||
private slots:
|
||||
|
@ -172,10 +169,9 @@ public:
|
|||
const QStyleOptionViewItem & /* option */,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
virtual void setEditorData(QWidget *editor, const QModelIndex &index)
|
||||
const override;
|
||||
virtual void setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model,
|
||||
virtual void setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const override;
|
||||
virtual void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const override;
|
||||
virtual void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
|
|
|
@ -82,8 +82,7 @@ static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb,
|
|||
static size_t http_header(char *buffer, size_t size, size_t nitems,
|
||||
struct update_info *info)
|
||||
{
|
||||
if (!strncmp(buffer, "ETag: ", 6))
|
||||
{
|
||||
if (!strncmp(buffer, "ETag: ", 6)) {
|
||||
char *etag = buffer + 6;
|
||||
if (*etag) {
|
||||
char *etag_clean, *p;
|
||||
|
@ -121,7 +120,8 @@ static bool do_http_request(struct update_info *info, const char *url,
|
|||
|
||||
if (!info->remote_url) {
|
||||
// We only care about headers from the main package file
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, http_header);
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION,
|
||||
http_header);
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERDATA, info);
|
||||
}
|
||||
|
||||
|
@ -280,8 +280,7 @@ static bool update_files_to_local(void *param, obs_data_t *local_file)
|
|||
struct update_info *info = param;
|
||||
struct file_update_data data = {
|
||||
.name = obs_data_get_string(local_file, "name"),
|
||||
.version = (int)obs_data_get_int(local_file, "version")
|
||||
};
|
||||
.version = (int)obs_data_get_int(local_file, "version")};
|
||||
|
||||
enum_files(info->cache_package, newer_than_cache, &data);
|
||||
if (data.newer || !data.found)
|
||||
|
@ -327,8 +326,7 @@ static inline void write_file_data(struct update_info *info,
|
|||
const char *base_path, const char *file)
|
||||
{
|
||||
char *full_path = get_path(base_path, file);
|
||||
os_quick_write_utf8_file(full_path,
|
||||
(char*)info->file_data.array,
|
||||
os_quick_write_utf8_file(full_path, (char *)info->file_data.array,
|
||||
info->file_data.num - 1, false);
|
||||
bfree(full_path);
|
||||
}
|
||||
|
@ -354,8 +352,7 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
|
||||
struct file_update_data data = {
|
||||
.name = obs_data_get_string(remote_file, "name"),
|
||||
.version = (int)obs_data_get_int(remote_file, "version")
|
||||
};
|
||||
.version = (int)obs_data_get_int(remote_file, "version")};
|
||||
|
||||
enum_files(info->cache_package, newer_than_cache, &data);
|
||||
if (!data.newer && data.found)
|
||||
|
@ -386,8 +383,8 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
write_file_data(info, info->temp, data.name);
|
||||
replace_file(info->temp, info->cache, data.name);
|
||||
|
||||
info("Successfully updated file '%s' (version %d)",
|
||||
data.name, data.version);
|
||||
info("Successfully updated file '%s' (version %d)", data.name,
|
||||
data.version);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -428,8 +425,8 @@ static void update_remote_version(struct update_info *info, int cur_version)
|
|||
|
||||
update_save_metadata(info);
|
||||
|
||||
info->remote_package = obs_data_create_from_json(
|
||||
(char*)info->file_data.array);
|
||||
info->remote_package =
|
||||
obs_data_create_from_json((char *)info->file_data.array);
|
||||
if (!info->remote_package) {
|
||||
warn("Failed to initialize remote package json");
|
||||
return;
|
||||
|
@ -476,11 +473,9 @@ static void *update_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
update_info_t *update_info_create(
|
||||
const char *log_prefix,
|
||||
update_info_t *update_info_create(const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url,
|
||||
const char *local_dir,
|
||||
const char *update_url, const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param)
|
||||
|
@ -550,12 +545,10 @@ static void *single_file_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
update_info_t *update_info_create_single(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
update_info_t *
|
||||
update_info_create_single(const char *log_prefix, const char *user_agent,
|
||||
const char *file_url,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param)
|
||||
confirm_file_callback_t confirm_callback, void *param)
|
||||
{
|
||||
struct update_info *info;
|
||||
|
||||
|
|
|
@ -15,18 +15,13 @@ struct file_download_data {
|
|||
typedef bool (*confirm_file_callback_t)(void *param,
|
||||
struct file_download_data *file);
|
||||
|
||||
update_info_t *update_info_create(
|
||||
const char *log_prefix,
|
||||
update_info_t *update_info_create(const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url,
|
||||
const char *local_dir,
|
||||
const char *update_url, const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param);
|
||||
update_info_t *update_info_create_single(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *file_url,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param);
|
||||
const char *log_prefix, const char *user_agent, const char *file_url,
|
||||
confirm_file_callback_t confirm_callback, void *param);
|
||||
void update_info_destroy(update_info_t *info);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue