Krita Source Code Documentation
Loading...
Searching...
No Matches
VideoExportOptionsDialog.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8#include "ui_video_export_options_dialog.h"
9
10#include <KoID.h>
11
12#include <ksharedconfig.h>
13#include <kconfiggroup.h>
16
17
19{
20 Private(ContainerType _containerType, const QStringList& validEncoders)
21 : containerType(_containerType)
22 {
24
25 // Cross check w/ arbitrary ffmpeg's list of present encoders if list is populated.
26 if (validEncoders.size() > 0) {
27 encoders = [validEncoders](const QVector<KoID>& input) -> QVector<KoID> {
28 QVector<KoID> filtered;
29 Q_FOREACH(const KoID& encoder, input) {
30 if (validEncoders.contains(encoder.id())) {
31 filtered << encoder;
32 }
33 }
34
35 return filtered;
36 }(encoders);
37 }
38
39 presetsXH264 << KoID("ultrafast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "ultrafast"));
40 presetsXH264 << KoID("superfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "superfast"));
41 presetsXH264 << KoID("veryfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryfast"));
42 presetsXH264 << KoID("faster", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "faster"));
43 presetsXH264 << KoID("fast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "fast"));
44 presetsXH264 << KoID("medium", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "medium"));
45 presetsXH264 << KoID("slow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slow"));
46 presetsXH264 << KoID("slower", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slower"));
47 presetsXH264 << KoID("veryslow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryslow"));
48 presetsXH264 << KoID("placebo", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "placebo"));
49
50 profilesXH264 << KoID("baseline", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "baseline"));
51 profilesXH264 << KoID("main", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "main"));
52 profilesXH264 << KoID("high", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high"));
53 profilesXH264 << KoID("high10", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high10"));
54 profilesXH264 << KoID("high422", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high422"));
55 profilesXH264 << KoID("high444", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high444"));
56
57 profilesXH265 << KoID("main", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "main"));
58 profilesXH265 << KoID("main10", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "main10 (HDR)"));
59
60 // TODO: add "none" tune option
61 tuningXH264 << KoID("film", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "film"));
62 tuningXH264 << KoID("animation", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "animation"));
63 tuningXH264 << KoID("grain", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "grain"));
64 tuningXH264 << KoID("stillimage", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "stillimage"));
65 tuningXH264 << KoID("psnr", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "psnr"));
66 tuningXH264 << KoID("ssim", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "ssim"));
67 tuningXH264 << KoID("fastdecode", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "fastdecode"));
68 tuningXH264 << KoID("zerolatency", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "zerolatency"));
69
70 tuningXH265 << KoID("none", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "none"));
71 tuningXH265 << KoID("animation", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "animation"));
72 tuningXH265 << KoID("grain", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "grain"));
73 tuningXH265 << KoID("psnr", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "psnr"));
74 tuningXH265 << KoID("ssim", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "ssim"));
75 tuningXH265 << KoID("fastdecode", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "fastdecode"));
76 tuningXH265 << KoID("zero-latency", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "zero-latency"));
77
78 predAPNG << KoID("none", i18nc("apng prediction option name", "none"));
79 predAPNG << KoID("sub", i18nc("apng prediction option name", "sub"));
80 predAPNG << KoID("up", i18nc("apng prediction option name", "up"));
81 predAPNG << KoID("avg", i18nc("apng prediction option name", "avg"));
82 predAPNG << KoID("paeth", i18nc("apng prediction option name", "paeth"));
83 predAPNG << KoID("mixed", i18nc("apng prediction option name", "mixed"));
84
85 presetsWEBP << KoID("default", i18nc("webp preset option name", "default"));
86 presetsWEBP << KoID("none", i18nc("webp preset option name", "none"));
87 presetsWEBP << KoID("drawing", i18nc("webp preset option name", "drawing"));
88 presetsWEBP << KoID("icon", i18nc("webp preset option name", "icon"));
89 presetsWEBP << KoID("photo", i18nc("webp preset option name", "photo"));
90 presetsWEBP << KoID("picture", i18nc("webp preset option name", "picture"));
91 presetsWEBP << KoID("text", i18nc("webp preset option name", "text"));
92
93 paletteGenModeGIF << KoID("full", i18nc("palettegen status mode option name", "Global/Full"));
94 paletteGenModeGIF << KoID("diff", i18nc("palettegen status mode option name", "Difference"));
95 paletteGenModeGIF << KoID("single", i18nc("palettegen status mode option name", "Per Single Frame"));
96
97 paletteDitherGIF << KoID("none", i18nc("paletteuse dither option name", "none"));
98 paletteDitherGIF << KoID("bayer", i18nc("paletteuse dither option name", "bayer"));
99 paletteDitherGIF << KoID("floyd_steinberg", i18nc("paletteuse dither option name", "floyd_steinberg"));
100 paletteDitherGIF << KoID("heckbert", i18nc("paletteuse dither option name", "heckbert"));
101 paletteDitherGIF << KoID("sierra2", i18nc("paletteuse dither option name", "sierra2"));
102 paletteDitherGIF << KoID("sierra2_4a", i18nc("paletteuse dither option name", "sierra2_4a"));
103
104 paletteDiffModeGIF << KoID("none", i18nc("paletteuse diff mode option name", "none"));
105 paletteDiffModeGIF << KoID("rectangle", i18nc("paletteuse diff mode option name", "rectangle"));
106 }
107
112
114
118
122
124
126
128 bool supportsHDR = false;
129};
130
131void populateComboWithKoIds(QComboBox *combo, const QVector<KoID> &ids, int defaultIndex)
132{
133 Q_FOREACH (const KoID &id, ids) {
134 combo->insertItem(combo->count(), id.name());
135 }
136 combo->setCurrentIndex(defaultIndex);
137 combo->setEnabled(combo->count() > 1);
138}
139
140KisVideoExportOptionsDialog::KisVideoExportOptionsDialog(ContainerType containerType, const QStringList& validEncoders, QWidget *parent)
141 : KisConfigWidget(parent),
142 ui(new Ui::VideoExportOptionsDialog),
143 m_d(new Private(containerType, validEncoders))
144{
145 ui->setupUi(this);
146
147 ui->intOpenH264bitrate->setRange(100, 10000);
148 ui->intOpenH264bitrate->setValue(5000);
149 ui->intOpenH264bitrate->setSuffix(i18nc("kilo-bits-per-second, video bitrate suffix", "kbps"));
150
151 ui->intCRFH264->setRange(0, 51);
152 ui->intCRFH264->setValue(28);
153
154 ui->intCRFH265->setRange(0, 51);
155 ui->intCRFH265->setValue(28);
156
157 populateComboWithKoIds(ui->cmbPresetH264, m_d->presetsXH264, 5);
158 populateComboWithKoIds(ui->cmbPresetH265, m_d->presetsXH264, 5);
159
160 populateComboWithKoIds(ui->cmbProfileH264, m_d->profilesXH264, 0);
161 populateComboWithKoIds(ui->cmbProfileH265, m_d->profilesXH265, 0);
162
163 populateComboWithKoIds(ui->cmbTuneH264, m_d->tuningXH264, 0);
164 populateComboWithKoIds(ui->cmbTuneH265, m_d->tuningXH265, 0);
165
166 ui->intBitrate->setRange(10, 50000);
167 ui->intBitrate->setValue(5000);
168 ui->intBitrate->setSuffix(i18nc("kilo-bits-per-second, video bitrate suffix", "kbps"));
169
170 ui->gifReserveTransparent->setChecked(true);
171 ui->gifLoop->setChecked(true);
172 ui->gifTransDiff->setChecked(true);
173
174 populateComboWithKoIds(ui->cmbPalettegenStatsModeGIF, m_d->paletteGenModeGIF, 0);
175 populateComboWithKoIds(ui->cmbPaletteuseDitherGIF, m_d->paletteDitherGIF, 5);
176 populateComboWithKoIds(ui->cmbPaletteuseDiffModeGIF, m_d->paletteDiffModeGIF, 0);
177
178 ui->intPaletteuseBayerScaleGIF->setRange(0, 5);
179 ui->intPaletteuseBayerScaleGIF->setValue(2);
180
181 ui->apngLoop->setChecked(true);
182
183 populateComboWithKoIds(ui->cmbPredAPNG, m_d->predAPNG, 0);
184
185 ui->intCompressWEBP->setRange(0, 6);
186 ui->intCompressWEBP->setValue(4);
187
188 ui->intQscaleWEBP->setRange(0, 100);
189 ui->intQscaleWEBP->setValue(75);
190
191 populateComboWithKoIds(ui->cmbPresetWEBP, m_d->presetsWEBP, 0);
192
193 ui->webpLoop->setChecked(true);
194
195 populateComboWithKoIds(ui->cmbCodec, m_d->encoders, 0);
196 connect(ui->cmbCodec, SIGNAL(currentIndexChanged(int)), SLOT(slotCodecSelected(int)));
198
199 // TODO: temporarily hidden! Some combinations of 'tune' and
200 // 'profile' options make ffmpeg generate empty file.
201 // We should not let the user shoot into his own foot!
202 ui->cmbTuneH264->setVisible(false);
203 ui->lblTuneH264->setVisible(false);
204
205 ui->cmbTuneH265->setVisible(false);
206 ui->lblTuneH265->setVisible(false);
207
209 connect(ui->chkCustomLine, SIGNAL(toggled(bool)), SLOT(slotCustomLineToggled(bool)));
210 connect(ui->txtCustomLine, SIGNAL(editingFinished()), SLOT(slotSaveCustomLine()));
211 connect(ui->btnResetCustomLine, SIGNAL(clicked()), SLOT(slotResetCustomLine()));
212
213 connect(ui->chkUseHDRMetadata, SIGNAL(toggled(bool)),
214 ui->btnHdrMetadata, SLOT(setEnabled(bool)));
215 connect(ui->cmbProfileH265,
216 SIGNAL(currentIndexChanged(int)),
217 SLOT(slotH265ProfileChanged(int)));
218 slotH265ProfileChanged(ui->cmbProfileH265->currentIndex());
219
220 connect(ui->btnHdrMetadata, SIGNAL(clicked()), SLOT(slotEditHDRMetadata()));
221
222 connect(ui->cmbPaletteuseDitherGIF,
223 SIGNAL(currentIndexChanged(int)),
224 SLOT(slotBayerFilterSelected(int)));
225
226 slotBayerFilterSelected(ui->cmbPaletteuseDitherGIF->currentIndex());
227
228 setSupportsHDR(false);
229}
230
235
237{
238 m_d->supportsHDR = value;
239 slotH265ProfileChanged(ui->cmbProfileH265->currentIndex());
240}
241
243{
245
246 cfg->setProperty("CodecId", currentCodecId());
247
248 cfg->setProperty("Openh264Bitrate", ui->intOpenH264bitrate->value());
249
250 cfg->setProperty("h264PresetIndex", ui->cmbPresetH264->currentIndex());
251 cfg->setProperty("h264ConstantRateFactor", ui->intCRFH264->value());
252 cfg->setProperty("h264ProfileIndex", ui->cmbProfileH264->currentIndex());
253 cfg->setProperty("h264TuneIndex", ui->cmbTuneH264->currentIndex());
254
255 cfg->setProperty("h265PresetIndex", ui->cmbPresetH265->currentIndex());
256 cfg->setProperty("h265ConstantRateFactor", ui->intCRFH265->value());
257 cfg->setProperty("h265ProfileIndex", ui->cmbProfileH265->currentIndex());
258 cfg->setProperty("h265TuneIndex", ui->cmbTuneH265->currentIndex());
259 cfg->setProperty("h265UseHDRMetadata", ui->chkUseHDRMetadata->isChecked());
260
261 cfg->setProperty("TheoraBitrate", ui->intBitrate->value());
262 cfg->setProperty("CustomLineValue", ui->txtCustomLine->text());
263 cfg->setProperty("customUserOptions", customUserOptions().join(' '));
264
265 cfg->setPrefixedProperties("hdrMetadata/", m_d->hdrMetadataOptions.toProperties());
266
267 return cfg;
268}
269
271{
272 if (mimeType == "video/webm") {
273 return ContainerType::WEBM;
274 } else if (mimeType == "video/ogg") {
275 return ContainerType::OGV;
276 } else if (mimeType == "image/gif") {
277 return ContainerType::GIF;
278 } else if (mimeType == "image/apng") {
279 return ContainerType::APNG;
280 } else if (mimeType == "image/webp") {
281 return ContainerType::WEBP;
282 }
283
285}
286
288{
289 KIS_ASSERT(type < ContainerType::NUM_CONTAINER_TYPE && type >= ContainerType::DEFAULT);
290 QVector<KoID> encoders;
291 QVector<KoID> h264Encoders = {
292 KoID("libopenh264", i18nc("openh264 codec name", "OpenH264")),
293 KoID("libx264", i18nc("h264 codec name, check simplescreenrecorder for standard translations", "H.264, MPEG-4 Part 10")),
294 KoID("libx265", i18nc("h265 codec name, check simplescreenrecorder for standard translations", "H.265, MPEG-H Part 2 (HEVC)"))
295 };
296
297 KoID vp9Encoder = KoID("libvpx-vp9", i18nc("VP9 codec name", "VP9"));
298
299
300 switch (type) {
302 encoders << KoID("libtheora", i18nc("theora codec name, check simplescreenrecorder for standard translations", "Theora"));
303 break;
305 encoders << KoID("libwebp", i18nc("WEBP codec name", "WEBP"));
306 break;
308 encoders << KoID("apng", i18nc("APNG codec name", "APNG"));
309 break;
311 encoders << KoID("gif", i18nc("GIF codec name", "GIF"));
312 break;
314 encoders << vp9Encoder;
315 break;
318 default:
319 encoders << h264Encoders;
320 encoders << vp9Encoder;
321 break;
322 }
323
324 return encoders;
325}
326
328{
329 QString customLine = m_d->currentCustomLine;
330
331 if (m_d->currentCustomLine.isEmpty() && value) {
332 customLine = generateCustomLine().join(" ");
333 } else if (!value) {
334 customLine = QString();
335 m_d->currentCustomLine = QString();
336 }
337
338 ui->txtCustomLine->setText(customLine);
339
340 ui->stackedWidget->setEnabled(!value);
341 ui->txtCustomLine->setEnabled(value);
342 ui->btnResetCustomLine->setEnabled(value);
343}
344
346{
347 ui->txtCustomLine->setText(generateCustomLine().join(" "));
349}
350
352{
353 const QString codec = m_d->encoders[index].id();
354 if (codec == "libopenh264") {
355 ui->stackedWidget->setCurrentIndex(CODEC_OPENH264);
356 } else if (codec == "libx264") {
357 ui->stackedWidget->setCurrentIndex(CODEC_H264);
358 } else if (codec == "libx265") {
359 ui->stackedWidget->setCurrentIndex(CODEC_H265);
360 } else if (codec == "libtheora") {
361 ui->stackedWidget->setCurrentIndex(CODEC_THEORA);
362 } else if (codec == "libvpx-vp9") {
363 ui->stackedWidget->setCurrentIndex(CODEC_VP9);
364 } else if (codec == "gif") {
365 ui->stackedWidget->setCurrentIndex(CODEC_GIF);
366 } else if (codec == "apng") {
367 ui->stackedWidget->setCurrentIndex(CODEC_APNG);
368 } else if (codec == "libwebp") {
369 ui->stackedWidget->setCurrentIndex(CODEC_WEBP);
370 }
371}
372
374{
375 m_d->currentCustomLine = ui->txtCustomLine->text();
376}
377
379{
380 return ui->chkCustomLine->isChecked() ?
381 ui->txtCustomLine->text().split(" ", Qt::SkipEmptyParts) :
383}
384
386{
387 return customUserOptions().join(' ');
388}
389
391{
392 return currentCodecId() == "libx265" &&
393 ui->chkUseHDRMetadata->isEnabled() &&
394 ui->chkUseHDRMetadata->isChecked();
395}
396
398 if (value && currentCodecId() != "libx265") {
399 ui->cmbCodec->setCurrentIndex(m_d->encoders.indexOf(KoID("libx265")));
400 ui->chkUseHDRMetadata->setEnabled(true);
401 }
402
403 //If HDR is enabled && the codec id is correct, we need to use main10.
404 if (value && currentCodecId() == "libx265") {
405 ui->cmbProfileH265->setCurrentIndex(m_d->profilesXH265.indexOf(KoID("main10")));
406 }
407
408 ui->chkUseHDRMetadata->setChecked(value);
409}
410
411int findIndexById(const QString &id, const QVector<KoID> &ids)
412{
413 int index = -1;
414 auto it = std::find_if(ids.begin(), ids.end(), kismpl::mem_equal_to(&KoID::id, id));
415 if (it != ids.end()) {
416 index = std::distance(ids.begin(), it);
417 }
418
419 return index;
420}
421
423{
424 ui->intOpenH264bitrate->setValue(cfg->getInt("Openh264Bitrate", 5000));
425
426 ui->cmbPresetH264->setCurrentIndex(cfg->getInt("h264PresetIndex", 5));
427 ui->intCRFH264->setValue(cfg->getInt("h264ConstantRateFactor", 23));
428 ui->cmbProfileH264->setCurrentIndex(cfg->getInt("h264ProfileIndex", 0));
429 ui->cmbTuneH264->setCurrentIndex(cfg->getInt("h264TuneIndex", 1));
430
431 ui->cmbPresetH265->setCurrentIndex(cfg->getInt("h265PresetIndex", 5));
432 ui->intCRFH265->setValue(cfg->getInt("h265ConstantRateFactor", 23));
433 ui->cmbProfileH265->setCurrentIndex(cfg->getInt("h265ProfileIndex", 0));
434 ui->cmbTuneH265->setCurrentIndex(cfg->getInt("h265TuneIndex", 1));
435 ui->chkUseHDRMetadata->setChecked(cfg->getBool("h265UseHDRMetadata", false));
436
437 ui->intBitrate->setValue(cfg->getInt("TheoraBitrate", 5000));
438
439 m_d->currentCustomLine = cfg->getString("CustomLineValue", QString());
440 ui->chkCustomLine->setChecked(!m_d->currentCustomLine.isEmpty());
441 slotCustomLineToggled(ui->chkCustomLine->isChecked());
442
443 const QString codecId = cfg->getString("CodecId", "");
444
445 const int index = qMax(0, findIndexById(codecId, m_d->encoders));
446 ui->cmbCodec->setCurrentIndex(index);
447 slotCodecSelected(index);
448
449 slotH265ProfileChanged(ui->cmbProfileH265->currentIndex());
450
452 cfg->getPrefixedProperties("hdrMetadata/", metadataProperties);
453 m_d->hdrMetadataOptions.fromProperties(metadataProperties);
454}
455
457{
458 QStringList options;
459
460 if (currentCodecId() == "libopenh264") {
461 options << "-c:v" << "libopenh264";
462 options << "-b:v" << QString::number(ui->intOpenH264bitrate->value()) + "k";
463 } else if (currentCodecId() == "libx264") {
464 options << "-crf" << QString::number(ui->intCRFH264->value());
465
466 const int presetIndex = ui->cmbPresetH264->currentIndex();
467 options << "-preset" << m_d->presetsXH264[presetIndex].id();
468
469 const int profileIndex = ui->cmbProfileH264->currentIndex();
470 options << "-profile:v" << m_d->profilesXH264[profileIndex].id();
471
472 if (m_d->profilesXH264[profileIndex].id() == "high422") {
473 options << "-pix_fmt" << "yuv422p";
474 } else if (m_d->profilesXH264[profileIndex].id() == "high444") {
475 options << "-pix_fmt" << "yuv444p";
476 } else {
477 options << "-pix_fmt" << "yuv420p";
478 }
479
480 // Disabled! see the comment in c-tor!
481 //const int tuneIndex = ui->cmbTune->currentIndex();
482 //options << "-tune" << m_d->tunes[tuneIndex].id();
483
484 } else if (currentCodecId() == "libx265") {
485 const bool enableHDR =
486 ui->chkUseHDRMetadata->isEnabled() &&
487 ui->chkUseHDRMetadata->isChecked();
488
489 if (enableHDR) {
490 options << "-colorspace" << "bt2020c"
491 << "-color_trc" << "smpte2084"
492 << "-color_primaries" << "bt2020";
493 }
494
495 options << "-c:v" << "libx265";
496 options << "-crf" << QString::number(ui->intCRFH265->value());
497
498 const int presetIndex = ui->cmbPresetH265->currentIndex();
499 options << "-preset" << m_d->presetsXH264[presetIndex].id();
500
501 const int profileIndex = ui->cmbProfileH265->currentIndex();
502 options << "-profile:v" << m_d->profilesXH265[profileIndex].id();
503
504 if (m_d->profilesXH265[profileIndex].id() == "main") {
505 options << "-pix_fmt" << "yuv420p";
506 } else if (m_d->profilesXH265[profileIndex].id() == "main10") {
507 options << "-pix_fmt" << "yuv420p10le";
508 } else {
509 KIS_SAFE_ASSERT_RECOVER_NOOP(0 && "Unknown profile selected for h265 encoder");
510 }
511
512 if (enableHDR) {
513 const QString metadataLine = m_d->hdrMetadataOptions.generateFFMpegOptions();
514 options << metadataLine.split(" ");
515 }
516
517 } else if (currentCodecId() == "libtheora") {
518 options << "-b" << QString::number(ui->intBitrate->value()) + "k";
519 } else if (currentCodecId() == "libvpx-vp9") {
520 options << "-c:v" << currentCodecId();
521 if (ui->vp9Lossless->isChecked()) {
522 options << "-lossless" << "1";
523 } else {
524 options << "-b:v" << QString::number(ui->vp9Mbits->value()) + "M";
525 }
526 } else if (currentCodecId() == "gif") {
527 const QString ditherFilterString = m_d->paletteDitherGIF[ ui->cmbPaletteuseDitherGIF->currentIndex() ].id();
528
529 options << "-f" << "gif"
530 << "-loop" << ( ui->gifLoop->isChecked() ? "0":"-1" )
531 << "-gifflags" << ( ui->gifTransDiff->isChecked() ? "+transdiff":"-transdiff" )
532 << "-palettegen" << QString("palettegen=stats_mode=%1%2")
533 .arg(m_d->paletteGenModeGIF[ ui->cmbPalettegenStatsModeGIF->currentIndex() ].id())
534 .arg(":reserve_transparent=" + QString(ui->gifReserveTransparent->isChecked() ? "1":"0"))
535 << "-lavfi" << QString("[0:v][1:v]paletteuse=dither=%1%2%3")
536 .arg(ditherFilterString)
537 .arg(ditherFilterString == "bayer" ? (QString(":bayer_scale=%1").arg(ui->intPaletteuseBayerScaleGIF->value()) ):"" )
538 .arg(":diff_mode=" + m_d->paletteDiffModeGIF[ ui->cmbPaletteuseDiffModeGIF->currentIndex() ].id() );
539
540 } else if (currentCodecId() == "apng") {
541 const int predIndex = ui->cmbPredAPNG->currentIndex();
542
543 options << "-f" << "apng"
544 << "-pred" << m_d->predAPNG[predIndex].id()
545 << "-plays" << ( ui->apngLoop->isChecked() ? "0":"1" );
546
547 } else if (currentCodecId() == "libwebp") {
548 const int presetIndex = ui->cmbPresetWEBP->currentIndex();
549
550 options << "-f" << "webp"
551 << "-lossless" << ( ui->webpLossless->isChecked() ? "1":"0" )
552 << "-compression_level" << QString::number(ui->intCompressWEBP->value())
553 << "-q:v" << QString::number(ui->intQscaleWEBP->value())
554 << "-preset" << m_d->presetsWEBP[presetIndex].id()
555 << "-loop" << ( ui->webpLoop->isChecked() ? "0":"1" );
556
557 }
558
559 return options;
560}
561
563{
564 return m_d->encoders[ui->cmbCodec->currentIndex()].id();
565}
566
568{
569 const bool enableHDR =
570 m_d->supportsHDR &&
571 index >= 0 &&
572 m_d->profilesXH265[index].id() == "main10";
573
574 ui->chkUseHDRMetadata->setEnabled(enableHDR);
575 ui->btnHdrMetadata->setEnabled(enableHDR && ui->chkUseHDRMetadata->isChecked());
576
577 QString hdrToolTip;
578
579 if (!m_d->supportsHDR) {
580 hdrToolTip = i18nc("@info:tooltip", "Exported animation format does not support HDR");
581 } else if (!enableHDR) {
582 hdrToolTip = i18nc("@info:tooltip", "HDR metadata available only with \"main10\" profile");
583 }
584
585 ui->chkUseHDRMetadata->setToolTip(hdrToolTip);
586 ui->btnHdrMetadata->setToolTip(hdrToolTip);
587}
588
590{
592 dlg.setHDRMetadataOptions(m_d->hdrMetadataOptions);
593
594 if (dlg.exec() == QDialog::Accepted) {
595 m_d->hdrMetadataOptions = dlg.hdrMetadataOptions();
596 }
597}
598
600{
601 const bool enableBayer = m_d->paletteDitherGIF[ index ].id() == "bayer";
602 ui->lblPaletteuseBayerScaleGIF->setEnabled( enableBayer );
603 ui->intPaletteuseBayerScaleGIF->setEnabled( enableBayer );
604}
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
int findIndexById(const QString &id, const QVector< KoID > &ids)
void populateComboWithKoIds(QComboBox *combo, const QVector< KoID > &ids, int defaultIndex)
KisPropertiesConfigurationSP configuration() const override
const QScopedPointer< Private > m_d
static ContainerType mimeToContainer(const QString &mimeType)
KisVideoExportOptionsDialog(ContainerType containerType, const QStringList &validEncoders, QWidget *parent=0)
void setConfiguration(const KisPropertiesConfigurationSP config) override
static QVector< KoID > encoderIdentifiers(ContainerType type)
Ui::VideoExportOptionsDialog * ui
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
KisHDRMetadataOptions hdrMetadataOptions() const
void setHDRMetadataOptions(const KisHDRMetadataOptions &options)
Encoder * encoder(Imf::OutputFile &file, const ExrPaintLayerSaveInfo &info, int width)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
auto mem_equal_to(MemTypeNoRef Class::*ptr, MemType &&value)
mem_equal_to is an unary functor that compares a member of the object to a given value
Definition KisMpl.h:233
Private(ContainerType _containerType, const QStringList &validEncoders)