Commit c0f34663 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Implemented HDR metadata editing when rendering video files

parent d205dbe9
......@@ -4,10 +4,13 @@ set(kritaanimationrenderer_SOURCES
KisAnimationRenderingOptions.cpp
video_export_options_dialog.cpp
video_saver.cpp
VideoHDRMetadataOptionsDialog.cpp
KisHDRMetadataOptions.cpp
)
ki18n_wrap_ui(kritaanimationrenderer_SOURCES
wdg_animationrenderer.ui
video_export_options_dialog.ui)
video_export_options_dialog.ui
VideoHDRMetadataOptionsDialog.ui)
add_library(kritaanimationrenderer MODULE ${kritaanimationrenderer_SOURCES})
target_link_libraries(kritaanimationrenderer kritaui)
......
/*
* Copyright (c) 2019 Dmitry Kazakov <dimula73@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KisHDRMetadataOptions.h"
#include "kis_properties_configuration.h"
KisHDRMetadataOptions::KisHDRMetadataOptions()
: predefinedMasterDisplayId("p2100-pq")
{
}
KisPropertiesConfigurationSP KisHDRMetadataOptions::toProperties() const
{
KisPropertiesConfigurationSP config = new KisPropertiesConfiguration();
config->setProperty("predefinedMasterDisplayId", predefinedMasterDisplayId);
config->setProperty("redX", redX);
config->setProperty("redY", redY);
config->setProperty("greenX", greenX);
config->setProperty("greenY", greenY);
config->setProperty("blueX", blueX);
config->setProperty("blueY", blueY);
config->setProperty("whiteX", whiteX);
config->setProperty("whiteY", whiteY);
config->setProperty("minLuminance", minLuminance);
config->setProperty("maxLuminance", maxLuminance);
config->setProperty("maxCLL", maxCLL);
config->setProperty("maxFALL", maxFALL);
return config;
}
void KisHDRMetadataOptions::fromProperties(KisPropertiesConfigurationSP config)
{
predefinedMasterDisplayId = config->getPropertyLazy("predefinedMasterDisplayId", predefinedMasterDisplayId);
redX = config->getPropertyLazy("redX", redX);
redY = config->getPropertyLazy("redY", redY);
greenX = config->getPropertyLazy("greenX", greenX);
greenY = config->getPropertyLazy("greenY", greenY);
blueX = config->getPropertyLazy("blueX", blueX);
blueY = config->getPropertyLazy("blueY", blueY);
whiteX = config->getPropertyLazy("whiteX", whiteX);
whiteY = config->getPropertyLazy("whiteY", whiteY);
minLuminance = config->getPropertyLazy("minLuminance", minLuminance);
maxLuminance = config->getPropertyLazy("maxLuminance", maxLuminance);
maxCLL = config->getPropertyLazy("maxCLL", maxCLL);
maxFALL = config->getPropertyLazy("maxFALL", maxFALL);
}
QString KisHDRMetadataOptions::generateFFMpegOptions() const
{
auto cprim = [] (qreal x) { return int(x / 0.00002); };
auto lum = [] (qreal x) { return int(x / 0.0001); };
const QString x265Params =
QString("-x265-params "
"master-display=R(%1,%2)G(%3,%4)B(%5,%6)WP(%7,%8)L(%9,%10):"
"max-cll=%11,%12:"
"colorprim=bt2020:"
"colormatrix=bt2020c:"
"transfer=smpte2084:"
"range=full")
.arg(cprim(redX)).arg(cprim(redY))
.arg(cprim(greenX)).arg(cprim(greenY))
.arg(cprim(blueX)).arg(cprim(blueY))
.arg(cprim(whiteX)).arg(cprim(whiteY))
.arg(lum(maxLuminance)).arg(lum(minLuminance))
.arg(int(maxCLL)).arg(int(maxFALL));
return x265Params;
}
/*
* Copyright (c) 2019 Dmitry Kazakov <dimula73@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KISHDRMETADATAOPTIONS_H
#define KISHDRMETADATAOPTIONS_H
#include <QString>
#include "kis_types.h"
struct KisHDRMetadataOptions
{
KisHDRMetadataOptions();
QString predefinedMasterDisplayId;
qreal redX = 0.708;
qreal redY = 0.292;
qreal greenX = 0.170;
qreal greenY = 0.797;
qreal blueX = 0.131;
qreal blueY = 0.046;
qreal whiteX = 0.3127;
qreal whiteY = 0.3290;
qreal minLuminance = 0.005;
qreal maxLuminance = 1000;
qreal maxCLL = 1000;
qreal maxFALL = 400;
KisPropertiesConfigurationSP toProperties() const;
void fromProperties(KisPropertiesConfigurationSP config);
QString generateFFMpegOptions() const;
};
#endif // KISHDRMETADATAOPTIONS_H
/*
* Copyright (c) 2019 Dmitry Kazakov <dimula73@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "VideoHDRMetadataOptionsDialog.h"
#include "ui_VideoHDRMetadataOptionsDialog.h"
#include "KisHDRMetadataOptions.h"
VideoHDRMetadataOptionsDialog::VideoHDRMetadataOptionsDialog(QWidget *parent)
: QDialog(parent),
ui(new Ui::VideoHDRMetadataOptionsDialog)
{
ui->setupUi(this);
connect(ui->btnBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->btnBox, SIGNAL(rejected()), this, SLOT(reject()));
ui->cmbMasterDisplay->addItem(i18n("Rec. 2100 PQ"), "p2100-pq");
ui->cmbMasterDisplay->addItem(i18n("DCI-P3 D65"), "dci-p3-d65");
ui->cmbMasterDisplay->addItem(i18n("Custom"), "custom");
connect(ui->cmbMasterDisplay, SIGNAL(currentIndexChanged(int)), SLOT(slotPredefinedDisplayIdChanged()));
}
VideoHDRMetadataOptionsDialog::~VideoHDRMetadataOptionsDialog()
{
delete ui;
}
void VideoHDRMetadataOptionsDialog::setHDRMetadataOptions(const KisHDRMetadataOptions &options)
{
ui->dblRedX->setValue(options.redX);
ui->dblRedY->setValue(options.redY);
ui->dblGreenX->setValue(options.greenX);
ui->dblGreenY->setValue(options.greenY);
ui->dblBlueX->setValue(options.blueX);
ui->dblBlueY->setValue(options.blueY);
ui->dblWhiteX->setValue(options.whiteX);
ui->dblWhiteY->setValue(options.whiteY);
ui->dblMinLuminance->setValue(options.minLuminance);
ui->dblMaxLuminance->setValue(options.maxLuminance);
ui->intMaxCLL->setValue(options.maxCLL);
ui->intMaxFALL->setValue(options.maxFALL);
int index = ui->cmbMasterDisplay->findData(options.predefinedMasterDisplayId);
if (index < 0) {
index = ui->cmbMasterDisplay->findData("custom");
}
ui->cmbMasterDisplay->setCurrentIndex(index);
slotPredefinedDisplayIdChanged();
}
KisHDRMetadataOptions VideoHDRMetadataOptionsDialog::hdrMetadataOptions() const
{
KisHDRMetadataOptions options;
ui->dblRedX->setValue(options.redX);
options.redY = ui->dblRedY->value();
options.greenX = ui->dblGreenX->value();
options.greenY = ui->dblGreenY->value();
options.blueX = ui->dblBlueX->value();
options.blueY = ui->dblBlueY->value();
options.whiteX = ui->dblWhiteX->value();
options.whiteY = ui->dblWhiteY->value();
options.minLuminance = ui->dblMinLuminance->value();
options.maxLuminance = ui->dblMaxLuminance->value();
options.maxCLL = ui->intMaxCLL->value();
options.maxFALL = ui->intMaxFALL->value();
options.predefinedMasterDisplayId = ui->cmbMasterDisplay->currentData().toString();
return options;
}
void VideoHDRMetadataOptionsDialog::slotPredefinedDisplayIdChanged()
{
const QString displayId = ui->cmbMasterDisplay->currentData().toString();
if (displayId == "p2100-pq") {
ui->grpCustomDisplay->setEnabled(false);
ui->dblRedX->setValue(0.708);
ui->dblRedY->setValue(0.292);
ui->dblGreenX->setValue(0.170);
ui->dblGreenY->setValue(0.797);
ui->dblBlueX->setValue(0.131);
ui->dblBlueY->setValue(0.046);
ui->dblWhiteX->setValue(0.3127);
ui->dblWhiteY->setValue(0.3290);
ui->dblMinLuminance->setValue(0.005);
ui->dblMaxLuminance->setValue(1000);
} else if (displayId == "dci-p3-d65") {
ui->grpCustomDisplay->setEnabled(false);
ui->dblRedX->setValue(0.680);
ui->dblRedY->setValue(0.320);
ui->dblGreenX->setValue(0.265);
ui->dblGreenY->setValue(0.690);
ui->dblBlueX->setValue(0.150);
ui->dblBlueY->setValue(0.060);
ui->dblWhiteX->setValue(0.3127);
ui->dblWhiteY->setValue(0.3290);
ui->dblMinLuminance->setValue(0.005);
ui->dblMaxLuminance->setValue(1000);
} else {
ui->grpCustomDisplay->setEnabled(true);
}
}
/*
* Copyright (c) 2019 Dmitry Kazakov <dimula73@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef VIDEOHDRMETADATAOPTIONSDIALOG_H
#define VIDEOHDRMETADATAOPTIONSDIALOG_H
#include <QDialog>
#include "kis_types.h"
class KisHDRMetadataOptions;
namespace Ui {
class VideoHDRMetadataOptionsDialog;
}
class VideoHDRMetadataOptionsDialog : public QDialog
{
Q_OBJECT
public:
explicit VideoHDRMetadataOptionsDialog(QWidget *parent = nullptr);
~VideoHDRMetadataOptionsDialog();
void setHDRMetadataOptions(const KisHDRMetadataOptions &options);
KisHDRMetadataOptions hdrMetadataOptions() const;
private Q_SLOTS:
void slotPredefinedDisplayIdChanged();
private:
Ui::VideoHDRMetadataOptionsDialog *ui;
};
#endif // VIDEOHDRMETADATAOPTIONSDIALOG_H
......@@ -23,6 +23,8 @@
#include <ksharedconfig.h>
#include <kconfiggroup.h>
#include "VideoHDRMetadataOptionsDialog.h"
#include "KisHDRMetadataOptions.h"
struct VideoExportOptionsDialog::Private
......@@ -89,6 +91,8 @@ struct VideoExportOptionsDialog::Private
ContainerType containerType;
QString currentCustomLine;
KisHDRMetadataOptions hdrMetadataOptions;
};
void populateComboWithKoIds(QComboBox *combo, const QVector<KoID> &ids, int defaultIndex)
......@@ -187,6 +191,8 @@ KisPropertiesConfigurationSP VideoExportOptionsDialog::configuration() const
cfg->setProperty("CustomLineValue", ui->txtCustomLine->text());
cfg->setProperty("customUserOptions", customUserOptions().join(' '));
cfg->setPrefixedProperties("hdrMetadata/", m_d->hdrMetadataOptions.toProperties());
return cfg;
}
......@@ -289,6 +295,10 @@ void VideoExportOptionsDialog::setConfiguration(const KisPropertiesConfiguration
slotCodecSelected(index);
slotH265ProfileChanged(ui->cmbProfileH265->currentIndex());
KisPropertiesConfigurationSP metadataProperties = new KisPropertiesConfiguration();
cfg->getPrefixedProperties("hdrMetadata/", metadataProperties);
m_d->hdrMetadataOptions.fromProperties(metadataProperties);
}
QStringList VideoExportOptionsDialog::generateCustomLine() const
......@@ -345,36 +355,8 @@ QStringList VideoExportOptionsDialog::generateCustomLine() const
}
if (enableHDR) {
const int r_x = 0.708 * 50000;
const int r_y = 0.292 * 50000;
const int g_x = 0.170 * 50000;
const int g_y = 0.797 * 50000;
const int b_x = 0.131 * 50000;
const int b_y = 0.046 * 50000;
const int w_x = 0.3127 * 50000;
const int w_y = 0.3290 * 50000;
const int minLightness = 0.01 * 10000;
const int maxLightness = 1000 * 10000;
const int maxCLL = 1000;
const int maxFALL = 80;
const QString x265Params =
QString("master-display=R(%1,%2)G(%3,%4)B(%5,%6)WP(%7,%8)L(%9,%10):"
"max-cll=%11,%12:"
"colorprim=bt2020:"
"colormatrix=bt2020c:"
"transfer=smpte2084:"
"range=full")
.arg(r_x).arg(r_y)
.arg(g_x).arg(g_y)
.arg(b_x).arg(b_y)
.arg(w_x).arg(w_y)
.arg(minLightness).arg(maxLightness)
.arg(maxCLL).arg(maxFALL);
options << "-x265-params" << x265Params;
const QString metadataLine = m_d->hdrMetadataOptions.generateFFMpegOptions();
options << metadataLine.split(" ");
}
} else if (currentCodecId() == "libtheora") {
......@@ -415,5 +397,10 @@ void VideoExportOptionsDialog::slotH265ProfileChanged(int index)
void VideoExportOptionsDialog::slotEditHDRMetadata()
{
ENTER_FUNCTION();
VideoHDRMetadataOptionsDialog dlg(this);
dlg.setHDRMetadataOptions(m_d->hdrMetadataOptions);
if (dlg.exec() == QDialog::Accepted) {
m_d->hdrMetadataOptions = dlg.hdrMetadataOptions();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment