video_export_options_dialog.cpp 9.77 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 *  Copyright (c) 2016 Dmitry Kazakov <dimula73@gmail.com>
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "video_export_options_dialog.h"
#include "ui_video_export_options_dialog.h"

#include <KoID.h>

24
25
26
#include <ksharedconfig.h>
#include <kconfiggroup.h>

27
28
29
30

struct VideoExportOptionsDialog::Private
{
    Private() {
31
32
33
34
35
36
37
38
39
40
        presets << KoID("ultrafast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "ultrafast"));
        presets << KoID("superfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "superfast"));
        presets << KoID("veryfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryfast"));
        presets << KoID("faster", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "faster"));
        presets << KoID("fast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "fast"));
        presets << KoID("medium", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "medium"));
        presets << KoID("slow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slow"));
        presets << KoID("slower", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slower"));
        presets << KoID("veryslow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryslow"));
        presets << KoID("placebo", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "placebo"));
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        profiles << KoID("baseline", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "baseline"));
        profiles << KoID("main", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "main"));
        profiles << KoID("high", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high"));
        profiles << KoID("high10", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high10"));
        profiles << KoID("high422", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high422"));
        profiles << KoID("high444", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high444"));

        tunes << KoID("film", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "film"));
        tunes << KoID("animation", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "animation"));
        tunes << KoID("grain", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "grain"));
        tunes << KoID("stillimage", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "stillimage"));
        tunes << KoID("psnr", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "psnr"));
        tunes << KoID("ssim", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "ssim"));
        tunes << KoID("fastdecode", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "fastdecode"));
        tunes << KoID("zerolatency", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "zerolatency"));
57
58
59
60
61
62
    }

    QVector<KoID> presets;
    int defaultPreset;
    int defaultBitrate;
    int defaultConstantRateFactor;
63
64
65
66
67
68

    QVector<KoID> profiles;
    int defaultProfile;

    QVector<KoID> tunes;
    int defaultTune;
69
70

    QString defaultCustomLine;
71
72
73
74
75
76
77
    QString currentCustomLine;

    void updateDefaultCustomLine()
    {
        defaultCustomLine = currentCustomLine;
    }

78
79
80
81
};


VideoExportOptionsDialog::VideoExportOptionsDialog(QWidget *parent) :
82
    KisConfigWidget(parent),
83
84
85
86
87
88
89
90
91
92
93
94
95
    ui(new Ui::VideoExportOptionsDialog),
    m_d(new Private)
{
    ui->setupUi(this);

    ui->intConstantRateFactor->setRange(0, 51);
    ui->intConstantRateFactor->setValue(m_d->defaultConstantRateFactor);

    Q_FOREACH (const KoID &preset, m_d->presets) {
        ui->cmbPreset->insertItem(ui->cmbPreset->count(), preset.name());
    }
    ui->cmbPreset->setCurrentIndex(m_d->defaultPreset);

96
97
98
99
100
101
102
103
104
105
    Q_FOREACH (const KoID &profile, m_d->profiles) {
        ui->cmbProfile->insertItem(ui->cmbProfile->count(), profile.name());
    }
    ui->cmbProfile->setCurrentIndex(m_d->defaultProfile);

    Q_FOREACH (const KoID &tune, m_d->tunes) {
        ui->cmbTune->insertItem(ui->cmbTune->count(), tune.name());
    }
    ui->cmbTune->setCurrentIndex(m_d->defaultTune);

106
107
108
109
    ui->intBitrate->setRange(10, 50000);
    ui->intBitrate->setValue(5000);
    ui->intBitrate->setSuffix(i18nc("kilo-bits-per-second, video bitrate suffix", "kbps"));

110
    connect(ui->cmbCodec, SIGNAL(currentIndexChanged(int)), ui->stackedWidget, SLOT(setCurrentIndex(int)));
111
112
113
114

    ui->cmbCodec->setCurrentIndex(0);
    ui->cmbCodec->setEnabled(false);

Dmitry Kazakov's avatar
Dmitry Kazakov committed
115
116
117
118
119
120
    // TODO: temporarily hidden! Some combinations of 'tune' and
    //       'profile' options make ffmpeg generate empty file.
    //       We should not let the user shoot into his own foot!
    ui->cmbTune->setVisible(false);
    ui->lblTune->setVisible(false);

121
122
123
124
125
    ui->chkCustomLine->setChecked(!m_d->defaultCustomLine.isEmpty());
    slotCustomLineToggled(!m_d->defaultCustomLine.isEmpty());
    connect(ui->chkCustomLine, SIGNAL(toggled(bool)), SLOT(slotCustomLineToggled(bool)));
    connect(ui->txtCustomLine, SIGNAL(editingFinished()), SLOT(slotSaveCustomLine()));
    connect(ui->btnResetCustomLine, SIGNAL(clicked()), SLOT(slotResetCustomLine()));
126
127
128
129
130
131
132
}

VideoExportOptionsDialog::~VideoExportOptionsDialog()
{
    delete ui;
}

133
KisPropertiesConfigurationSP VideoExportOptionsDialog::configuration() const
134
{
135
    KisPropertiesConfigurationSP cfg(new KisPropertiesConfiguration());
136

137
138
139
140
141
142
143
144
    cfg->setProperty("h264PresetIndex", ui->cmbPreset->currentIndex());
    cfg->setProperty("h264ConstantRateFactor", ui->intConstantRateFactor->value());
    cfg->setProperty("h264ProfileIndex", ui->cmbProfile->currentIndex());
    cfg->setProperty("h264TuneIndex", ui->cmbTune->currentIndex());
    cfg->setProperty("TheoraBitrate", ui->intBitrate->value());
    cfg->setProperty("CustomLineValue", ui->txtCustomLine->text());

    return cfg;
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
}

void VideoExportOptionsDialog::slotCustomLineToggled(bool value)
{
    m_d->updateDefaultCustomLine();
    QString customLine = m_d->defaultCustomLine;

    if (customLine.isEmpty() && value) {
        customLine = generateCustomLine().join(" ");
    } else if (!value) {
        customLine = "";
    }

    ui->txtCustomLine->setText(customLine);

    ui->stackedWidget->setEnabled(!value);
    ui->txtCustomLine->setEnabled(value);
    ui->btnResetCustomLine->setEnabled(value);
}

void VideoExportOptionsDialog::slotResetCustomLine()
{
    ui->txtCustomLine->setText(generateCustomLine().join(" "));
    slotSaveCustomLine();
169
170
}

171
172
173
174
175
void VideoExportOptionsDialog::slotSaveCustomLine()
{
    m_d->currentCustomLine = ui->txtCustomLine->text();
}

176
177
178
179
180
void VideoExportOptionsDialog::setCodec(CodecIndex index)
{
    ui->cmbCodec->setCurrentIndex(int(index));
}

181
QStringList VideoExportOptionsDialog::customUserOptions() const
182
183
184
{
    return ui->chkCustomLine->isChecked() ?
        ui->txtCustomLine->text().split(" ", QString::SkipEmptyParts) :
185
186
187
188
189
190
191
192
193
194
195
                generateCustomLine();
}

void VideoExportOptionsDialog::setConfiguration(const KisPropertiesConfigurationSP cfg)
{
    m_d->defaultPreset = cfg->getInt("h264PresetIndex", 5);
    m_d->defaultConstantRateFactor = cfg->getInt("h264ConstantRateFactor", 23);
    m_d->defaultProfile = cfg->getInt("h264ProfileIndex", 4);
    m_d->defaultTune = cfg->getInt("h264TuneIndex", 1);
    m_d->defaultBitrate = cfg->getInt("TheoraBitrate", 5000);
    m_d->defaultCustomLine = cfg->getString("CustomLineValue", "");
196
197
198
199
200
201
    if (cfg->hasProperty("CodecIndex")) {
        setCodec((VideoExportOptionsDialog::CodecIndex)cfg->getInt("CodecIndex"));
    }
    else {
        ui->cmbCodec->setEnabled(false);
    }
202
203
204
}

QStringList VideoExportOptionsDialog::generateCustomLine() const
205
{
206
    QStringList options;
207
208

    if (ui->cmbCodec->currentIndex() == int(CODEC_H264)) {
209
        options << "-crf" << QString::number(ui->intConstantRateFactor->value());
210
211

        const int presetIndex = ui->cmbPreset->currentIndex();
212
        qDebug() << "presetIndex" << presetIndex << m_d->presets;
213
        options << "-preset" << m_d->presets[presetIndex].id();
214

215
        const int profileIndex = ui->cmbProfile->currentIndex();
216
        options << "-profile" << m_d->profiles[profileIndex].id();
217

218
        if (m_d->profiles[profileIndex].id() == "high422") {
219
            options << "-pix_fmt" << "yuv422p";
220
        } else if (m_d->profiles[profileIndex].id() == "high444") {
221
            options << "-pix_fmt" << "yuv444p";
222
        } else {
223
            options << "-pix_fmt" << "yuv420p";
224
225
        }

Dmitry Kazakov's avatar
Dmitry Kazakov committed
226
227
        // Disabled! see the comment in c-tor!
        //const int tuneIndex = ui->cmbTune->currentIndex();
228
        //options << "-tune" << m_d->tunes[tuneIndex].id();
Dmitry Kazakov's avatar
Dmitry Kazakov committed
229

230
    } else if (ui->cmbCodec->currentIndex() == int(CODEC_THEORA)) {
231
        options << "-b" << QString::number(ui->intBitrate->value()) + "k";
232
233
234
235
    }

    return options;
}