viewer: implemented basic deinterlace
Implements a very basic GLSL deinterlace that simply halves the vertical resolution and then interpolates between the fields. This can be toggled on or off. The reasons for being so basic is: - Speed, very quick code running in OpenGL - It would seem the highest quality deinterlacers are temporally based which doesn't make much sense for the viewer, particularly since we can't double the frame rate since our timecode is fixed to the frames. Higher quality interlacing/deinterlacing will be present in the actual renderer.
This commit is contained in:
@@ -167,12 +167,15 @@ void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
connect(n, &ViewerOutput::SizeChanged, this, &ViewerWidget::SetViewerResolution);
|
||||
connect(n, &ViewerOutput::PixelAspectChanged, this, &ViewerWidget::SetViewerPixelAspect);
|
||||
connect(n, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
connect(n, &ViewerOutput::InterlacingChanged, this, &ViewerWidget::InterlacingChangedSlot);
|
||||
connect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters);
|
||||
connect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
|
||||
connect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
|
||||
connect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange);
|
||||
connect(n, &ViewerOutput::GraphChangedFrom, this, &ViewerWidget::UpdateStack);
|
||||
|
||||
InterlacingChangedSlot(n->video_params().interlacing());
|
||||
|
||||
ruler()->SetPlaybackCache(n->video_frame_cache());
|
||||
|
||||
n->audio_playback_cache()->SetParameters(n->audio_params());
|
||||
@@ -218,6 +221,7 @@ void ViewerWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
disconnect(n, &ViewerOutput::SizeChanged, this, &ViewerWidget::SetViewerResolution);
|
||||
disconnect(n, &ViewerOutput::PixelAspectChanged, this, &ViewerWidget::SetViewerPixelAspect);
|
||||
disconnect(n, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
disconnect(n, &ViewerOutput::InterlacingChanged, this, &ViewerWidget::InterlacingChangedSlot);
|
||||
disconnect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters);
|
||||
disconnect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
|
||||
disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
|
||||
@@ -824,6 +828,16 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
connect(full_screen_menu, &QMenu::triggered, this, &ViewerWidget::ContextMenuSetFullScreen);
|
||||
}
|
||||
|
||||
{
|
||||
// Deinterlace Option
|
||||
if (GetConnectedNode()->video_params().interlacing() != VideoParams::kInterlaceNone) {
|
||||
QAction* deinterlace_action = menu.addAction(tr("Deinterlace"));
|
||||
deinterlace_action->setCheckable(true);
|
||||
deinterlace_action->setChecked(display_widget_->IsDeinterlacing());
|
||||
connect(deinterlace_action, &QAction::triggered, display_widget_, &ViewerDisplayWidget::SetDeinterlacing);
|
||||
}
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
{
|
||||
@@ -1089,6 +1103,14 @@ void ViewerWidget::LengthChangedSlot(const rational &length)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::InterlacingChangedSlot(VideoParams::Interlacing interlacing)
|
||||
{
|
||||
// Automatically set a "sane" deinterlacing option
|
||||
display_widget_->SetDeinterlacing(interlacing != VideoParams::kInterlaceNone);
|
||||
|
||||
// FIXME: Set windows too
|
||||
}
|
||||
|
||||
void ViewerWidget::UpdateRendererVideoParameters()
|
||||
{
|
||||
renderer_->ClearVideoQueue();
|
||||
|
||||
@@ -261,6 +261,8 @@ private slots:
|
||||
|
||||
void LengthChangedSlot(const rational& length);
|
||||
|
||||
void InterlacingChangedSlot(VideoParams::Interlacing interlacing);
|
||||
|
||||
void UpdateRendererVideoParameters();
|
||||
|
||||
void UpdateRendererAudioParameters();
|
||||
|
||||
@@ -43,7 +43,8 @@ ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent) :
|
||||
signal_cursor_color_(false),
|
||||
gizmos_(nullptr),
|
||||
gizmo_click_(false),
|
||||
last_loaded_buffer_(nullptr)
|
||||
last_loaded_buffer_(nullptr),
|
||||
deinterlace_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,6 +87,12 @@ void ViewerDisplayWidget::SetImage(FramePtr in_buffer)
|
||||
update();
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::SetDeinterlacing(bool e)
|
||||
{
|
||||
deinterlace_ = e;
|
||||
update();
|
||||
}
|
||||
|
||||
const ViewerSafeMarginInfo &ViewerDisplayWidget::GetSafeMargin() const
|
||||
{
|
||||
return safe_margin_;
|
||||
@@ -212,6 +219,12 @@ void ViewerDisplayWidget::paintGL()
|
||||
// Bind retrieved texture
|
||||
f->glBindTexture(GL_TEXTURE_2D, texture_.texture());
|
||||
|
||||
// Set some parameters
|
||||
color_service()->pipeline()->bind();
|
||||
color_service()->pipeline()->setUniformValue("ove_resolution", texture_.width(), texture_.height());
|
||||
color_service()->pipeline()->setUniformValue("ove_deinterlace", deinterlace_);
|
||||
color_service()->pipeline()->release();
|
||||
|
||||
// Blit using the color service
|
||||
color_service()->ProcessOpenGL(true, matrix_);
|
||||
|
||||
|
||||
@@ -77,6 +77,11 @@ public:
|
||||
|
||||
FramePtr last_loaded_buffer() const;
|
||||
|
||||
bool IsDeinterlacing() const
|
||||
{
|
||||
return deinterlace_;
|
||||
}
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Set the transformation matrix to draw with
|
||||
@@ -102,6 +107,11 @@ public slots:
|
||||
*/
|
||||
void SetImage(FramePtr in_buffer);
|
||||
|
||||
/**
|
||||
* @brief Enables/disables a basic deinterlace on the viewer
|
||||
*/
|
||||
void SetDeinterlacing(bool e);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the user starts dragging from the viewer
|
||||
@@ -174,6 +184,8 @@ private:
|
||||
|
||||
FramePtr last_loaded_buffer_;
|
||||
|
||||
bool deinterlace_;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Slot to connect just before the OpenGL context is destroyed to clean up resources
|
||||
|
||||
Reference in New Issue
Block a user