From 757aaa21c44e5617da38973ff88ce3a21b69896e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 20 Dec 2019 04:34:32 +1100 Subject: [PATCH] began exporter classes for handling render backends in an exporting context --- app/render/backend/exporter.cpp | 131 +++++++++++++++++++ app/render/backend/exporter.h | 75 +++++++++++ app/render/backend/opengl/openglexporter.cpp | 64 +++++++++ app/render/backend/opengl/openglexporter.h | 33 +++++ app/render/exporter.cpp | 6 - app/render/exporter.h | 11 -- app/render/exporter/openglexporter.cpp | 6 - app/render/exporter/openglexporter.h | 11 -- 8 files changed, 303 insertions(+), 34 deletions(-) create mode 100644 app/render/backend/exporter.cpp create mode 100644 app/render/backend/exporter.h create mode 100644 app/render/backend/opengl/openglexporter.cpp create mode 100644 app/render/backend/opengl/openglexporter.h delete mode 100644 app/render/exporter.cpp delete mode 100644 app/render/exporter.h delete mode 100644 app/render/exporter/openglexporter.cpp delete mode 100644 app/render/exporter/openglexporter.h diff --git a/app/render/backend/exporter.cpp b/app/render/backend/exporter.cpp new file mode 100644 index 000000000..e28b5a294 --- /dev/null +++ b/app/render/backend/exporter.cpp @@ -0,0 +1,131 @@ +#include "exporter.h" + +#include "render/colormanager.h" +#include "render/pixelservice.h" + +Exporter::Exporter(ViewerOutput* viewer, const VideoRenderingParams& params, const QMatrix4x4 &transform, ColorProcessorPtr color_processor, QObject* parent) : + QObject(parent), + video_backend_(nullptr), + audio_backend_(nullptr), + viewer_node_(viewer), + params_(params), + color_processor_(color_processor), + export_status_(false), + export_msg_(tr("Export hasn't started yet")) +{ +} + +bool Exporter::GetExportStatus() const +{ + return export_status_; +} + +const QString &Exporter::GetExportError() const +{ + return export_msg_; +} + +void Exporter::StartExporting() +{ + // Default to error state until ExportEnd is called + export_status_ = false; + + // Create renderers + if (!Initialize()) { + ExportFailed(); + return; + } + + video_backend_->SetViewerNode(viewer_node_); + video_backend_->SetParameters(VideoRenderingParams(viewer_node_->video_params(), olive::PIX_FMT_RGBA32F, olive::kOnline)); + video_backend_->SetExportMode(true); + video_backend_->Compile(); + //audio_backend_->SetViewerNode(viewer_node_); + //audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(), SAMPLE_FMT_FLT)); + + // Connect to renderers + connect(video_backend_, SIGNAL(CachedFrameReady(const rational&, QVariant)), this, SLOT(FrameRendered(const rational&, QVariant))); + connect(video_backend_, SIGNAL(CachedTimeReady(const rational&)), this, SLOT(TimeRendered(const rational&))); + + // Create renderers + waiting_for_frame_ = 0; + + // Invalidate caches + video_backend_->InvalidateCache(0, viewer_node_->Length()); + //viewer_node_->InvalidateCache(0, viewer_node_->Length(), viewer_node_->samples_input()); +} + +void Exporter::SetExportMessage(const QString &s) +{ + export_msg_ = s; +} + +void Exporter::ExportSucceeded() +{ + Cleanup(); + + delete video_backend_; + delete audio_backend_; + + export_status_ = true; + export_msg_ = tr("Export succeeded"); + + emit ExportEnded(); +} + +void Exporter::ExportFailed() +{ + emit ExportEnded(); +} + +void Exporter::FrameRendered(const rational &time, QVariant value) +{ + qDebug() << "Retrieved frame" << time.toDouble() << "- waiting for frame" << waiting_for_frame_.toDouble(); + + if (time == waiting_for_frame_) { + bool get_cached = false; + + do { + if (get_cached) { + value = cached_frames_.take(waiting_for_frame_); + } else { + get_cached = true; + } + + // Convert texture to frame + FramePtr frame = TextureToFrame(value); + + // OCIO conversion requires a frame in 32F format + if (frame->format() != olive::PIX_FMT_RGBA32F) { + frame = PixelService::ConvertPixelFormat(frame, olive::PIX_FMT_RGBA32F); + } + + // Color conversion must be done with unassociated alpha, and the pipeline is always associated + ColorManager::DisassociateAlpha(frame); + + // Convert color space + color_processor_->ConvertFrame(frame); + + // Encode (may require re-associating alpha?) + + waiting_for_frame_ += viewer_node_->video_params().time_base(); + + // Calculate progress + int progress = qRound(100.0 * (waiting_for_frame_.toDouble() / viewer_node_->Length().toDouble())); + qDebug() << "Hello progress" << progress; + emit ProgressChanged(progress); + + } while (cached_frames_.contains(waiting_for_frame_)); + } else { + cached_frames_.insert(time, value); + } + + /*if (time == viewer_node_->Length()) { + ExportSucceeded(); + }*/ +} + +void Exporter::TimeRendered(const rational &time) +{ + qDebug() << "Retrieved time rendered!" << time.toDouble(); +} diff --git a/app/render/backend/exporter.h b/app/render/backend/exporter.h new file mode 100644 index 000000000..276735f26 --- /dev/null +++ b/app/render/backend/exporter.h @@ -0,0 +1,75 @@ +#ifndef EXPORTER_H +#define EXPORTER_H + +#include +#include +#include + +#include "node/output/viewer/viewer.h" +#include "render/backend/audiorenderbackend.h" +#include "render/backend/videorenderbackend.h" +#include "render/colorprocessor.h" + +class Exporter : public QObject +{ + Q_OBJECT +public: + Exporter(ViewerOutput* viewer, const VideoRenderingParams& params, const QMatrix4x4& transform, ColorProcessorPtr color_processor, QObject* parent = nullptr); + + bool GetExportStatus() const; + const QString& GetExportError() const; + +public slots: + void StartExporting(); + +signals: + void ProgressChanged(int); + + void ExportEnded(); + +protected: + virtual bool Initialize() = 0; + virtual void Cleanup() = 0; + + virtual FramePtr TextureToFrame(const QVariant &texture) = 0; + + void SetExportMessage(const QString& s); + + // Renderers + VideoRenderBackend* video_backend_; + AudioRenderBackend* audio_backend_; + + // Viewer node + ViewerOutput* viewer_node_; + + // Export parameters + VideoRenderingParams params_; + + // Export transform + QMatrix4x4 transform_; + + // Copied graph + NodeGraph copied_graph_; + +private: + void ExportSucceeded(); + + void ExportFailed(); + + ColorProcessorPtr color_processor_; + + bool export_status_; + + QString export_msg_; + + rational waiting_for_frame_; + + QHash cached_frames_; + +private slots: + void FrameRendered(const rational& time, QVariant value); + void TimeRendered(const rational& time); + +}; + +#endif // EXPORTER_H diff --git a/app/render/backend/opengl/openglexporter.cpp b/app/render/backend/opengl/openglexporter.cpp new file mode 100644 index 000000000..7bef27c6c --- /dev/null +++ b/app/render/backend/opengl/openglexporter.cpp @@ -0,0 +1,64 @@ +#include "openglexporter.h" + +#include "render/backend/opengl/functions.h" + +OpenGLExporter::OpenGLExporter(ViewerOutput* viewer, const VideoRenderingParams& params, const QMatrix4x4& transform, ColorProcessorPtr color_processor, QObject* parent) : + Exporter(viewer, params, transform, color_processor, parent) +{ +} + +OpenGLExporter::~OpenGLExporter() +{ +} + +bool OpenGLExporter::Initialize() +{ + QOpenGLContext* ctx = QOpenGLContext::currentContext(); + + // Create rendering backends + video_backend_ = new OpenGLBackend(); + audio_backend_ = new AudioBackend(); + + // Create blitting framebuffer and texture + buffer_.Create(ctx); + + texture_ = std::make_shared(); + texture_->Create(ctx, params_.effective_width(), params_.effective_height(), params_.format()); + + pipeline_ = OpenGLShader::CreateDefault(); + + return true; +} + +void OpenGLExporter::Cleanup() +{ + texture_->Destroy(); + buffer_.Destroy(); +} + +FramePtr OpenGLExporter::TextureToFrame(const QVariant& texture) +{ + FramePtr frame = Frame::Create(); + frame->set_width(params_.width()); + frame->set_height(params_.height()); + frame->set_format(params_.format()); + frame->allocate(); + + // Blit for transform if the width/height are different + OpenGLTexturePtr input_tex = texture.value(); + if (input_tex) { + buffer_.Attach(texture_); + buffer_.Bind(); + input_tex->Bind(); + + olive::gl::Blit(pipeline_, false, transform_); + + input_tex->Release(); + buffer_.Release(); + buffer_.Detach(); + } + + // Perform OpenGL read + + return frame; +} diff --git a/app/render/backend/opengl/openglexporter.h b/app/render/backend/opengl/openglexporter.h new file mode 100644 index 000000000..4290e6a23 --- /dev/null +++ b/app/render/backend/opengl/openglexporter.h @@ -0,0 +1,33 @@ +#ifndef OPENGLEXPORTER_H +#define OPENGLEXPORTER_H + +#include "render/backend/exporter.h" +#include "render/backend/opengl/openglbackend.h" +#include "render/backend/audio/audiobackend.h" +#include "render/backend/opengl/openglframebuffer.h" +#include "render/backend/opengl/opengltexture.h" + +class OpenGLExporter : public Exporter +{ +public: + OpenGLExporter(ViewerOutput *viewer, const VideoRenderingParams ¶ms, const QMatrix4x4 &transform, ColorProcessorPtr color_processor, QObject* parent = nullptr); + + virtual ~OpenGLExporter() override; + +protected: + virtual bool Initialize() override; + + virtual void Cleanup() override; + + virtual FramePtr TextureToFrame(const QVariant &texture) override; + +private: + OpenGLFramebuffer buffer_; + + OpenGLTexturePtr texture_; + + OpenGLShaderPtr pipeline_; + +}; + +#endif // OPENGLEXPORTER_H diff --git a/app/render/exporter.cpp b/app/render/exporter.cpp deleted file mode 100644 index 159908ab4..000000000 --- a/app/render/exporter.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "exporter.h" - -Exporter::Exporter() -{ - -} diff --git a/app/render/exporter.h b/app/render/exporter.h deleted file mode 100644 index 527da5515..000000000 --- a/app/render/exporter.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef EXPORTER_H -#define EXPORTER_H - - -class Exporter -{ -public: - Exporter(); -}; - -#endif // EXPORTER_H diff --git a/app/render/exporter/openglexporter.cpp b/app/render/exporter/openglexporter.cpp deleted file mode 100644 index 7f4c64904..000000000 --- a/app/render/exporter/openglexporter.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "openglexporter.h" - -OpenGLExporter::OpenGLExporter() -{ - -} diff --git a/app/render/exporter/openglexporter.h b/app/render/exporter/openglexporter.h deleted file mode 100644 index 8d657d3c5..000000000 --- a/app/render/exporter/openglexporter.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef OPENGLEXPORTER_H -#define OPENGLEXPORTER_H - - -class OpenGLExporter -{ -public: - OpenGLExporter(); -}; - -#endif // OPENGLEXPORTER_H