142 ui(new
Ui::VideoExportOptionsDialog),
143 m_d(new
Private(containerType, validEncoders))
147 ui->intOpenH264bitrate->setRange(100, 10000);
148 ui->intOpenH264bitrate->setValue(5000);
149 ui->intOpenH264bitrate->setSuffix(i18nc(
"kilo-bits-per-second, video bitrate suffix",
"kbps"));
151 ui->intCRFH264->setRange(0, 51);
152 ui->intCRFH264->setValue(28);
154 ui->intCRFH265->setRange(0, 51);
155 ui->intCRFH265->setValue(28);
166 ui->intBitrate->setRange(10, 50000);
167 ui->intBitrate->setValue(5000);
168 ui->intBitrate->setSuffix(i18nc(
"kilo-bits-per-second, video bitrate suffix",
"kbps"));
170 ui->gifReserveTransparent->setChecked(
true);
171 ui->gifLoop->setChecked(
true);
172 ui->gifTransDiff->setChecked(
true);
178 ui->intPaletteuseBayerScaleGIF->setRange(0, 5);
179 ui->intPaletteuseBayerScaleGIF->setValue(2);
181 ui->apngLoop->setChecked(
true);
185 ui->intCompressWEBP->setRange(0, 6);
186 ui->intCompressWEBP->setValue(4);
188 ui->intQscaleWEBP->setRange(0, 100);
189 ui->intQscaleWEBP->setValue(75);
193 ui->webpLoop->setChecked(
true);
202 ui->cmbTuneH264->setVisible(
false);
203 ui->lblTuneH264->setVisible(
false);
205 ui->cmbTuneH265->setVisible(
false);
206 ui->lblTuneH265->setVisible(
false);
213 connect(
ui->chkUseHDRMetadata, SIGNAL(toggled(
bool)),
214 ui->btnHdrMetadata, SLOT(setEnabled(
bool)));
216 SIGNAL(currentIndexChanged(
int)),
223 SIGNAL(currentIndexChanged(
int)),
248 cfg->setProperty(
"Openh264Bitrate",
ui->intOpenH264bitrate->value());
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());
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());
261 cfg->setProperty(
"TheoraBitrate",
ui->intBitrate->value());
262 cfg->setProperty(
"CustomLineValue",
ui->txtCustomLine->text());
265 cfg->setPrefixedProperties(
"hdrMetadata/",
m_d->hdrMetadataOptions.toProperties());
353 const QString codec =
m_d->encoders[index].id();
354 if (codec ==
"libopenh264") {
356 }
else if (codec ==
"libx264") {
358 }
else if (codec ==
"libx265") {
360 }
else if (codec ==
"libtheora") {
362 }
else if (codec ==
"libvpx-vp9") {
364 }
else if (codec ==
"gif") {
366 }
else if (codec ==
"apng") {
368 }
else if (codec ==
"libwebp") {
424 ui->intOpenH264bitrate->setValue(cfg->getInt(
"Openh264Bitrate", 5000));
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));
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));
437 ui->intBitrate->setValue(cfg->getInt(
"TheoraBitrate", 5000));
439 m_d->currentCustomLine = cfg->getString(
"CustomLineValue", QString());
440 ui->chkCustomLine->setChecked(!
m_d->currentCustomLine.isEmpty());
443 const QString codecId = cfg->getString(
"CodecId",
"");
446 ui->cmbCodec->setCurrentIndex(index);
452 cfg->getPrefixedProperties(
"hdrMetadata/", metadataProperties);
453 m_d->hdrMetadataOptions.fromProperties(metadataProperties);
461 options <<
"-c:v" <<
"libopenh264";
462 options <<
"-b:v" << QString::number(
ui->intOpenH264bitrate->value()) +
"k";
464 options <<
"-crf" << QString::number(
ui->intCRFH264->value());
466 const int presetIndex =
ui->cmbPresetH264->currentIndex();
467 options <<
"-preset" <<
m_d->presetsXH264[presetIndex].id();
469 const int profileIndex =
ui->cmbProfileH264->currentIndex();
470 options <<
"-profile:v" <<
m_d->profilesXH264[profileIndex].id();
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";
477 options <<
"-pix_fmt" <<
"yuv420p";
485 const bool enableHDR =
486 ui->chkUseHDRMetadata->isEnabled() &&
487 ui->chkUseHDRMetadata->isChecked();
490 options <<
"-colorspace" <<
"bt2020c"
491 <<
"-color_trc" <<
"smpte2084"
492 <<
"-color_primaries" <<
"bt2020";
495 options <<
"-c:v" <<
"libx265";
496 options <<
"-crf" << QString::number(
ui->intCRFH265->value());
498 const int presetIndex =
ui->cmbPresetH265->currentIndex();
499 options <<
"-preset" <<
m_d->presetsXH264[presetIndex].id();
501 const int profileIndex =
ui->cmbProfileH265->currentIndex();
502 options <<
"-profile:v" <<
m_d->profilesXH265[profileIndex].id();
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";
513 const QString metadataLine =
m_d->hdrMetadataOptions.generateFFMpegOptions();
514 options << metadataLine.split(
" ");
518 options <<
"-b" << QString::number(
ui->intBitrate->value()) +
"k";
521 if (
ui->vp9Lossless->isChecked()) {
522 options <<
"-lossless" <<
"1";
524 options <<
"-b:v" << QString::number(
ui->vp9Mbits->value()) +
"M";
527 const QString ditherFilterString =
m_d->paletteDitherGIF[
ui->cmbPaletteuseDitherGIF->currentIndex() ].id();
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() );
541 const int predIndex =
ui->cmbPredAPNG->currentIndex();
543 options <<
"-f" <<
"apng"
544 <<
"-pred" <<
m_d->predAPNG[predIndex].id()
545 <<
"-plays" << (
ui->apngLoop->isChecked() ?
"0":
"1" );
548 const int presetIndex =
ui->cmbPresetWEBP->currentIndex();
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" );
569 const bool enableHDR =
572 m_d->profilesXH265[index].id() ==
"main10";
574 ui->chkUseHDRMetadata->setEnabled(enableHDR);
575 ui->btnHdrMetadata->setEnabled(enableHDR &&
ui->chkUseHDRMetadata->isChecked());
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");
585 ui->chkUseHDRMetadata->setToolTip(hdrToolTip);
586 ui->btnHdrMetadata->setToolTip(hdrToolTip);