export: allow selecting output pixel format

This commit is contained in:
itsmattkc
2020-07-24 14:45:27 +10:00
parent 86b66004b0
commit 5235975d6d
11 changed files with 183 additions and 55 deletions
+10
View File
@@ -88,6 +88,11 @@ void EncodingParams::set_video_threads(const int &threads)
video_threads_ = threads;
}
void EncodingParams::set_video_pix_fmt(const QString &s)
{
video_pix_fmt_ = s;
}
const QString &EncodingParams::filename() const
{
return filename_;
@@ -133,6 +138,11 @@ const int &EncodingParams::video_threads() const
return video_threads_;
}
const QString &EncodingParams::video_pix_fmt() const
{
return video_pix_fmt_;
}
bool EncodingParams::audio_enabled() const
{
return audio_enabled_;
+3
View File
@@ -51,6 +51,7 @@ public:
void set_video_max_bit_rate(const int64_t& rate);
void set_video_buffer_size(const int64_t& sz);
void set_video_threads(const int& threads);
void set_video_pix_fmt(const QString& s);
const QString& filename() const;
@@ -62,6 +63,7 @@ public:
const int64_t& video_max_bit_rate() const;
const int64_t& video_buffer_size() const;
const int& video_threads() const;
const QString& video_pix_fmt() const;
bool audio_enabled() const;
const ExportCodec::Codec &audio_codec() const;
@@ -83,6 +85,7 @@ private:
int64_t video_max_bit_rate_;
int64_t video_buffer_size_;
int video_threads_;
QString video_pix_fmt_;
bool audio_enabled_;
ExportCodec::Codec audio_codec_;
+50
View File
@@ -20,6 +20,11 @@
#include "exportcodec.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/pixdesc.h>
}
OLIVE_NAMESPACE_ENTER
QString ExportCodec::GetCodecName(ExportCodec::Codec c)
@@ -77,4 +82,49 @@ bool ExportCodec::IsCodecAStillImage(ExportCodec::Codec c)
return false;
}
QStringList ExportCodec::GetPixelFormatsForCodec(ExportCodec::Codec c)
{
QStringList pix_fmts;
AVCodec* codec_info;
switch (c) {
case kCodecH264:
codec_info = avcodec_find_encoder(AV_CODEC_ID_H264);
break;
case kCodecDNxHD:
codec_info = avcodec_find_encoder(AV_CODEC_ID_DNXHD);
break;
case kCodecProRes:
codec_info = avcodec_find_encoder(AV_CODEC_ID_PRORES);
break;
case kCodecH265:
codec_info = avcodec_find_encoder(AV_CODEC_ID_HEVC);
break;
case kCodecOpenEXR:
case kCodecPNG:
case kCodecTIFF:
// FIXME: Add these in (these will most likely use an OIIOEncoder which doesn't exist yet)
codec_info = nullptr;
break;
case kCodecMP2:
case kCodecMP3:
case kCodecAAC:
case kCodecPCM:
case kCodecCount:
// These are audio or invalid codecs and therefore have no pixel formats
codec_info = nullptr;
break;
}
if (codec_info) {
for (int i=0; codec_info->pix_fmts[i]!=-1; i++) {
const char* pix_fmt_name = av_get_pix_fmt_name(codec_info->pix_fmts[i]);
pix_fmts.append(pix_fmt_name);
}
}
return pix_fmts;
}
OLIVE_NAMESPACE_EXIT
+2
View File
@@ -51,6 +51,8 @@ public:
static bool IsCodecAStillImage(Codec c);
static QStringList GetPixelFormatsForCodec(Codec c);
};
OLIVE_NAMESPACE_EXIT
+5 -3
View File
@@ -20,6 +20,10 @@
#include "ffmpegencoder.h"
extern "C" {
#include <libavutil/pixdesc.h>
}
#include <QFile>
#include "ffmpegcommon.h"
@@ -441,9 +445,7 @@ bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AV
codec_ctx->height = params().video_params().height();
codec_ctx->sample_aspect_ratio = {1, 1};
codec_ctx->time_base = params().video_params().time_base().toAVRational();
// FIXME: Make this customizable again
codec_ctx->pix_fmt = encoder->pix_fmts[0];
codec_ctx->pix_fmt = av_get_pix_fmt(params().video_pix_fmt().toUtf8());
// Set custom options
{
+5 -20
View File
@@ -203,11 +203,6 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
this,
&ExportDialog::ResolutionChanged);
connect(video_tab_->codec_combobox(),
static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this,
&ExportDialog::VideoCodecChanged);
connect(video_tab_,
&ExportVideoTab::ColorSpaceChanged,
preview_viewer_,
@@ -232,8 +227,8 @@ void ExportDialog::StartExport()
return;
}
// Validate if the entered filename contains the correct extension (the extension is necessary for both FFmpeg and
// OIIO to determine the output format)
// Validate if the entered filename contains the correct extension (the extension is necessary
// for both FFmpeg and OIIO to determine the output format)
QString necessary_ext = QStringLiteral(".%1").arg(ExportFormat::GetExtension(static_cast<ExportFormat::Format>(format_combobox_->currentIndex())));
// If it doesn't, see if the user wants to append it automatically. If not, we don't abort the export.
@@ -356,7 +351,6 @@ void ExportDialog::FormatChanged(int index)
foreach (ExportCodec::Codec vcodec, ExportFormat::GetVideoCodecs(current_format)) {
video_tab_->codec_combobox()->addItem(ExportCodec::GetCodecName(vcodec), vcodec);
}
VideoCodecChanged();
audio_tab_->codec_combobox()->clear();
foreach (ExportCodec::Codec acodec, ExportFormat::GetAudioCodecs(current_format)) {
@@ -396,17 +390,6 @@ void ExportDialog::ResolutionChanged()
UpdateViewerDimensions();
}
void ExportDialog::VideoCodecChanged()
{
ExportCodec::Codec codec = static_cast<ExportCodec::Codec>(video_tab_->codec_combobox()->currentData().toInt());
if (codec == ExportCodec::kCodecH264) {
video_tab_->SetCodecSection(video_tab_->h264_section());
} else if (ExportCodec::IsCodecAStillImage(codec)) {
video_tab_->SetCodecSection(video_tab_->image_section());
}
}
void ExportDialog::LoadPresets()
{
@@ -457,7 +440,7 @@ ExportParams ExportDialog::GenerateParams() const
}
if (video_enabled_->isChecked()) {
ExportCodec::Codec video_codec = static_cast<ExportCodec::Codec>(video_tab_->codec_combobox()->currentData().toInt());
ExportCodec::Codec video_codec = video_tab_->GetSelectedCodec();
params.EnableVideo(video_render_params, video_codec);
params.set_video_threads(video_tab_->threads());
@@ -465,6 +448,8 @@ ExportParams ExportDialog::GenerateParams() const
video_tab_->GetCodecSection()->AddOpts(&params);
params.set_color_transform(video_tab_->CurrentOCIOColorSpace());
params.set_video_pix_fmt(video_tab_->pix_fmt());
}
if (audio_enabled_->isChecked()) {
-2
View File
@@ -81,8 +81,6 @@ private slots:
void ResolutionChanged();
void VideoCodecChanged();
void UpdateViewerDimensions();
void StartExport();
+39 -20
View File
@@ -2,42 +2,61 @@
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
OLIVE_NAMESPACE_ENTER
ExportAdvancedVideoDialog::ExportAdvancedVideoDialog(QWidget *parent) :
ExportAdvancedVideoDialog::ExportAdvancedVideoDialog(const QList<QString> &pix_fmts, QWidget *parent) :
QDialog(parent)
{
setWindowTitle(tr("Advanced"));
QGridLayout* layout = new QGridLayout(this);
QVBoxLayout* layout = new QVBoxLayout(this);
int row = 0;
{
// Pixel Settings
QGroupBox* pixel_group = new QGroupBox();
layout->addWidget(pixel_group);
pixel_group->setTitle(tr("Pixel"));
layout->addWidget(new QLabel(tr("Threads:")), row, 0);
QGridLayout* pixel_layout = new QGridLayout(pixel_group);
thread_slider_ = new IntegerSlider();
thread_slider_->SetMinimum(0);
thread_slider_->SetDefaultValue(0);
layout->addWidget(thread_slider_, row, 1);
int row = 0;
row++;
pixel_layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0);
pixel_format_combobox_ = new QComboBox();
pixel_format_combobox_->addItems(pix_fmts);
pixel_layout->addWidget(pixel_format_combobox_, row, 1);
row++;
}
{
// Performance Settings
QGroupBox* performance_group = new QGroupBox();
layout->addWidget(performance_group);
performance_group->setTitle(tr("Performance"));
QGridLayout* performance_layout = new QGridLayout(performance_group);
int row = 0;
performance_layout->addWidget(new QLabel(tr("Threads:")), row, 0);
thread_slider_ = new IntegerSlider();
thread_slider_->SetMinimum(0);
thread_slider_->SetDefaultValue(0);
performance_layout->addWidget(thread_slider_, row, 1);
row++;
}
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttons, &QDialogButtonBox::accepted, this, &ExportAdvancedVideoDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &ExportAdvancedVideoDialog::reject);
layout->addWidget(buttons, row, 0, 1, 2);
}
int ExportAdvancedVideoDialog::threads() const
{
return static_cast<int>(thread_slider_->GetValue());
}
void ExportAdvancedVideoDialog::set_threads(int t)
{
thread_slider_->SetValue(t);
layout->addWidget(buttons);
}
OLIVE_NAMESPACE_EXIT
+24 -3
View File
@@ -1,6 +1,7 @@
#ifndef EXPORTADVANCEDVIDEODIALOG_H
#define EXPORTADVANCEDVIDEODIALOG_H
#include <QComboBox>
#include <QDialog>
#include "widget/slider/integerslider.h"
@@ -11,14 +12,34 @@ class ExportAdvancedVideoDialog : public QDialog
{
Q_OBJECT
public:
ExportAdvancedVideoDialog(QWidget* parent = nullptr);
ExportAdvancedVideoDialog(const QList<QString>& pix_fmts,
QWidget* parent = nullptr);
int threads() const;
void set_threads(int t);
int threads() const
{
return static_cast<int>(thread_slider_->GetValue());
}
void set_threads(int t)
{
thread_slider_->SetValue(t);
}
QString pix_fmt() const
{
return pixel_format_combobox_->currentText();
}
void set_pix_fmt(const QString& s)
{
pixel_format_combobox_->setCurrentText(s);
}
private:
IntegerSlider* thread_slider_;
QComboBox* pixel_format_combobox_;
};
OLIVE_NAMESPACE_EXIT
+30 -6
View File
@@ -49,6 +49,11 @@ ExportVideoTab::ExportVideoTab(ColorManager* color_manager, QWidget *parent) :
outer_layout->addStretch();
}
ExportCodec::Codec ExportVideoTab::GetSelectedCodec() const
{
return static_cast<ExportCodec::Codec>(codec_combobox()->currentData().toInt());
}
QComboBox *ExportVideoTab::codec_combobox() const
{
return codec_combobox_;
@@ -109,11 +114,6 @@ H264Section *ExportVideoTab::h264_section() const
return h264_section_;
}
const int &ExportVideoTab::threads() const
{
return threads_;
}
QWidget* ExportVideoTab::SetupResolutionSection()
{
int row = 0;
@@ -194,6 +194,10 @@ QWidget *ExportVideoTab::SetupCodecSection()
codec_combobox_ = new QComboBox();
codec_layout->addWidget(codec_combobox_, row, 1);
connect(codec_combobox_,
static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this,
&ExportVideoTab::VideoCodecChanged);
row++;
@@ -222,13 +226,33 @@ void ExportVideoTab::MaintainAspectRatioChanged(bool val)
void ExportVideoTab::OpenAdvancedDialog()
{
ExportAdvancedVideoDialog d(this);
// Find export formats compatible with this encoder
QStringList pixel_formats = ExportCodec::GetPixelFormatsForCodec(GetSelectedCodec());
ExportAdvancedVideoDialog d(pixel_formats, this);
d.set_threads(threads_);
d.set_pix_fmt(pix_fmt_);
if (d.exec() == QDialog::Accepted) {
threads_ = d.threads();
pix_fmt_ = d.pix_fmt();
}
}
void ExportVideoTab::VideoCodecChanged()
{
ExportCodec::Codec codec = GetSelectedCodec();
if (codec == ExportCodec::kCodecH264) {
SetCodecSection(h264_section());
} else if (ExportCodec::IsCodecAStillImage(codec)) {
SetCodecSection(image_section());
}
// Set default pixel format
pix_fmt_ = ExportCodec::GetPixelFormatsForCodec(codec).first();
qDebug() << "Set default pix fmt" << pix_fmt_;
}
OLIVE_NAMESPACE_EXIT
+15 -1
View File
@@ -40,6 +40,8 @@ class ExportVideoTab : public QWidget
public:
ExportVideoTab(ColorManager* color_manager, QWidget* parent = nullptr);
ExportCodec::Codec GetSelectedCodec() const;
QComboBox* codec_combobox() const;
IntegerSlider* width_slider() const;
@@ -57,7 +59,17 @@ public:
ImageSection* image_section() const;
H264Section* h264_section() const;
const int& threads() const;
const int& threads() const
{
return threads_;
}
const QString& pix_fmt() const {
return pix_fmt_;
}
public slots:
void VideoCodecChanged();
signals:
void ColorSpaceChanged(const QString& colorspace);
@@ -87,6 +99,8 @@ private:
int threads_;
QString pix_fmt_;
private slots:
void MaintainAspectRatioChanged(bool val);