exportdialog: allow restoring parameters

This commit is contained in:
itsmattkc
2022-08-10 11:49:21 -07:00
parent a2b400a1dc
commit 409f24be39
22 changed files with 331 additions and 222 deletions
+58 -2
View File
@@ -93,7 +93,9 @@ EncodingParams::EncodingParams() :
audio_enabled_(false), audio_enabled_(false),
audio_bit_rate_(0), audio_bit_rate_(0),
subtitles_enabled_(false), subtitles_enabled_(false),
subtitles_are_sidecar_(false) subtitles_are_sidecar_(false),
video_scaling_method_(kStretch),
has_custom_range_(false)
{ {
} }
@@ -142,7 +144,14 @@ void EncodingParams::DisableSubtitles()
void EncodingParams::Save(QXmlStreamWriter *writer) const void EncodingParams::Save(QXmlStreamWriter *writer) const
{ {
writer->writeTextElement(QStringLiteral("version"), QString::number(kEncoderParamsVersion));
writer->writeTextElement(QStringLiteral("filename"), filename_); writer->writeTextElement(QStringLiteral("filename"), filename_);
writer->writeTextElement(QStringLiteral("format"), QString::number(format_));
writer->writeTextElement(QStringLiteral("range"), QString::number(has_custom_range_));
writer->writeTextElement(QStringLiteral("customrangein"), custom_range_.in().toString());
writer->writeTextElement(QStringLiteral("customrangeout"), custom_range_.out().toString());
writer->writeStartElement(QStringLiteral("video")); writer->writeStartElement(QStringLiteral("video"));
@@ -156,10 +165,18 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("timebase"), video_params_.time_base().toString()); writer->writeTextElement(QStringLiteral("timebase"), video_params_.time_base().toString());
writer->writeTextElement(QStringLiteral("divider"), QString::number(video_params_.divider())); writer->writeTextElement(QStringLiteral("divider"), QString::number(video_params_.divider()));
writer->writeTextElement(QStringLiteral("bitrate"), QString::number(video_bit_rate_)); writer->writeTextElement(QStringLiteral("bitrate"), QString::number(video_bit_rate_));
writer->writeTextElement(QStringLiteral("minbitrate"), QString::number(video_max_bit_rate_)); writer->writeTextElement(QStringLiteral("minbitrate"), QString::number(video_min_bit_rate_));
writer->writeTextElement(QStringLiteral("maxbitrate"), QString::number(video_max_bit_rate_)); writer->writeTextElement(QStringLiteral("maxbitrate"), QString::number(video_max_bit_rate_));
writer->writeTextElement(QStringLiteral("bufsize"), QString::number(video_buffer_size_)); writer->writeTextElement(QStringLiteral("bufsize"), QString::number(video_buffer_size_));
writer->writeTextElement(QStringLiteral("threads"), QString::number(video_threads_)); writer->writeTextElement(QStringLiteral("threads"), QString::number(video_threads_));
writer->writeTextElement(QStringLiteral("pixfmt"), video_pix_fmt_);
writer->writeTextElement(QStringLiteral("imgseq"), QString::number(video_is_image_sequence_));
writer->writeStartElement(QStringLiteral("color"));
writer->writeTextElement(QStringLiteral("output"), color_transform_.output());
writer->writeEndElement(); // colortransform
writer->writeTextElement(QStringLiteral("vscale"), QString::number(video_scaling_method_));
if (!video_opts_.isEmpty()) { if (!video_opts_.isEmpty()) {
writer->writeStartElement(QStringLiteral("opts")); writer->writeStartElement(QStringLiteral("opts"));
@@ -191,6 +208,19 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("format"), QString::number(audio_params_.format())); writer->writeTextElement(QStringLiteral("format"), QString::number(audio_params_.format()));
} }
writer->writeStartElement(QStringLiteral("subtitles"));
writer->writeAttribute(QStringLiteral("enabled"), QString::number(subtitles_enabled_));
if (subtitles_enabled_) {
writer->writeTextElement(QStringLiteral("sidecar"), QString::number(subtitles_are_sidecar_));
writer->writeTextElement(QStringLiteral("sidecarformat"), QString::number(subtitle_sidecar_fmt_));
writer->writeTextElement(QStringLiteral("codec"), QString::number(subtitles_codec_));
}
writer->writeEndElement(); // subtitles
writer->writeEndElement(); // audio writer->writeEndElement(); // audio
} }
@@ -255,4 +285,30 @@ std::vector<AudioParams::Format> Encoder::GetSampleFormatsForCodec(ExportCodec::
return std::vector<AudioParams::Format>(); return std::vector<AudioParams::Format>();
} }
QMatrix4x4 EncodingParams::GenerateMatrix(EncodingParams::VideoScalingMethod method,
int source_width, int source_height,
int dest_width, int dest_height)
{
QMatrix4x4 preview_matrix;
if (method == EncodingParams::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 == EncodingParams::kFit)) {
preview_matrix.scale(source_ar / export_ar, 1.0F);
} else {
preview_matrix.scale(1.0F, export_ar / source_ar);
}
return preview_matrix;
}
} }
+37 -2
View File
@@ -41,10 +41,22 @@ namespace olive {
class Encoder; class Encoder;
using EncoderPtr = std::shared_ptr<Encoder>; using EncoderPtr = std::shared_ptr<Encoder>;
class EncodingParams { class EncodingParams
{
public: public:
enum VideoScalingMethod {
kFit,
kStretch,
kCrop
};
EncodingParams(); EncodingParams();
bool IsValid() const
{
return video_enabled_ || audio_enabled_ || subtitles_enabled_;
}
void SetFilename(const QString& filename) { filename_ = filename; } void SetFilename(const QString& filename) { filename_ = filename; }
void EnableVideo(const VideoParams& video_params, const ExportCodec::Codec& vcodec); void EnableVideo(const VideoParams& video_params, const ExportCodec::Codec& vcodec);
@@ -75,6 +87,8 @@ public:
const ExportCodec::Codec& video_codec() const { return video_codec_; } const ExportCodec::Codec& video_codec() const { return video_codec_; }
const VideoParams& video_params() const { return video_params_; } const VideoParams& video_params() const { return video_params_; }
const QHash<QString, QString>& video_opts() const { return video_opts_; } const QHash<QString, QString>& video_opts() const { return video_opts_; }
QString video_option(const QString &key) const { return video_opts_.value(key); }
bool has_video_opt(const QString &key) const { return video_opts_.contains(key); }
const int64_t& video_bit_rate() const { return video_bit_rate_; } const int64_t& video_bit_rate() const { return video_bit_rate_; }
const int64_t& video_min_bit_rate() const { return video_min_bit_rate_; } const int64_t& video_min_bit_rate() const { return video_min_bit_rate_; }
const int64_t& video_max_bit_rate() const { return video_max_bit_rate_; } const int64_t& video_max_bit_rate() const { return video_max_bit_rate_; }
@@ -99,9 +113,26 @@ public:
const rational& GetExportLength() const { return export_length_; } const rational& GetExportLength() const { return export_length_; }
void SetExportLength(const rational& export_length) { export_length_ = export_length; } void SetExportLength(const rational& export_length) { export_length_ = export_length; }
virtual void Save(QXmlStreamWriter* writer) const; void Save(QXmlStreamWriter* writer) const;
bool has_custom_range() const { return has_custom_range_; }
const TimeRange& custom_range() const { return custom_range_; }
void set_custom_range(const TimeRange& custom_range)
{
has_custom_range_ = true;
custom_range_ = custom_range;
}
const VideoScalingMethod& video_scaling_method() const { return video_scaling_method_; }
void set_video_scaling_method(const VideoScalingMethod& video_scaling_method) { video_scaling_method_ = video_scaling_method; }
static QMatrix4x4 GenerateMatrix(VideoScalingMethod method,
int source_width, int source_height,
int dest_width, int dest_height);
private: private:
static const int kEncoderParamsVersion = 1;
QString filename_; QString filename_;
ExportFormat::Format format_; ExportFormat::Format format_;
@@ -129,6 +160,10 @@ private:
ExportCodec::Codec subtitles_codec_; ExportCodec::Codec subtitles_codec_;
rational export_length_; rational export_length_;
VideoScalingMethod video_scaling_method_;
bool has_custom_range_;
TimeRange custom_range_;
}; };
+3 -1
View File
@@ -638,7 +638,9 @@ bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AV
// Set custom options // Set custom options
{ {
for (auto i=params().video_opts().begin();i!=params().video_opts().end();i++) { for (auto i=params().video_opts().begin();i!=params().video_opts().end();i++) {
av_opt_set(codec_ctx->priv_data, i.key().toUtf8(), i.value().toUtf8(), AV_OPT_SEARCH_CHILDREN); if (!i.key().startsWith(QStringLiteral("ove_"))) {
av_opt_set(codec_ctx->priv_data, i.key().toUtf8(), i.value().toUtf8(), AV_OPT_SEARCH_CHILDREN);
}
} }
if (params().video_bit_rate() > 0) { if (params().video_bit_rate() > 0) {
+10
View File
@@ -145,4 +145,14 @@ QStringList QtUtils::WordWrapString(const QString &s, const QFontMetrics &fm, in
return list; return list;
} }
void QtUtils::SetComboBoxData(QComboBox *cb, int data)
{
for (int i=0; i<cb->count(); i++) {
if (cb->itemData(i).toInt() == data) {
cb->setCurrentIndex(i);
break;
}
}
}
} }
+3 -6
View File
@@ -21,12 +21,7 @@
#ifndef QTVERSIONABSTRACTION_H #ifndef QTVERSIONABSTRACTION_H
#define QTVERSIONABSTRACTION_H #define QTVERSIONABSTRACTION_H
/** #include <QComboBox>
*
* A fairly simple header for reducing the amount of Qt version checks necessary throughout the code
*
*/
#include <QDateTime> #include <QDateTime>
#include <QFileInfo> #include <QFileInfo>
#include <QFontMetrics> #include <QFontMetrics>
@@ -58,6 +53,8 @@ public:
static QStringList WordWrapString(const QString &s, const QFontMetrics &fm, int bounding_width); static QStringList WordWrapString(const QString &s, const QFontMetrics &fm, int bounding_width);
static void SetComboBoxData(QComboBox *cb, int data);
template <typename T> template <typename T>
static T *GetParentOfType(const QObject *child) static T *GetParentOfType(const QObject *child)
{ {
@@ -82,4 +82,9 @@ void CineformSection::AddOpts(EncodingParams *params)
params->set_video_option(QStringLiteral("quality"), QString::number(quality_combobox_->currentIndex())); params->set_video_option(QStringLiteral("quality"), QString::number(quality_combobox_->currentIndex()));
} }
void CineformSection::SetOpts(const EncodingParams *p)
{
quality_combobox_->setCurrentIndex(p->video_option(QStringLiteral("quality")).toInt());
}
} }
@@ -35,6 +35,8 @@ public:
virtual void AddOpts(EncodingParams* params) override; virtual void AddOpts(EncodingParams* params) override;
virtual void SetOpts(const EncodingParams *p) override;
private: private:
QComboBox *quality_combobox_; QComboBox *quality_combobox_;
+2
View File
@@ -35,6 +35,8 @@ public:
virtual void AddOpts(EncodingParams* params){Q_UNUSED(params)} virtual void AddOpts(EncodingParams* params){Q_UNUSED(params)}
virtual void SetOpts(const EncodingParams *p){Q_UNUSED(p)}
}; };
} }
+54 -3
View File
@@ -60,7 +60,7 @@ H264Section::H264Section(int default_crf, QWidget *parent) :
preset_combobox_->addItem(tr("Slow")); preset_combobox_->addItem(tr("Slow"));
preset_combobox_->addItem(tr("Slower")); preset_combobox_->addItem(tr("Slower"));
preset_combobox_->addItem(tr("Very Slow")); preset_combobox_->addItem(tr("Very Slow"));
//Default to "medium" //Default to "medium"
preset_combobox_->setCurrentIndex(5); preset_combobox_->setCurrentIndex(5);
@@ -105,6 +105,10 @@ void H264Section::AddOpts(EncodingParams *params)
CompressionMethod method = static_cast<CompressionMethod>(compression_method_stack_->currentIndex()); CompressionMethod method = static_cast<CompressionMethod>(compression_method_stack_->currentIndex());
// This option is not used by the encoder (nor is anything with the ove_ prefix), it's to help us
// identify which option was chosen when params are restored
params->set_video_option(QStringLiteral("ove_compressionmethod"), QString::number(method));
if (method == kConstantRateFactor) { if (method == kConstantRateFactor) {
// Simply set CRF value // Simply set CRF value
@@ -121,9 +125,12 @@ void H264Section::AddOpts(EncodingParams *params)
max_rate = bitrate_section_->GetMaximumBitRate(); max_rate = bitrate_section_->GetMaximumBitRate();
} else { } else {
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second) // Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
target_rate = qRound64(static_cast<double>(filesize_section_->GetFileSize()) / params->GetExportLength().toDouble()); int64_t target_fs = filesize_section_->GetFileSize();
target_rate = qRound64(static_cast<double>(target_fs) / params->GetExportLength().toDouble());
min_rate = target_rate; min_rate = target_rate;
max_rate = target_rate; max_rate = target_rate;
params->set_video_option(QStringLiteral("ove_targetfilesize"), QString::number(target_fs));
} }
// Disable CRF encoding // Disable CRF encoding
@@ -135,10 +142,33 @@ void H264Section::AddOpts(EncodingParams *params)
params->set_video_buffer_size(2000000); params->set_video_buffer_size(2000000);
} }
params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex())); params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex()));
} }
void H264Section::SetOpts(const EncodingParams *p)
{
CompressionMethod method = static_cast<CompressionMethod>(p->video_option(QStringLiteral("ove_compressionmethod")).toInt());
compression_method_stack_->setCurrentIndex(method);
if (method == kConstantRateFactor) {
crf_section_->SetValue(p->video_option(QStringLiteral("crf")).toInt());
} else {
int64_t target_rate = p->video_bit_rate();
int64_t max_rate = p->video_max_bit_rate();
if (method == kTargetBitRate) {
// Use user-supplied values for the bit rate
bitrate_section_->SetTargetBitRate(target_rate);
bitrate_section_->SetMaximumBitRate(max_rate);
} else {
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
filesize_section_->SetFileSize(p->video_option(QStringLiteral("ove_targetfilesize")).toLongLong());
}
}
}
H264CRFSection::H264CRFSection(int default_crf, QWidget *parent) : H264CRFSection::H264CRFSection(int default_crf, QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
@@ -168,6 +198,11 @@ int H264CRFSection::GetValue() const
return crf_slider_->value(); return crf_slider_->value();
} }
void H264CRFSection::SetValue(int c)
{
crf_slider_->setValue(c);
}
H264BitRateSection::H264BitRateSection(QWidget *parent) : H264BitRateSection::H264BitRateSection(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
@@ -207,11 +242,21 @@ int64_t H264BitRateSection::GetTargetBitRate() const
return qRound64(target_rate_->GetValue() * 1000000.0); return qRound64(target_rate_->GetValue() * 1000000.0);
} }
void H264BitRateSection::SetTargetBitRate(int64_t b)
{
target_rate_->SetValue(double(b) * 0.000001);
}
int64_t H264BitRateSection::GetMaximumBitRate() const int64_t H264BitRateSection::GetMaximumBitRate() const
{ {
return qRound64(max_rate_->GetValue() * 1000000.0); return qRound64(max_rate_->GetValue() * 1000000.0);
} }
void H264BitRateSection::SetMaximumBitRate(int64_t b)
{
max_rate_->SetValue(double(b) * 0.000001);
}
H264FileSizeSection::H264FileSizeSection(QWidget *parent) : H264FileSizeSection::H264FileSizeSection(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
@@ -243,6 +288,12 @@ int64_t H264FileSizeSection::GetFileSize() const
return qRound64(file_size_->GetValue() * 1024.0 * 1024.0 * 8.0); return qRound64(file_size_->GetValue() * 1024.0 * 1024.0 * 8.0);
} }
void H264FileSizeSection::SetFileSize(int64_t f)
{
// Convert bits back to megabytes
file_size_->SetValue(double(f) / 8.0 / 1024.0 / 1024.0);
}
H265Section::H265Section(QWidget *parent) : H265Section::H265Section(QWidget *parent) :
H264Section(H264CRFSection::kDefaultH265CRF, parent) H264Section(H264CRFSection::kDefaultH265CRF, parent)
{ {
+6
View File
@@ -37,6 +37,7 @@ public:
H264CRFSection(int default_crf, QWidget* parent = nullptr); H264CRFSection(int default_crf, QWidget* parent = nullptr);
int GetValue() const; int GetValue() const;
void SetValue(int c);
static const int kDefaultH264CRF = 18; static const int kDefaultH264CRF = 18;
static const int kDefaultH265CRF = 23; static const int kDefaultH265CRF = 23;
@@ -59,11 +60,13 @@ public:
* @brief Get user-selected target bit rate (returns in BITS) * @brief Get user-selected target bit rate (returns in BITS)
*/ */
int64_t GetTargetBitRate() const; int64_t GetTargetBitRate() const;
void SetTargetBitRate(int64_t b);
/** /**
* @brief Get user-selected maximum bit rate (returns in BITS) * @brief Get user-selected maximum bit rate (returns in BITS)
*/ */
int64_t GetMaximumBitRate() const; int64_t GetMaximumBitRate() const;
void SetMaximumBitRate(int64_t b);
private: private:
FloatSlider* target_rate_; FloatSlider* target_rate_;
@@ -82,6 +85,7 @@ public:
* @brief Returns file size in BITS * @brief Returns file size in BITS
*/ */
int64_t GetFileSize() const; int64_t GetFileSize() const;
void SetFileSize(int64_t f);
private: private:
FloatSlider* file_size_; FloatSlider* file_size_;
@@ -103,6 +107,8 @@ public:
virtual void AddOpts(EncodingParams* params) override; virtual void AddOpts(EncodingParams* params) override;
virtual void SetOpts(const EncodingParams *p) override;
private: private:
QStackedWidget* compression_method_stack_; QStackedWidget* compression_method_stack_;
+5
View File
@@ -39,6 +39,11 @@ public:
return image_sequence_checkbox_->isChecked(); return image_sequence_checkbox_->isChecked();
} }
void SetImageSequenceChecked(bool e)
{
image_sequence_checkbox_->setChecked(e);
}
void SetTimebase(const rational& r) void SetTimebase(const rational& r)
{ {
frame_slider_->SetTimebase(r); frame_slider_->SetTimebase(r);
+88 -13
View File
@@ -41,8 +41,10 @@
namespace olive { namespace olive {
#define super QDialog
ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
QDialog(parent), super(parent),
viewer_node_(viewer_node) viewer_node_(viewer_node)
{ {
QHBoxLayout* layout = new QHBoxLayout(this); QHBoxLayout* layout = new QHBoxLayout(this);
@@ -255,6 +257,11 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
connect(subtitles_enabled_, &QCheckBox::toggled, subtitle_tab_, &QWidget::setEnabled); connect(subtitles_enabled_, &QCheckBox::toggled, subtitle_tab_, &QWidget::setEnabled);
subtitles_enabled_->setChecked(has_subtitle_codecs); subtitles_enabled_->setChecked(has_subtitle_codecs);
subtitles_enabled_->setEnabled(has_subtitle_codecs); subtitles_enabled_->setEnabled(has_subtitle_codecs);
// If the viewer already has cached params, use them
if (viewer_node_->GetLastUsedEncodingParams().IsValid()) {
SetParams(viewer_node_->GetLastUsedEncodingParams());
}
} }
rational ExportDialog::GetSelectedTimebase() const rational ExportDialog::GetSelectedTimebase() const
@@ -262,6 +269,11 @@ rational ExportDialog::GetSelectedTimebase() const
return video_tab_->GetSelectedFrameRate().flipped(); return video_tab_->GetSelectedFrameRate().flipped();
} }
void ExportDialog::SetSelectedTimebase(const rational &r)
{
video_tab_->SetSelectedFrameRate(r.flipped());
}
void ExportDialog::StartExport() void ExportDialog::StartExport()
{ {
if (!video_enabled_->isChecked() && !audio_enabled_->isChecked() && !subtitles_enabled_->isChecked()) { if (!video_enabled_->isChecked() && !audio_enabled_->isChecked() && !subtitles_enabled_->isChecked()) {
@@ -390,13 +402,6 @@ void ExportDialog::ImageSequenceCheckBoxChanged(bool e)
filename_edit_->setText(current_fileinfo.dir().filePath(basename)); filename_edit_->setText(current_fileinfo.dir().filePath(basename));
} }
void ExportDialog::closeEvent(QCloseEvent *e)
{
preview_viewer_->ConnectViewerNode(nullptr);
QDialog::closeEvent(e);
}
void ExportDialog::AddPreferencesTab(QWidget *inner_widget, const QString &title) void ExportDialog::AddPreferencesTab(QWidget *inner_widget, const QString &title)
{ {
QScrollArea* scroll_area = new QScrollArea(); QScrollArea* scroll_area = new QScrollArea();
@@ -522,7 +527,7 @@ bool ExportDialog::SequenceHasSubtitles() const
return false; return false;
} }
ExportParams ExportDialog::GenerateParams() const EncodingParams ExportDialog::GenerateParams() const
{ {
VideoParams video_render_params(static_cast<int>(video_tab_->width_slider()->GetValue()), VideoParams video_render_params(static_cast<int>(video_tab_->width_slider()->GetValue()),
static_cast<int>(video_tab_->height_slider()->GetValue()), static_cast<int>(video_tab_->height_slider()->GetValue()),
@@ -537,7 +542,7 @@ ExportParams ExportDialog::GenerateParams() const
audio_tab_->channel_layout_combobox()->GetChannelLayout(), audio_tab_->channel_layout_combobox()->GetChannelLayout(),
audio_tab_->sample_format_combobox()->GetSampleFormat()); audio_tab_->sample_format_combobox()->GetSampleFormat());
ExportParams params; EncodingParams params;
params.set_format(format_combobox_->GetFormat()); params.set_format(format_combobox_->GetFormat());
params.SetFilename(filename_edit_->text().trimmed()); params.SetFilename(filename_edit_->text().trimmed());
params.SetExportLength(viewer_node_->GetLength()); params.SetExportLength(viewer_node_->GetLength());
@@ -552,7 +557,7 @@ ExportParams ExportDialog::GenerateParams() const
} }
if (video_tab_->scaling_method_combobox()->isEnabled()) { if (video_tab_->scaling_method_combobox()->isEnabled()) {
params.set_video_scaling_method(static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt())); params.set_video_scaling_method(static_cast<EncodingParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()));
} }
if (video_enabled_->isChecked()) { if (video_enabled_->isChecked()) {
@@ -596,6 +601,76 @@ ExportParams ExportDialog::GenerateParams() const
return params; return params;
} }
void ExportDialog::SetParams(const EncodingParams &e)
{
format_combobox_->SetFormat(e.format());
filename_edit_->setText(e.filename());
if (e.has_custom_range() && viewer_node_->GetWorkArea()->enabled()) {
range_combobox_->setCurrentIndex(kRangeInToOut);
}
QtUtils::SetComboBoxData(video_tab_->scaling_method_combobox(), e.video_scaling_method());
video_enabled_->setChecked(e.video_enabled());
if (e.video_enabled()) {
video_tab_->width_slider()->SetValue(e.video_params().width());
video_tab_->height_slider()->SetValue(e.video_params().height());
SetSelectedTimebase(e.video_params().time_base());
video_tab_->pixel_format_field()->SetPixelFormat(e.video_params().format());
video_tab_->pixel_aspect_combobox()->SetPixelAspectRatio(e.video_params().pixel_aspect_ratio());
video_tab_->interlaced_combobox()->SetInterlaceMode(e.video_params().interlacing());
video_tab_->SetSelectedCodec(e.video_codec());
video_tab_->SetColorRange(e.video_params().color_range());
video_tab_->SetThreads(e.video_threads());
if (video_tab_->isVisible()) {
video_tab_->GetCodecSection()->SetOpts(&e);
}
video_tab_->SetOCIOColorSpace(e.color_transform().output());
video_tab_->SetPixFmt(e.video_pix_fmt());
video_tab_->SetImageSequence(e.video_is_image_sequence());
}
audio_enabled_->setChecked(e.audio_enabled());
if (e.audio_enabled()) {
audio_tab_->sample_rate_combobox()->SetSampleRate(e.audio_params().sample_rate());
audio_tab_->channel_layout_combobox()->SetChannelLayout(e.audio_params().channel_layout());
audio_tab_->sample_format_combobox()->SetSampleFormat(e.audio_params().format());
audio_tab_->SetCodec(e.audio_codec());
audio_tab_->bit_rate_slider()->SetValue(e.audio_bit_rate() / 1000);
}
if (subtitles_enabled_->isEnabled()) {
subtitles_enabled_->setChecked(e.subtitles_enabled());
subtitle_tab_->SetSidecarEnabled(e.subtitles_are_sidecar());
if (e.subtitles_enabled()) {
subtitle_tab_->SetSubtitleCodec(e.subtitles_codec());
if (e.subtitles_are_sidecar()) {
subtitle_tab_->SetSidecarFormat(e.subtitle_sidecar_fmt());
}
}
}
}
void ExportDialog::done(int r)
{
qDebug() << "done???";
preview_viewer_->ConnectViewerNode(nullptr);
viewer_node_->SetLastUsedEncodingParams(GenerateParams());
super::done(r);
}
rational ExportDialog::GetExportLength() const rational ExportDialog::GetExportLength() const
{ {
if (range_combobox_->currentIndex() == kRangeInToOut) { if (range_combobox_->currentIndex() == kRangeInToOut) {
@@ -617,8 +692,8 @@ void ExportDialog::UpdateViewerDimensions()
VideoParams vp = viewer_node_->GetVideoParams(); VideoParams vp = viewer_node_->GetVideoParams();
QMatrix4x4 transform = ExportParams::GenerateMatrix( QMatrix4x4 transform = EncodingParams::GenerateMatrix(
static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()), static_cast<EncodingParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
vp.width(), vp.width(),
vp.height(), vp.height(),
static_cast<int>(video_tab_->width_slider()->GetValue()), static_cast<int>(video_tab_->width_slider()->GetValue()),
+6 -4
View File
@@ -45,6 +45,7 @@ public:
ExportDialog(ViewerOutput* viewer_node, QWidget* parent = nullptr); ExportDialog(ViewerOutput* viewer_node, QWidget* parent = nullptr);
rational GetSelectedTimebase() const; rational GetSelectedTimebase() const;
void SetSelectedTimebase(const rational &r);
void SetTime(const rational &time) void SetTime(const rational &time)
{ {
@@ -54,8 +55,11 @@ public:
preview_viewer_->SetAudioScrubbingEnabled(true); preview_viewer_->SetAudioScrubbingEnabled(true);
} }
protected: EncodingParams GenerateParams() const;
virtual void closeEvent(QCloseEvent *e) override; void SetParams(const EncodingParams &e);
public slots:
virtual void done(int r) override;
private: private:
void AddPreferencesTab(QWidget *inner_widget, const QString &title); void AddPreferencesTab(QWidget *inner_widget, const QString &title);
@@ -65,8 +69,6 @@ private:
bool SequenceHasSubtitles() const; bool SequenceHasSubtitles() const;
ExportParams GenerateParams() const;
ViewerOutput* viewer_node_; ViewerOutput* viewer_node_;
ExportFormat::Format previously_selected_format_; ExportFormat::Format previously_selected_format_;
+6
View File
@@ -26,6 +26,7 @@
#include <QLabel> #include <QLabel>
#include "codec/exportformat.h" #include "codec/exportformat.h"
#include "common/qtutils.h"
#include "dialog/export/exportformatcombobox.h" #include "dialog/export/exportformatcombobox.h"
namespace olive { namespace olive {
@@ -49,6 +50,11 @@ public:
return static_cast<ExportCodec::Codec>(codec_combobox_->currentData().toInt()); return static_cast<ExportCodec::Codec>(codec_combobox_->currentData().toInt());
} }
void SetSubtitleCodec(ExportCodec::Codec c)
{
QtUtils::SetComboBoxData(codec_combobox_, c);
}
private: private:
QCheckBox *sidecar_checkbox_; QCheckBox *sidecar_checkbox_;
+10 -4
View File
@@ -29,7 +29,6 @@
#include "core.h" #include "core.h"
#include "exportadvancedvideodialog.h" #include "exportadvancedvideodialog.h"
#include "node/color/colormanager/colormanager.h" #include "node/color/colormanager/colormanager.h"
#include "task/export/exportparams.h"
namespace olive { namespace olive {
@@ -70,6 +69,13 @@ bool ExportVideoTab::IsImageSequenceSet() const
return (img_section && img_section->IsImageSequenceChecked()); return (img_section && img_section->IsImageSequenceChecked());
} }
void ExportVideoTab::SetImageSequence(bool e) const
{
if (ImageSection* img_section = dynamic_cast<ImageSection*>(codec_stack_->currentWidget())) {
img_section->SetImageSequenceChecked(e);
}
}
QWidget* ExportVideoTab::SetupResolutionSection() QWidget* ExportVideoTab::SetupResolutionSection()
{ {
int row = 0; int row = 0;
@@ -107,9 +113,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"), ExportParams::kFit); scaling_method_combobox_->addItem(tr("Fit"), EncodingParams::kFit);
scaling_method_combobox_->addItem(tr("Stretch"), ExportParams::kStretch); scaling_method_combobox_->addItem(tr("Stretch"), EncodingParams::kStretch);
scaling_method_combobox_->addItem(tr("Crop"), ExportParams::kCrop); scaling_method_combobox_->addItem(tr("Crop"), EncodingParams::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
+19 -6
View File
@@ -25,6 +25,7 @@
#include <QComboBox> #include <QComboBox>
#include <QWidget> #include <QWidget>
#include "common/qtutils.h"
#include "common/rational.h" #include "common/rational.h"
#include "dialog/export/codec/cineformsection.h" #include "dialog/export/codec/cineformsection.h"
#include "dialog/export/codec/codecstack.h" #include "dialog/export/codec/codecstack.h"
@@ -46,6 +47,7 @@ public:
int SetFormat(ExportFormat::Format format); int SetFormat(ExportFormat::Format format);
bool IsImageSequenceSet() const; bool IsImageSequenceSet() const;
void SetImageSequence(bool e) const;
rational GetStillImageTime() const rational GetStillImageTime() const
{ {
@@ -57,6 +59,11 @@ public:
return static_cast<ExportCodec::Codec>(codec_combobox()->currentData().toInt()); return static_cast<ExportCodec::Codec>(codec_combobox()->currentData().toInt());
} }
void SetSelectedCodec(ExportCodec::Codec c)
{
QtUtils::SetComboBoxData(codec_combobox(), c);
}
QComboBox* codec_combobox() const QComboBox* codec_combobox() const
{ {
return codec_combobox_; return codec_combobox_;
@@ -98,6 +105,11 @@ public:
return color_space_chooser_->input(); return color_space_chooser_->input();
} }
void SetOCIOColorSpace(const QString &s)
{
color_space_chooser_->set_input(s);
}
CodecSection* GetCodecSection() const CodecSection* GetCodecSection() const
{ {
return static_cast<CodecSection*>(codec_stack_->currentWidget()); return static_cast<CodecSection*>(codec_stack_->currentWidget());
@@ -133,15 +145,16 @@ public:
return threads_; return threads_;
} }
const QString& pix_fmt() const void SetThreads(int t)
{ {
return pix_fmt_; threads_ = t;
} }
VideoParams::ColorRange color_range() const const QString& pix_fmt() const { return pix_fmt_; }
{ void SetPixFmt(const QString &s) { pix_fmt_ = s; }
return color_range_;
} VideoParams::ColorRange color_range() const { return color_range_; }
void SetColorRange(VideoParams::ColorRange c) { color_range_ = c; }
public slots: public slots:
void VideoCodecChanged(); void VideoCodecChanged();
+6
View File
@@ -21,6 +21,7 @@
#ifndef VIEWER_H #ifndef VIEWER_H
#define VIEWER_H #define VIEWER_H
#include "codec/encoder.h"
#include "common/rational.h" #include "common/rational.h"
#include "node/node.h" #include "node/node.h"
#include "node/output/track/track.h" #include "node/output/track/track.h"
@@ -164,6 +165,9 @@ public:
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override; virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
const EncodingParams &GetLastUsedEncodingParams() const { return last_used_encoding_params_; }
void SetLastUsedEncodingParams(const EncodingParams &p) { last_used_encoding_params_ = p; }
static const QString kVideoParamsInput; static const QString kVideoParamsInput;
static const QString kAudioParamsInput; static const QString kAudioParamsInput;
static const QString kSubtitleParamsInput; static const QString kSubtitleParamsInput;
@@ -216,6 +220,8 @@ private:
TimelineWorkArea *workarea_; TimelineWorkArea *workarea_;
TimelineMarkerList *markers_; TimelineMarkerList *markers_;
EncodingParams last_used_encoding_params_;
}; };
} }
-2
View File
@@ -18,7 +18,5 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES} ${OLIVE_SOURCES}
task/export/export.h task/export/export.h
task/export/export.cpp task/export/export.cpp
task/export/exportparams.h
task/export/exportparams.cpp
PARENT_SCOPE PARENT_SCOPE
) )
+8 -8
View File
@@ -27,7 +27,7 @@ namespace olive {
ExportTask::ExportTask(ViewerOutput *viewer_node, ExportTask::ExportTask(ViewerOutput *viewer_node,
ColorManager* color_manager, ColorManager* color_manager,
const ExportParams& params) : const EncodingParams& params) :
color_manager_(color_manager), color_manager_(color_manager),
params_(params) params_(params)
{ {
@@ -60,7 +60,7 @@ bool ExportTask::Run()
// If we're exporting to a sidecar subtitle file, disable the subtitles in the main encoder // If we're exporting to a sidecar subtitle file, disable the subtitles in the main encoder
bool subtitles_enabled = params_.subtitles_enabled(); bool subtitles_enabled = params_.subtitles_enabled();
ExportParams sidecar_params = params_; EncodingParams sidecar_params = params_;
if (subtitles_enabled && params_.subtitles_are_sidecar()) { if (subtitles_enabled && params_.subtitles_are_sidecar()) {
params_.DisableSubtitles(); params_.DisableSubtitles();
} }
@@ -126,12 +126,12 @@ bool ExportTask::Run()
|| video_params().height() != params_.video_params().height()) { || video_params().height() != params_.video_params().height()) {
video_force_size = QSize(params_.video_params().width(), params_.video_params().height()); video_force_size = QSize(params_.video_params().width(), params_.video_params().height());
if (params_.video_scaling_method() != ExportParams::kStretch) { if (params_.video_scaling_method() != EncodingParams::kStretch) {
video_force_matrix = ExportParams::GenerateMatrix(params_.video_scaling_method(), video_force_matrix = EncodingParams::GenerateMatrix(params_.video_scaling_method(),
video_params().width(), video_params().width(),
video_params().height(), video_params().height(),
params_.video_params().width(), params_.video_params().width(),
params_.video_params().height()); params_.video_params().height());
} }
} else { } else {
// Disables forcing size in the renderer // Disables forcing size in the renderer
+3 -3
View File
@@ -21,7 +21,7 @@
#ifndef EXPORTTASK_H #ifndef EXPORTTASK_H
#define EXPORTTASK_H #define EXPORTTASK_H
#include "exportparams.h" #include "codec/encoder.h"
#include "node/output/viewer/viewer.h" #include "node/output/viewer/viewer.h"
#include "render/colorprocessor.h" #include "render/colorprocessor.h"
#include "task/render/render.h" #include "task/render/render.h"
@@ -33,7 +33,7 @@ class ExportTask : public RenderTask
{ {
Q_OBJECT Q_OBJECT
public: public:
ExportTask(ViewerOutput *viewer_node, ColorManager *color_manager, const ExportParams &params); ExportTask(ViewerOutput *viewer_node, ColorManager *color_manager, const EncodingParams &params);
protected: protected:
virtual bool Run() override; virtual bool Run() override;
@@ -58,7 +58,7 @@ private:
ColorManager* color_manager_; ColorManager* color_manager_;
ExportParams params_; EncodingParams params_;
std::shared_ptr<Encoder> encoder_; std::shared_ptr<Encoder> encoder_;
-103
View File
@@ -1,103 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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"
namespace olive {
ExportParams::ExportParams() :
video_scaling_method_(kStretch),
has_custom_range_(false)
{
}
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;
}
QMatrix4x4 ExportParams::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 ExportParams::Save(QXmlStreamWriter *writer) const
{
writer->writeStartElement(QStringLiteral("export"));
writer->writeTextElement(QStringLiteral("vscale"), QString::number(video_scaling_method_));
writer->writeTextElement(QStringLiteral("range"), QString::number(has_custom_range_));
writer->writeTextElement(QStringLiteral("customrangein"), custom_range_.in().toString());
writer->writeTextElement(QStringLiteral("customrangeout"), custom_range_.out().toString());
// FIXME: Change this when color chains are implemented
writer->writeTextElement(QStringLiteral("color"), color_transform().output());
EncodingParams::Save(writer);
writer->writeEndElement(); // export
}
}
-65
View File
@@ -1,65 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 <QMatrix4x4>
#include "codec/encoder.h"
#include "node/output/viewer/viewer.h"
#include "render/colortransform.h"
namespace olive {
class ExportParams : public EncodingParams {
public:
enum VideoScalingMethod {
kFit,
kStretch,
kCrop
};
ExportParams();
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);
static QMatrix4x4 GenerateMatrix(ExportParams::VideoScalingMethod method,
int source_width, int source_height,
int dest_width, int dest_height);
virtual void Save(QXmlStreamWriter* writer) const override;
private:
VideoScalingMethod video_scaling_method_;
bool has_custom_range_;
TimeRange custom_range_;
};
}
#endif // EXPORTPARAMS_H