window-basic-auto-config.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #pragma once
  2. #include <QWizard>
  3. #include <QPointer>
  4. #include <QFormLayout>
  5. #include <QWizardPage>
  6. #include <condition_variable>
  7. #include <utility>
  8. #include <thread>
  9. #include <memory>
  10. #include <vector>
  11. #include <string>
  12. #include <mutex>
  13. #include <optional>
  14. class Ui_AutoConfigStartPage;
  15. class Ui_AutoConfigVideoPage;
  16. class Ui_AutoConfigStreamPage;
  17. class Ui_AutoConfigTestPage;
  18. class AutoConfigStreamPage;
  19. class Auth;
  20. class AutoConfig : public QWizard {
  21. Q_OBJECT
  22. friend class AutoConfigStartPage;
  23. friend class AutoConfigVideoPage;
  24. friend class AutoConfigStreamPage;
  25. friend class AutoConfigTestPage;
  26. enum class Type {
  27. Invalid,
  28. Streaming,
  29. Recording,
  30. VirtualCam,
  31. };
  32. enum class Service {
  33. Twitch,
  34. YouTube,
  35. Other,
  36. };
  37. enum class Encoder {
  38. x264,
  39. NVENC,
  40. QSV,
  41. AMD,
  42. Apple,
  43. Stream,
  44. };
  45. enum class Quality {
  46. Stream,
  47. High,
  48. };
  49. enum class FPSType : int {
  50. PreferHighFPS,
  51. PreferHighRes,
  52. UseCurrent,
  53. fps30,
  54. fps60,
  55. };
  56. struct StreamServer {
  57. std::string name;
  58. std::string address;
  59. };
  60. static inline const char *GetEncoderId(Encoder enc);
  61. AutoConfigStreamPage *streamPage = nullptr;
  62. Service service = Service::Other;
  63. Quality recordingQuality = Quality::Stream;
  64. Encoder recordingEncoder = Encoder::Stream;
  65. Encoder streamingEncoder = Encoder::x264;
  66. Type type = Type::Streaming;
  67. FPSType fpsType = FPSType::PreferHighFPS;
  68. int idealBitrate = 2500;
  69. struct {
  70. std::optional<int> targetBitrate;
  71. std::optional<int> bitrate;
  72. bool testSuccessful = false;
  73. } multitrackVideo;
  74. int baseResolutionCX = 1920;
  75. int baseResolutionCY = 1080;
  76. int idealResolutionCX = 1280;
  77. int idealResolutionCY = 720;
  78. int idealFPSNum = 60;
  79. int idealFPSDen = 1;
  80. std::string serviceName;
  81. std::string serverName;
  82. std::string server;
  83. std::vector<StreamServer> serviceConfigServers;
  84. std::string key;
  85. bool hardwareEncodingAvailable = false;
  86. bool nvencAvailable = false;
  87. bool qsvAvailable = false;
  88. bool vceAvailable = false;
  89. bool appleAvailable = false;
  90. int startingBitrate = 2500;
  91. bool customServer = false;
  92. bool bandwidthTest = false;
  93. bool testMultitrackVideo = false;
  94. bool testRegions = true;
  95. bool twitchAuto = false;
  96. bool regionUS = true;
  97. bool regionEU = true;
  98. bool regionAsia = true;
  99. bool regionOther = true;
  100. bool preferHighFPS = false;
  101. bool preferHardware = false;
  102. int specificFPSNum = 0;
  103. int specificFPSDen = 0;
  104. void TestHardwareEncoding();
  105. bool CanTestServer(const char *server);
  106. virtual void done(int result) override;
  107. void SaveStreamSettings();
  108. void SaveSettings();
  109. public:
  110. AutoConfig(QWidget *parent);
  111. ~AutoConfig();
  112. enum Page {
  113. StartPage,
  114. VideoPage,
  115. StreamPage,
  116. TestPage,
  117. };
  118. };
  119. class AutoConfigStartPage : public QWizardPage {
  120. Q_OBJECT
  121. friend class AutoConfig;
  122. std::unique_ptr<Ui_AutoConfigStartPage> ui;
  123. public:
  124. AutoConfigStartPage(QWidget *parent = nullptr);
  125. ~AutoConfigStartPage();
  126. virtual int nextId() const override;
  127. public slots:
  128. void on_prioritizeStreaming_clicked();
  129. void on_prioritizeRecording_clicked();
  130. void PrioritizeVCam();
  131. };
  132. class AutoConfigVideoPage : public QWizardPage {
  133. Q_OBJECT
  134. friend class AutoConfig;
  135. std::unique_ptr<Ui_AutoConfigVideoPage> ui;
  136. public:
  137. AutoConfigVideoPage(QWidget *parent = nullptr);
  138. ~AutoConfigVideoPage();
  139. virtual int nextId() const override;
  140. virtual bool validatePage() override;
  141. };
  142. class AutoConfigStreamPage : public QWizardPage {
  143. Q_OBJECT
  144. friend class AutoConfig;
  145. enum class Section : int {
  146. Connect,
  147. StreamKey,
  148. };
  149. std::shared_ptr<Auth> auth;
  150. std::unique_ptr<Ui_AutoConfigStreamPage> ui;
  151. QString lastService;
  152. bool ready = false;
  153. void LoadServices(bool showAll);
  154. inline bool IsCustomService() const;
  155. public:
  156. AutoConfigStreamPage(QWidget *parent = nullptr);
  157. ~AutoConfigStreamPage();
  158. virtual bool isComplete() const override;
  159. virtual int nextId() const override;
  160. virtual bool validatePage() override;
  161. void OnAuthConnected();
  162. void OnOAuthStreamKeyConnected();
  163. public slots:
  164. void on_show_clicked();
  165. void on_connectAccount_clicked();
  166. void on_disconnectAccount_clicked();
  167. void on_useStreamKey_clicked();
  168. void on_preferHardware_clicked();
  169. void ServiceChanged();
  170. void UpdateKeyLink();
  171. void UpdateMoreInfoLink();
  172. void UpdateServerList();
  173. void UpdateCompleted();
  174. void reset_service_ui_fields(std::string &service);
  175. };
  176. class AutoConfigTestPage : public QWizardPage {
  177. Q_OBJECT
  178. friend class AutoConfig;
  179. QPointer<QFormLayout> results;
  180. std::unique_ptr<Ui_AutoConfigTestPage> ui;
  181. std::thread testThread;
  182. std::condition_variable cv;
  183. std::mutex m;
  184. bool cancel = false;
  185. bool started = false;
  186. enum class Stage {
  187. Starting,
  188. BandwidthTest,
  189. StreamEncoder,
  190. RecordingEncoder,
  191. Finished,
  192. };
  193. Stage stage = Stage::Starting;
  194. bool softwareTested = false;
  195. void StartBandwidthStage();
  196. void StartStreamEncoderStage();
  197. void StartRecordingEncoderStage();
  198. void FindIdealHardwareResolution();
  199. bool TestSoftwareEncoding();
  200. void TestBandwidthThread();
  201. void TestStreamEncoderThread();
  202. void TestRecordingEncoderThread();
  203. void FinalizeResults();
  204. struct ServerInfo {
  205. std::string name;
  206. std::string address;
  207. int bitrate = 0;
  208. int ms = -1;
  209. inline ServerInfo() {}
  210. inline ServerInfo(const char *name_, const char *address_)
  211. : name(name_),
  212. address(address_)
  213. {
  214. }
  215. };
  216. void GetServers(std::vector<ServerInfo> &servers);
  217. public:
  218. AutoConfigTestPage(QWidget *parent = nullptr);
  219. ~AutoConfigTestPage();
  220. virtual void initializePage() override;
  221. virtual void cleanupPage() override;
  222. virtual bool isComplete() const override;
  223. virtual int nextId() const override;
  224. public slots:
  225. void NextStage();
  226. void UpdateMessage(QString message);
  227. void Failure(QString message);
  228. void Progress(int percentage);
  229. };