From 83f00b3618fa1cb4527b59f6e2d2f8d3f52cc25a Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 18 Jun 2018 00:41:06 +0200 Subject: [PATCH] =?utf8?q?Make=20it=20possible=20to=20switch=20camera=20an?= =?utf8?q?gles=20for=20previews=20with=20the=201=E2=80=934=20keys.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- mainwindow.cpp | 31 +++++++++++++++++ mainwindow.h | 1 + player.cpp | 59 ++++++++++++++++++++++++++++++-- player.h | 5 ++- ui_mainwindow.ui | 87 +++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 171 insertions(+), 12 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 579dbb1..67f5862 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -58,6 +58,22 @@ MainWindow::MainWindow() connect(play, &QShortcut::activated, ui->play_btn, &QPushButton::click); connect(ui->play_btn, &QPushButton::clicked, this, &MainWindow::play_clicked); + QShortcut *preview_1 = new QShortcut(QKeySequence(Qt::Key_1), this); + connect(preview_1, &QShortcut::activated, ui->preview_1_btn, &QPushButton::click); + connect(ui->preview_1_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(0); }); + + QShortcut *preview_2 = new QShortcut(QKeySequence(Qt::Key_2), this); + connect(preview_2, &QShortcut::activated, ui->preview_2_btn, &QPushButton::click); + connect(ui->preview_2_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(1); }); + + QShortcut *preview_3 = new QShortcut(QKeySequence(Qt::Key_3), this); + connect(preview_3, &QShortcut::activated, ui->preview_3_btn, &QPushButton::click); + connect(ui->preview_3_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(2); }); + + QShortcut *preview_4 = new QShortcut(QKeySequence(Qt::Key_4), this); + connect(preview_4, &QShortcut::activated, ui->preview_4_btn, &QPushButton::click); + connect(ui->preview_4_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(3); }); + preview_player = new Player(ui->preview_display); live_player = new Player(ui->live_display); live_player->set_done_callback([this]{ @@ -123,6 +139,21 @@ void MainWindow::preview_clicked() } } +void MainWindow::preview_angle_clicked(unsigned stream_idx) +{ + preview_player->override_angle(stream_idx); + + // Change the selection if we were previewing a clip from the clip list. + // (The only other thing we could be showing is a pts scrub, and if so, + // that would be selected.) + QItemSelectionModel *selected = ui->clip_list->selectionModel(); + if (selected->hasSelection()) { + QModelIndex cell = selected->selectedIndexes()[0]; + int column = int(ClipList::Column::CAMERA_1) + stream_idx; + selected->setCurrentIndex(cell.sibling(cell.row(), column), QItemSelectionModel::ClearAndSelect); + } +} + void MainWindow::play_clicked() { if (playlist_clips->empty()) return; diff --git a/mainwindow.h b/mainwindow.h index 6d214ff..76124ae 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -40,6 +40,7 @@ private: void cue_out_clicked(); void queue_clicked(); void preview_clicked(); + void preview_angle_clicked(unsigned stream_idx); void play_clicked(); void live_player_clip_done(); diff --git a/player.cpp b/player.cpp index 1f2d9e5..9f524bb 100644 --- a/player.cpp +++ b/player.cpp @@ -26,6 +26,7 @@ void Player::thread_func() return new_clip_ready && current_clip.pts_in != -1; }); new_clip_ready = false; + playing = true; } Clip clip; @@ -62,16 +63,25 @@ void Player::thread_func() // Sleep until the next frame start, or until there's a new clip we're supposed to play. { unique_lock lock(queue_state_mu); - aborted = new_clip_changed.wait_until(lock, next_frame_start, [this]{ - return new_clip_ready; + new_clip_changed.wait_until(lock, next_frame_start, [this]{ + return new_clip_ready || override_stream_idx != -1; }); - if (aborted) break; + if (new_clip_ready) break; + if (override_stream_idx != -1) { + stream_idx = override_stream_idx; + override_stream_idx = -1; + continue; + } } destination->setFrame(stream_idx, next_pts); } + { + unique_lock lock(queue_state_mu); + playing = false; + } if (done_callback != nullptr && !aborted) { done_callback(); } @@ -95,6 +105,49 @@ void Player::play_clip(const Clip &clip, unsigned stream_idx) { lock_guard lock(queue_state_mu); new_clip_ready = true; + override_stream_idx = -1; new_clip_changed.notify_all(); } } + +void Player::override_angle(unsigned stream_idx) +{ + // Corner case: If a new clip is waiting to be played, change its stream and then we're done. + { + unique_lock lock(queue_state_mu); + if (new_clip_ready) { + lock_guard lock2(mu); + current_stream_idx = stream_idx; + return; + } + } + + // If we are playing a clip, set override_stream_idx, and the player thread will + // pick it up and change its internal index. + { + unique_lock lock(queue_state_mu); + if (playing) { + override_stream_idx = stream_idx; + new_clip_changed.notify_all(); + } + } + + // OK, so we're standing still, presumably at the end of a clip. + // Look at the current pts_out (if it exists), and show the closest + // thing we've got. + int64_t pts_out; + { + lock_guard lock(mu); + if (current_clip.pts_out < 0) { + return; + } + pts_out = current_clip.pts_out; + } + + lock_guard lock(frame_mu); + auto it = upper_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts_out); + if (it == frames[stream_idx].end()) { + return; + } + destination->setFrame(stream_idx, *it); +} diff --git a/player.h b/player.h index bcc81ac..e251c6e 100644 --- a/player.h +++ b/player.h @@ -14,6 +14,7 @@ public: Player(JPEGFrameView *destination); void play_clip(const Clip &clip, unsigned stream_idx); + void override_angle(unsigned stream_idx); // For the current clip only. // Not thread-safe to set concurrently with playing. // Will be called back from the player thread. @@ -30,9 +31,11 @@ private: Clip current_clip; // Under mu. Can have pts_in = -1 for no clip. unsigned current_stream_idx; // Under mu. - bool new_clip_ready = false; // Under queue_state_mu. std::mutex queue_state_mu; std::condition_variable new_clip_changed; + bool new_clip_ready = false; // Under queue_state_mu. + bool playing = false; // Under queue_state_mu. + int override_stream_idx = -1; // Under queue_state_mu. }; #endif // !defined(_PLAYER_H) diff --git a/ui_mainwindow.ui b/ui_mainwindow.ui index c3597d9..2dd07d7 100644 --- a/ui_mainwindow.ui +++ b/ui_mainwindow.ui @@ -53,19 +53,90 @@ - + - - - Preview output - - - Qt::AlignCenter + + + 0 - + + + + Preview output + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 20 + 17 + + + + 1 + + + + + + + + 0 + 0 + + + + + 20 + 17 + + + + 2 + + + + + + + + 20 + 17 + + + + 3 + + + + + + + + 20 + 17 + + + + 4 + + + + -- 2.39.2