exportdialog: allow restoring parameters
This commit is contained in:
+58
-2
@@ -93,7 +93,9 @@ EncodingParams::EncodingParams() :
|
||||
audio_enabled_(false),
|
||||
audio_bit_rate_(0),
|
||||
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
|
||||
{
|
||||
writer->writeTextElement(QStringLiteral("version"), QString::number(kEncoderParamsVersion));
|
||||
|
||||
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"));
|
||||
|
||||
@@ -156,10 +165,18 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
|
||||
writer->writeTextElement(QStringLiteral("timebase"), video_params_.time_base().toString());
|
||||
writer->writeTextElement(QStringLiteral("divider"), QString::number(video_params_.divider()));
|
||||
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("bufsize"), QString::number(video_buffer_size_));
|
||||
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()) {
|
||||
writer->writeStartElement(QStringLiteral("opts"));
|
||||
@@ -191,6 +208,19 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
|
||||
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
|
||||
}
|
||||
|
||||
@@ -255,4 +285,30 @@ std::vector<AudioParams::Format> Encoder::GetSampleFormatsForCodec(ExportCodec::
|
||||
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
@@ -41,10 +41,22 @@ namespace olive {
|
||||
class Encoder;
|
||||
using EncoderPtr = std::shared_ptr<Encoder>;
|
||||
|
||||
class EncodingParams {
|
||||
class EncodingParams
|
||||
{
|
||||
public:
|
||||
enum VideoScalingMethod {
|
||||
kFit,
|
||||
kStretch,
|
||||
kCrop
|
||||
};
|
||||
|
||||
EncodingParams();
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return video_enabled_ || audio_enabled_ || subtitles_enabled_;
|
||||
}
|
||||
|
||||
void SetFilename(const QString& filename) { filename_ = filename; }
|
||||
|
||||
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 VideoParams& video_params() const { return video_params_; }
|
||||
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_min_bit_rate() const { return video_min_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_; }
|
||||
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:
|
||||
static const int kEncoderParamsVersion = 1;
|
||||
|
||||
QString filename_;
|
||||
ExportFormat::Format format_;
|
||||
|
||||
@@ -129,6 +160,10 @@ private:
|
||||
ExportCodec::Codec subtitles_codec_;
|
||||
|
||||
rational export_length_;
|
||||
VideoScalingMethod video_scaling_method_;
|
||||
|
||||
bool has_custom_range_;
|
||||
TimeRange custom_range_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -638,7 +638,9 @@ bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AV
|
||||
// Set custom options
|
||||
{
|
||||
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) {
|
||||
|
||||
@@ -145,4 +145,14 @@ QStringList QtUtils::WordWrapString(const QString &s, const QFontMetrics &fm, in
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,12 +21,7 @@
|
||||
#ifndef QTVERSIONABSTRACTION_H
|
||||
#define QTVERSIONABSTRACTION_H
|
||||
|
||||
/**
|
||||
*
|
||||
* A fairly simple header for reducing the amount of Qt version checks necessary throughout the code
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
#include <QFontMetrics>
|
||||
@@ -58,6 +53,8 @@ public:
|
||||
|
||||
static QStringList WordWrapString(const QString &s, const QFontMetrics &fm, int bounding_width);
|
||||
|
||||
static void SetComboBoxData(QComboBox *cb, int data);
|
||||
|
||||
template <typename T>
|
||||
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()));
|
||||
}
|
||||
|
||||
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 SetOpts(const EncodingParams *p) override;
|
||||
|
||||
private:
|
||||
QComboBox *quality_combobox_;
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
virtual void AddOpts(EncodingParams* params){Q_UNUSED(params)}
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p){Q_UNUSED(p)}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -105,6 +105,10 @@ void H264Section::AddOpts(EncodingParams *params)
|
||||
|
||||
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) {
|
||||
|
||||
// Simply set CRF value
|
||||
@@ -121,9 +125,12 @@ void H264Section::AddOpts(EncodingParams *params)
|
||||
max_rate = bitrate_section_->GetMaximumBitRate();
|
||||
} else {
|
||||
// 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;
|
||||
max_rate = target_rate;
|
||||
|
||||
params->set_video_option(QStringLiteral("ove_targetfilesize"), QString::number(target_fs));
|
||||
}
|
||||
|
||||
// Disable CRF encoding
|
||||
@@ -139,6 +146,29 @@ void H264Section::AddOpts(EncodingParams *params)
|
||||
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) :
|
||||
QWidget(parent)
|
||||
{
|
||||
@@ -168,6 +198,11 @@ int H264CRFSection::GetValue() const
|
||||
return crf_slider_->value();
|
||||
}
|
||||
|
||||
void H264CRFSection::SetValue(int c)
|
||||
{
|
||||
crf_slider_->setValue(c);
|
||||
}
|
||||
|
||||
H264BitRateSection::H264BitRateSection(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
@@ -207,11 +242,21 @@ int64_t H264BitRateSection::GetTargetBitRate() const
|
||||
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
|
||||
{
|
||||
return qRound64(max_rate_->GetValue() * 1000000.0);
|
||||
}
|
||||
|
||||
void H264BitRateSection::SetMaximumBitRate(int64_t b)
|
||||
{
|
||||
max_rate_->SetValue(double(b) * 0.000001);
|
||||
}
|
||||
|
||||
H264FileSizeSection::H264FileSizeSection(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
@@ -243,6 +288,12 @@ int64_t H264FileSizeSection::GetFileSize() const
|
||||
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) :
|
||||
H264Section(H264CRFSection::kDefaultH265CRF, parent)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
H264CRFSection(int default_crf, QWidget* parent = nullptr);
|
||||
|
||||
int GetValue() const;
|
||||
void SetValue(int c);
|
||||
|
||||
static const int kDefaultH264CRF = 18;
|
||||
static const int kDefaultH265CRF = 23;
|
||||
@@ -59,11 +60,13 @@ public:
|
||||
* @brief Get user-selected target bit rate (returns in BITS)
|
||||
*/
|
||||
int64_t GetTargetBitRate() const;
|
||||
void SetTargetBitRate(int64_t b);
|
||||
|
||||
/**
|
||||
* @brief Get user-selected maximum bit rate (returns in BITS)
|
||||
*/
|
||||
int64_t GetMaximumBitRate() const;
|
||||
void SetMaximumBitRate(int64_t b);
|
||||
|
||||
private:
|
||||
FloatSlider* target_rate_;
|
||||
@@ -82,6 +85,7 @@ public:
|
||||
* @brief Returns file size in BITS
|
||||
*/
|
||||
int64_t GetFileSize() const;
|
||||
void SetFileSize(int64_t f);
|
||||
|
||||
private:
|
||||
FloatSlider* file_size_;
|
||||
@@ -103,6 +107,8 @@ public:
|
||||
|
||||
virtual void AddOpts(EncodingParams* params) override;
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p) override;
|
||||
|
||||
private:
|
||||
QStackedWidget* compression_method_stack_;
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ public:
|
||||
return image_sequence_checkbox_->isChecked();
|
||||
}
|
||||
|
||||
void SetImageSequenceChecked(bool e)
|
||||
{
|
||||
image_sequence_checkbox_->setChecked(e);
|
||||
}
|
||||
|
||||
void SetTimebase(const rational& r)
|
||||
{
|
||||
frame_slider_->SetTimebase(r);
|
||||
|
||||
@@ -41,8 +41,10 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super QDialog
|
||||
|
||||
ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
super(parent),
|
||||
viewer_node_(viewer_node)
|
||||
{
|
||||
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);
|
||||
subtitles_enabled_->setChecked(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
|
||||
@@ -262,6 +269,11 @@ rational ExportDialog::GetSelectedTimebase() const
|
||||
return video_tab_->GetSelectedFrameRate().flipped();
|
||||
}
|
||||
|
||||
void ExportDialog::SetSelectedTimebase(const rational &r)
|
||||
{
|
||||
video_tab_->SetSelectedFrameRate(r.flipped());
|
||||
}
|
||||
|
||||
void ExportDialog::StartExport()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
void ExportDialog::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
preview_viewer_->ConnectViewerNode(nullptr);
|
||||
|
||||
QDialog::closeEvent(e);
|
||||
}
|
||||
|
||||
void ExportDialog::AddPreferencesTab(QWidget *inner_widget, const QString &title)
|
||||
{
|
||||
QScrollArea* scroll_area = new QScrollArea();
|
||||
@@ -522,7 +527,7 @@ bool ExportDialog::SequenceHasSubtitles() const
|
||||
return false;
|
||||
}
|
||||
|
||||
ExportParams ExportDialog::GenerateParams() const
|
||||
EncodingParams ExportDialog::GenerateParams() const
|
||||
{
|
||||
VideoParams video_render_params(static_cast<int>(video_tab_->width_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_->sample_format_combobox()->GetSampleFormat());
|
||||
|
||||
ExportParams params;
|
||||
EncodingParams params;
|
||||
params.set_format(format_combobox_->GetFormat());
|
||||
params.SetFilename(filename_edit_->text().trimmed());
|
||||
params.SetExportLength(viewer_node_->GetLength());
|
||||
@@ -552,7 +557,7 @@ ExportParams ExportDialog::GenerateParams() const
|
||||
}
|
||||
|
||||
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()) {
|
||||
@@ -596,6 +601,76 @@ ExportParams ExportDialog::GenerateParams() const
|
||||
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
|
||||
{
|
||||
if (range_combobox_->currentIndex() == kRangeInToOut) {
|
||||
@@ -617,8 +692,8 @@ void ExportDialog::UpdateViewerDimensions()
|
||||
|
||||
VideoParams vp = viewer_node_->GetVideoParams();
|
||||
|
||||
QMatrix4x4 transform = ExportParams::GenerateMatrix(
|
||||
static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
||||
QMatrix4x4 transform = EncodingParams::GenerateMatrix(
|
||||
static_cast<EncodingParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
||||
vp.width(),
|
||||
vp.height(),
|
||||
static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
ExportDialog(ViewerOutput* viewer_node, QWidget* parent = nullptr);
|
||||
|
||||
rational GetSelectedTimebase() const;
|
||||
void SetSelectedTimebase(const rational &r);
|
||||
|
||||
void SetTime(const rational &time)
|
||||
{
|
||||
@@ -54,8 +55,11 @@ public:
|
||||
preview_viewer_->SetAudioScrubbingEnabled(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *e) override;
|
||||
EncodingParams GenerateParams() const;
|
||||
void SetParams(const EncodingParams &e);
|
||||
|
||||
public slots:
|
||||
virtual void done(int r) override;
|
||||
|
||||
private:
|
||||
void AddPreferencesTab(QWidget *inner_widget, const QString &title);
|
||||
@@ -65,8 +69,6 @@ private:
|
||||
|
||||
bool SequenceHasSubtitles() const;
|
||||
|
||||
ExportParams GenerateParams() const;
|
||||
|
||||
ViewerOutput* viewer_node_;
|
||||
|
||||
ExportFormat::Format previously_selected_format_;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <QLabel>
|
||||
|
||||
#include "codec/exportformat.h"
|
||||
#include "common/qtutils.h"
|
||||
#include "dialog/export/exportformatcombobox.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -49,6 +50,11 @@ public:
|
||||
return static_cast<ExportCodec::Codec>(codec_combobox_->currentData().toInt());
|
||||
}
|
||||
|
||||
void SetSubtitleCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox_, c);
|
||||
}
|
||||
|
||||
private:
|
||||
QCheckBox *sidecar_checkbox_;
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "core.h"
|
||||
#include "exportadvancedvideodialog.h"
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
#include "task/export/exportparams.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -70,6 +69,13 @@ bool ExportVideoTab::IsImageSequenceSet() const
|
||||
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()
|
||||
{
|
||||
int row = 0;
|
||||
@@ -107,9 +113,9 @@ QWidget* ExportVideoTab::SetupResolutionSection()
|
||||
|
||||
scaling_method_combobox_ = new QComboBox();
|
||||
scaling_method_combobox_->setEnabled(false);
|
||||
scaling_method_combobox_->addItem(tr("Fit"), ExportParams::kFit);
|
||||
scaling_method_combobox_->addItem(tr("Stretch"), ExportParams::kStretch);
|
||||
scaling_method_combobox_->addItem(tr("Crop"), ExportParams::kCrop);
|
||||
scaling_method_combobox_->addItem(tr("Fit"), EncodingParams::kFit);
|
||||
scaling_method_combobox_->addItem(tr("Stretch"), EncodingParams::kStretch);
|
||||
scaling_method_combobox_->addItem(tr("Crop"), EncodingParams::kCrop);
|
||||
layout->addWidget(scaling_method_combobox_, row, 1);
|
||||
|
||||
// Automatically enable/disable the scaling method depending on maintain aspect ratio
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QComboBox>
|
||||
#include <QWidget>
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "common/rational.h"
|
||||
#include "dialog/export/codec/cineformsection.h"
|
||||
#include "dialog/export/codec/codecstack.h"
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
|
||||
bool IsImageSequenceSet() const;
|
||||
void SetImageSequence(bool e) const;
|
||||
|
||||
rational GetStillImageTime() const
|
||||
{
|
||||
@@ -57,6 +59,11 @@ public:
|
||||
return static_cast<ExportCodec::Codec>(codec_combobox()->currentData().toInt());
|
||||
}
|
||||
|
||||
void SetSelectedCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox(), c);
|
||||
}
|
||||
|
||||
QComboBox* codec_combobox() const
|
||||
{
|
||||
return codec_combobox_;
|
||||
@@ -98,6 +105,11 @@ public:
|
||||
return color_space_chooser_->input();
|
||||
}
|
||||
|
||||
void SetOCIOColorSpace(const QString &s)
|
||||
{
|
||||
color_space_chooser_->set_input(s);
|
||||
}
|
||||
|
||||
CodecSection* GetCodecSection() const
|
||||
{
|
||||
return static_cast<CodecSection*>(codec_stack_->currentWidget());
|
||||
@@ -133,15 +145,16 @@ public:
|
||||
return threads_;
|
||||
}
|
||||
|
||||
const QString& pix_fmt() const
|
||||
void SetThreads(int t)
|
||||
{
|
||||
return pix_fmt_;
|
||||
threads_ = t;
|
||||
}
|
||||
|
||||
VideoParams::ColorRange color_range() const
|
||||
{
|
||||
return color_range_;
|
||||
}
|
||||
const QString& pix_fmt() const { return pix_fmt_; }
|
||||
void SetPixFmt(const QString &s) { pix_fmt_ = s; }
|
||||
|
||||
VideoParams::ColorRange color_range() const { return color_range_; }
|
||||
void SetColorRange(VideoParams::ColorRange c) { color_range_ = c; }
|
||||
|
||||
public slots:
|
||||
void VideoCodecChanged();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef VIEWER_H
|
||||
#define VIEWER_H
|
||||
|
||||
#include "codec/encoder.h"
|
||||
#include "common/rational.h"
|
||||
#include "node/node.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;
|
||||
|
||||
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 kAudioParamsInput;
|
||||
static const QString kSubtitleParamsInput;
|
||||
@@ -216,6 +220,8 @@ private:
|
||||
TimelineWorkArea *workarea_;
|
||||
TimelineMarkerList *markers_;
|
||||
|
||||
EncodingParams last_used_encoding_params_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,5 @@ set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
task/export/export.h
|
||||
task/export/export.cpp
|
||||
task/export/exportparams.h
|
||||
task/export/exportparams.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace olive {
|
||||
|
||||
ExportTask::ExportTask(ViewerOutput *viewer_node,
|
||||
ColorManager* color_manager,
|
||||
const ExportParams& params) :
|
||||
const EncodingParams& params) :
|
||||
color_manager_(color_manager),
|
||||
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
|
||||
bool subtitles_enabled = params_.subtitles_enabled();
|
||||
ExportParams sidecar_params = params_;
|
||||
EncodingParams sidecar_params = params_;
|
||||
if (subtitles_enabled && params_.subtitles_are_sidecar()) {
|
||||
params_.DisableSubtitles();
|
||||
}
|
||||
@@ -126,12 +126,12 @@ bool ExportTask::Run()
|
||||
|| video_params().height() != params_.video_params().height()) {
|
||||
video_force_size = QSize(params_.video_params().width(), params_.video_params().height());
|
||||
|
||||
if (params_.video_scaling_method() != ExportParams::kStretch) {
|
||||
video_force_matrix = ExportParams::GenerateMatrix(params_.video_scaling_method(),
|
||||
video_params().width(),
|
||||
video_params().height(),
|
||||
params_.video_params().width(),
|
||||
params_.video_params().height());
|
||||
if (params_.video_scaling_method() != EncodingParams::kStretch) {
|
||||
video_force_matrix = EncodingParams::GenerateMatrix(params_.video_scaling_method(),
|
||||
video_params().width(),
|
||||
video_params().height(),
|
||||
params_.video_params().width(),
|
||||
params_.video_params().height());
|
||||
}
|
||||
} else {
|
||||
// Disables forcing size in the renderer
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef EXPORTTASK_H
|
||||
#define EXPORTTASK_H
|
||||
|
||||
#include "exportparams.h"
|
||||
#include "codec/encoder.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "render/colorprocessor.h"
|
||||
#include "task/render/render.h"
|
||||
@@ -33,7 +33,7 @@ class ExportTask : public RenderTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportTask(ViewerOutput *viewer_node, ColorManager *color_manager, const ExportParams ¶ms);
|
||||
ExportTask(ViewerOutput *viewer_node, ColorManager *color_manager, const EncodingParams ¶ms);
|
||||
|
||||
protected:
|
||||
virtual bool Run() override;
|
||||
@@ -58,7 +58,7 @@ private:
|
||||
|
||||
ColorManager* color_manager_;
|
||||
|
||||
ExportParams params_;
|
||||
EncodingParams params_;
|
||||
|
||||
std::shared_ptr<Encoder> encoder_;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user