diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index d16034231..fbb2b971a 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -56,7 +56,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) : color_menu_enabled_(true), time_changed_from_timer_(false), pause_autocache_during_playback_(false), - prequeuing_(false) + prequeuing_(false), + last_loaded_buffer_(nullptr), + last_loaded_buffer_is_empty_(false) { // Set up main layout QVBoxLayout* layout = new QVBoxLayout(this); @@ -340,7 +342,7 @@ void ViewerWidget::SetFullScreen(QScreen *screen) vw->display_widget()->SetDeinterlacing(vw->display_widget()->IsDeinterlacing()); } - vw->display_widget()->SetImage(display_widget_->last_loaded_buffer()); + vw->display_widget()->SetImage(last_loaded_buffer_); windows_.insert(screen, vw); } @@ -405,6 +407,38 @@ bool ViewerWidget::ShouldForceWaveform() const && GetConnectedNode()->GetConnectedSampleOutput().IsValid(); } +void ViewerWidget::SetEmptyImage() +{ + FramePtr frame = nullptr; + + if (GetConnectedNode()) { + frame = last_loaded_buffer_; + + if (!frame) { + frame = Frame::Create(); + } + + if (frame->video_params() != GetConnectedNode()->GetVideoParams()) { + frame->destroy(); + frame->set_video_params(GetConnectedNode()->GetVideoParams()); + } + + if (!frame->is_allocated()) { + frame->allocate(); + } + + if (!last_loaded_buffer_is_empty_) { + memset(frame->data(), 0, frame->allocated_size()); + } + } + + SetDisplayImage(frame, false); + + if (frame) { + last_loaded_buffer_is_empty_ = true; + } +} + void ViewerWidget::StartAudioOutput() { AudioPlaybackCache* audio_cache = GetConnectedNode()->audio_playback_cache(); @@ -473,7 +507,7 @@ void ViewerWidget::UpdateTextureFromNode(const rational& time) } else { // There is definitely no frame here, we can immediately flip to showing nothing nonqueue_watchers_.clear(); - SetDisplayImage(nullptr, false); + SetEmptyImage(); return; } } @@ -632,6 +666,8 @@ void ViewerWidget::SetDisplayImage(FramePtr frame, bool main_only) } } + last_loaded_buffer_ = frame; + last_loaded_buffer_is_empty_ = false; emit LoadedBuffer(frame.get()); } diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 0f5f6dffc..21ef2a33e 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -203,6 +203,8 @@ private: bool ShouldForceWaveform() const; + void SetEmptyImage(); + QStackedWidget* stack_; ViewerSizer* sizer_; @@ -247,6 +249,9 @@ private: QTimer audio_restart_timer_; + FramePtr last_loaded_buffer_; + bool last_loaded_buffer_is_empty_; + static QVector instances_; private slots: diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index dcbe87433..cf57c2d12 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -170,11 +170,6 @@ void ViewerDisplayWidget::SetTime(const rational &time) } } -FramePtr ViewerDisplayWidget::last_loaded_buffer() const -{ - return last_loaded_buffer_; -} - QPoint ViewerDisplayWidget::TransformViewerSpaceToBufferSpace(QPoint pos) { /* diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h index fa05485c2..7f649399d 100644 --- a/app/widget/viewer/viewerdisplay.h +++ b/app/widget/viewer/viewerdisplay.h @@ -77,8 +77,6 @@ public: update(); } - FramePtr last_loaded_buffer() const; - /** * @brief Transform a point from viewer space to the buffer space. * Multiplies by the inverted transform matrix to undo the scaling and translation.