began work on headless export path
This commit is contained in:
@@ -30,6 +30,7 @@ if (WIN32)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(audio)
|
add_subdirectory(audio)
|
||||||
|
add_subdirectory(cli)
|
||||||
add_subdirectory(codec)
|
add_subdirectory(codec)
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(config)
|
add_subdirectory(config)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
add_subdirectory(cliprogress)
|
||||||
|
add_subdirectory(clitask)
|
||||||
|
|
||||||
|
set(OLIVE_SOURCES
|
||||||
|
${OLIVE_SOURCES}
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
set(OLIVE_SOURCES
|
||||||
|
${OLIVE_SOURCES}
|
||||||
|
cli/cliprogress/cliprogressdialog.h
|
||||||
|
cli/cliprogress/cliprogressdialog.cpp
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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 "cliprogressdialog.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
CLIProgressDialog::CLIProgressDialog(const QString& title, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
title_(title),
|
||||||
|
progress_(0),
|
||||||
|
drawn_(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLIProgressDialog::Update()
|
||||||
|
{
|
||||||
|
if (drawn_) {
|
||||||
|
// We've been here before, do a carriage return back to the start of the terminal line
|
||||||
|
std::cout << "\r";
|
||||||
|
} else {
|
||||||
|
drawn_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Get real column count
|
||||||
|
int columns = 80;
|
||||||
|
|
||||||
|
int title_columns = columns / 2 - 1;
|
||||||
|
|
||||||
|
// Print "title" text
|
||||||
|
QString sized_title = title_;
|
||||||
|
|
||||||
|
if (title_.size() > title_columns) {
|
||||||
|
sized_title = title_.left(title_columns - 3).append(QStringLiteral("..."));
|
||||||
|
} else {
|
||||||
|
sized_title = title_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << sized_title.toUtf8().constData();
|
||||||
|
|
||||||
|
// Pad out the rest of the title area if necessary
|
||||||
|
for (int i=sized_title.size(); i<title_columns; i++) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Percentage counter " 100% " is 5 characters + the enclosing brackets [] are 2 characters
|
||||||
|
int progress_bar_columns = columns / 2 - 7;
|
||||||
|
|
||||||
|
std::cout << "[";
|
||||||
|
|
||||||
|
// Get UI bar progress
|
||||||
|
int bar_prog = qRound(progress_ * 0.01 * progress_bar_columns);
|
||||||
|
|
||||||
|
// Draw filled in bar
|
||||||
|
for (int i=0;i<bar_prog;i++) {
|
||||||
|
std::cout << "=";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw empty space
|
||||||
|
for (int i=bar_prog;i<progress_bar_columns;i++) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "] ";
|
||||||
|
|
||||||
|
if (progress_ < 100) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress_ < 10) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << progress_ << "% " << std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLIProgressDialog::SetProgress(int p)
|
||||||
|
{
|
||||||
|
if (progress_ != p) {
|
||||||
|
progress_ = p;
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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 CLIPROGRESSDIALOG_H
|
||||||
|
#define CLIPROGRESSDIALOG_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "common/define.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
class CLIProgressDialog : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CLIProgressDialog(const QString &title, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void SetProgress(int p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
QString title_;
|
||||||
|
|
||||||
|
int progress_;
|
||||||
|
|
||||||
|
bool drawn_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
|
|
||||||
|
#endif // CLIPROGRESSDIALOG_H
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
set(OLIVE_SOURCES
|
||||||
|
${OLIVE_SOURCES}
|
||||||
|
cli/clitask/clitaskdialog.h
|
||||||
|
cli/clitask/clitaskdialog.cpp
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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 "clitaskdialog.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
CLITaskDialog::CLITaskDialog(Task *task, QObject* parent) :
|
||||||
|
CLIProgressDialog(task->GetTitle(), parent)
|
||||||
|
{
|
||||||
|
//connect(task, &Task::ProgressChanged, this, &CLITaskDialog::SetProgress);
|
||||||
|
|
||||||
|
task->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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 CLITASKDIALOG_H
|
||||||
|
#define CLITASKDIALOG_H
|
||||||
|
|
||||||
|
#include "cli/cliprogress/cliprogressdialog.h"
|
||||||
|
#include "task/task.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
class CLITaskDialog : public CLIProgressDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CLITaskDialog(Task *task, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Task* task_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
|
|
||||||
|
#endif // CLITASKDIALOG_H
|
||||||
+73
-27
@@ -31,6 +31,7 @@
|
|||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
|
||||||
#include "audio/audiomanager.h"
|
#include "audio/audiomanager.h"
|
||||||
|
#include "cli/clitask/clitaskdialog.h"
|
||||||
#include "common/filefunctions.h"
|
#include "common/filefunctions.h"
|
||||||
#include "common/xmlutils.h"
|
#include "common/xmlutils.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
@@ -67,7 +68,8 @@ Core::Core() :
|
|||||||
main_window_(nullptr),
|
main_window_(nullptr),
|
||||||
tool_(Tool::kPointer),
|
tool_(Tool::kPointer),
|
||||||
addable_object_(Tool::kAddableEmpty),
|
addable_object_(Tool::kAddableEmpty),
|
||||||
snapping_(true)
|
snapping_(true),
|
||||||
|
gui_active_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ Core *Core::instance()
|
|||||||
return &instance_;
|
return &instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Start()
|
bool Core::Start()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
@@ -97,6 +99,10 @@ void Core::Start()
|
|||||||
QCommandLineOption fullscreen_option({"f", "fullscreen"}, tr("Start in full screen mode"));
|
QCommandLineOption fullscreen_option({"f", "fullscreen"}, tr("Start in full screen mode"));
|
||||||
parser.addOption(fullscreen_option);
|
parser.addOption(fullscreen_option);
|
||||||
|
|
||||||
|
// Create headless export option
|
||||||
|
QCommandLineOption headless_export_option({"x", "export"}, tr("Export project from command line"));
|
||||||
|
parser.addOption(headless_export_option);
|
||||||
|
|
||||||
// Parse options
|
// Parse options
|
||||||
parser.process(*app);
|
parser.process(*app);
|
||||||
|
|
||||||
@@ -116,6 +122,12 @@ void Core::Start()
|
|||||||
// Set up the index manager for renderers
|
// Set up the index manager for renderers
|
||||||
IndexManager::CreateInstance();
|
IndexManager::CreateInstance();
|
||||||
|
|
||||||
|
// Initialize disk service
|
||||||
|
DiskManager::CreateInstance();
|
||||||
|
|
||||||
|
// Initialize task manager
|
||||||
|
TaskManager::CreateInstance();
|
||||||
|
|
||||||
// Reset config (Config sets to default on construction already, but we do it again here as a workaround that fixes
|
// Reset config (Config sets to default on construction already, but we do it again here as a workaround that fixes
|
||||||
// the fact that some of the config paths set by default rely on the app name having been set (in main())
|
// the fact that some of the config paths set by default rely on the app name having been set (in main())
|
||||||
Config::Current().SetDefaults();
|
Config::Current().SetDefaults();
|
||||||
@@ -139,26 +151,56 @@ void Core::Start()
|
|||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start GUI (FIXME CLI mode)
|
// Start application
|
||||||
//
|
//
|
||||||
|
|
||||||
StartGUI(parser.isSet(fullscreen_option));
|
qInfo() << "Using Qt version:" << qVersion();
|
||||||
|
|
||||||
// Load startup project
|
gui_active_ = !parser.isSet(headless_export_option);
|
||||||
if (!startup_project_.isEmpty() && !QFileInfo::exists(startup_project_)) {
|
|
||||||
QMessageBox::warning(main_window(),
|
|
||||||
tr("Failed to open startup file"),
|
|
||||||
tr("The project \"%1\" doesn't exist. A new project will be started instead.").arg(startup_project_),
|
|
||||||
QMessageBox::Ok);
|
|
||||||
|
|
||||||
startup_project_.clear();
|
if (gui_active_) {
|
||||||
}
|
|
||||||
|
// Start GUI
|
||||||
|
StartGUI(parser.isSet(fullscreen_option));
|
||||||
|
|
||||||
|
// Load startup project
|
||||||
|
if (!startup_project_.isEmpty() && !QFileInfo::exists(startup_project_)) {
|
||||||
|
QMessageBox::warning(main_window(),
|
||||||
|
tr("Failed to open startup file"),
|
||||||
|
tr("The project \"%1\" doesn't exist. A new project will be started instead.").arg(startup_project_),
|
||||||
|
QMessageBox::Ok);
|
||||||
|
|
||||||
|
startup_project_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startup_project_.isEmpty()) {
|
||||||
|
// If no load project is set, create a new one on open
|
||||||
|
CreateNewProject();
|
||||||
|
} else {
|
||||||
|
OpenProjectInternal(startup_project_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
if (startup_project_.isEmpty()) {
|
|
||||||
// If no load project is set, create a new one on open
|
|
||||||
CreateNewProject();
|
|
||||||
} else {
|
} else {
|
||||||
OpenProjectInternal(startup_project_);
|
|
||||||
|
if (parser.isSet(headless_export_option)) {
|
||||||
|
|
||||||
|
if (startup_project_.isEmpty()) {
|
||||||
|
qCritical().noquote() << tr("You must specify a project file to export");
|
||||||
|
} else {
|
||||||
|
OpenProjectInternal(startup_project_);
|
||||||
|
|
||||||
|
qDebug() << "Ready for exporting!";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error fallback
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,12 +567,6 @@ void Core::StartGUI(bool full_screen)
|
|||||||
// Initialize audio service
|
// Initialize audio service
|
||||||
AudioManager::CreateInstance();
|
AudioManager::CreateInstance();
|
||||||
|
|
||||||
// Initialize disk service
|
|
||||||
DiskManager::CreateInstance();
|
|
||||||
|
|
||||||
// Initialize task manager
|
|
||||||
TaskManager::CreateInstance();
|
|
||||||
|
|
||||||
// Initialize pixel service
|
// Initialize pixel service
|
||||||
PixelFormat::CreateInstance();
|
PixelFormat::CreateInstance();
|
||||||
|
|
||||||
@@ -843,12 +879,22 @@ void Core::OpenProjectInternal(const QString &filename)
|
|||||||
|
|
||||||
ProjectLoadManager* plm = new ProjectLoadManager(filename);
|
ProjectLoadManager* plm = new ProjectLoadManager(filename);
|
||||||
|
|
||||||
// We use a blocking queued connection here because we want to ensure we have this project instance before the
|
if (gui_active_) {
|
||||||
// ProjectLoadManager is destroyed
|
|
||||||
connect(plm, &ProjectLoadManager::ProjectLoaded, this, &Core::AddOpenProject, Qt::BlockingQueuedConnection);
|
|
||||||
|
|
||||||
TaskDialog* task_dialog = new TaskDialog(plm, tr("Load Project"), main_window());
|
// We use a blocking queued connection here because we want to ensure we have this project instance before the
|
||||||
task_dialog->open();
|
// ProjectLoadManager is destroyed
|
||||||
|
connect(plm, &ProjectLoadManager::ProjectLoaded, this, &Core::AddOpenProject, Qt::BlockingQueuedConnection);
|
||||||
|
|
||||||
|
TaskDialog* task_dialog = new TaskDialog(plm, tr("Load Project"), main_window());
|
||||||
|
task_dialog->open();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
connect(plm, &ProjectLoadManager::ProjectLoaded, this, &Core::AddOpenProject);
|
||||||
|
|
||||||
|
CLITaskDialog task_dialog(plm);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Core::CountFilesInFileList(const QFileInfoList &filenames)
|
int Core::CountFilesInFileList(const QFileInfoList &filenames)
|
||||||
|
|||||||
+6
-1
@@ -71,7 +71,7 @@ public:
|
|||||||
*
|
*
|
||||||
* Main application launcher. Parses command line arguments and constructs main window (if entering a GUI mode).
|
* Main application launcher. Parses command line arguments and constructs main window (if entering a GUI mode).
|
||||||
*/
|
*/
|
||||||
void Start();
|
bool Start();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stop Olive Core
|
* @brief Stop Olive Core
|
||||||
@@ -464,6 +464,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
QStringList recent_projects_;
|
QStringList recent_projects_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal variable for whether the GUI is active
|
||||||
|
*/
|
||||||
|
bool gui_active_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Static singleton core instance
|
* @brief Static singleton core instance
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "project/item/sequence/sequence.h"
|
#include "project/item/sequence/sequence.h"
|
||||||
#include "project/project.h"
|
#include "project/project.h"
|
||||||
|
#include "render/backend/exportparams.h"
|
||||||
#include "render/pixelformat.h"
|
#include "render/pixelformat.h"
|
||||||
#include "ui/icons/icons.h"
|
#include "ui/icons/icons.h"
|
||||||
#include "window/mainwindow/mainwindow.h"
|
#include "window/mainwindow/mainwindow.h"
|
||||||
@@ -238,9 +239,9 @@ void ExportDialog::accept()
|
|||||||
{
|
{
|
||||||
if (!video_enabled_->isChecked() && !audio_enabled_->isChecked()) {
|
if (!video_enabled_->isChecked() && !audio_enabled_->isChecked()) {
|
||||||
QMessageBox::critical(this,
|
QMessageBox::critical(this,
|
||||||
tr("Invalid parameters"),
|
tr("Invalid parameters"),
|
||||||
tr("Both video and audio are disabled. There's nothing to export."),
|
tr("Both video and audio are disabled. There's nothing to export."),
|
||||||
QMessageBox::Ok);
|
QMessageBox::Ok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,70 +283,8 @@ void ExportDialog::accept()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMatrix4x4 transform;
|
// Set up export parameters
|
||||||
|
exporter_ = new Exporter(viewer_node_, color_manager_, GenerateParams());
|
||||||
int dest_width = static_cast<int>(video_tab_->width_slider()->GetValue());
|
|
||||||
int dest_height = static_cast<int>(video_tab_->height_slider()->GetValue());
|
|
||||||
|
|
||||||
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<ExportVideoTab::ScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
|
||||||
source_width,
|
|
||||||
source_height,
|
|
||||||
dest_width,
|
|
||||||
dest_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderMode::Mode render_mode = RenderMode::kOnline;
|
|
||||||
|
|
||||||
VideoRenderingParams video_render_params(dest_width,
|
|
||||||
dest_height,
|
|
||||||
video_tab_->frame_rate().flipped(),
|
|
||||||
PixelFormat::instance()->GetConfiguredFormatForMode(render_mode),
|
|
||||||
render_mode);
|
|
||||||
|
|
||||||
AudioRenderingParams audio_render_params(audio_tab_->sample_rate_combobox()->currentData().toInt(),
|
|
||||||
audio_tab_->channel_layout_combobox()->currentData().toULongLong(),
|
|
||||||
SampleFormat::GetConfiguredFormatForMode(render_mode));
|
|
||||||
|
|
||||||
ColorProcessorPtr color_processor = ColorProcessor::Create(color_manager_,
|
|
||||||
color_manager_->GetReferenceColorSpace(),
|
|
||||||
video_tab_->CurrentOCIODisplay(),
|
|
||||||
video_tab_->CurrentOCIOView(),
|
|
||||||
video_tab_->CurrentOCIOLook());
|
|
||||||
|
|
||||||
// Set up encoder
|
|
||||||
EncodingParams encoding_params;
|
|
||||||
encoding_params.SetFilename(filename_edit_->text());
|
|
||||||
encoding_params.SetExportLength(viewer_node_->Length());
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
video_tab_->GetCodecSection()->AddOpts(&encoding_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
exporter_ = new Exporter(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::ExportEnded, this, &ExportDialog::ExporterIsDone);
|
||||||
connect(exporter_, &Exporter::ProgressChanged, this, &ExportDialog::ProgressUpdated);
|
connect(exporter_, &Exporter::ProgressChanged, this, &ExportDialog::ProgressUpdated);
|
||||||
@@ -556,30 +495,6 @@ void ExportDialog::SetDefaultFilename()
|
|||||||
filename_edit_->setText(file_location);
|
filename_edit_->setText(file_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMatrix4x4 ExportDialog::GenerateMatrix(ExportVideoTab::ScalingMethod method, int source_width, int source_height, int dest_width, int dest_height)
|
|
||||||
{
|
|
||||||
QMatrix4x4 preview_matrix;
|
|
||||||
|
|
||||||
if (method == ExportVideoTab::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 == ExportVideoTab::kFit)) {
|
|
||||||
preview_matrix.scale(source_ar / export_ar, 1.0F);
|
|
||||||
} else {
|
|
||||||
preview_matrix.scale(1.0F, export_ar / source_ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
return preview_matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExportDialog::SetUIElementsEnabled(bool enabled)
|
void ExportDialog::SetUIElementsEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
preferences_area_->setEnabled(enabled);
|
preferences_area_->setEnabled(enabled);
|
||||||
@@ -589,6 +504,49 @@ void ExportDialog::SetUIElementsEnabled(bool enabled)
|
|||||||
elapsed_label_->setEnabled(!enabled);
|
elapsed_label_->setEnabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExportParams ExportDialog::GenerateParams() const
|
||||||
|
{
|
||||||
|
RenderMode::Mode render_mode = RenderMode::kOnline;
|
||||||
|
|
||||||
|
VideoRenderingParams video_render_params(static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||||
|
static_cast<int>(video_tab_->height_slider()->GetValue()),
|
||||||
|
video_tab_->frame_rate().flipped(),
|
||||||
|
PixelFormat::instance()->GetConfiguredFormatForMode(render_mode),
|
||||||
|
render_mode);
|
||||||
|
|
||||||
|
AudioRenderingParams audio_render_params(audio_tab_->sample_rate_combobox()->currentData().toInt(),
|
||||||
|
audio_tab_->channel_layout_combobox()->currentData().toULongLong(),
|
||||||
|
SampleFormat::GetConfiguredFormatForMode(render_mode));
|
||||||
|
|
||||||
|
ExportParams params;
|
||||||
|
params.SetFilename(filename_edit_->text());
|
||||||
|
params.SetExportLength(viewer_node_->Length());
|
||||||
|
|
||||||
|
if (video_tab_->scaling_method_combobox()->isEnabled()) {
|
||||||
|
params.set_video_scaling_method(static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video_enabled_->isChecked()) {
|
||||||
|
const ExportCodec& video_codec = codecs_.at(video_tab_->codec_combobox()->currentData().toInt());
|
||||||
|
params.EnableVideo(video_render_params,
|
||||||
|
video_codec.id());
|
||||||
|
|
||||||
|
video_tab_->GetCodecSection()->AddOpts(¶ms);
|
||||||
|
|
||||||
|
params.set_ocio_output(video_tab_->CurrentOCIODisplay(),
|
||||||
|
video_tab_->CurrentOCIOView(),
|
||||||
|
video_tab_->CurrentOCIOLook());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audio_enabled_->isChecked()) {
|
||||||
|
const ExportCodec& audio_codec = codecs_.at(audio_tab_->codec_combobox()->currentData().toInt());
|
||||||
|
params.EnableAudio(audio_render_params,
|
||||||
|
audio_codec.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
void ExportDialog::UpdateTimeLabels()
|
void ExportDialog::UpdateTimeLabels()
|
||||||
{
|
{
|
||||||
qint64 elapsed, remaining;
|
qint64 elapsed, remaining;
|
||||||
@@ -641,11 +599,11 @@ void ExportDialog::UpdateViewerDimensions()
|
|||||||
preview_viewer_->SetOverrideSize(static_cast<int>(video_tab_->width_slider()->GetValue()),
|
preview_viewer_->SetOverrideSize(static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||||
static_cast<int>(video_tab_->height_slider()->GetValue()));
|
static_cast<int>(video_tab_->height_slider()->GetValue()));
|
||||||
|
|
||||||
preview_viewer_->SetMatrix(GenerateMatrix(static_cast<ExportVideoTab::ScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
preview_viewer_->SetMatrix(Exporter::GenerateMatrix(static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
||||||
viewer_node_->video_params().width(),
|
viewer_node_->video_params().width(),
|
||||||
viewer_node_->video_params().height(),
|
viewer_node_->video_params().height(),
|
||||||
static_cast<int>(video_tab_->width_slider()->GetValue()),
|
static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||||
static_cast<int>(video_tab_->height_slider()->GetValue())));
|
static_cast<int>(video_tab_->height_slider()->GetValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportDialog::ExporterIsDone()
|
void ExportDialog::ExporterIsDone()
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ private:
|
|||||||
void LoadPresets();
|
void LoadPresets();
|
||||||
void SetDefaultFilename();
|
void SetDefaultFilename();
|
||||||
|
|
||||||
QMatrix4x4 GenerateMatrix(ExportVideoTab::ScalingMethod method, int source_width, int source_height, int dest_width, int height);
|
|
||||||
|
|
||||||
void SetUIElementsEnabled(bool enabled);
|
void SetUIElementsEnabled(bool enabled);
|
||||||
|
|
||||||
|
ExportParams GenerateParams() const;
|
||||||
|
|
||||||
static QString TimeToString(int64_t ms);
|
static QString TimeToString(int64_t ms);
|
||||||
|
|
||||||
ViewerOutput* viewer_node_;
|
ViewerOutput* viewer_node_;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "render/backend/exportparams.h"
|
||||||
#include "render/colormanager.h"
|
#include "render/colormanager.h"
|
||||||
|
|
||||||
OLIVE_NAMESPACE_ENTER
|
OLIVE_NAMESPACE_ENTER
|
||||||
@@ -150,9 +151,9 @@ QWidget* ExportVideoTab::SetupResolutionSection()
|
|||||||
|
|
||||||
scaling_method_combobox_ = new QComboBox();
|
scaling_method_combobox_ = new QComboBox();
|
||||||
scaling_method_combobox_->setEnabled(false);
|
scaling_method_combobox_->setEnabled(false);
|
||||||
scaling_method_combobox_->addItem(tr("Fit"), kFit);
|
scaling_method_combobox_->addItem(tr("Fit"), ExportParams::kFit);
|
||||||
scaling_method_combobox_->addItem(tr("Stretch"), kStretch);
|
scaling_method_combobox_->addItem(tr("Stretch"), ExportParams::kStretch);
|
||||||
scaling_method_combobox_->addItem(tr("Crop"), kCrop);
|
scaling_method_combobox_->addItem(tr("Crop"), ExportParams::kCrop);
|
||||||
layout->addWidget(scaling_method_combobox_, row, 1);
|
layout->addWidget(scaling_method_combobox_, row, 1);
|
||||||
|
|
||||||
// Automatically enable/disable the scaling method depending on maintain aspect ratio
|
// Automatically enable/disable the scaling method depending on maintain aspect ratio
|
||||||
|
|||||||
@@ -40,12 +40,6 @@ class ExportVideoTab : public QWidget
|
|||||||
public:
|
public:
|
||||||
ExportVideoTab(ColorManager* color_manager, QWidget* parent = nullptr);
|
ExportVideoTab(ColorManager* color_manager, QWidget* parent = nullptr);
|
||||||
|
|
||||||
enum ScalingMethod {
|
|
||||||
kFit,
|
|
||||||
kStretch,
|
|
||||||
kCrop
|
|
||||||
};
|
|
||||||
|
|
||||||
QComboBox* codec_combobox() const;
|
QComboBox* codec_combobox() const;
|
||||||
|
|
||||||
IntegerSlider* width_slider() const;
|
IntegerSlider* width_slider() const;
|
||||||
|
|||||||
+13
-6
@@ -66,8 +66,6 @@ int main(int argc, char *argv[]) {
|
|||||||
app_version.append(GITHASH);
|
app_version.append(GITHASH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qInfo() << "Using Qt version:" << qVersion();
|
|
||||||
|
|
||||||
QCoreApplication::setApplicationVersion(app_version);
|
QCoreApplication::setApplicationVersion(app_version);
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
|
||||||
@@ -85,11 +83,20 @@ int main(int argc, char *argv[]) {
|
|||||||
avfilter_register_all();
|
avfilter_register_all();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Start core
|
int exit_code;
|
||||||
OLIVE_NAMESPACE::Core::instance()->Start();
|
|
||||||
|
|
||||||
// Run application loop and receive exit code
|
// Start core
|
||||||
int exit_code = a.exec();
|
if (OLIVE_NAMESPACE::Core::instance()->Start()) {
|
||||||
|
|
||||||
|
// Run application loop and receive exit code
|
||||||
|
exit_code = a.exec();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Core failed to start, exit now
|
||||||
|
exit_code = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Clear core memory
|
// Clear core memory
|
||||||
OLIVE_NAMESPACE::Core::instance()->Stop();
|
OLIVE_NAMESPACE::Core::instance()->Stop();
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ set(OLIVE_SOURCES
|
|||||||
|
|
||||||
render/backend/exporter.h
|
render/backend/exporter.h
|
||||||
render/backend/exporter.cpp
|
render/backend/exporter.cpp
|
||||||
|
render/backend/exportparams.h
|
||||||
|
render/backend/exportparams.cpp
|
||||||
|
|
||||||
render/backend/renderbackend.h
|
render/backend/renderbackend.h
|
||||||
render/backend/renderbackend.cpp
|
render/backend/renderbackend.cpp
|
||||||
|
|||||||
@@ -27,46 +27,52 @@
|
|||||||
|
|
||||||
OLIVE_NAMESPACE_ENTER
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
Exporter::Exporter(ViewerOutput* viewer,
|
Exporter::Exporter(ViewerOutput *viewer_node,
|
||||||
Encoder *encoder,
|
ColorManager *color_manager,
|
||||||
|
const ExportParams& params,
|
||||||
QObject* parent) :
|
QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
|
viewer_node_(viewer_node),
|
||||||
|
params_(params),
|
||||||
video_backend_(nullptr),
|
video_backend_(nullptr),
|
||||||
audio_backend_(nullptr),
|
audio_backend_(nullptr),
|
||||||
viewer_node_(viewer),
|
|
||||||
video_done_(true),
|
|
||||||
audio_done_(true),
|
|
||||||
encoder_(encoder),
|
|
||||||
export_status_(false),
|
export_status_(false),
|
||||||
export_msg_(tr("Export hasn't started yet"))
|
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);
|
debug_timer_.setInterval(5000);
|
||||||
connect(&debug_timer_, &QTimer::timeout, this, &Exporter::DebugTimerMessage);
|
connect(&debug_timer_, &QTimer::timeout, this, &Exporter::DebugTimerMessage);
|
||||||
|
|
||||||
connect(this, &Exporter::ExportEnded, this, &Exporter::deleteLater);
|
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)
|
if (params_.video_enabled()) {
|
||||||
{
|
|
||||||
video_params_ = video_params;
|
|
||||||
transform_ = transform;
|
|
||||||
color_processor_ = color_processor;
|
|
||||||
|
|
||||||
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)
|
// Create color processor
|
||||||
{
|
color_processor_ = ColorProcessor::Create(color_manager,
|
||||||
audio_params_ = audio_params;
|
color_manager->GetReferenceColorSpace(),
|
||||||
|
params.ocio_display(),
|
||||||
audio_done_ = false;
|
params.ocio_view(),
|
||||||
}
|
params.ocio_look());
|
||||||
|
}
|
||||||
void Exporter::OverrideExportRange(const TimeRange &range)
|
|
||||||
{
|
|
||||||
export_range_ = range;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Exporter::GetExportStatus() const
|
bool Exporter::GetExportStatus() const
|
||||||
@@ -110,9 +116,9 @@ void Exporter::StartExporting()
|
|||||||
video_backend_->SetViewerNode(viewer_node_);
|
video_backend_->SetViewerNode(viewer_node_);
|
||||||
video_backend_->SetParameters(VideoRenderingParams(viewer_node_->video_params().width(),
|
video_backend_->SetParameters(VideoRenderingParams(viewer_node_->video_params().width(),
|
||||||
viewer_node_->video_params().height(),
|
viewer_node_->video_params().height(),
|
||||||
video_params_.time_base(),
|
params_.video_params().time_base(),
|
||||||
video_params_.format(),
|
params_.video_params().format(),
|
||||||
video_params_.mode()));
|
params_.video_params().mode()));
|
||||||
|
|
||||||
waiting_for_frame_ = 0;
|
waiting_for_frame_ = 0;
|
||||||
}
|
}
|
||||||
@@ -121,7 +127,7 @@ void Exporter::StartExporting()
|
|||||||
audio_backend_ = new AudioBackend();
|
audio_backend_ = new AudioBackend();
|
||||||
|
|
||||||
audio_backend_->SetViewerNode(viewer_node_);
|
audio_backend_->SetViewerNode(viewer_node_);
|
||||||
audio_backend_->SetParameters(audio_params_);
|
audio_backend_->SetParameters(params_.audio_params());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open encoder and wait for result
|
// Open encoder and wait for result
|
||||||
@@ -190,7 +196,7 @@ void Exporter::EncodeFrame()
|
|||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
OLIVE_NS_ARG(FramePtr, frame));
|
OLIVE_NS_ARG(FramePtr, frame));
|
||||||
|
|
||||||
waiting_for_frame_ += video_params_.time_base();
|
waiting_for_frame_ += params_.video_params().time_base();
|
||||||
|
|
||||||
// Calculate progress
|
// Calculate progress
|
||||||
emit ProgressChanged(waiting_for_frame_.toDouble() / viewer_node_->Length().toDouble());
|
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)
|
void Exporter::FrameRendered(const rational &time, FramePtr value)
|
||||||
{
|
{
|
||||||
debug_timer_.stop();
|
debug_timer_.stop();
|
||||||
@@ -261,14 +291,14 @@ void Exporter::EncoderOpenedSuccessfully()
|
|||||||
video_backend_->SetOperatingMode(VideoRenderWorker::kHashOnly);
|
video_backend_->SetOperatingMode(VideoRenderWorker::kHashOnly);
|
||||||
connect(video_backend_, &VideoRenderBackend::QueueComplete, this, &Exporter::VideoHashesComplete);
|
connect(video_backend_, &VideoRenderBackend::QueueComplete, this, &Exporter::VideoHashesComplete);
|
||||||
|
|
||||||
video_backend_->InvalidateCache(TimeRange(0, viewer_node_->Length()));
|
video_backend_->InvalidateCache(export_range_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!audio_done_) {
|
if (!audio_done_) {
|
||||||
// We set the audio backend to render the full sequence to the disk
|
// We set the audio backend to render the full sequence to the disk
|
||||||
connect(audio_backend_, &AudioRenderBackend::AudioComplete, this, &Exporter::AudioRendered);
|
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_->SetOperatingMode(VideoRenderWorker::kRenderOnly);
|
||||||
video_backend_->SetOnlySignalLastFrameRequested(false);
|
video_backend_->SetOnlySignalLastFrameRequested(false);
|
||||||
|
|
||||||
// FIXME: Exporting is now broken because of this
|
|
||||||
connect(video_backend_, &VideoRenderBackend::GeneratedFrame, this, &Exporter::FrameRendered);
|
connect(video_backend_, &VideoRenderBackend::GeneratedFrame, this, &Exporter::FrameRendered);
|
||||||
|
|
||||||
foreach (const TimeRange& range, ranges) {
|
foreach (const TimeRange& range, ranges) {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "codec/encoder.h"
|
#include "codec/encoder.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
#include "render/backend/audiorenderbackend.h"
|
#include "render/backend/audiorenderbackend.h"
|
||||||
|
#include "render/backend/exportparams.h"
|
||||||
#include "render/backend/videorenderbackend.h"
|
#include "render/backend/videorenderbackend.h"
|
||||||
#include "render/colorprocessor.h"
|
#include "render/colorprocessor.h"
|
||||||
|
|
||||||
@@ -38,20 +39,18 @@ class Exporter : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Exporter(ViewerOutput* viewer,
|
Exporter(ViewerOutput* viewer_node,
|
||||||
Encoder* encoder,
|
ColorManager* color_manager,
|
||||||
|
const ExportParams& params,
|
||||||
QObject* parent = nullptr);
|
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;
|
bool GetExportStatus() const;
|
||||||
const QString& GetExportError() const;
|
const QString& GetExportError() const;
|
||||||
|
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
|
static QMatrix4x4 GenerateMatrix(ExportParams::VideoScalingMethod method, int source_width, int source_height, int dest_width, int dest_height);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void StartExporting();
|
void StartExporting();
|
||||||
|
|
||||||
@@ -63,17 +62,23 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
void SetExportMessage(const QString& s);
|
void SetExportMessage(const QString& s);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ExportSucceeded();
|
||||||
|
|
||||||
|
void ExportStopped();
|
||||||
|
|
||||||
|
void EncodeFrame();
|
||||||
|
|
||||||
|
ViewerOutput* viewer_node_;
|
||||||
|
|
||||||
|
ColorProcessorPtr color_processor_;
|
||||||
|
|
||||||
|
ExportParams params_;
|
||||||
|
|
||||||
// Renderers
|
// Renderers
|
||||||
VideoRenderBackend* video_backend_;
|
VideoRenderBackend* video_backend_;
|
||||||
AudioRenderBackend* audio_backend_;
|
AudioRenderBackend* audio_backend_;
|
||||||
|
|
||||||
// Viewer node
|
|
||||||
ViewerOutput* viewer_node_;
|
|
||||||
|
|
||||||
// Export parameters
|
|
||||||
VideoRenderingParams video_params_;
|
|
||||||
AudioRenderingParams audio_params_;
|
|
||||||
|
|
||||||
// Export transform
|
// Export transform
|
||||||
QMatrix4x4 transform_;
|
QMatrix4x4 transform_;
|
||||||
|
|
||||||
@@ -81,23 +86,14 @@ protected:
|
|||||||
|
|
||||||
bool audio_done_;
|
bool audio_done_;
|
||||||
|
|
||||||
TimeRange export_range_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ExportSucceeded();
|
|
||||||
|
|
||||||
void ExportStopped();
|
|
||||||
|
|
||||||
void EncodeFrame();
|
|
||||||
|
|
||||||
ColorProcessorPtr color_processor_;
|
|
||||||
|
|
||||||
Encoder* encoder_;
|
Encoder* encoder_;
|
||||||
|
|
||||||
bool export_status_;
|
bool export_status_;
|
||||||
|
|
||||||
QString export_msg_;
|
QString export_msg_;
|
||||||
|
|
||||||
|
TimeRange export_range_;
|
||||||
|
|
||||||
rational waiting_for_frame_;
|
rational waiting_for_frame_;
|
||||||
|
|
||||||
QHash<rational, FramePtr> cached_frames_;
|
QHash<rational, FramePtr> cached_frames_;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user