window-basic-status-bar.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. }
  91. void OBSBasicStatusBar::UpdateDroppedFrames()
  92. {
  93. if (!streamOutput)
  94. return;
  95. int totalDropped = obs_output_get_frames_dropped(streamOutput);
  96. int totalFrames = obs_output_get_total_frames(streamOutput);
  97. double percent = (double)totalDropped / (double)totalFrames * 100.0;
  98. if (!totalFrames)
  99. return;
  100. QString text = QTStr("DroppedFrames");
  101. text = text.arg(QString::number(totalDropped),
  102. QString::number(percent, 'f', 1));
  103. droppedFrames->setText(text);
  104. droppedFrames->setMinimumWidth(droppedFrames->width());
  105. }
  106. void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t params)
  107. {
  108. OBSBasicStatusBar *statusBar =
  109. reinterpret_cast<OBSBasicStatusBar*>(data);
  110. QMetaObject::invokeMethod(statusBar, "Reconnect");
  111. UNUSED_PARAMETER(params);
  112. }
  113. void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t params)
  114. {
  115. OBSBasicStatusBar *statusBar =
  116. reinterpret_cast<OBSBasicStatusBar*>(data);
  117. QMetaObject::invokeMethod(statusBar, "ReconnectSuccess");
  118. UNUSED_PARAMETER(params);
  119. }
  120. void OBSBasicStatusBar::Reconnect()
  121. {
  122. retries++;
  123. QString reconnectMsg = QTStr("Basic.StatusBar.Reconnecting");
  124. showMessage(reconnectMsg.arg(QString::number(retries)));
  125. }
  126. void OBSBasicStatusBar::ReconnectSuccess()
  127. {
  128. showMessage(QTStr("Basic.StatusBar.ReconnectSuccessful"), 4000);
  129. retries = 0;
  130. bitrateUpdateSeconds = -1;
  131. lastBytesSent = 0;
  132. lastBytesSentTime = os_gettime_ns();
  133. }
  134. void OBSBasicStatusBar::UpdateStatusBar()
  135. {
  136. UpdateBandwidth();
  137. UpdateSessionTime();
  138. UpdateDroppedFrames();
  139. }
  140. void OBSBasicStatusBar::StreamStarted(obs_output_t output)
  141. {
  142. streamOutput = output;
  143. signal_handler_connect(obs_output_get_signal_handler(streamOutput),
  144. "reconnect", OBSOutputReconnect, this);
  145. signal_handler_connect(obs_output_get_signal_handler(streamOutput),
  146. "reconnect_success", OBSOutputReconnectSuccess, this);
  147. retries = 0;
  148. lastBytesSent = 0;
  149. lastBytesSentTime = os_gettime_ns();
  150. IncRef();
  151. }
  152. void OBSBasicStatusBar::StreamStopped()
  153. {
  154. if (streamOutput) {
  155. signal_handler_disconnect(
  156. obs_output_get_signal_handler(streamOutput),
  157. "reconnect", OBSOutputReconnect, this);
  158. signal_handler_disconnect(
  159. obs_output_get_signal_handler(streamOutput),
  160. "reconnect_success", OBSOutputReconnectSuccess,
  161. this);
  162. streamOutput = nullptr;
  163. clearMessage();
  164. DecRef();
  165. }
  166. }
  167. void OBSBasicStatusBar::RecordingStarted(obs_output_t output)
  168. {
  169. recordOutput = output;
  170. IncRef();
  171. }
  172. void OBSBasicStatusBar::RecordingStopped()
  173. {
  174. recordOutput = nullptr;
  175. DecRef();
  176. }