Merge branch 'master' into pr/1717

This commit is contained in:
itsmattkc
2022-05-01 10:58:44 -07:00
1583 changed files with 89018 additions and 321451 deletions
+7 -3
View File
@@ -16,11 +16,15 @@
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/export/codec/codecsection.h
dialog/export/codec/cineformsection.cpp
dialog/export/codec/cineformsection.h
dialog/export/codec/codecsection.cpp
dialog/export/codec/h264section.h
dialog/export/codec/codecsection.h
dialog/export/codec/codecstack.cpp
dialog/export/codec/codecstack.h
dialog/export/codec/h264section.cpp
dialog/export/codec/imagesection.h
dialog/export/codec/h264section.h
dialog/export/codec/imagesection.cpp
dialog/export/codec/imagesection.h
PARENT_SCOPE
)
@@ -0,0 +1,85 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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 "cineformsection.h"
#include <QGridLayout>
#include <QLabel>
namespace olive {
CineformSection::CineformSection(QWidget *parent) :
CodecSection(parent)
{
QGridLayout *layout = new QGridLayout(this);
layout->setMargin(0);
int row = 0;
layout->addWidget(new QLabel(tr("Quality:")), row, 0);
quality_combobox_ = new QComboBox();
/* Correspond to the following indexes for FFmpeg
*
* -quality <int> E..V....... set quality (from 0 to 12) (default film3+)
* film3+ 0 E..V.......
* film3 1 E..V.......
* film2+ 2 E..V.......
* film2 3 E..V.......
* film1.5 4 E..V.......
* film1+ 5 E..V.......
* film1 6 E..V.......
* high+ 7 E..V.......
* high 8 E..V.......
* medium+ 9 E..V.......
* medium 10 E..V.......
* low+ 11 E..V.......
* low 12 E..V.......
*
*/
quality_combobox_->addItem(tr("Film Scan 3+"));
quality_combobox_->addItem(tr("Film Scan 3"));
quality_combobox_->addItem(tr("Film Scan 2+"));
quality_combobox_->addItem(tr("Film Scan 2"));
quality_combobox_->addItem(tr("Film Scan 1.5"));
quality_combobox_->addItem(tr("Film Scan 1+"));
quality_combobox_->addItem(tr("Film Scan 1"));
quality_combobox_->addItem(tr("High+"));
quality_combobox_->addItem(tr("High"));
quality_combobox_->addItem(tr("Medium+"));
quality_combobox_->addItem(tr("Medium"));
quality_combobox_->addItem(tr("Low+"));
quality_combobox_->addItem(tr("Low"));
// Default to "medium"
quality_combobox_->setCurrentIndex(10);
layout->addWidget(quality_combobox_, row, 1);
}
void CineformSection::AddOpts(EncodingParams *params)
{
params->set_video_option(QStringLiteral("quality"), QString::number(quality_combobox_->currentIndex()));
}
}
+45
View File
@@ -0,0 +1,45 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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 CINEFORMSECTION_H
#define CINEFORMSECTION_H
#include <QComboBox>
#include "codecsection.h"
namespace olive {
class CineformSection : public CodecSection
{
Q_OBJECT
public:
CineformSection(QWidget *parent = nullptr);
virtual void AddOpts(EncodingParams* params) override;
private:
QComboBox *quality_combobox_;
};
}
#endif // CINEFORMSECTION_H
+53
View File
@@ -0,0 +1,53 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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 "codecstack.h"
namespace olive {
#define super QStackedWidget
CodecStack::CodecStack(QWidget *parent)
: super{parent}
{
connect(this, &CodecStack::currentChanged, this, &CodecStack::OnChange);
}
void CodecStack::addWidget(QWidget *widget)
{
super::addWidget(widget);
OnChange(currentIndex());
}
void CodecStack::OnChange(int index)
{
for (int i=0; i<count(); i++) {
if (i == index) {
widget(i)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
} else {
widget(i)->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
}
widget(i)->adjustSize();
}
adjustSize();
}
}
+45
View File
@@ -0,0 +1,45 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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 CODECSTACK_H
#define CODECSTACK_H
#include <QStackedWidget>
namespace olive {
class CodecStack : public QStackedWidget
{
Q_OBJECT
public:
explicit CodecStack(QWidget *parent = nullptr);
void addWidget(QWidget *widget);
signals:
private slots:
void OnChange(int index);
};
}
#endif // CODECSTACK_H
+27
View File
@@ -42,6 +42,31 @@ H264Section::H264Section(int default_crf, QWidget *parent) :
layout->setMargin(0);
int row = 0;
layout->addWidget(new QLabel(tr("Encode Speed:")), row, 0);
preset_combobox_ = new QComboBox();
preset_combobox_->setToolTip(tr("This setting allows you to tweak the ratio of export speed to compression quality. \n\n"
"If using Constant Rate Factor, slower speeds will result in smaller file sizes for the same quality. \n\n"
"If using Target Bit Rate or Target File Size, slower speeds will result in higher quality for the same bitrate/filesize. \n\n"
"This setting is equivalent to the `preset` setting in libx264."));
preset_combobox_->addItem(tr("Ultra Fast"));
preset_combobox_->addItem(tr("Super Fast"));
preset_combobox_->addItem(tr("Very Fast"));
preset_combobox_->addItem(tr("Faster"));
preset_combobox_->addItem(tr("Fast"));
preset_combobox_->addItem(tr("Medium"));
preset_combobox_->addItem(tr("Slow"));
preset_combobox_->addItem(tr("Slower"));
preset_combobox_->addItem(tr("Very Slow"));
//Default to "medium"
preset_combobox_->setCurrentIndex(5);
layout->addWidget(preset_combobox_, row, 1);
row++;
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
@@ -110,6 +135,8 @@ void H264Section::AddOpts(EncodingParams *params)
params->set_video_buffer_size(2000000);
}
params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex()));
}
H264CRFSection::H264CRFSection(int default_crf, QWidget *parent) :
+2
View File
@@ -23,6 +23,7 @@
#include <QSlider>
#include <QStackedWidget>
#include <QComboBox>
#include "codecsection.h"
#include "widget/slider/floatslider.h"
@@ -111,6 +112,7 @@ private:
H264FileSizeSection* filesize_section_;
QComboBox *preset_combobox_;
};
class H265Section : public H264Section
+2 -1
View File
@@ -312,7 +312,8 @@ void ExportDialog::StartExport()
QFileInfo dir_info(file_info.path());
// If the directory does not exist, try to create it
if (!QDir(file_info.path()).mkpath(QStringLiteral("."))) {
QDir dest_dir(file_info.path());
if (!FileFunctions::DirectoryIsValid(dest_dir)) {
QtUtils::MessageBox(this, QMessageBox::Critical, tr("Failed to create output directory"),
tr("The intended output directory doesn't exist and Olive couldn't create it. "
"Please choose a different filename."));
@@ -48,6 +48,7 @@ ExportAdvancedVideoDialog::ExportAdvancedVideoDialog(const QList<QString> &pix_f
thread_slider_ = new IntegerSlider();
thread_slider_->SetMinimum(0);
thread_slider_->SetDefaultValue(0);
thread_slider_->InsertLabelSubstitution(0, tr("Auto"));
performance_layout->addWidget(thread_slider_, row, 1);
row++;
+7 -2
View File
@@ -173,7 +173,7 @@ QWidget *ExportVideoTab::SetupCodecSection()
row++;
codec_stack_ = new QStackedWidget();
codec_stack_ = new CodecStack();
codec_layout->addWidget(codec_stack_, row, 0, 1, 2);
image_section_ = new ImageSection();
@@ -185,6 +185,9 @@ QWidget *ExportVideoTab::SetupCodecSection()
h265_section_ = new H265Section();
codec_stack_->addWidget(h265_section_);
cineform_section_ = new CineformSection();
codec_stack_->addWidget(cineform_section_);
row++;
QPushButton* advanced_btn = new QPushButton(tr("Advanced"));
@@ -240,6 +243,9 @@ void ExportVideoTab::VideoCodecChanged()
case ExportCodec::kCodecH265:
SetCodecSection(h265_section_);
break;
case ExportCodec::kCodecCineform:
SetCodecSection(cineform_section_);
break;
default:
SetCodecSection(ExportCodec::IsCodecAStillImage(codec) ? image_section_ : nullptr);
}
@@ -251,7 +257,6 @@ void ExportVideoTab::VideoCodecChanged()
} else {
pix_fmt_.clear();
}
qDebug() << "Set default pix fmt" << pix_fmt_;
}
void ExportVideoTab::SetTime(const rational &time)
+4 -1
View File
@@ -26,6 +26,8 @@
#include <QWidget>
#include "common/rational.h"
#include "dialog/export/codec/cineformsection.h"
#include "dialog/export/codec/codecstack.h"
#include "dialog/export/codec/h264section.h"
#include "dialog/export/codec/imagesection.h"
#include "node/color/colormanager/colormanager.h"
@@ -155,10 +157,11 @@ private:
QCheckBox* maintain_aspect_checkbox_;
QComboBox* scaling_method_combobox_;
QStackedWidget* codec_stack_;
CodecStack* codec_stack_;
ImageSection* image_section_;
H264Section* h264_section_;
H264Section* h265_section_;
CineformSection *cineform_section_;
ColorSpaceChooser* color_space_chooser_;
@@ -96,7 +96,7 @@ bool PreferencesDiskTab::Validate()
}
// Check validity of the new path
if (!FileFunctions::DirectoryIsValid(disk_cache_location_->text(), true)) {
if (!FileFunctions::DirectoryIsValid(disk_cache_location_->text())) {
QMessageBox::critical(this,
tr("Disk Cache"),
tr("Failed to set disk cache location. Access was denied."));
@@ -186,7 +186,7 @@ void ProjectPropertiesDialog::accept()
bool ProjectPropertiesDialog::VerifyPathAndWarnIfBad(const QString &path)
{
if (!FileFunctions::DirectoryIsValid(path, true)) {
if (!FileFunctions::DirectoryIsValid(path)) {
QMessageBox mb(this);
mb.setWindowModality(Qt::WindowModal);
mb.setIcon(QMessageBox::Critical);
@@ -31,6 +31,7 @@
#include "common/filefunctions.h"
#include "config/config.h"
#include "render/audioparams.h"
#include "render/videoparams.h"
#include "ui/icons/icons.h"
#include "widget/menu/menu.h"
@@ -22,6 +22,7 @@
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QMessageBox>
#include "core.h"
@@ -39,58 +40,82 @@ SpeedDurationDialog::SpeedDurationDialog(const QVector<ClipBlock *> &clips, cons
{
setWindowTitle(tr("Speed/Duration"));
QGridLayout *layout = new QGridLayout(this);
QVBoxLayout *layout = new QVBoxLayout(this);
int row = 0;
{
QGroupBox *speed_group = new QGroupBox();
layout->addWidget(speed_group);
layout->addWidget(new QLabel(tr("Speed:")), row, 0);
QGridLayout *speed_layout = new QGridLayout(speed_group);
speed_slider_ = new FloatSlider();
speed_slider_->SetDisplayType(FloatSlider::kPercentage);
connect(speed_slider_, &FloatSlider::ValueChanged, this, &SpeedDurationDialog::SpeedChanged);
layout->addWidget(speed_slider_, row, 1);
int row = 0;
row++;
speed_layout->addWidget(new QLabel(tr("Speed:")), row, 0);
layout->addWidget(new QLabel(tr("Duration:")), row, 0);
speed_slider_ = new FloatSlider();
speed_slider_->SetDisplayType(FloatSlider::kPercentage);
connect(speed_slider_, &FloatSlider::ValueChanged, this, &SpeedDurationDialog::SpeedChanged);
speed_layout->addWidget(speed_slider_, row, 1);
dur_slider_ = new RationalSlider();
dur_slider_->SetTimebase(timebase);
dur_slider_->SetDisplayType(RationalSlider::kTime);
connect(dur_slider_, &RationalSlider::ValueChanged, this, &SpeedDurationDialog::DurationChanged);
layout->addWidget(dur_slider_, row, 1);
row++;
row++;
speed_layout->addWidget(new QLabel(tr("Duration:")), row, 0);
link_box_ = new QCheckBox(tr("Link Speed and Duration"));
link_box_->setChecked(true);
layout->addWidget(link_box_, row, 0, 1, 2);
dur_slider_ = new RationalSlider();
dur_slider_->SetTimebase(timebase);
dur_slider_->SetDisplayType(RationalSlider::kTime);
connect(dur_slider_, &RationalSlider::ValueChanged, this, &SpeedDurationDialog::DurationChanged);
speed_layout->addWidget(dur_slider_, row, 1);
row++;
row++;
link_box_ = new QCheckBox(tr("Link Speed and Duration"));
link_box_->setChecked(true);
speed_layout->addWidget(link_box_, row, 0, 1, 2);
}
reverse_box_ = new QCheckBox(tr("Reverse"));
layout->addWidget(reverse_box_);
maintain_audio_pitch_box_ = new QCheckBox(tr("Maintain Audio Pitch"));
layout->addWidget(maintain_audio_pitch_box_);
ripple_box_ = new QCheckBox(tr("Ripple Trailing Clips"));
layout->addWidget(ripple_box_, row, 0, 1, 2);
row++;
layout->addWidget(ripple_box_);
QDialogButtonBox *btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
btns->setCenterButtons(true);
connect(btns, &QDialogButtonBox::accepted, this, &SpeedDurationDialog::accept);
connect(btns, &QDialogButtonBox::rejected, this, &SpeedDurationDialog::reject);
layout->addWidget(btns, row, 0, 1, 2);
layout->addWidget(btns);
// Determine which speed value to use
start_speed_ = clips.first()->speed();
start_duration_ = clips.first()->length();
start_reverse_ = clips.first()->reverse();
start_maintain_audio_pitch_ = clips.first()->maintain_audio_pitch();
for (int i=1; i<clips.size(); i++) {
if (!qIsNaN(start_speed_) && !qFuzzyCompare(start_speed_, clips.at(i)->speed())) {
ClipBlock *c = clips.at(i);
if (!qIsNaN(start_speed_) && !qFuzzyCompare(start_speed_, c->speed())) {
// Speed differs per clip
start_speed_ = qSNaN();
}
if (start_duration_ != -1 && clips.at(i)->length() != start_duration_) {
if (start_duration_ != -1 && c->length() != start_duration_) {
start_duration_ = -1;
}
// Yes, in theory a bool should only ever be 0 or 1 anyway, but MSVC complained and it is
// *possible* that a bool could be something else, so this code is safer
int clip_reverse = c->reverse() ? 1 : 0;
int clip_maintain_pitch = c->maintain_audio_pitch() ? 1 : 0;
if (start_reverse_ != -1 && clip_reverse != start_reverse_) {
start_reverse_ = -1;
}
if (start_maintain_audio_pitch_ != -1 && clip_maintain_pitch != start_maintain_audio_pitch_) {
start_maintain_audio_pitch_ = -1;
}
}
if (qIsNaN(start_speed_)) {
@@ -104,6 +129,18 @@ SpeedDurationDialog::SpeedDurationDialog(const QVector<ClipBlock *> &clips, cons
} else {
dur_slider_->SetValue(start_duration_);
}
if (start_reverse_ == -1) {
reverse_box_->setTristate();
} else {
reverse_box_->setChecked(start_reverse_);
}
if (start_maintain_audio_pitch_ == -1) {
maintain_audio_pitch_box_->setTristate();
} else {
maintain_audio_pitch_box_->setChecked(start_maintain_audio_pitch_);
}
}
void SpeedDurationDialog::accept()
@@ -118,21 +155,6 @@ void SpeedDurationDialog::accept()
MultiUndoCommand *command = new MultiUndoCommand();
// Set speed values
if (speed_slider_->IsTristate()) {
if (link_box_->isChecked() && !dur_slider_->IsTristate()) {
// Automatically determine speed from duration
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), GetSpeedAdjustment(c->speed(), c->length(), dur_slider_->GetValue())));
}
}
} else {
// Set speeds to value of slider
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), speed_slider_->GetValue()));
}
}
// Set duration values
foreach (ClipBlock *c, clips_) {
rational proposed_length = c->length();
@@ -161,6 +183,35 @@ void SpeedDurationDialog::accept()
}
}
// Set speed values
if (speed_slider_->IsTristate()) {
if (link_box_->isChecked() && !dur_slider_->IsTristate()) {
// Automatically determine speed from duration
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), GetSpeedAdjustment(c->speed(), c->length(), dur_slider_->GetValue())));
}
}
} else {
// Set speeds to value of slider
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), speed_slider_->GetValue()));
}
}
// Set reverse values
if (!reverse_box_->isTristate()) {
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kReverseInput)), reverse_box_->isChecked()));
}
}
// Set reverse values
if (!maintain_audio_pitch_box_->isTristate()) {
foreach (ClipBlock *c, clips_) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kMaintainAudioPitchInput)), maintain_audio_pitch_box_->isChecked()));
}
}
Core::instance()->undo_stack()->push(command);
super::accept();
@@ -56,8 +56,16 @@ private:
QCheckBox *link_box_;
QCheckBox *reverse_box_;
QCheckBox *maintain_audio_pitch_box_;
QCheckBox *ripple_box_;
int start_reverse_;
int start_maintain_audio_pitch_;
double start_speed_;
rational start_duration_;