Changes of Revision 62
obs-studio.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Wed Feb 27 21:36:03 UTC 2019 - jimmy@boombatower.com
4
+
5
+- Update to version 23.0.1:
6
+ * obs-browser: Fix widgets being initially blank on high-DPI
7
+ * libobs: Update version to 23.0.1
8
+ * libobs-d3d11: Disable NV12 textures if NVENC unavailable
9
+ * UI: Don't show "What's New" for new users
10
+ * UI: Don't delete auto-remux file (just in case)
11
+ * libobs-d3d11: Blacklist certain adapters from NV12
12
+ * UI: Do not allow post-GPU rescaling on gpu encoders
13
+ * libobs: Add func to get encoder caps by encoder pointer
14
+ * obs-ffmpeg: Fix bitrate being set on NVENC CQP/lossless
15
+ * UI: Fix Mixer allowing endless login retries
16
+ * UI: Make workaround for Logitech plugin hard lock
17
+ * UI: Check CEF available when loading auth
18
+ * libobs-d3d11: Improve check for NV12 texture support
19
+
20
+-------------------------------------------------------------------
21
Tue Feb 26 00:11:02 UTC 2019 - Jimmy Berry <jimmy@boombatower.com>
22
23
- Include pkg-config (.pc) file in devel subpackage.
24
obs-studio.spec
Changed
8
1
2
Name: obs-studio
3
-Version: 23.0.0
4
+Version: 23.0.1
5
Release: 0
6
Summary: A recording/broadcasting program
7
Group: Productivity/Multimedia/Video/Editors and Convertors
8
_service
Changed
10
1
2
<services>
3
<service name="tar_scm" mode="disabled">
4
<param name="versionformat">@PARENT_TAG@</param>
5
- <param name="revision">refs/tags/23.0.0</param>
6
+ <param name="revision">refs/tags/23.0.1</param>
7
<param name="url">git://github.com/jp9000/obs-studio.git</param>
8
<param name="scm">git</param>
9
<param name="changesgenerate">enable</param>
10
_servicedata
Changed
9
1
2
<servicedata>
3
<service name="tar_scm">
4
<param name="url">git://github.com/jp9000/obs-studio.git</param>
5
- <param name="changesrevision">8181f776093bde3d078709e4b5d50cba50cad92c</param>
6
+ <param name="changesrevision">f2d7f5b2e713266138df656121da35ff89407991</param>
7
</service>
8
</servicedata>
9
obs-studio-23.0.0.tar.xz/UI/api-interface.cpp -> obs-studio-23.0.1.tar.xz/UI/api-interface.cpp
Changed
54
1
2
void EnumProfiles(function<bool (const char *, const char *)> &&cb);
3
void EnumSceneCollections(function<bool (const char *, const char *)> &&cb);
4
5
+extern volatile bool streaming_active;
6
+extern volatile bool recording_active;
7
+extern volatile bool replaybuf_active;
8
+
9
/* ------------------------------------------------------------------------- */
10
11
template<typename T> struct OBSStudioCallback {
12
13
14
bool obs_frontend_streaming_active(void) override
15
{
16
- bool active;
17
- QMetaObject::invokeMethod(main,
18
- "StreamingActive",
19
- WaitConnection(),
20
- Q_RETURN_ARG(bool, active));
21
- return active;
22
+ return os_atomic_load_bool(&streaming_active);
23
}
24
25
void obs_frontend_recording_start(void) override
26
27
28
bool obs_frontend_recording_active(void) override
29
{
30
- bool active;
31
- QMetaObject::invokeMethod(main,
32
- "RecordingActive",
33
- WaitConnection(),
34
- Q_RETURN_ARG(bool, active));
35
- return active;
36
+ return os_atomic_load_bool(&recording_active);
37
}
38
39
void obs_frontend_replay_buffer_start(void) override
40
41
42
bool obs_frontend_replay_buffer_active(void) override
43
{
44
- bool active;
45
- QMetaObject::invokeMethod(main,
46
- "ReplayBufferActive",
47
- WaitConnection(),
48
- Q_RETURN_ARG(bool, active));
49
- return active;
50
+ return os_atomic_load_bool(&replaybuf_active);
51
}
52
53
void *obs_frontend_add_tools_menu_qaction(const char *name) override
54
obs-studio-23.0.0.tar.xz/UI/auth-mixer.cpp -> obs-studio-23.0.1.tar.xz/UI/auth-mixer.cpp
Changed
60
1
2
{
3
}
4
5
-bool MixerAuth::GetChannelInfo()
6
+bool MixerAuth::GetChannelInfo(bool allow_retry)
7
try {
8
std::string client_id = MIXER_CLIENTID;
9
deobfuscate_str(&client_id[0], MIXER_HASH);
10
11
* it'll be an empty stream key usually. So treat empty stream key as
12
* an error. */
13
if (key_suffix.empty()) {
14
- if (RetryLogin()) {
15
- return GetChannelInfo();
16
+ if (allow_retry && RetryLogin()) {
17
+ return GetChannelInfo(false);
18
}
19
throw ErrorInfo("Auth Failure", "Could not get channel data");
20
}
21
22
23
void MixerAuth::LoadUI()
24
{
25
+ if (!cef)
26
+ return;
27
if (uiLoaded)
28
return;
29
if (!GetChannelInfo())
30
31
32
bool MixerAuth::RetryLogin()
33
{
34
+ if (!cef)
35
+ return false;
36
+
37
OAuthLogin login(OBSBasic::Get(), MIXER_AUTH_URL, false);
38
cef->add_popup_whitelist_url("about:blank", &login);
39
40
41
42
std::shared_ptr<Auth> MixerAuth::Login(QWidget *parent)
43
{
44
+ if (!cef) {
45
+ return nullptr;
46
+ }
47
+
48
OAuthLogin login(parent, MIXER_AUTH_URL, false);
49
cef->add_popup_whitelist_url("about:blank", &login);
50
51
52
}
53
54
std::string error;
55
- if (auth->GetChannelInfo()) {
56
+ if (auth->GetChannelInfo(false)) {
57
return auth;
58
}
59
60
obs-studio-23.0.0.tar.xz/UI/auth-mixer.hpp -> obs-studio-23.0.1.tar.xz/UI/auth-mixer.hpp
Changed
10
1
2
virtual void SaveInternal() override;
3
virtual bool LoadInternal() override;
4
5
- bool GetChannelInfo();
6
+ bool GetChannelInfo(bool allow_retry = true);
7
8
virtual void LoadUI() override;
9
10
obs-studio-23.0.0.tar.xz/UI/auth-oauth.cpp -> obs-studio-23.0.1.tar.xz/UI/auth-oauth.cpp
Changed
28
1
2
: QDialog (parent),
3
get_token (token)
4
{
5
+ if (!cef) {
6
+ return;
7
+ }
8
+
9
setWindowTitle("Auth");
10
setMinimumSize(400, 400);
11
resize(700, 700);
12
13
delete cefWidget;
14
}
15
16
+int OAuthLogin::exec()
17
+{
18
+ if (cefWidget) {
19
+ return QDialog::exec();
20
+ }
21
+
22
+ return QDialog::Rejected;
23
+}
24
+
25
void OAuthLogin::urlChanged(const QString &url)
26
{
27
std::string uri = get_token ? "access_token=" : "code=";
28
obs-studio-23.0.0.tar.xz/UI/auth-oauth.hpp -> obs-studio-23.0.1.tar.xz/UI/auth-oauth.hpp
Changed
10
1
2
inline QString GetCode() const {return code;}
3
inline bool LoadFail() const {return fail;}
4
5
+ virtual int exec() override;
6
+
7
public slots:
8
void urlChanged(const QString &url);
9
};
10
obs-studio-23.0.0.tar.xz/UI/auth-twitch.cpp -> obs-studio-23.0.1.tar.xz/UI/auth-twitch.cpp
Changed
20
1
2
TwitchAuth::TwitchAuth(const Def &d)
3
: OAuthStreamKey(d)
4
{
5
+ if (!cef)
6
+ return;
7
+
8
cef->add_popup_whitelist_url(
9
"https://twitch.tv/popout/frankerfacez/chat?ffz-settings",
10
this);
11
12
13
void TwitchAuth::LoadUI()
14
{
15
+ if (!cef)
16
+ return;
17
if (uiLoaded)
18
return;
19
if (!GetChannelInfo())
20
obs-studio-23.0.0.tar.xz/UI/window-basic-main-outputs.cpp -> obs-studio-23.0.1.tar.xz/UI/window-basic-main-outputs.cpp
Changed
87
1
2
3
extern bool EncoderAvailable(const char *encoder);
4
5
+volatile bool streaming_active = false;
6
+volatile bool recording_active = false;
7
+volatile bool replaybuf_active = false;
8
+
9
static void OBSStreamStarting(void *data, calldata_t *params)
10
{
11
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
12
13
{
14
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
15
output->streamingActive = true;
16
+ os_atomic_set_bool(&streaming_active, true);
17
QMetaObject::invokeMethod(output->main, "StreamingStart");
18
19
UNUSED_PARAMETER(params);
20
21
22
output->streamingActive = false;
23
output->delayActive = false;
24
+ os_atomic_set_bool(&streaming_active, false);
25
QMetaObject::invokeMethod(output->main,
26
"StreamingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error));
27
}
28
29
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
30
31
output->recordingActive = true;
32
+ os_atomic_set_bool(&recording_active, true);
33
QMetaObject::invokeMethod(output->main, "RecordingStart");
34
35
UNUSED_PARAMETER(params);
36
37
int code = (int)calldata_int(params, "code");
38
39
output->recordingActive = false;
40
+ os_atomic_set_bool(&recording_active, false);
41
QMetaObject::invokeMethod(output->main,
42
"RecordingStop", Q_ARG(int, code));
43
44
45
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
46
47
output->replayBufferActive = true;
48
+ os_atomic_set_bool(&replaybuf_active, true);
49
QMetaObject::invokeMethod(output->main, "ReplayBufferStart");
50
51
UNUSED_PARAMETER(params);
52
53
int code = (int)calldata_int(params, "code");
54
55
output->replayBufferActive = false;
56
+ os_atomic_set_bool(&replaybuf_active, false);
57
QMetaObject::invokeMethod(output->main,
58
"ReplayBufferStop", Q_ARG(int, code));
59
60
61
"Rescale");
62
const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
63
"RescaleRes");
64
+ uint32_t caps = obs_encoder_get_caps(h264Streaming);
65
unsigned int cx = 0;
66
unsigned int cy = 0;
67
68
+ if ((caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) {
69
+ rescale = false;
70
+ }
71
+
72
if (rescale && rescaleRes && *rescaleRes) {
73
if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) {
74
cx = 0;
75
76
obs_output_set_video_encoder(replayBuffer,
77
h264Streaming);
78
} else {
79
+ uint32_t caps = obs_encoder_get_caps(h264Recording);
80
+ if ((caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) {
81
+ rescale = false;
82
+ }
83
+
84
if (rescale && rescaleRes && *rescaleRes) {
85
if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) {
86
cx = 0;
87
obs-studio-23.0.0.tar.xz/UI/window-basic-main.cpp -> obs-studio-23.0.1.tar.xz/UI/window-basic-main.cpp
Changed
23
1
2
return;
3
}
4
5
- cef->init_browser();
6
- ExecuteFuncSafeBlock([] {cef->wait_for_browser_init();});
7
-
8
config_set_int(App()->GlobalConfig(), "General",
9
"InfoIncrement", info_increment);
10
11
+ /* Don't show What's New dialog for new users */
12
+#if !defined(OBS_RELEASE_CANDIDATE) || OBS_RELEASE_CANDIDATE == 0
13
+ if (!lastVersion) {
14
+ return;
15
+ }
16
+#endif
17
+ cef->init_browser();
18
+ ExecuteFuncSafeBlock([] {cef->wait_for_browser_init();});
19
+
20
QDialog *dlg = new QDialog(this);
21
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
22
dlg->setWindowTitle("What's New");
23
obs-studio-23.0.0.tar.xz/UI/window-remux.cpp -> obs-studio-23.0.1.tar.xz/UI/window-remux.cpp
Changed
9
1
2
queueModel->finishEntry(success);
3
4
if (autoRemux && autoRemuxFile != "") {
5
- QFile::remove(autoRemuxFile);
6
QTimer::singleShot(3000, this, SLOT(close()));
7
}
8
9
obs-studio-23.0.0.tar.xz/libobs-d3d11/d3d11-subsystem.cpp -> obs-studio-23.0.1.tar.xz/libobs-d3d11/d3d11-subsystem.cpp
Changed
126
1
2
#include <cinttypes>
3
#include <util/base.h>
4
#include <util/platform.h>
5
+#include <util/dstr.h>
6
+#include <util/util.hpp>
7
#include <graphics/matrix3.h>
8
#include "d3d11-subsystem.hpp"
9
10
11
D3D_FEATURE_LEVEL_9_3,
12
};
13
14
+static const char *blacklisted_nv12_geforce_gpus[] = {
15
+ "8100",
16
+ "8200",
17
+ "8300",
18
+ "8400",
19
+ "8500",
20
+ "8600",
21
+ "8800",
22
+ "9300",
23
+ "9400",
24
+ "9500",
25
+ "9600",
26
+ "9800"
27
+};
28
+
29
void gs_device::InitDevice(uint32_t adapterIdx)
30
{
31
wstring adapterName;
32
33
adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description :
34
L"<unknown>";
35
36
- char *adapterNameUTF8;
37
+ BPtr<char> adapterNameUTF8;
38
os_wcs_to_utf8_ptr(adapterName.c_str(), 0, &adapterNameUTF8);
39
blog(LOG_INFO, "Loading up D3D11 on adapter %s (%" PRIu32 ")",
40
- adapterNameUTF8, adapterIdx);
41
- bfree(adapterNameUTF8);
42
+ adapterNameUTF8.Get(), adapterIdx);
43
44
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN,
45
NULL, createFlags, featureLevels,
46
47
if (FAILED(hr))
48
throw UnsupportedHWError("Failed to create device", hr);
49
50
- ComQIPtr<ID3D11Device1> d3d11_1(device);
51
- if (!!d3d11_1) {
52
- D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {};
53
- hr = d3d11_1->CheckFeatureSupport(
54
- D3D11_FEATURE_D3D11_OPTIONS,
55
- &opts, sizeof(opts));
56
- if (SUCCEEDED(hr)) {
57
- nv12Supported = !!opts.ExtendedResourceSharing;
58
+ blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u",
59
+ (unsigned int)levelUsed);
60
+
61
+ /* ---------------------------------------- */
62
+ /* check for nv12 texture output support */
63
+
64
+ nv12Supported = false;
65
+ bool geforce = astrstri(adapterNameUTF8, "geforce") != nullptr;
66
+ bool nvidia = astrstri(adapterNameUTF8, "nvidia") != nullptr;
67
+
68
+ /* don't use on blacklisted adapters */
69
+ if (geforce) {
70
+ for (const char *old_gpu : blacklisted_nv12_geforce_gpus) {
71
+ if (astrstri(adapterNameUTF8, old_gpu) != nullptr) {
72
+ return;
73
+ }
74
}
75
}
76
77
- blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u",
78
- (unsigned int)levelUsed);
79
+ /* Disable NV12 textures if NVENC not available, just as a safety
80
+ * measure */
81
+ if (nvidia) {
82
+ HMODULE nvenc = LoadLibraryW((sizeof(void*) == 8)
83
+ ? L"nvEncodeAPI64.dll"
84
+ : L"nvEncodeAPI.dll");
85
+ if (!nvenc) {
86
+ return;
87
+ }
88
+ }
89
+
90
+ ComQIPtr<ID3D11Device1> d3d11_1(device);
91
+ if (!d3d11_1) {
92
+ return;
93
+ }
94
+
95
+ /* needs to support extended resource sharing */
96
+ D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {};
97
+ hr = d3d11_1->CheckFeatureSupport(
98
+ D3D11_FEATURE_D3D11_OPTIONS,
99
+ &opts, sizeof(opts));
100
+ if (FAILED(hr) || !opts.ExtendedResourceSharing) {
101
+ return;
102
+ }
103
+
104
+ /* needs to support the actual format */
105
+ UINT support = 0;
106
+ hr = device->CheckFormatSupport(
107
+ DXGI_FORMAT_NV12,
108
+ &support);
109
+ if (FAILED(hr)) {
110
+ return;
111
+ }
112
+
113
+ if ((support & D3D11_FORMAT_SUPPORT_TEXTURE2D) == 0) {
114
+ return;
115
+ }
116
+
117
+ /* must be usable as a render target */
118
+ if ((support & D3D11_FORMAT_SUPPORT_RENDER_TARGET) == 0) {
119
+ return;
120
+ }
121
+
122
+ nv12Supported = true;
123
}
124
125
static inline void ConvertStencilSide(D3D11_DEPTH_STENCILOP_DESC &desc,
126
obs-studio-23.0.0.tar.xz/libobs/obs-config.h -> obs-studio-23.0.1.tar.xz/libobs/obs-config.h
Changed
10
1
2
*
3
* Reset to zero each major or minor version
4
*/
5
-#define LIBOBS_API_PATCH_VER 0
6
+#define LIBOBS_API_PATCH_VER 1
7
8
#define MAKE_SEMANTIC_VERSION(major, minor, patch) \
9
((major << 24) | \
10
obs-studio-23.0.0.tar.xz/libobs/obs-encoder.c -> obs-studio-23.0.1.tar.xz/libobs/obs-encoder.c
Changed
11
1
2
struct obs_encoder_info *info = find_encoder(encoder_id);
3
return info ? info->caps : 0;
4
}
5
+
6
+uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder)
7
+{
8
+ return obs_encoder_valid(encoder, "obs_encoder_get_caps")
9
+ ? encoder->orig_info.caps : 0;
10
+}
11
obs-studio-23.0.0.tar.xz/libobs/obs.h -> obs-studio-23.0.1.tar.xz/libobs/obs.h
Changed
9
1
2
EXPORT const char *obs_encoder_get_id(const obs_encoder_t *encoder);
3
4
EXPORT uint32_t obs_get_encoder_caps(const char *encoder_id);
5
+EXPORT uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder);
6
7
#ifndef SWIG
8
/** Duplicates an encoder packet */
9
obs-studio-23.0.0.tar.xz/plugins/obs-browser/panel/browser-panel-internal.hpp -> obs-studio-23.0.1.tar.xz/plugins/obs-browser/panel/browser-panel-internal.hpp
Changed
10
1
2
virtual void setURL(const std::string &url) override;
3
virtual void setStartupScript(const std::string &script) override;
4
5
+ void Resize();
6
+
7
public slots:
8
void Init();
9
};
10
obs-studio-23.0.0.tar.xz/plugins/obs-browser/panel/browser-panel.cpp -> obs-studio-23.0.1.tar.xz/plugins/obs-browser/panel/browser-panel.cpp
Changed
32
1
2
url,
3
cefBrowserSettings,
4
rqc);
5
+#ifdef _WIN32
6
+ Resize();
7
+#endif
8
});
9
10
if (success)
11
12
void QCefWidgetInternal::resizeEvent(QResizeEvent *event)
13
{
14
QWidget::resizeEvent(event);
15
+ Resize();
16
+}
17
18
+void QCefWidgetInternal::Resize()
19
+{
20
QSize size = this->size() * devicePixelRatio();
21
22
QueueCEFTask([this, size] ()
23
24
HWND hwnd = cefBrowser->GetHost()->GetWindowHandle();
25
SetWindowPos(hwnd, nullptr, 0, 0, size.width(), size.height(),
26
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
27
+ SendMessage(hwnd, WM_SIZE, 0,
28
+ MAKELPARAM(size.width(), size.height()));
29
#endif
30
});
31
}
32
obs-studio-23.0.0.tar.xz/plugins/obs-ffmpeg/jim-nvenc.c -> obs-studio-23.0.1.tar.xz/plugins/obs-ffmpeg/jim-nvenc.c
Changed
30
1
2
params->encodeConfig = &enc->config;
3
params->maxEncodeWidth = voi->width;
4
params->maxEncodeHeight = voi->height;
5
- config->rcParams.averageBitRate = bitrate * 1000;
6
- config->rcParams.maxBitRate = vbr ? max_bitrate * 1000 : bitrate * 1000;
7
config->gopLength = gop_size;
8
config->frameIntervalP = 1 + bf;
9
h264_config->idrPeriod = gop_size;
10
11
config->rcParams.constQP.qpIntra = cqp;
12
enc->can_change_bitrate = false;
13
14
+ bitrate = 0;
15
+ max_bitrate = 0;
16
+
17
} else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */
18
h264_config->outputBufferingPeriodSEI = 1;
19
h264_config->outputPictureTimingSEI = 1;
20
21
: NV_ENC_PARAMS_RC_CBR;
22
}
23
24
+ config->rcParams.averageBitRate = bitrate * 1000;
25
+ config->rcParams.maxBitRate = vbr ? max_bitrate * 1000 : bitrate * 1000;
26
+
27
/* -------------------------- */
28
/* profile */
29
30