window-basic-status-bar.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include <QLabel>
  2. #include "obs-app.hpp"
  3. #include "window-basic-main.hpp"
  4. #include "window-basic-status-bar.hpp"
  5. OBSBasicStatusBar::OBSBasicStatusBar(QWidget *parent)
  6. : QStatusBar (parent),
  7. droppedFrames (new QLabel),
  8. sessionTime (new QLabel),
  9. cpuUsage (new QLabel),
  10. kbps (new QLabel)
  11. {
  12. sessionTime->setText(QString("00:00:00"));
  13. cpuUsage->setText(QString("CPU: 0.0%"));
  14. droppedFrames->setAlignment(Qt::AlignRight);
  15. sessionTime->setAlignment(Qt::AlignRight);
  16. cpuUsage->setAlignment(Qt::AlignRight);
  17. kbps->setAlignment(Qt::AlignRight);
  18. droppedFrames->setIndent(20);
  19. sessionTime->setIndent(20);
  20. cpuUsage->setIndent(20);
  21. kbps->setIndent(10);
  22. addPermanentWidget(droppedFrames);
  23. addPermanentWidget(sessionTime);
  24. addPermanentWidget(cpuUsage);
  25. addPermanentWidget(kbps);
  26. }
  27. void OBSBasicStatusBar::IncRef()
  28. {
  29. if (activeRefs++ == 0) {
  30. refreshTimer = new QTimer(this);
  31. connect(refreshTimer, SIGNAL(timeout()),
  32. this, SLOT(UpdateStatusBar()));
  33. totalSeconds = 0;
  34. refreshTimer->start(1000);
  35. }
  36. }
  37. void OBSBasicStatusBar::DecRef()
  38. {
  39. if (--activeRefs == 0) {
  40. delete refreshTimer;
  41. sessionTime->setText(QString("00:00:00"));
  42. droppedFrames->setText("");
  43. kbps->setText("");
  44. }
  45. }
  46. #define BITRATE_UPDATE_SECONDS 2
  47. void OBSBasicStatusBar::UpdateBandwidth()
  48. {
  49. if (!streamOutput)
  50. return;
  51. if (++bitrateUpdateSeconds < BITRATE_UPDATE_SECONDS)
  52. return;
  53. uint64_t bytesSent = obs_output_get_total_bytes(streamOutput);
  54. uint64_t bytesSentTime = os_gettime_ns();
  55. uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
  56. double timePassed = double(bytesSentTime - lastBytesSentTime) /
  57. 1000000000.0;
  58. double kbitsPerSec = double(bitsBetween) / timePassed / 1000.0;
  59. QString text;
  60. text += QString("kb/s: ") +
  61. QString::number(kbitsPerSec, 'f', 0);
  62. kbps->setText(text);
  63. kbps->setMinimumWidth(kbps->width());
  64. lastBytesSent = bytesSent;
  65. lastBytesSentTime = bytesSentTime;
  66. bitrateUpdateSeconds = 0;
  67. }
  68. void OBSBasicStatusBar::UpdateCPUUsage()
  69. {
  70. OBSBasic *main = qobject_cast<OBSBasic*>(parent());
  71. if (!main)
  72. return;
  73. QString text;
  74. text += QString("CPU: ") +
  75. QString::number(main->GetCPUUsage(), 'f', 1) + QString("%");
  76. cpuUsage->setText(text);
  77. cpuUsage->setMinimumWidth(cpuUsage->width());
  78. }
  79. void OBSBasicStatusBar::UpdateSessionTime()
  80. {
  81. totalSeconds++;
  82. int seconds = totalSeconds % 60;
  83. int totalMinutes = totalSeconds / 60;
  84. int minutes = totalMinutes % 60;
  85. int hours = totalMinutes / 60;
  86. QString text;
  87. text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
  88. sessionTime->setText(text);
  89. sessionTime->setMinimumWidth(sessionTime->width());
  90. if (reconnectTimeout > 0) {
  91. QString msg = QTStr("Basic.StatusBar.Reconnecting");
  92. showMessage(msg.arg(QString::number(retries),
  93. QString::number(reconnectTimeout)));
  94. reconnectTimeout--;
  95. } else if (retries > 0) {
  96. QString msg = QTStr("Basic.StatusBar.AttemptingReconnect");
  97. showMessage(msg.arg(QString::number(retries)));
  98. }
  99. }
  100. void OBSBasicStatusBar::UpdateDroppedFrames()
  101. {
  102. if (!streamOutput)
  103. return;
  104. int totalDropped = obs_output_get_frames_dropped(streamOutput);
  105. int totalFrames = obs_output_get_total_frames(streamOutput);
  106. double percent = (double)totalDropped / (double)totalFrames * 100.0;
  107. if (!totalFrames)
  108. return;
  109. QString text = QTStr("DroppedFrames");
  110. text = text.arg(QString::number(totalDropped),
  111. QString::number(percent, 'f', 1));
  112. droppedFrames->setText(text);
  113. droppedFrames->setMinimumWidth(droppedFrames->width());
  114. }
  115. void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t *params)
  116. {
  117. OBSBasicStatusBar *statusBar =
  118. reinterpret_cast<OBSBasicStatusBar*>(data);
  119. int seconds = (int)calldata_int(params, "timeout_sec");
  120. QMetaObject::invokeMethod(statusBar, "Reconnect", Q_ARG(int, seconds));
  121. UNUSED_PARAMETER(params);
  122. }
  123. void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *params)
  124. {
  125. OBSBasicStatusBar *statusBar =
  126. reinterpret_cast<OBSBasicStatusBar*>(data);
  127. QMetaObject::invokeMethod(statusBar, "ReconnectSuccess");
  128. UNUSED_PARAMETER(params);
  129. }
  130. void OBSBasicStatusBar::Reconnect(int seconds)
  131. {
  132. retries++;
  133. reconnectTimeout = seconds;
  134. }
  135. void OBSBasicStatusBar::ReconnectSuccess()
  136. {
  137. showMessage(QTStr("Basic.StatusBar.ReconnectSuccessful"), 4000);
  138. retries = 0;
  139. reconnectTimeout = 0;
  140. bitrateUpdateSeconds = -1;
  141. lastBytesSent = 0;
  142. lastBytesSentTime = os_gettime_ns();
  143. }
  144. void OBSBasicStatusBar::UpdateStatusBar()
  145. {
  146. UpdateBandwidth();
  147. UpdateSessionTime();
  148. UpdateDroppedFrames();
  149. }
  150. void OBSBasicStatusBar::StreamStarted(obs_output_t *output)
  151. {
  152. streamOutput = output;
  153. signal_handler_connect(obs_output_get_signal_handler(streamOutput),
  154. "reconnect", OBSOutputReconnect, this);
  155. signal_handler_connect(obs_output_get_signal_handler(streamOutput),
  156. "reconnect_success", OBSOutputReconnectSuccess, this);
  157. retries = 0;
  158. lastBytesSent = 0;
  159. lastBytesSentTime = os_gettime_ns();
  160. IncRef();
  161. }
  162. void OBSBasicStatusBar::StreamStopped()
  163. {
  164. if (streamOutput) {
  165. signal_handler_disconnect(
  166. obs_output_get_signal_handler(streamOutput),
  167. "reconnect", OBSOutputReconnect, this);
  168. signal_handler_disconnect(
  169. obs_output_get_signal_handler(streamOutput),
  170. "reconnect_success", OBSOutputReconnectSuccess,
  171. this);
  172. streamOutput = nullptr;
  173. clearMessage();
  174. DecRef();
  175. }
  176. }
  177. void OBSBasicStatusBar::RecordingStarted(obs_output_t *output)
  178. {
  179. recordOutput = output;
  180. IncRef();
  181. }
  182. void OBSBasicStatusBar::RecordingStopped()
  183. {
  184. recordOutput = nullptr;
  185. DecRef();
  186. }