]> git.sesse.net Git - nageru/blobdiff - futatabi/mainwindow.cpp
Make the SDL dependencies optional.
[nageru] / futatabi / mainwindow.cpp
index 68b29e4be57127b97b3bd058f335ebbfecdf9d11..38a50df371886d4045a31993e5fa93ae19699061 100644 (file)
@@ -15,6 +15,7 @@
 #include <QFileDialog>
 #include <QMessageBox>
 #include <QMouseEvent>
+#include <QNetworkReply>
 #include <QShortcut>
 #include <QTimer>
 #include <QWheelEvent>
@@ -179,10 +180,32 @@ MainWindow::MainWindow()
        connect(ui->clip_list->selectionModel(), &QItemSelectionModel::currentChanged,
                this, &MainWindow::clip_list_selection_changed);
 
-       // Make the display rows.
-       unsigned display_rows = (NUM_CAMERAS + 1) / 2;
+       // Find out how many cameras we have in the existing frames;
+       // if none, we start with two cameras.
+       num_cameras = 2;
+       {
+               lock_guard<mutex> lock(frame_mu);
+               for (size_t stream_idx = 2; stream_idx < MAX_STREAMS; ++stream_idx) {
+                       if (!frames[stream_idx].empty()) {
+                               num_cameras = stream_idx + 1;
+                       }
+               }
+       }
+       change_num_cameras();
+
+       if (!global_flags.tally_url.empty()) {
+               start_tally();
+       }
+}
+
+void MainWindow::change_num_cameras()
+{
+       assert(num_cameras >= displays.size());  // We only add, never remove.
+
+       // Make new display rows.
+       unsigned display_rows = (num_cameras + 1) / 2;
        ui->video_displays->setStretch(1, display_rows);
-       for (unsigned i = 0; i < NUM_CAMERAS; ++i) {
+       for (unsigned i = displays.size(); i < num_cameras; ++i) {
                QFrame *frame = new QFrame(this);
                frame->setAutoFillBackground(true);
 
@@ -210,6 +233,11 @@ MainWindow::MainWindow()
 
                connect(preview_btn, &QPushButton::clicked, [this, i]{ preview_angle_clicked(i); });
        }
+
+       cliplist_clips->change_num_cameras(num_cameras);
+       playlist_clips->change_num_cameras(num_cameras);
+
+       QMetaObject::invokeMethod(this, "relayout", Qt::QueuedConnection);
 }
 
 MainWindow::~MainWindow()
@@ -258,7 +286,7 @@ void MainWindow::queue_clicked()
 
        QModelIndex index = selected->currentIndex();
        Clip clip = *cliplist_clips->clip(index.row());
-       if (ClipList::is_camera_column(index.column())) {
+       if (cliplist_clips->is_camera_column(index.column())) {
                clip.stream_idx = index.column() - int(ClipList::Column::CAMERA_1);
        } else {
                clip.stream_idx = ui->preview_display->get_stream_idx();
@@ -300,7 +328,7 @@ void MainWindow::preview_clicked()
 
        QModelIndex index = selected->currentIndex();
        unsigned stream_idx;
-       if (ClipList::is_camera_column(index.column())) {
+       if (cliplist_clips->is_camera_column(index.column())) {
                stream_idx = index.column() - int(ClipList::Column::CAMERA_1);
        } else {
                stream_idx = ui->preview_display->get_stream_idx();
@@ -734,7 +762,7 @@ bool MainWindow::eventFilter(QObject *watched, QEvent *event)
 
                                int stream_idx = clip->stream_idx + angle_degrees / camera_degrees_per_pixel;
                                stream_idx = std::max(stream_idx, 0);
-                               stream_idx = std::min(stream_idx, NUM_CAMERAS - 1);
+                               stream_idx = std::min<int>(stream_idx, num_cameras - 1);
                                clip->stream_idx = stream_idx;
 
                                last_mousewheel_camera_row = row;
@@ -805,7 +833,7 @@ void MainWindow::playlist_selection_changed()
 void MainWindow::clip_list_selection_changed(const QModelIndex &current, const QModelIndex &)
 {
        int camera_selected = -1;
-       if (ClipList::is_camera_column(current.column())) {
+       if (cliplist_clips->is_camera_column(current.column())) {
                camera_selected = current.column() - int(ClipList::Column::CAMERA_1);
        }
        highlight_camera_input(camera_selected);
@@ -983,8 +1011,8 @@ void MainWindow::quality_toggled(int quality, bool checked)
 
 void MainWindow::highlight_camera_input(int stream_idx)
 {
-       for (unsigned i = 0; i < NUM_CAMERAS; ++i) {
-               if (stream_idx == i) {
+       for (unsigned i = 0; i < num_cameras; ++i) {
+               if (unsigned(stream_idx) == i) {
                        displays[i].frame->setStyleSheet("background: rgb(0,255,0)");
                } else {
                        displays[i].frame->setStyleSheet("");
@@ -1007,9 +1035,17 @@ pair<string, string> MainWindow::get_queue_status() const {
 
 void MainWindow::display_frame(unsigned stream_idx, const FrameOnDisk &frame)
 {
-       if (stream_idx < NUM_CAMERAS) {
-               displays[stream_idx].display->setFrame(stream_idx, frame);
+       if (stream_idx >= MAX_STREAMS) {
+               fprintf(stderr, "WARNING: Ignoring too-high stream index %u.\n", stream_idx);
+               return;
+       }
+       if (stream_idx >= num_cameras) {
+               post_to_main_thread_and_wait([this, stream_idx]{
+                       num_cameras = stream_idx + 1;
+                       change_num_cameras();
+               });
        }
+       displays[stream_idx].display->setFrame(stream_idx, frame);
 }
 
 template <class Model>
@@ -1022,3 +1058,28 @@ void MainWindow::replace_model(QTableView *view, Model **model, Model *new_model
        *model = new_model;
        connect(new_model, &Model::any_content_changed, this, &MainWindow::content_changed);
 }
+
+void MainWindow::start_tally()
+{
+       http_reply = http.get(QNetworkRequest(QString::fromStdString(global_flags.tally_url)));
+       connect(http_reply, &QNetworkReply::finished, this, &MainWindow::tally_received);
+}
+
+void MainWindow::tally_received()
+{
+       unsigned time_to_next_tally_ms;
+       if (http_reply->error()) {
+               fprintf(stderr, "HTTP get of '%s' failed: %s\n", global_flags.tally_url.c_str(),
+                       http_reply->errorString().toStdString().c_str());
+               ui->live_frame->setStyleSheet("");
+               time_to_next_tally_ms = 1000;
+       } else {
+               string contents = http_reply->readAll().toStdString();
+               ui->live_frame->setStyleSheet(QString::fromStdString("background: " + contents));
+               time_to_next_tally_ms = 100;
+       }
+       http_reply->deleteLater();
+       http_reply = nullptr;
+
+       QTimer::singleShot(time_to_next_tally_ms, this, &MainWindow::start_tally);
+}