window-basic-main.hpp 16.2 KB
Newer Older
1
/******************************************************************************
2
    Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
3 4 5

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation, either version 2 of the License, or
7 8 9 10 11 12 13 14 15 16 17 18 19
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#pragma once

J
jp9000 已提交
20
#include <QBuffer>
J
jp9000 已提交
21
#include <QAction>
C
cg2121 已提交
22
#include <QSystemTrayIcon>
J
jp9000 已提交
23
#include <obs.hpp>
24
#include <vector>
J
jp9000 已提交
25
#include <memory>
26
#include "window-main.hpp"
J
John Bradley 已提交
27
#include "window-basic-interaction.hpp"
28
#include "window-basic-properties.hpp"
J
jp9000 已提交
29
#include "window-basic-transform.hpp"
J
jp9000 已提交
30
#include "window-basic-adv-audio.hpp"
J
jp9000 已提交
31
#include "window-basic-filters.hpp"
J
jp9000 已提交
32

J
jp9000 已提交
33 34
#include <obs-frontend-internal.hpp>

35
#include <util/platform.h>
36
#include <util/threading.h>
37 38
#include <util/util.hpp>

39 40
#include <QPointer>

J
jp9000 已提交
41
class QListWidgetItem;
42
class VolControl;
J
jp9000 已提交
43
class QNetworkReply;
J
jp9000 已提交
44

B
BtbN 已提交
45
#include "ui_OBSBasic.h"
J
jp9000 已提交
46

47 48 49 50 51 52
#define DESKTOP_AUDIO_1 Str("DesktopAudioDevice1")
#define DESKTOP_AUDIO_2 Str("DesktopAudioDevice2")
#define AUX_AUDIO_1     Str("AuxAudioDevice1")
#define AUX_AUDIO_2     Str("AuxAudioDevice2")
#define AUX_AUDIO_3     Str("AuxAudioDevice3")

53 54
#define SIMPLE_ENCODER_X264                    "x264"
#define SIMPLE_ENCODER_X264_LOWCPU             "x264_lowcpu"
55
#define SIMPLE_ENCODER_QSV                     "qsv"
J
jp9000 已提交
56
#define SIMPLE_ENCODER_NVENC                   "nvenc"
57

58 59
#define PREVIEW_EDGE_SIZE 10

J
jp9000 已提交
60 61
struct BasicOutputHandler;

P
Palana 已提交
62 63 64 65 66
enum class QtDataRole {
	OBSRef = Qt::UserRole,
	OBSSignals,
};

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
struct QuickTransition {
	QPushButton *button = nullptr;
	OBSSource source;
	obs_hotkey_id hotkey = 0;
	int duration = 0;
	int id = 0;

	inline QuickTransition() {}
	inline QuickTransition(OBSSource source_, int duration_, int id_)
		: source   (source_),
		  duration (duration_),
		  id       (id_)
	{}
};

82
class OBSBasic : public OBSMainWindow {
J
jp9000 已提交
83 84
	Q_OBJECT

J
jp9000 已提交
85
	friend class OBSBasicPreview;
J
jp9000 已提交
86
	friend class OBSBasicStatusBar;
J
jp9000 已提交
87
	friend class OBSBasicSourceSelect;
J
jp9000 已提交
88
	friend struct OBSStudioAPI;
J
jp9000 已提交
89

90 91 92 93 94 95 96
	enum class MoveDir {
		Up,
		Down,
		Left,
		Right
	};

J
jp9000 已提交
97
private:
J
jp9000 已提交
98 99
	obs_frontend_callbacks *api = nullptr;

100 101
	std::vector<VolControl*> volumes;

P
Palana 已提交
102 103
	std::vector<OBSSignal> signalHandlers;

104
	bool loaded = false;
J
jp9000 已提交
105
	long disableSaving = 1;
J
jp9000 已提交
106
	bool projectChanged = false;
107
	bool previewEnabled = true;
108

109 110 111
	QPointer<QThread> updateCheckThread;
	QPointer<QThread> logUploadThread;

J
John Bradley 已提交
112
	QPointer<OBSBasicInteraction> interaction;
113
	QPointer<OBSBasicProperties> properties;
J
jp9000 已提交
114
	QPointer<OBSBasicTransform> transformWindow;
J
jp9000 已提交
115
	QPointer<OBSBasicAdvAudio> advAudioWindow;
J
jp9000 已提交
116
	QPointer<OBSBasicFilters> filters;
117

J
jp9000 已提交
118
	QPointer<QTimer>    cpuUsageTimer;
119
	os_cpu_usage_info_t *cpuUsageInfo = nullptr;
120

121
	OBSService service;
J
jp9000 已提交
122
	std::unique_ptr<BasicOutputHandler> outputHandler;
123 124
	bool streamingStopping = false;
	bool recordingStopping = false;
J
jp9000 已提交
125

126
	gs_vertbuffer_t *box = nullptr;
127 128 129 130
	gs_vertbuffer_t *boxLeft = nullptr;
	gs_vertbuffer_t *boxTop = nullptr;
	gs_vertbuffer_t *boxRight = nullptr;
	gs_vertbuffer_t *boxBottom = nullptr;
131
	gs_vertbuffer_t *circle = nullptr;
J
jp9000 已提交
132

J
jp9000 已提交
133
	bool          sceneChanging = false;
134
	bool          ignoreSelectionUpdate = false;
135

J
jp9000 已提交
136 137 138
	int           previewX = 0,  previewY = 0;
	int           previewCX = 0, previewCY = 0;
	float         previewScale = 0.0f;
J
jp9000 已提交
139

140
	ConfigFile    basicConfig;
141

J
jp9000 已提交
142 143
	QPointer<QWidget> projectors[10];

J
jp9000 已提交
144 145
	QPointer<QMenu> startStreamMenu;

C
cg2121 已提交
146 147 148 149 150 151 152
	QSystemTrayIcon *trayIcon;
	QMenu         *trayMenu;
	QAction       *sysTrayStream;
	QAction       *sysTrayRecord;
	QAction       *showHide;
	QAction       *showPreview;
	QAction       *exit;
J
jp9000 已提交
153
	bool          disableHiding = false;
C
cg2121 已提交
154

155 156
	void          DrawBackdrop(float cx, float cy);

157 158
	void          SetupEncoders();

159
	void          CreateFirstRunSources();
160
	void          CreateDefaultScene(bool firstStart);
161 162

	void          ClearVolumeControls();
163

J
jp9000 已提交
164 165
	void          UploadLog(const char *file);

166 167 168
	void          Save(const char *file);
	void          Load(const char *file);

P
Palana 已提交
169
	void          InitHotkeys();
170
	void          CreateHotkeys();
J
jp9000 已提交
171
	void          ClearHotkeys();
P
Palana 已提交
172

173 174 175 176 177
	bool          InitService();

	bool          InitBasicConfigDefaults();
	bool          InitBasicConfig();

178 179
	void          InitOBSCallbacks();

J
jp9000 已提交
180 181
	void          InitPrimitives();

182
	OBSSceneItem  GetSceneItem(QListWidgetItem *item);
183 184
	OBSSceneItem  GetCurrentSceneItem();

185
	bool          QueryRemoveSource(obs_source_t *source);
186

J
jp9000 已提交
187 188 189
	void          TimedCheckForUpdates();
	void          CheckForUpdates();

190 191 192 193 194 195
	void GetFPSCommon(uint32_t &num, uint32_t &den) const;
	void GetFPSInteger(uint32_t &num, uint32_t &den) const;
	void GetFPSFraction(uint32_t &num, uint32_t &den) const;
	void GetFPSNanoseconds(uint32_t &num, uint32_t &den) const;
	void GetConfigFPS(uint32_t &num, uint32_t &den) const;

196
	void UpdateSources(OBSScene scene);
197
	void InsertSceneItem(obs_sceneitem_t *item);
198

J
jp9000 已提交
199 200 201 202
	void LoadSceneListOrder(obs_data_array_t *array);
	obs_data_array_t *SaveSceneListOrder();
	void ChangeSceneIndex(bool relative, int idx, int invalidIdx);

J
jp9000 已提交
203 204 205 206
	void TempFileOutput(const char *path, int vBitrate, int aBitrate);
	void TempStreamOutput(const char *url, const char *key,
			int vBitrate, int aBitrate);

207 208
	void CreateInteractionWindow(obs_source_t *source);
	void CreatePropertiesWindow(obs_source_t *source);
J
jp9000 已提交
209
	void CreateFiltersWindow(obs_source_t *source);
210

211 212 213
	void CloseDialogs();
	void ClearSceneData();

214
	void Nudge(int dist, MoveDir dir);
J
jp9000 已提交
215
	void OpenProjector(obs_source_t *source, int monitor);
216

217 218 219 220
	void GetAudioSourceFilters();
	void GetAudioSourceProperties();
	void VolControlContextMenu();

J
jp9000 已提交
221 222 223
	void AddSceneCollection(bool create_new);
	void RefreshSceneCollections();
	void ChangeSceneCollection();
224
	void LogScenes();
J
jp9000 已提交
225

J
jp9000 已提交
226 227 228 229 230 231 232 233
	void LoadProfile();
	void ResetProfileData();
	bool AddProfile(bool create_new, const char *title, const char *text,
			const char *init_text = nullptr);
	void DeleteProfile(const char *profile_name, const char *profile_dir);
	void RefreshProfiles();
	void ChangeProfile();

J
jp9000 已提交
234 235
	void SaveProjectNow();

236 237
	QListWidgetItem *GetTopSelectedSourceItem();

238
	obs_hotkey_pair_id streamingHotkeys, recordingHotkeys;
J
jp9000 已提交
239
	obs_hotkey_id forceStreamingStopHotkey;
240

241 242 243 244
	void InitDefaultTransitions();
	void InitTransition(obs_source_t *transition);
	obs_source_t *FindTransition(const char *name);
	OBSSource GetCurrentTransition();
J
jp9000 已提交
245 246
	obs_data_array_t *SaveTransitions();
	void LoadTransitions(obs_data_array_t *transitions);
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297

	obs_source_t *fadeTransition;

	void CreateProgramDisplay();
	void CreateProgramOptions();
	void AddQuickTransitionId(int id);
	void AddQuickTransition();
	void AddQuickTransitionHotkey(QuickTransition *qt);
	void RemoveQuickTransitionHotkey(QuickTransition *qt);
	void LoadQuickTransitions(obs_data_array_t *array);
	obs_data_array_t *SaveQuickTransitions();
	void RefreshQuickTransitions();
	void CreateDefaultQuickTransitions();

	QuickTransition *GetQuickTransition(int id);
	int GetQuickTransitionIdx(int id);
	QMenu *CreateTransitionMenu(QWidget *parent, QuickTransition *qt);
	void ClearQuickTransitions();
	void QuickTransitionClicked();
	void QuickTransitionChange();
	void QuickTransitionChangeDuration(int value);
	void QuickTransitionRemoveClicked();

	void SetPreviewProgramMode(bool enabled);
	void ResizeProgram(uint32_t cx, uint32_t cy);
	void SetCurrentScene(obs_scene_t *scene, bool force = false);
	static void RenderProgram(void *data, uint32_t cx, uint32_t cy);

	std::vector<QuickTransition> quickTransitions;
	QPointer<QWidget> programOptions;
	QPointer<OBSQTDisplay> program;
	OBSWeakSource lastScene;
	OBSWeakSource swapScene;
	OBSWeakSource programScene;
	bool editPropertiesMode = false;
	bool sceneDuplicationMode = true;
	bool swapScenesMode = true;
	volatile bool previewProgramMode = false;
	obs_hotkey_id togglePreviewProgramHotkey = 0;
	obs_hotkey_id transitionHotkey = 0;
	int quickTransitionIdCounter = 1;

	int   programX = 0,  programY = 0;
	int   programCX = 0, programCY = 0;
	float programScale = 0.0f;

	inline bool IsPreviewProgramMode() const
	{
		return os_atomic_load_bool(&previewProgramMode);
	}

298 299 300
	inline void OnActivate();
	inline void OnDeactivate();

301
public slots:
302 303
	void StartStreaming();
	void StopStreaming();
J
jp9000 已提交
304 305 306 307
	void ForceStopStreaming();

	void StreamDelayStarting(int sec);
	void StreamDelayStopping(int sec);
308

309
	void StreamingStart();
310
	void StreamStopping();
311
	void StreamingStop(int errorcode);
312

313 314 315
	void StartRecording();
	void StopRecording();

P
Palana 已提交
316
	void RecordingStart();
317
	void RecordStopping();
318
	void RecordingStop(int code);
319

J
jp9000 已提交
320
	void SaveProjectDeferred();
J
jp9000 已提交
321 322
	void SaveProject();

323 324 325 326 327
	void SetTransition(OBSSource transition);
	void TransitionToScene(OBSScene scene, bool force = false);
	void TransitionToScene(OBSSource scene, bool force = false);
	void SetCurrentScene(OBSSource scene, bool force = false);

328 329 330 331 332
private slots:
	void AddSceneItem(OBSSceneItem item);
	void RemoveSceneItem(OBSSceneItem item);
	void AddScene(OBSSource source);
	void RemoveScene(OBSSource source);
J
jp9000 已提交
333
	void RenameSources(QString newName, QString prevName);
334

335
	void SelectSceneItem(OBSScene scene, OBSSceneItem item, bool select);
J
jp9000 已提交
336

337 338 339
	void ActivateAudioSource(OBSSource source);
	void DeactivateAudioSource(OBSSource source);

340
	void DuplicateSelectedScene();
341 342
	void RemoveSelectedScene();
	void RemoveSelectedSceneItem();
J
jp9000 已提交
343

344 345
	void ToggleAlwaysOnTop();

346 347
	void ReorderSources(OBSScene scene);

P
Palana 已提交
348 349
	void ProcessHotkey(obs_hotkey_id id, bool pressed);

J
jp9000 已提交
350 351
	void AddTransition();
	void RenameTransition();
352 353 354 355
	void TransitionClicked();
	void TransitionStopped();
	void TriggerQuickTransition(int id);

J
jp9000 已提交
356 357 358
	void SetDeinterlacingMode();
	void SetDeinterlacingOrder();

359 360
	void SetScaleFilter();

C
cg2121 已提交
361 362 363 364 365
	void IconActivated(QSystemTrayIcon::ActivationReason reason);
	void SetShowing(bool showing);

	inline void ToggleShowHide()
	{
J
jp9000 已提交
366 367 368
		bool showing = isVisible();
		if (disableHiding && showing)
			return;
369 370
		if (showing)
			CloseDialogs();
J
jp9000 已提交
371
		SetShowing(!showing);
C
cg2121 已提交
372 373
	}

374
private:
375
	/* OBS Callbacks */
376
	static void SceneReordered(void *data, calldata_t *params);
377 378
	static void SceneItemAdded(void *data, calldata_t *params);
	static void SceneItemRemoved(void *data, calldata_t *params);
379 380
	static void SceneItemSelected(void *data, calldata_t *params);
	static void SceneItemDeselected(void *data, calldata_t *params);
381
	static void SourceLoaded(void *data, obs_source_t *source);
382 383 384 385
	static void SourceRemoved(void *data, calldata_t *params);
	static void SourceActivated(void *data, calldata_t *params);
	static void SourceDeactivated(void *data, calldata_t *params);
	static void SourceRenamed(void *data, calldata_t *params);
386
	static void RenderMain(void *data, uint32_t cx, uint32_t cy);
387

J
jp9000 已提交
388 389
	void ResizePreview(uint32_t cx, uint32_t cy);

J
jp9000 已提交
390
	void AddSource(const char *id);
391
	QMenu *CreateAddSourcePopupMenu();
J
jp9000 已提交
392
	void AddSourcePopupMenu(const QPoint &pos);
S
Socapex 已提交
393
	void copyActionsDynamicProperties();
394

P
Palana 已提交
395 396
	static void HotkeyTriggered(void *data, obs_hotkey_id id, bool pressed);

397
public:
J
jp9000 已提交
398 399
	OBSScene      GetCurrentScene();

C
cg2121 已提交
400 401
	void SysTrayNotify(const QString &text, QSystemTrayIcon::MessageIcon n);

402 403 404 405 406 407
	inline OBSSource GetCurrentSceneSource()
	{
		OBSScene curScene = GetCurrentScene();
		return OBSSource(obs_scene_get_source(curScene));
	}

408 409
	obs_service_t *GetService();
	void          SetService(obs_service_t *service);
410

411 412
	bool StreamingActive() const;
	bool Active() const;
413

414
	int  ResetVideo();
415
	bool ResetAudio();
J
jp9000 已提交
416 417

	void ResetOutputs();
J
jp9000 已提交
418

419
	void ResetAudioDevice(const char *sourceId, const char *deviceId,
420
			const char *deviceDesc, int channel);
J
jp9000 已提交
421

422 423 424
	void NewProject();
	void LoadProject();

J
jp9000 已提交
425 426 427 428 429 430 431 432
	inline void GetDisplayRect(int &x, int &y, int &cx, int &cy)
	{
		x  = previewX;
		y  = previewY;
		cx = previewCX;
		cy = previewCY;
	}

433 434 435 436 437
	inline double GetCPUUsage() const
	{
		return os_cpu_usage_info_query(cpuUsageInfo);
	}

438 439 440
	void SaveService();
	bool LoadService();

441 442
	void ReorderSceneItem(obs_sceneitem_t *item, size_t idx);

J
jp9000 已提交
443
	QMenu *AddDeinterlacingMenu(obs_source_t *source);
444
	QMenu *AddScaleFilteringMenu(obs_sceneitem_t *item);
J
jp9000 已提交
445 446
	void CreateSourcePopupMenu(QListWidgetItem *item, bool preview);

447
	void UpdateTitleBar();
448
	void UpdateSceneSelection(OBSSource source);
449

C
cg2121 已提交
450 451 452
	void SystemTrayInit();
	void SystemTray(bool firstStarted);

453
protected:
454 455
	virtual void closeEvent(QCloseEvent *event) override;
	virtual void changeEvent(QEvent *event) override;
J
jp9000 已提交
456 457

private slots:
458
	void on_actionShow_Recordings_triggered();
P
Palana 已提交
459
	void on_actionRemux_triggered();
P
Palana 已提交
460
	void on_action_Settings_triggered();
J
jp9000 已提交
461
	void on_actionAdvAudioProperties_triggered();
462
	void on_advAudioProps_clicked();
463
	void on_advAudioProps_destroyed();
P
Palana 已提交
464
	void on_actionShowLogs_triggered();
J
jp9000 已提交
465 466
	void on_actionUploadCurrentLog_triggered();
	void on_actionUploadLastLog_triggered();
467
	void on_actionViewCurrentLog_triggered();
J
jp9000 已提交
468
	void on_actionCheckForUpdates_triggered();
J
jp9000 已提交
469 470 471 472 473 474 475 476 477 478 479

	void on_actionEditTransform_triggered();
	void on_actionRotate90CW_triggered();
	void on_actionRotate90CCW_triggered();
	void on_actionRotate180_triggered();
	void on_actionFlipHorizontal_triggered();
	void on_actionFlipVertical_triggered();
	void on_actionFitToScreen_triggered();
	void on_actionStretchToScreen_triggered();
	void on_actionCenterToScreen_triggered();

480 481
	void on_scenes_currentItemChanged(QListWidgetItem *current,
			QListWidgetItem *prev);
J
jp9000 已提交
482 483 484 485 486
	void on_scenes_customContextMenuRequested(const QPoint &pos);
	void on_actionAddScene_triggered();
	void on_actionRemoveScene_triggered();
	void on_actionSceneUp_triggered();
	void on_actionSceneDown_triggered();
J
jp9000 已提交
487
	void on_sources_itemSelectionChanged();
J
jp9000 已提交
488
	void on_sources_customContextMenuRequested(const QPoint &pos);
P
Palana 已提交
489
	void on_sources_itemDoubleClicked(QListWidgetItem *item);
J
jp9000 已提交
490 491
	void on_actionAddSource_triggered();
	void on_actionRemoveSource_triggered();
J
John Bradley 已提交
492
	void on_actionInteract_triggered();
J
jp9000 已提交
493 494 495
	void on_actionSourceProperties_triggered();
	void on_actionSourceUp_triggered();
	void on_actionSourceDown_triggered();
J
jp9000 已提交
496

J
jp9000 已提交
497 498 499 500 501
	void on_actionMoveUp_triggered();
	void on_actionMoveDown_triggered();
	void on_actionMoveToTop_triggered();
	void on_actionMoveToBottom_triggered();

J
jp9000 已提交
502 503
	void on_actionLockPreview_triggered();

504
	void on_streamButton_clicked();
505
	void on_recordButton_clicked();
J
jp9000 已提交
506
	void on_settingsButton_clicked();
507

508 509
	void on_actionWebsite_triggered();

J
jp9000 已提交
510 511 512 513
	void on_preview_customContextMenuRequested(const QPoint &pos);
	void on_previewDisabledLabel_customContextMenuRequested(
			const QPoint &pos);

J
jp9000 已提交
514 515 516 517 518
	void on_actionNewSceneCollection_triggered();
	void on_actionDupSceneCollection_triggered();
	void on_actionRenameSceneCollection_triggered();
	void on_actionRemoveSceneCollection_triggered();

J
jp9000 已提交
519 520 521 522 523
	void on_actionNewProfile_triggered();
	void on_actionDupProfile_triggered();
	void on_actionRenameProfile_triggered();
	void on_actionRemoveProfile_triggered();

524 525 526
	void on_actionShowSettingsFolder_triggered();
	void on_actionShowProfileFolder_triggered();

527 528
	void on_actionAlwaysOnTop_triggered();

529 530 531 532
	void on_toggleSceneTransitions_toggled(bool visible);
	void on_toggleListboxToolbars_toggled(bool visible);
	void on_toggleStatusBar_toggled(bool visible);

533
	void on_transitions_currentIndexChanged(int index);
J
jp9000 已提交
534 535
	void on_transitionAdd_clicked();
	void on_transitionRemove_clicked();
536 537 538 539
	void on_transitionProps_clicked();

	void on_modeSwitch_clicked();

540
	void logUploadFinished(const QString &text, const QString &error);
J
jp9000 已提交
541

542
	void updateFileFinished(const QString &text, const QString &error);
J
jp9000 已提交
543

J
jp9000 已提交
544 545
	void AddSourceFromAction();

J
jp9000 已提交
546 547 548
	void MoveSceneToTop();
	void MoveSceneToBottom();

J
jp9000 已提交
549 550 551
	void EditSceneName();
	void EditSceneItemName();

J
jp9000 已提交
552 553 554 555 556
	void SceneNameEdited(QWidget *editor,
			QAbstractItemDelegate::EndEditHint endHint);
	void SceneItemNameEdited(QWidget *editor,
			QAbstractItemDelegate::EndEditHint endHint);

J
jp9000 已提交
557
	void OpenSceneFilters();
J
jp9000 已提交
558 559
	void OpenFilters();

560
	void EnablePreviewDisplay(bool enable);
J
jp9000 已提交
561 562
	void TogglePreview();

563 564 565 566 567
	void NudgeUp();
	void NudgeDown();
	void NudgeLeft();
	void NudgeRight();

J
jp9000 已提交
568 569 570 571
	void OpenPreviewProjector();
	void OpenSourceProjector();
	void OpenSceneProjector();

572 573 574
public slots:
	void on_actionResetTransform_triggered();

575
public:
J
jp9000 已提交
576
	explicit OBSBasic(QWidget *parent = 0);
J
jp9000 已提交
577
	virtual ~OBSBasic();
J
jp9000 已提交
578

579 580
	virtual void OBSInit() override;

581
	virtual config_t *Config() const override;
582

J
jp9000 已提交
583
	virtual int GetProfilePath(char *path, size_t size, const char *file)
P
Palana 已提交
584
		const override;
J
jp9000 已提交
585

J
jp9000 已提交
586 587
private:
	std::unique_ptr<Ui::OBSBasic> ui;
588
};