began work on headless export path

This commit is contained in:
itsmattkc
2020-04-20 02:37:10 +10:00
parent 1474a505ee
commit 1c3c8cd9b2
20 changed files with 695 additions and 199 deletions
+2
View File
@@ -22,6 +22,8 @@ set(OLIVE_SOURCES
render/backend/exporter.h
render/backend/exporter.cpp
render/backend/exportparams.h
render/backend/exportparams.cpp
render/backend/renderbackend.h
render/backend/renderbackend.cpp
+62 -33
View File
@@ -27,46 +27,52 @@
OLIVE_NAMESPACE_ENTER
Exporter::Exporter(ViewerOutput* viewer,
Encoder *encoder,
Exporter::Exporter(ViewerOutput *viewer_node,
ColorManager *color_manager,
const ExportParams& params,
QObject* parent) :
QObject(parent),
viewer_node_(viewer_node),
params_(params),
video_backend_(nullptr),
audio_backend_(nullptr),
viewer_node_(viewer),
video_done_(true),
audio_done_(true),
encoder_(encoder),
export_status_(false),
export_msg_(tr("Export hasn't started yet"))
{
encoder_ = Encoder::CreateFromID(params_.encoder(), params_);
video_done_ = !params_.video_enabled();
audio_done_ = !params_.audio_enabled();
debug_timer_.setInterval(5000);
connect(&debug_timer_, &QTimer::timeout, this, &Exporter::DebugTimerMessage);
connect(this, &Exporter::ExportEnded, this, &Exporter::deleteLater);
export_range_ = TimeRange(0, viewer_node_->Length());
}
if (params_.has_custom_range()) {
export_range_ = params_.custom_range();
} else {
export_range_ = TimeRange(0, viewer_node_->Length());
}
void Exporter::EnableVideo(const VideoRenderingParams &video_params, const QMatrix4x4 &transform, ColorProcessorPtr color_processor)
{
video_params_ = video_params;
transform_ = transform;
color_processor_ = color_processor;
if (params_.video_enabled()) {
video_done_ = false;
}
// If a transformation matrix is applied to this video, create it here
if (params_.video_scaling_method() != ExportParams::kStretch) {
transform_ = GenerateMatrix(params_.video_scaling_method(),
viewer_node_->video_params().width(),
viewer_node_->video_params().height(),
params_.video_params().width(),
params_.video_params().height());
}
void Exporter::EnableAudio(const AudioRenderingParams &audio_params)
{
audio_params_ = audio_params;
audio_done_ = false;
}
void Exporter::OverrideExportRange(const TimeRange &range)
{
export_range_ = range;
// Create color processor
color_processor_ = ColorProcessor::Create(color_manager,
color_manager->GetReferenceColorSpace(),
params.ocio_display(),
params.ocio_view(),
params.ocio_look());
}
}
bool Exporter::GetExportStatus() const
@@ -110,9 +116,9 @@ void Exporter::StartExporting()
video_backend_->SetViewerNode(viewer_node_);
video_backend_->SetParameters(VideoRenderingParams(viewer_node_->video_params().width(),
viewer_node_->video_params().height(),
video_params_.time_base(),
video_params_.format(),
video_params_.mode()));
params_.video_params().time_base(),
params_.video_params().format(),
params_.video_params().mode()));
waiting_for_frame_ = 0;
}
@@ -121,7 +127,7 @@ void Exporter::StartExporting()
audio_backend_ = new AudioBackend();
audio_backend_->SetViewerNode(viewer_node_);
audio_backend_->SetParameters(audio_params_);
audio_backend_->SetParameters(params_.audio_params());
}
// Open encoder and wait for result
@@ -190,7 +196,7 @@ void Exporter::EncodeFrame()
Qt::QueuedConnection,
OLIVE_NS_ARG(FramePtr, frame));
waiting_for_frame_ += video_params_.time_base();
waiting_for_frame_ += params_.video_params().time_base();
// Calculate progress
emit ProgressChanged(waiting_for_frame_.toDouble() / viewer_node_->Length().toDouble());
@@ -204,6 +210,30 @@ void Exporter::EncodeFrame()
}
}
QMatrix4x4 Exporter::GenerateMatrix(ExportParams::VideoScalingMethod method, int source_width, int source_height, int dest_width, int dest_height)
{
QMatrix4x4 preview_matrix;
if (method == ExportParams::kStretch) {
return preview_matrix;
}
float export_ar = static_cast<float>(dest_width) / static_cast<float>(dest_height);
float source_ar = static_cast<float>(source_width) / static_cast<float>(source_height);
if (qFuzzyCompare(export_ar, source_ar)) {
return preview_matrix;
}
if ((export_ar > source_ar) == (method == ExportParams::kFit)) {
preview_matrix.scale(source_ar / export_ar, 1.0F);
} else {
preview_matrix.scale(1.0F, export_ar / source_ar);
}
return preview_matrix;
}
void Exporter::FrameRendered(const rational &time, FramePtr value)
{
debug_timer_.stop();
@@ -261,14 +291,14 @@ void Exporter::EncoderOpenedSuccessfully()
video_backend_->SetOperatingMode(VideoRenderWorker::kHashOnly);
connect(video_backend_, &VideoRenderBackend::QueueComplete, this, &Exporter::VideoHashesComplete);
video_backend_->InvalidateCache(TimeRange(0, viewer_node_->Length()));
video_backend_->InvalidateCache(export_range_);
}
if (!audio_done_) {
// We set the audio backend to render the full sequence to the disk
connect(audio_backend_, &AudioRenderBackend::AudioComplete, this, &Exporter::AudioRendered);
audio_backend_->InvalidateCache(TimeRange(0, viewer_node_->Length()));
audio_backend_->InvalidateCache(export_range_);
}
}
@@ -297,7 +327,6 @@ void Exporter::VideoHashesComplete()
video_backend_->SetOperatingMode(VideoRenderWorker::kRenderOnly);
video_backend_->SetOnlySignalLastFrameRequested(false);
// FIXME: Exporting is now broken because of this
connect(video_backend_, &VideoRenderBackend::GeneratedFrame, this, &Exporter::FrameRendered);
foreach (const TimeRange& range, ranges) {
+21 -25
View File
@@ -29,6 +29,7 @@
#include "codec/encoder.h"
#include "node/output/viewer/viewer.h"
#include "render/backend/audiorenderbackend.h"
#include "render/backend/exportparams.h"
#include "render/backend/videorenderbackend.h"
#include "render/colorprocessor.h"
@@ -38,20 +39,18 @@ class Exporter : public QObject
{
Q_OBJECT
public:
Exporter(ViewerOutput* viewer,
Encoder* encoder,
Exporter(ViewerOutput* viewer_node,
ColorManager* color_manager,
const ExportParams& params,
QObject* parent = nullptr);
void EnableVideo(const VideoRenderingParams& video_params, const QMatrix4x4& transform, ColorProcessorPtr color_processor);
void EnableAudio(const AudioRenderingParams& audio_params);
void OverrideExportRange(const TimeRange& range);
bool GetExportStatus() const;
const QString& GetExportError() const;
void Cancel();
static QMatrix4x4 GenerateMatrix(ExportParams::VideoScalingMethod method, int source_width, int source_height, int dest_width, int dest_height);
public slots:
void StartExporting();
@@ -63,17 +62,23 @@ signals:
protected:
void SetExportMessage(const QString& s);
private:
void ExportSucceeded();
void ExportStopped();
void EncodeFrame();
ViewerOutput* viewer_node_;
ColorProcessorPtr color_processor_;
ExportParams params_;
// Renderers
VideoRenderBackend* video_backend_;
AudioRenderBackend* audio_backend_;
// Viewer node
ViewerOutput* viewer_node_;
// Export parameters
VideoRenderingParams video_params_;
AudioRenderingParams audio_params_;
// Export transform
QMatrix4x4 transform_;
@@ -81,23 +86,14 @@ protected:
bool audio_done_;
TimeRange export_range_;
private:
void ExportSucceeded();
void ExportStopped();
void EncodeFrame();
ColorProcessorPtr color_processor_;
Encoder* encoder_;
bool export_status_;
QString export_msg_;
TimeRange export_range_;
rational waiting_for_frame_;
QHash<rational, FramePtr> cached_frames_;
+89
View File
@@ -0,0 +1,89 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 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/>.
***/
#include "exportparams.h"
OLIVE_NAMESPACE_ENTER
ExportParams::ExportParams() :
video_scaling_method_(kStretch),
has_custom_range_(false)
{
}
const QString &ExportParams::encoder() const
{
return encoder_id_;
}
void ExportParams::set_encoder(const QString &id)
{
encoder_id_ = id;
}
bool ExportParams::has_custom_range() const
{
return has_custom_range_;
}
const TimeRange &ExportParams::custom_range() const
{
return custom_range_;
}
void ExportParams::set_custom_range(const TimeRange &custom_range)
{
has_custom_range_ = true;
custom_range_ = custom_range;
}
const ExportParams::VideoScalingMethod &ExportParams::video_scaling_method() const
{
return video_scaling_method_;
}
void ExportParams::set_video_scaling_method(const ExportParams::VideoScalingMethod &video_scaling_method)
{
video_scaling_method_ = video_scaling_method;
}
void ExportParams::set_ocio_output(const QString &display, const QString &view, const QString &look)
{
ocio_display_ = display;
ocio_view_ = view;
ocio_look_ = look;
}
const QString &ExportParams::ocio_display() const
{
return ocio_display_;
}
const QString &ExportParams::ocio_view() const
{
return ocio_view_;
}
const QString &ExportParams::ocio_look() const
{
return ocio_look_;
}
OLIVE_NAMESPACE_EXIT
+70
View File
@@ -0,0 +1,70 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 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/>.
***/
#ifndef EXPORTPARAMS_H
#define EXPORTPARAMS_H
#include "codec/encoder.h"
#include "node/output/viewer/viewer.h"
OLIVE_NAMESPACE_ENTER
class ExportParams : public EncodingParams {
public:
enum VideoScalingMethod {
kFit,
kStretch,
kCrop
};
ExportParams();
const QString& encoder() const;
void set_encoder(const QString& id);
bool has_custom_range() const;
const TimeRange& custom_range() const;
void set_custom_range(const TimeRange& custom_range);
const VideoScalingMethod& video_scaling_method() const;
void set_video_scaling_method(const VideoScalingMethod& video_scaling_method);
const QString& ocio_display() const;
const QString& ocio_view() const;
const QString& ocio_look() const;
void set_ocio_output(const QString& display, const QString& view, const QString& look);
private:
QString encoder_id_;
VideoScalingMethod video_scaling_method_;
bool has_custom_range_;
TimeRange custom_range_;
QString ocio_display_;
QString ocio_view_;
QString ocio_look_;
};
OLIVE_NAMESPACE_EXIT
#endif // EXPORTPARAMS_H