this, &MainWindow::playlist_selection_changed);
playlist_selection_changed(); // First time set-up.
- preview_player = new Player(ui->preview_display, /*also_output_to_stream=*/false);
- live_player = new Player(ui->live_display, /*also_output_to_stream=*/true);
+ 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));
live_player->set_done_callback([this]{
post_to_main_thread([this]{
live_player_clip_done();
this, &MainWindow::clip_list_selection_changed);
}
+MainWindow::~MainWindow()
+{
+ // Empty so that we can forward-declare Player in the .h file.
+}
+
void MainWindow::cue_in_clicked()
{
if (!cliplist_clips->empty() && cliplist_clips->back()->pts_out < 0) {
{
// playlist_clips can only be accessed on the main thread.
// Hopefully, we won't have to wait too long for this to come back.
+ //
+ // TODO: If MainWindow is in the process of being destroyed and waiting
+ // for Player to shut down, we could have a deadlock here.
promise<pair<Clip, size_t>> clip_promise;
future<pair<Clip, size_t>> clip = clip_promise.get_future();
post_to_main_thread([this, &clip_promise] {
lock_guard<mutex> 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;
}
lock_guard<mutex> 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;
}