viewer: implement lookahead to ensure footage is ready in advance

This commit is contained in:
itsmattkc
2022-07-26 14:49:19 -07:00
parent d1ec2b909b
commit 25e94112f8
9 changed files with 137 additions and 62 deletions
+35 -1
View File
@@ -60,7 +60,7 @@ QVector<ViewerWidget*> ViewerWidget::instances_;
// changing values. 1/4 second seems to be a good middleground.
const rational ViewerWidget::kAudioPlaybackInterval = rational(1, 4);
const rational kVideoPlaybackInterval = rational(2);
const rational kVideoPlaybackInterval = rational(1, 2);
ViewerWidget::ViewerWidget(QWidget *parent) :
super(false, true, parent),
@@ -560,6 +560,35 @@ void ViewerWidget::ShowSubtitleProperties()
}
}
void ViewerWidget::DryRunFinished()
{
RenderTicketWatcher *w = static_cast<RenderTicketWatcher*>(sender());
if (dry_run_watchers_.contains(w)) {
RequestNextDryRun();
}
delete w;
}
void ViewerWidget::RequestNextDryRun()
{
if (IsPlaying()) {
rational next_time = Timecode::timestamp_to_time(dry_run_next_frame_, timebase());
if (FrameExistsAtTime(next_time)) {
if (next_time > GetTime() + RenderManager::kDryRunInterval) {
QTimer::singleShot(timebase().toDouble() / playback_speed_, this, &ViewerWidget::RequestNextDryRun);
} else {
RenderTicketWatcher *watcher = new RenderTicketWatcher(this);
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::DryRunFinished);
watcher->SetTicket(auto_cacher_.GetSingleFrame(next_time, true));
dry_run_next_frame_ += playback_speed_;
dry_run_watchers_.append(watcher);
}
}
}
}
void ViewerWidget::CloseAudioProcessor()
{
audio_processor_.Close();
@@ -828,6 +857,9 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
for (int i=0; i<prequeue_length_; i++) {
RequestNextFrameForQueue();
}
dry_run_next_frame_ = playback_queue_next_frame_;
RequestNextDryRun();
}
}
@@ -845,6 +877,7 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
QueueNextAudioBuffer();
}
}
// Force screen to stay awake
PreventSleep(true);
}
@@ -893,6 +926,7 @@ void ViewerWidget::PauseInternal()
prequeuing_video_ = false;
prequeuing_audio_ = 0;
dry_run_watchers_.clear();
// Reset screen timeout timer
PreventSleep(false);