X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=futatabi%2Fmainwindow.cpp;h=54efa1c1de221c107f3b57cbcc15a74418096fd5;hb=eaba7288c4fb39ca195c9355970293bcaf088dbc;hp=24a9d5b7e4e7db58e1d6bc894e060ba23548e485;hpb=a64b7a670a29674aa4a6cb2abe2f5a29f6cc14bc;p=nageru diff --git a/futatabi/mainwindow.cpp b/futatabi/mainwindow.cpp index 24a9d5b..54efa1c 100644 --- a/futatabi/mainwindow.cpp +++ b/futatabi/mainwindow.cpp @@ -2,6 +2,7 @@ #include "shared/aboutdialog.h" #include "clip_list.h" +#include "export.h" #include "shared/disk_space_estimator.h" #include "flags.h" #include "frame_on_disk.h" @@ -11,6 +12,7 @@ #include "ui_mainwindow.h" #include +#include #include #include #include @@ -39,6 +41,8 @@ MainWindow::MainWindow() // The menus. connect(ui->exit_action, &QAction::triggered, this, &MainWindow::exit_triggered); + connect(ui->export_cliplist_clip_multitrack_action, &QAction::triggered, this, &MainWindow::export_cliplist_clip_multitrack_triggered); + connect(ui->export_playlist_clip_interpolated_action, &QAction::triggered, this, &MainWindow::export_playlist_clip_interpolated_triggered); connect(ui->manual_action, &QAction::triggered, this, &MainWindow::manual_triggered); connect(ui->about_action, &QAction::triggered, this, &MainWindow::about_triggered); @@ -126,8 +130,8 @@ MainWindow::MainWindow() this, &MainWindow::playlist_selection_changed); playlist_selection_changed(); // First time set-up. - preview_player.reset(new Player(ui->preview_display, /*also_output_to_stream=*/false)); - live_player.reset(new Player(ui->live_display, /*also_output_to_stream=*/true)); + preview_player.reset(new Player(ui->preview_display, Player::NO_STREAM_OUTPUT)); + live_player.reset(new Player(ui->live_display, Player::HTTPD_STREAM_OUTPUT)); live_player->set_done_callback([this]{ post_to_main_thread([this]{ live_player_clip_done(); @@ -661,8 +665,7 @@ void MainWindow::preview_single_frame(int64_t pts, unsigned stream_idx, MainWind lock_guard lock(frame_mu); if (frames[stream_idx].empty()) return; - auto it = lower_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts, - [](const FrameOnDisk &frame, int64_t pts) { return frame.pts < pts; }); + auto it = find_last_frame_before(frames[stream_idx], pts); if (it != frames[stream_idx].end()) { pts = it->pts; } @@ -671,8 +674,7 @@ void MainWindow::preview_single_frame(int64_t pts, unsigned stream_idx, MainWind lock_guard lock(frame_mu); if (frames[stream_idx].empty()) return; - auto it = upper_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts - 1, - [](int64_t pts, const FrameOnDisk &frame) { return pts < frame.pts; }); + auto it = find_first_frame_at_or_after(frames[stream_idx], pts); if (it != frames[stream_idx].end()) { pts = it->pts; } @@ -756,6 +758,54 @@ void MainWindow::exit_triggered() close(); } +void MainWindow::export_cliplist_clip_multitrack_triggered() +{ + QItemSelectionModel *selected = ui->clip_list->selectionModel(); + if (!selected->hasSelection()) { + QMessageBox msgbox; + msgbox.setText("No clip selected in the clip list. Select one and try exporting again."); + msgbox.exec(); + return; + } + + QModelIndex index = selected->currentIndex(); + Clip clip = *cliplist_clips->clip(index.row()); + QString filename = QFileDialog::getSaveFileName(this, + "Export multitrack clip", QString(), tr("Matroska video files (*.mkv)")); + if (filename.isNull()) { + // Cancel. + return; + } + if (!filename.endsWith(".mkv")) { + filename += ".mkv"; + } + export_multitrack_clip(filename.toStdString(), clip); +} + +void MainWindow::export_playlist_clip_interpolated_triggered() +{ + QItemSelectionModel *selected = ui->playlist->selectionModel(); + if (!selected->hasSelection()) { + QMessageBox msgbox; + msgbox.setText("No clip selected in the playlist. Select one and try exporting again."); + msgbox.exec(); + return; + } + + QModelIndex index = selected->currentIndex(); + Clip clip = *playlist_clips->clip(index.row()); + QString filename = QFileDialog::getSaveFileName(this, + "Export interpolated clip", QString(), tr("Matroska video files (*.mkv)")); + if (filename.isNull()) { + // Cancel. + return; + } + if (!filename.endsWith(".mkv")) { + filename += ".mkv"; + } + export_interpolated_clip(filename.toStdString(), clip); +} + void MainWindow::manual_triggered() { if (!QDesktopServices::openUrl(QUrl("https://nageru.sesse.net/doc/"))) {