diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index f6a71f333..49f260dd4 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -321,7 +321,8 @@ void ViewerWidget::SetFullScreen(QScreen *screen) connect(vw->display_widget(), &ViewerDisplayWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu); if (GetConnectedNode()) { - vw->SetResolution(GetConnectedNode()->video_params().width(), GetConnectedNode()->video_params().height()); + vw->SetVideoParams(GetConnectedNode()->video_params()); + vw->display_widget()->SetDeinterlacing(vw->display_widget()->IsDeinterlacing()); } vw->display_widget()->SetImage(display_widget_->last_loaded_buffer()); @@ -1086,7 +1087,9 @@ void ViewerWidget::SetViewerPixelAspect(const rational &ratio) { sizer_->SetPixelAspectRatio(ratio); - // FIXME: Update windows too + foreach (ViewerWindow* vw, windows_) { + vw->SetPixelAspectRatio(ratio); + } } void ViewerWidget::LengthChangedSlot(const rational &length) @@ -1108,7 +1111,9 @@ void ViewerWidget::InterlacingChangedSlot(VideoParams::Interlacing interlacing) // Automatically set a "sane" deinterlacing option display_widget_->SetDeinterlacing(interlacing != VideoParams::kInterlaceNone); - // FIXME: Set windows too + foreach (ViewerWindow* vw, windows_) { + vw->display_widget()->SetDeinterlacing(interlacing != VideoParams::kInterlaceNone); + } } void ViewerWidget::UpdateRendererVideoParameters() diff --git a/app/widget/viewer/viewerwindow.cpp b/app/widget/viewer/viewerwindow.cpp index 983d4289b..525e992be 100644 --- a/app/widget/viewer/viewerwindow.cpp +++ b/app/widget/viewer/viewerwindow.cpp @@ -28,7 +28,8 @@ OLIVE_NAMESPACE_ENTER ViewerWindow::ViewerWindow(QWidget *parent) : - QWidget(parent, Qt::Window | Qt::WindowStaysOnTopHint) + QWidget(parent, Qt::Window | Qt::WindowStaysOnTopHint), + pixel_aspect_(1) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setMargin(0); @@ -43,23 +44,28 @@ ViewerDisplayWidget *ViewerWindow::display_widget() const return display_widget_; } +void ViewerWindow::SetVideoParams(const VideoParams ¶ms) +{ + width_ = params.width(); + height_ = params.height(); + pixel_aspect_ = params.pixel_aspect_ratio(); + + UpdateMatrix(); +} + void ViewerWindow::SetResolution(int width, int height) { - // Set GL widget matrix to maintain this texture's aspect ratio - double window_ar = static_cast(this->width()) / static_cast(this->height()); - double image_ar = static_cast(width) / static_cast(height); + width_ = width; + height_ = height; - QMatrix4x4 mat; + UpdateMatrix(); +} - if (window_ar > image_ar) { - // Window is wider than image, adjust X scale - mat.scale(image_ar / window_ar, 1.0f, 1.0f); - } else if (window_ar < image_ar) { - // Window is taller than image, adjust Y scale - mat.scale(1.0f, window_ar / image_ar, 1.0f); - } +void ViewerWindow::SetPixelAspectRatio(const rational &pixel_aspect) +{ + pixel_aspect_ = pixel_aspect; - display_widget_->SetMatrix(mat); + UpdateMatrix(); } void ViewerWindow::Play(const int64_t& start_timestamp, const int& playback_speed, const rational &timebase) @@ -115,4 +121,23 @@ void ViewerWindow::UpdateFromQueue() } } +void ViewerWindow::UpdateMatrix() +{ + // Set GL widget matrix to maintain this texture's aspect ratio + double window_ar = static_cast(this->width()) / static_cast(this->height()); + double image_ar = static_cast(width_) / static_cast(height_) * pixel_aspect_.toDouble(); + + QMatrix4x4 mat; + + if (window_ar > image_ar) { + // Window is wider than image, adjust X scale + mat.scale(image_ar / window_ar, 1.0f, 1.0f); + } else if (window_ar < image_ar) { + // Window is taller than image, adjust Y scale + mat.scale(1.0f, window_ar / image_ar, 1.0f); + } + + display_widget_->SetMatrix(mat); +} + OLIVE_NAMESPACE_EXIT diff --git a/app/widget/viewer/viewerwindow.h b/app/widget/viewer/viewerwindow.h index 2f7742c9f..289f0ea87 100644 --- a/app/widget/viewer/viewerwindow.h +++ b/app/widget/viewer/viewerwindow.h @@ -36,11 +36,24 @@ public: ViewerDisplayWidget* display_widget() const; + /** + * @brief Used to adjust resulting picture to be the right aspect ratio + * + * Equivalent to calling SetResolution and SetPixelAspectRatio, just slightly faster since we + * only calculate the matrix once rather than twice. + */ + void SetVideoParams(const VideoParams ¶ms); + /** * @brief Used to adjust resulting picture to be the right aspect ratio */ void SetResolution(int width, int height); + /** + * @brief Used to adjust resulting picture to be the right aspect ratio + */ + void SetPixelAspectRatio(const rational& pixel_aspect); + ViewerQueue* queue() { return &queue_; } @@ -58,6 +71,8 @@ private slots: void UpdateFromQueue(); private: + void UpdateMatrix(); + ViewerDisplayWidget* display_widget_; ViewerQueue queue_; @@ -66,6 +81,12 @@ private: rational playback_timebase_; + int width_; + + int height_; + + rational pixel_aspect_; + }; OLIVE_NAMESPACE_EXIT