From b697d2faecc3a5a0750c02cb48edca7bcd0392e9 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 8 Jan 2020 02:59:30 +1100 Subject: [PATCH] implemented settings for exporting ONLY video or ONLY audio --- app/dialog/export/export.cpp | 73 +++++++++++++++----- app/dialog/export/export.h | 3 + app/dialog/export/exportvideotab.cpp | 8 +++ app/dialog/export/exportvideotab.h | 2 + app/render/backend/exporter.cpp | 63 ++++++++++------- app/render/backend/exporter.h | 15 ++-- app/render/backend/opengl/openglexporter.cpp | 33 ++++++--- app/render/backend/opengl/openglexporter.h | 4 -- 8 files changed, 136 insertions(+), 65 deletions(-) diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index a1734332c..b6d381122 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -82,6 +82,20 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : row++; + QHBoxLayout* av_enabled_layout = new QHBoxLayout(); + + video_enabled_ = new QCheckBox(tr("Export Video")); + video_enabled_->setChecked(true); + av_enabled_layout->addWidget(video_enabled_); + + audio_enabled_ = new QCheckBox(tr("Export Audio")); + audio_enabled_->setChecked(true); + av_enabled_layout->addWidget(audio_enabled_); + + preferences_layout->addLayout(av_enabled_layout, row, 0, 1, 4); + + row++; + QTabWidget* preferences_tabs = new QTabWidget(); QScrollArea* video_area = new QScrollArea(); color_manager_ = static_cast(viewer_node_->parent())->project()->color_manager(); @@ -167,16 +181,29 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : void ExportDialog::accept() { - int source_width = viewer_node_->video_params().width(); - int source_height = viewer_node_->video_params().height(); + if (!video_enabled_->isChecked() && !audio_enabled_->isChecked()) { + QMessageBox::warning(this, + tr("Invalid parameters"), + tr("Both video and audio are disabled. There's nothing to export."), + QMessageBox::Ok); + return; + } + + QMatrix4x4 transform; + int dest_width = video_tab_->width_slider()->GetValue(); int dest_height = video_tab_->height_slider()->GetValue(); - QMatrix4x4 transform = GenerateMatrix(static_cast(video_tab_->scaling_method_combobox()->currentData().toInt()), - source_width, - source_height, - dest_width, - dest_height); + if (video_tab_->scaling_method_combobox()->isEnabled()) { + int source_width = viewer_node_->video_params().width(); + int source_height = viewer_node_->video_params().height(); + + transform = GenerateMatrix(static_cast(video_tab_->scaling_method_combobox()->currentData().toInt()), + source_width, + source_height, + dest_width, + dest_height); + } // FIXME: Hardcoded pixel format VideoRenderingParams video_render_params(dest_width, dest_height, video_tab_->frame_rate().flipped(), PixelFormat::PIX_FMT_RGBA32F, RenderMode::kOnline); @@ -196,16 +223,29 @@ void ExportDialog::accept() EncodingParams encoding_params; encoding_params.SetFilename(filename_edit_->text()); // FIXME: Validate extension - const ExportCodec& video_codec = codecs_.at(video_tab_->codec_combobox()->currentData().toInt()); - const ExportCodec& audio_codec = codecs_.at(audio_tab_->codec_combobox()->currentData().toInt()); - encoding_params.EnableVideo(video_render_params, - video_codec.id()); - encoding_params.EnableAudio(audio_render_params, - audio_codec.id()); + if (video_enabled_->isChecked()) { + const ExportCodec& video_codec = codecs_.at(video_tab_->codec_combobox()->currentData().toInt()); + encoding_params.EnableVideo(video_render_params, + video_codec.id()); + } + + if (audio_enabled_->isChecked()) { + const ExportCodec& audio_codec = codecs_.at(audio_tab_->codec_combobox()->currentData().toInt()); + encoding_params.EnableAudio(audio_render_params, + audio_codec.id()); + } Encoder* encoder = Encoder::CreateFromID("ffmpeg", encoding_params); - OpenGLExporter* exporter = new OpenGLExporter(viewer_node_, video_render_params, audio_render_params, transform, color_processor, encoder); + OpenGLExporter* exporter = new OpenGLExporter(viewer_node_, encoder); + + if (video_enabled_->isChecked()) { + exporter->EnableVideo(video_render_params, transform, color_processor); + } + + if (audio_enabled_->isChecked()) { + exporter->EnableAudio(audio_render_params); + } connect(exporter, &Exporter::ExportEnded, this, &ExportDialog::ExporterIsDone); connect(exporter, &Exporter::ProgressChanged, progress_bar_, &QProgressBar::setValue); @@ -269,11 +309,6 @@ void ExportDialog::ResolutionChanged() // This catches both the width slider changing and the maintain aspect ratio checkbox changing video_tab_->height_slider()->SetValue(qRound(static_cast(video_tab_->width_slider()->GetValue()) / video_aspect_ratio_)); } - } else { - double current_ratio = static_cast(video_tab_->width_slider()->GetValue()) / static_cast(video_tab_->height_slider()->GetValue()); - - // Enable scaling method combobox only if width/height are not equal to sequence size - video_tab_->scaling_method_combobox()->setEnabled(!qFuzzyCompare(current_ratio, video_aspect_ratio_)); } UpdateViewerDimensions(); diff --git a/app/dialog/export/export.h b/app/dialog/export/export.h index ad99fdef4..619d534eb 100644 --- a/app/dialog/export/export.h +++ b/app/dialog/export/export.h @@ -33,6 +33,9 @@ private: QList formats_; int previously_selected_format_; + QCheckBox* video_enabled_; + QCheckBox* audio_enabled_; + QList codecs_; ViewerWidget* preview_viewer_; diff --git a/app/dialog/export/exportvideotab.cpp b/app/dialog/export/exportvideotab.cpp index 52bf59372..330a5ea35 100644 --- a/app/dialog/export/exportvideotab.cpp +++ b/app/dialog/export/exportvideotab.cpp @@ -124,6 +124,9 @@ QWidget* ExportVideoTab::SetupResolutionSection() scaling_method_combobox_->addItem(tr("Crop"), kCrop); layout->addWidget(scaling_method_combobox_, row, 1); + // Automatically enable/disable the scaling method depending on maintain aspect ratio + connect(maintain_aspect_checkbox_, &QCheckBox::toggled, this, &ExportVideoTab::MaintainAspectRatioChanged); + row++; layout->addWidget(new QLabel(tr("Frame Rate:")), row, 0); @@ -230,3 +233,8 @@ void ExportVideoTab::ColorLookChanged() { emit LookChanged(looks_combobox_->currentData().toString()); } + +void ExportVideoTab::MaintainAspectRatioChanged(bool val) +{ + scaling_method_combobox_->setEnabled(!val); +} diff --git a/app/dialog/export/exportvideotab.h b/app/dialog/export/exportvideotab.h index 03e06ec8c..8cffe5d60 100644 --- a/app/dialog/export/exportvideotab.h +++ b/app/dialog/export/exportvideotab.h @@ -71,6 +71,8 @@ private slots: void ColorViewChanged(); void ColorLookChanged(); + void MaintainAspectRatioChanged(bool val); + }; #endif // EXPORTVIDEOTAB_H diff --git a/app/render/backend/exporter.cpp b/app/render/backend/exporter.cpp index 5a4ed1c03..0d2e48e46 100644 --- a/app/render/backend/exporter.cpp +++ b/app/render/backend/exporter.cpp @@ -4,29 +4,37 @@ #include "render/pixelservice.h" Exporter::Exporter(ViewerOutput* viewer, - const VideoRenderingParams& video_params, - const AudioRenderingParams& audio_params, - const QMatrix4x4 &transform, - ColorProcessorPtr color_processor, Encoder *encoder, QObject* parent) : QObject(parent), video_backend_(nullptr), audio_backend_(nullptr), viewer_node_(viewer), - video_params_(video_params), - audio_params_(audio_params), - transform_(transform), - color_processor_(color_processor), + video_done_(true), + audio_done_(true), encoder_(encoder), export_status_(false), - export_msg_(tr("Export hasn't started yet")), - video_done_(false), - audio_done_(false) + export_msg_(tr("Export hasn't started yet")) { connect(this, &Exporter::ExportEnded, this, &Exporter::deleteLater); } +void Exporter::EnableVideo(const VideoRenderingParams &video_params, const QMatrix4x4 &transform, ColorProcessorPtr color_processor) +{ + video_params_ = video_params; + transform_ = transform; + color_processor_ = color_processor; + + video_done_ = false; +} + +void Exporter::EnableAudio(const AudioRenderingParams &audio_params) +{ + audio_params_ = audio_params; + + audio_done_ = false; +} + bool Exporter::GetExportStatus() const { return export_status_; @@ -49,17 +57,22 @@ void Exporter::StartExporting() return; } - 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())); - audio_backend_->SetViewerNode(viewer_node_); - audio_backend_->SetParameters(audio_params_); - // Create renderers - waiting_for_frame_ = 0; + if (!video_done_) { + 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())); + + waiting_for_frame_ = 0; + } + + if (!audio_done_) { + audio_backend_->SetViewerNode(viewer_node_); + audio_backend_->SetParameters(audio_params_); + } // Open encoder and wait for result connect(encoder_, &Encoder::OpenSucceeded, this, &Exporter::EncoderOpenedSuccessfully, Qt::QueuedConnection); @@ -85,7 +98,9 @@ void Exporter::ExportSucceeded() Cleanup(); - video_backend_->deleteLater(); + if (video_backend_) { + video_backend_->deleteLater(); + } export_status_ = true; @@ -196,7 +211,7 @@ void Exporter::AudioEncodeComplete() void Exporter::EncoderOpenedSuccessfully() { // Invalidate caches - if (encoder_->params().video_enabled()) { + if (!video_done_) { // First we generate the hashes so we know exactly how many frames we need video_backend_->SetOperatingMode(VideoRenderWorker::kHashOnly); connect(video_backend_, &VideoRenderBackend::QueueComplete, this, &Exporter::VideoHashesComplete); @@ -204,7 +219,7 @@ void Exporter::EncoderOpenedSuccessfully() video_backend_->InvalidateCache(0, viewer_node_->Length()); } - if (encoder_->params().audio_enabled()) { + if (!audio_done_) { // We set the audio backend to render the full sequence to the disk connect(audio_backend_, &AudioRenderBackend::QueueComplete, this, &Exporter::AudioRendered); diff --git a/app/render/backend/exporter.h b/app/render/backend/exporter.h index 1ab757179..eeac9c181 100644 --- a/app/render/backend/exporter.h +++ b/app/render/backend/exporter.h @@ -16,13 +16,12 @@ class Exporter : public QObject Q_OBJECT public: Exporter(ViewerOutput* viewer, - const VideoRenderingParams& video_params, - const AudioRenderingParams& audio_params, - const QMatrix4x4& transform, - ColorProcessorPtr color_processor, Encoder* encoder, QObject* parent = nullptr); + void EnableVideo(const VideoRenderingParams& video_params, const QMatrix4x4& transform, ColorProcessorPtr color_processor); + void EnableAudio(const AudioRenderingParams& audio_params); + bool GetExportStatus() const; const QString& GetExportError() const; @@ -56,6 +55,10 @@ protected: // Export transform QMatrix4x4 transform_; + bool video_done_; + + bool audio_done_; + private: void ExportSucceeded(); @@ -77,10 +80,6 @@ private: QHash< QByteArray, QList > matched_frames_; - bool video_done_; - - bool audio_done_; - private slots: void FrameRendered(const rational& time, QVariant value); diff --git a/app/render/backend/opengl/openglexporter.cpp b/app/render/backend/opengl/openglexporter.cpp index e85a03e15..6942b5294 100644 --- a/app/render/backend/opengl/openglexporter.cpp +++ b/app/render/backend/opengl/openglexporter.cpp @@ -3,8 +3,10 @@ #include "render/backend/opengl/openglrenderfunctions.h" #include "render/pixelservice.h" -OpenGLExporter::OpenGLExporter(ViewerOutput* viewer, const VideoRenderingParams& video_params, const AudioRenderingParams &audio_params, const QMatrix4x4 &transform, ColorProcessorPtr color_processor, Encoder *encoder, QObject* parent) : - Exporter(viewer, video_params, audio_params, transform, color_processor, encoder, parent) +OpenGLExporter::OpenGLExporter(ViewerOutput* viewer, Encoder *encoder, QObject* parent) : + Exporter(viewer, encoder, parent), + texture_(nullptr), + pipeline_(nullptr) { } @@ -17,23 +19,34 @@ bool OpenGLExporter::Initialize() QOpenGLContext* ctx = QOpenGLContext::currentContext(); // Create rendering backends - video_backend_ = new OpenGLBackend(); - audio_backend_ = new AudioBackend(); + if (!video_done_) { + video_backend_ = new OpenGLBackend(); - // Create blitting framebuffer and texture - buffer_.Create(ctx); + // Create blitting framebuffer and texture + buffer_.Create(ctx); - texture_ = std::make_shared(); - texture_->Create(ctx, video_params_.effective_width(), video_params_.effective_height(), video_params_.format()); + texture_ = std::make_shared(); + texture_->Create(ctx, video_params_.effective_width(), video_params_.effective_height(), video_params_.format()); - pipeline_ = OpenGLShader::CreateDefault(); + pipeline_ = OpenGLShader::CreateDefault(); + } + + if (!audio_done_) { + audio_backend_ = new AudioBackend(); + } return true; } void OpenGLExporter::Cleanup() { - texture_->Destroy(); + if (texture_) { + texture_->Destroy(); + texture_ = nullptr; + } + + pipeline_ = nullptr; + buffer_.Destroy(); } diff --git a/app/render/backend/opengl/openglexporter.h b/app/render/backend/opengl/openglexporter.h index 0ccec5461..868e8b15e 100644 --- a/app/render/backend/opengl/openglexporter.h +++ b/app/render/backend/opengl/openglexporter.h @@ -11,10 +11,6 @@ class OpenGLExporter : public Exporter { public: OpenGLExporter(ViewerOutput* viewer, - const VideoRenderingParams& video_params, - const AudioRenderingParams& audio_params, - const QMatrix4x4& transform, - ColorProcessorPtr color_processor, Encoder* encoder, QObject* parent = nullptr);