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