141 ui(new
Ui::VideoExportOptionsDialog),
142 m_d(new
Private(containerType, validEncoders))
146 ui->intOpenH264bitrate->setRange(100, 10000);
147 ui->intOpenH264bitrate->setValue(5000);
148 ui->intOpenH264bitrate->setSuffix(i18nc(
"kilo-bits-per-second, video bitrate suffix",
"kbps"));
150 ui->intCRFH264->setRange(0, 51);
151 ui->intCRFH264->setValue(28);
153 ui->intCRFH265->setRange(0, 51);
154 ui->intCRFH265->setValue(28);
165 ui->intBitrate->setRange(10, 50000);
166 ui->intBitrate->setValue(5000);
167 ui->intBitrate->setSuffix(i18nc(
"kilo-bits-per-second, video bitrate suffix",
"kbps"));
169 ui->gifReserveTransparent->setChecked(
true);
170 ui->gifLoop->setChecked(
true);
171 ui->gifTransDiff->setChecked(
true);
177 ui->intPaletteuseBayerScaleGIF->setRange(0, 5);
178 ui->intPaletteuseBayerScaleGIF->setValue(2);
180 ui->apngLoop->setChecked(
true);
184 ui->intCompressWEBP->setRange(0, 6);
185 ui->intCompressWEBP->setValue(4);
187 ui->intQscaleWEBP->setRange(0, 100);
188 ui->intQscaleWEBP->setValue(75);
192 ui->webpLoop->setChecked(
true);
201 ui->cmbTuneH264->setVisible(
false);
202 ui->lblTuneH264->setVisible(
false);
204 ui->cmbTuneH265->setVisible(
false);
205 ui->lblTuneH265->setVisible(
false);
212 connect(
ui->cmbProfileH265,
213 SIGNAL(currentIndexChanged(
int)),
218 connect(
ui->cmbPaletteuseDitherGIF,
219 SIGNAL(currentIndexChanged(
int)),
225 m_d->hdrMetadataOptions = hdrOptions;
245 cfg->setProperty(
"Openh264Bitrate",
ui->intOpenH264bitrate->value());
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());
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());
258 cfg->setProperty(
"TheoraBitrate",
ui->intBitrate->value());
259 cfg->setProperty(
"CustomLineValue",
ui->txtCustomLine->text());
262 cfg->setPrefixedProperties(
"hdrMetadata/",
m_d->hdrMetadataOptions.toProperties());
350 const QString codec =
m_d->encoders[index].id();
351 if (codec ==
"libopenh264") {
353 }
else if (codec ==
"libx264") {
355 }
else if (codec ==
"libx265") {
357 }
else if (codec ==
"libtheora") {
359 }
else if (codec ==
"libvpx-vp9") {
361 }
else if (codec ==
"gif") {
363 }
else if (codec ==
"apng") {
365 }
else if (codec ==
"libwebp") {
421 ui->intOpenH264bitrate->setValue(cfg->getInt(
"Openh264Bitrate", 5000));
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));
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));
434 ui->intBitrate->setValue(cfg->getInt(
"TheoraBitrate", 5000));
436 m_d->currentCustomLine = cfg->getString(
"CustomLineValue", QString());
437 ui->chkCustomLine->setChecked(!
m_d->currentCustomLine.isEmpty());
440 const QString codecId = cfg->getString(
"CodecId",
"");
443 ui->cmbCodec->setCurrentIndex(index);
454 options <<
"-c:v" <<
"libopenh264";
455 options <<
"-b:v" << QString::number(
ui->intOpenH264bitrate->value()) +
"k";
457 options <<
"-crf" << QString::number(
ui->intCRFH264->value());
459 const int presetIndex =
ui->cmbPresetH264->currentIndex();
460 options <<
"-preset" <<
m_d->presetsXH264[presetIndex].id();
462 const int profileIndex =
ui->cmbProfileH264->currentIndex();
463 options <<
"-profile:v" <<
m_d->profilesXH264[profileIndex].id();
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";
470 options <<
"-pix_fmt" <<
"yuv420p";
478 const bool enableHDR =
479 ui->chkUseHDRMetadata->isEnabled() &&
480 ui->chkUseHDRMetadata->isChecked();
483 options <<
"-colorspace" <<
"bt2020nc"
484 <<
"-color_trc" <<
"smpte2084"
485 <<
"-color_primaries" <<
"bt2020";
488 options <<
"-c:v" <<
"libx265";
489 options <<
"-crf" << QString::number(
ui->intCRFH265->value());
491 const int presetIndex =
ui->cmbPresetH265->currentIndex();
492 options <<
"-preset" <<
m_d->presetsXH264[presetIndex].id();
494 const int profileIndex =
ui->cmbProfileH265->currentIndex();
495 options <<
"-profile:v" <<
m_d->profilesXH265[profileIndex].id();
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";
506 const QString metadataLine =
m_d->hdrMetadataOptions.generateFFMpegOptions();
507 options << metadataLine.split(
" ");
511 options <<
"-b" << QString::number(
ui->intBitrate->value()) +
"k";
514 if (
ui->vp9Lossless->isChecked()) {
515 options <<
"-lossless" <<
"1";
517 options <<
"-b:v" << QString::number(
ui->vp9Mbits->value()) +
"M";
520 const QString ditherFilterString =
m_d->paletteDitherGIF[
ui->cmbPaletteuseDitherGIF->currentIndex() ].id();
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() );
534 const int predIndex =
ui->cmbPredAPNG->currentIndex();
536 options <<
"-f" <<
"apng"
537 <<
"-pred" <<
m_d->predAPNG[predIndex].id()
538 <<
"-plays" << (
ui->apngLoop->isChecked() ?
"0":
"1" );
541 const int presetIndex =
ui->cmbPresetWEBP->currentIndex();
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" );