start implementation of multicam panel

This commit is contained in:
itsmattkc
2022-09-21 13:16:19 -07:00
parent 2dc2edf3e0
commit 487cd166d7
21 changed files with 347 additions and 25 deletions
+1
View File
@@ -30,6 +30,7 @@ add_subdirectory(handmovableview)
add_subdirectory(keyframeview)
add_subdirectory(manageddisplay)
add_subdirectory(menu)
add_subdirectory(multicam)
add_subdirectory(nodecombobox)
add_subdirectory(nodeparamview)
add_subdirectory(nodetableview)
@@ -275,6 +275,14 @@ void ManagedDisplayWidget::SetInnerMouseTracking(bool e)
}
}
VideoParams ManagedDisplayWidget::GetViewportParams() const
{
int device_width = width() * devicePixelRatioF();
int device_height = height() * devicePixelRatioF();
VideoParams::Format device_format = static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
return VideoParams(device_width, device_height, device_format, VideoParams::kInternalChannelCount);
}
void ManagedDisplayWidget::update()
{
if (RenderManager::instance()->backend() == RenderManager::kOpenGL) {
+4 -1
View File
@@ -58,7 +58,8 @@ protected:
virtual void initializeGL() override
{
connect(context(), &QOpenGLContext::aboutToBeDestroyed,
this, &ManagedDisplayWidgetOpenGL::OnDestroy);
this, &ManagedDisplayWidgetOpenGL::DestroyListener,
Qt::DirectConnection);
emit OnInit();
}
@@ -211,6 +212,8 @@ protected:
return wrapper_ ? wrapper_->rect() : QRect();
}
VideoParams GetViewportParams() const;
protected slots:
/**
* @brief Called whenever the internal rendering context has been created
+22
View File
@@ -0,0 +1,22 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2022 Olive Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/multicam/multicamwidget.cpp
widget/multicam/multicamwidget.h
PARENT_SCOPE
)
+104
View File
@@ -0,0 +1,104 @@
#include "multicamwidget.h"
namespace olive {
#define super ManagedDisplayWidget
MulticamWidget::MulticamWidget(QWidget *parent) :
super{parent},
node_(nullptr),
cacher_(nullptr),
tex_(nullptr)
{
}
void MulticamWidget::SetNode(MultiCamNode *n)
{
if (node_ == n) {
return;
}
if (node_) {
// Disconnect
}
node_ = n;
if (node_) {
// Connect
}
SetTime(time_);
}
void MulticamWidget::SetTime(const rational &r)
{
time_ = r;
if (node_) {
if (cacher_) {
int sources = node_->InputArraySize(node_->kSourcesInput);
watchers_.resize(sources);
textures_.resize(sources);
watchers_.fill(nullptr);
textures_.fill(nullptr);
for (int i=0; i<sources; i++) {
if (Node *n = node_->GetConnectedOutput(node_->kSourcesInput, 0)) {
auto w = new RenderTicketWatcher(this);
connect(w, &RenderTicketWatcher::Finished, this, &MulticamWidget::RenderedFrame);
w->SetTicket(cacher_->GetSingleFrame(n, time_, false));
watchers_[i] = w;
}
}
}
}
}
void MulticamWidget::OnInit()
{
super::OnInit();
pipeline_ = renderer()->CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/multicam.frag"))));
}
void MulticamWidget::OnPaint()
{
// Clear display surface
renderer()->ClearDestination();
if (tex_) {
ColorTransformJob job;
job.SetColorProcessor(color_service());
job.SetInputTexture(tex_);
job.SetInputAlphaAssociation(kAlphaNone);
renderer()->BlitColorManaged(job, GetViewportParams());
}
}
void MulticamWidget::OnDestroy()
{
pipeline_.clear();
tex_ = nullptr;
super::OnDestroy();
}
void MulticamWidget::RenderedFrame()
{
auto watcher = static_cast<RenderTicketWatcher*>(sender());
if (watcher->HasResult()) {
int index = watchers_.indexOf(watcher);
if (index != -1) {
if ((textures_[index] = watcher->Get().value<TexturePtr>())) {
update();
}
}
}
delete watcher;
}
}
+59
View File
@@ -0,0 +1,59 @@
#ifndef MULTICAMWIDGET_H
#define MULTICAMWIDGET_H
#include "node/input/multicam/multicamnode.h"
#include "render/previewautocacher.h"
#include "widget/manageddisplay/manageddisplay.h"
namespace olive {
class MulticamWidget : public ManagedDisplayWidget
{
Q_OBJECT
public:
explicit MulticamWidget(QWidget *parent = nullptr);
MANAGEDDISPLAYWIDGET_DEFAULT_DESTRUCTOR(MulticamWidget)
void SetNode(MultiCamNode *n);
void ConnectCacher(PreviewAutoCacher *c)
{
cacher_ = c;
}
public slots:
void SetTime(const rational &r);
protected slots:
virtual void OnInit() override;
virtual void OnPaint() override;
virtual void OnDestroy() override;
signals:
private:
MultiCamNode *node_;
QVariant pipeline_;
PreviewAutoCacher *cacher_;
rational time_;
TexturePtr tex_;
QVector<RenderTicketWatcher*> watchers_;
QVector<TexturePtr> textures_;
private slots:
void RenderedFrame();
};
}
#endif // MULTICAMWIDGET_H
+2 -2
View File
@@ -47,10 +47,10 @@ void HistogramScope::OnInit()
void HistogramScope::OnDestroy()
{
super::OnDestroy();
pipeline_secondary_.clear();
texture_row_sums_ = nullptr;
super::OnDestroy();
}
ShaderCode HistogramScope::GenerateShaderCode()
+3 -5
View File
@@ -52,9 +52,7 @@ void ScopeBase::DrawScope(TexturePtr managed_tex, QVariant pipeline)
job.Insert(QStringLiteral("ove_maintex"), NodeValue(NodeValue::kTexture, QVariant::fromValue(managed_tex)));
renderer()->Blit(pipeline, job, VideoParams(width(), height(),
static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
VideoParams::kInternalChannelCount));
renderer()->Blit(pipeline, job, GetViewportParams());
}
void ScopeBase::OnInit()
@@ -89,11 +87,11 @@ void ScopeBase::OnPaint()
void ScopeBase::OnDestroy()
{
super::OnDestroy();
managed_tex_ = nullptr;
texture_ = nullptr;
pipeline_.clear();
super::OnDestroy();
}
}
+1 -3
View File
@@ -72,9 +72,7 @@ void WaveformScope::DrawScope(TexturePtr managed_tex, QVariant pipeline)
job.Insert(QStringLiteral("ove_maintex"),
NodeValue(NodeValue::kTexture, QVariant::fromValue(managed_tex)));
renderer()->Blit(pipeline, job, VideoParams(width(), height(),
static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
VideoParams::kInternalChannelCount));
renderer()->Blit(pipeline, job, GetViewportParams());
float waveform_dim_x = ceil((width() - 1.0) * waveform_scale);
float waveform_dim_y = ceil((height() - 1.0) * waveform_scale);
+2
View File
@@ -100,6 +100,8 @@ public:
enable_audio_scrubbing_ = e;
}
PreviewAutoCacher *GetCacher() const { return auto_cacher_; }
public slots:
void Play(bool in_to_out_only);
+1 -4
View File
@@ -361,10 +361,7 @@ void ViewerDisplayWidget::OnPaint()
// We only draw if we have a pipeline
if (push_mode_ != kPushNull) {
// Draw texture through color transform
int device_width = width() * devicePixelRatioF();
int device_height = height() * devicePixelRatioF();
VideoParams::Format device_format = static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
VideoParams device_params(device_width, device_height, device_format, VideoParams::kInternalChannelCount);
VideoParams device_params = GetViewportParams();
if (push_mode_ == kPushBlank) {
if (blank_shader_.isNull()) {