void BinController::saveDocumentProperties(const QMap <QString, QString> props, const QMap <double, QString> guidesData) { // Clear previous properites Mlt::Properties playlistProps(m_binPlaylist->get_properties()); Mlt::Properties docProperties; docProperties.pass_values(playlistProps, "kdenlive:docproperties."); for (int i = 0; i < docProperties.count(); i++) { QString propName = QStringLiteral("kdenlive:docproperties.") + docProperties.get_name(i); playlistProps.set(propName.toUtf8().constData(), (char *)NULL); } // Clear previous guides Mlt::Properties guideProperties; guideProperties.pass_values(playlistProps, "kdenlive:guide."); for (int i = 0; i < guideProperties.count(); i++) { QString propName = QStringLiteral("kdenlive:guide.") + guideProperties.get_name(i); playlistProps.set(propName.toUtf8().constData(), (char *)NULL); } QMapIterator<QString, QString> i(props); while (i.hasNext()) { i.next(); playlistProps.set(("kdenlive:docproperties." + i.key()).toUtf8().constData(), i.value().toUtf8().constData()); } // Append guides QMapIterator<double, QString> g(guidesData); QLocale locale; while (g.hasNext()) { g.next(); QString propertyName = "kdenlive:guide." + locale.toString(g.key()); playlistProps.set(propertyName.toUtf8().constData(), g.value().toUtf8().constData()); } }
QMap <QString, QString> ClipController::getPropertiesFromPrefix(const QString &prefix, bool withPrefix) { Mlt::Properties subProperties; subProperties.pass_values(*m_properties, prefix.toUtf8().constData()); QMap <QString,QString> subclipsData; for (int i = 0; i < subProperties.count(); i++) { subclipsData.insert(withPrefix ? QString(prefix + subProperties.get_name(i)) : subProperties.get_name(i), subProperties.get(i)); } return subclipsData; }
QMap<double,QString> BinController::takeGuidesData() { QLocale locale; // Load guides Mlt::Properties guidesProperties; Mlt::Properties playlistProps(m_binPlaylist->get_properties()); guidesProperties.pass_values(playlistProps, "kdenlive:guide."); qDebug()<<"***********\nFOUND GUIDES: "<<guidesProperties.count()<<"\n**********"; QMap <double,QString> guidesData; for (int i = 0; i < guidesProperties.count(); i++) { double time = locale.toDouble(guidesProperties.get_name(i)); guidesData.insert(time, guidesProperties.get(i)); // Clear bin data QString propertyName = "kdenlive:guide." + QString(guidesProperties.get_name(i)); m_binPlaylist->set(propertyName.toUtf8().constData(), (char *) NULL); } return guidesData; }
void TransitionHandler::cloneProperties(Mlt::Properties &dest, Mlt::Properties &source) { int count = source.count(); int i = 0; for ( i = 0; i < count; i ++ ) { char *value = source.get(i); if ( value != NULL ) { char *name = source.get_name( i ); if (name != NULL && name[0] != '_') dest.set(name, value); } } }
void Wizard::checkMltComponents() { QSize itemSize(20, fontMetrics().height() * 2.5); m_mltCheck.programList->setColumnWidth(0, 30); m_mltCheck.programList->setIconSize(QSize(24, 24)); QTreeWidgetItem *mltitem = new QTreeWidgetItem(m_mltCheck.programList); QTreeWidgetItem *meltitem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("Melt") + " (" + KdenliveSettings::rendererpath() + ')'); meltitem->setData(1, Qt::UserRole, i18n("Required for rendering (part of MLT package)")); meltitem->setSizeHint(0, itemSize); meltitem->setIcon(0, m_okIcon); Mlt::Repository *repository = Mlt::Factory::init(); if (!repository) { mltitem->setData(1, Qt::UserRole, i18n("Cannot start the MLT video backend!")); mltitem->setIcon(0, m_badIcon); m_systemCheckIsOk = false; button(QWizard::NextButton)->setEnabled(false); } else { int mltVersion = (mltVersionMajor << 16) + (mltVersionMinor << 8) + mltVersionRevision; mltitem->setText(1, i18n("MLT version: %1", mlt_version_get_string())); mltitem->setSizeHint(0, itemSize); if (mlt_version_get_int() < 1792) { mltitem->setData(1, Qt::UserRole, i18n("Your MLT version is unsupported!!!")); mltitem->setIcon(0, m_badIcon); m_systemCheckIsOk = false; button(QWizard::NextButton)->setEnabled(false); } else if (mlt_version_get_int() < mltVersion) { mltitem->setData(1, Qt::UserRole, i18n("Please upgrade to MLT %1.%2.%3", mltVersionMajor, mltVersionMinor, mltVersionRevision)); mltitem->setIcon(0, m_badIcon); } else { mltitem->setData(1, Qt::UserRole, i18n("MLT video backend!")); mltitem->setIcon(0, m_okIcon); } // Retrieve the list of available transitions. Mlt::Properties *producers = repository->producers(); QStringList producersItemList; for (int i = 0; i < producers->count(); ++i) producersItemList << producers->get_name(i); delete producers; Mlt::Properties *consumers = repository->consumers(); QStringList consumersItemList; for (int i = 0; i < consumers->count(); ++i) consumersItemList << consumers->get_name(i); delete consumers; // SDL module QTreeWidgetItem *sdlItem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("SDL module")); sdlItem->setData(1, Qt::UserRole, i18n("Required for Kdenlive")); sdlItem->setSizeHint(0, itemSize); if (!consumersItemList.contains("sdl")) { sdlItem->setIcon(0, m_badIcon); m_systemCheckIsOk = false; button(QWizard::NextButton)->setEnabled(false); } else { sdlItem->setIcon(0, m_okIcon); } // AVformat module QTreeWidgetItem *avformatItem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("Avformat module (FFmpeg)")); avformatItem->setData(1, Qt::UserRole, i18n("Required to work with various video formats (hdv, mpeg, flash, ...)")); avformatItem->setSizeHint(0, itemSize); Mlt::Consumer *consumer = NULL; Mlt::Profile p; if (consumersItemList.contains("avformat")) consumer = new Mlt::Consumer(p, "avformat"); if (consumer == NULL || !consumer->is_valid()) { avformatItem->setIcon(0, m_badIcon); m_mltCheck.tabWidget->setTabEnabled(1, false); } else { avformatItem->setIcon(0, m_okIcon); consumer->set("vcodec", "list"); consumer->set("acodec", "list"); consumer->set("f", "list"); consumer->start(); QStringList result; Mlt::Properties vcodecs((mlt_properties) consumer->get_data("vcodec")); for (int i = 0; i < vcodecs.count(); ++i) result << QString(vcodecs.get(i)); m_mltCheck.vcodecs_list->addItems(result); KdenliveSettings::setVideocodecs(result); result.clear(); Mlt::Properties acodecs((mlt_properties) consumer->get_data("acodec")); for (int i = 0; i < acodecs.count(); ++i) result << QString(acodecs.get(i)); m_mltCheck.acodecs_list->addItems(result); KdenliveSettings::setAudiocodecs(result); result.clear(); Mlt::Properties formats((mlt_properties) consumer->get_data("f")); for (int i = 0; i < formats.count(); ++i) result << QString(formats.get(i)); m_mltCheck.formats_list->addItems(result); KdenliveSettings::setSupportedformats(result); checkMissingCodecs(); delete consumer; } // Image module QTreeWidgetItem *imageItem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("QImage module")); imageItem->setData(1, Qt::UserRole, i18n("Required to work with images")); imageItem->setSizeHint(0, itemSize); if (!producersItemList.contains("qimage")) { imageItem->setIcon(0, m_badIcon); imageItem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("Pixbuf module")); imageItem->setData(1, Qt::UserRole, i18n("Required to work with images")); imageItem->setSizeHint(0, itemSize); if (producersItemList.contains("pixbuf")) { imageItem->setIcon(0, m_badIcon); } else { imageItem->setIcon(0, m_okIcon); } } else { imageItem->setIcon(0, m_okIcon); } // Titler module QTreeWidgetItem *titleItem = new QTreeWidgetItem(m_mltCheck.programList, QStringList() << QString() << i18n("Title module")); titleItem->setData(1, Qt::UserRole, i18n("Required to work with titles")); titleItem->setSizeHint(0, itemSize); if (!producersItemList.contains("kdenlivetitle")) { KdenliveSettings::setHastitleproducer(false); titleItem->setIcon(0, m_badIcon); } else { titleItem->setIcon(0, m_okIcon); KdenliveSettings::setHastitleproducer(true); } } }
void EncodeDock::loadPresetFromProperties(Mlt::Properties& preset) { int audioQuality = -1; int videoQuality = -1; QStringList other; ui->disableAudioCheckbox->setChecked(preset.get_int("an")); ui->disableVideoCheckbox->setChecked(preset.get_int("vn")); m_extension.clear(); for (int i = 0; i < preset.count(); i++) { QString name(preset.get_name(i)); if (name == "f") { for (int i = 0; i < ui->formatCombo->count(); i++) if (ui->formatCombo->itemText(i) == preset.get("f")) { ui->formatCombo->blockSignals(true); ui->formatCombo->setCurrentIndex(i); ui->formatCombo->blockSignals(false); break; } } else if (name == "acodec") { for (int i = 0; i < ui->audioCodecCombo->count(); i++) if (ui->audioCodecCombo->itemText(i) == preset.get("acodec")) ui->audioCodecCombo->setCurrentIndex(i); if (ui->audioCodecCombo->currentText() == "libopus") // reset libopus to VBR (its default) ui->audioRateControlCombo->setCurrentIndex(RateControlQuality); } else if (name == "vcodec") { for (int i = 0; i < ui->videoCodecCombo->count(); i++) if (ui->videoCodecCombo->itemText(i) == preset.get("vcodec")) ui->videoCodecCombo->setCurrentIndex(i); } else if (name == "ar") ui->sampleRateCombo->lineEdit()->setText(preset.get("ar")); else if (name == "ab") ui->audioBitrateCombo->lineEdit()->setText(preset.get("ab")); else if (name == "vb") { ui->videoRateControlCombo->setCurrentIndex(RateControlAverage); ui->videoBitrateCombo->lineEdit()->setText(preset.get("vb")); } else if (name == "g") ui->gopSpinner->setValue(preset.get_int("g")); else if (name == "bf") ui->bFramesSpinner->setValue(preset.get_int("bf")); else if (name == "deinterlace") { ui->scanModeCombo->setCurrentIndex(preset.get_int("deinterlace")); ui->scanModeCombo->setEnabled(false); } else if (name == "progressive") { ui->scanModeCombo->setCurrentIndex(preset.get_int("progressive")); ui->scanModeCombo->setEnabled(false); } else if (name == "top_field_first") { ui->fieldOrderCombo->setCurrentIndex(preset.get_int("top_field_first")); } else if (name == "width") { ui->widthSpinner->setValue(preset.get_int("width")); ui->widthSpinner->setEnabled(false); } else if (name == "height") { ui->heightSpinner->setValue(preset.get_int("height")); ui->heightSpinner->setEnabled(false); } else if (name == "aspect") { double dar = preset.get_double("aspect"); switch (int(dar * 100)) { case 133: ui->aspectNumSpinner->setValue(4); ui->aspectDenSpinner->setValue(3); break; case 177: ui->aspectNumSpinner->setValue(16); ui->aspectDenSpinner->setValue(9); break; case 56: ui->aspectNumSpinner->setValue(9); ui->aspectDenSpinner->setValue(16); break; default: ui->aspectNumSpinner->setValue(dar * 1000); ui->aspectDenSpinner->setValue(1000); break; } ui->aspectNumSpinner->setEnabled(false); ui->aspectDenSpinner->setEnabled(false); } else if (name == "r") { ui->fpsSpinner->setValue(preset.get_double("r")); ui->fpsSpinner->setEnabled(false); } else if (name == "pix_fmt") { QString pix_fmt(preset.get("pix_fmt")); if (pix_fmt != "yuv420p") other.append(QString("%1=%2").arg(name).arg(pix_fmt)); } else if (name == "pass") ui->dualPassCheckbox->setChecked(true); else if (name == "aq") { ui->audioRateControlCombo->setCurrentIndex(RateControlQuality); audioQuality = preset.get_int("aq"); } else if (name == "vbr") { // libopus rate mode QString value(preset.get("vbr")); if (value == "off") ui->audioRateControlCombo->setCurrentIndex(RateControlConstant); else if (value == "constrained") ui->audioRateControlCombo->setCurrentIndex(RateControlAverage); else ui->audioRateControlCombo->setCurrentIndex(RateControlQuality); } else if (name == "vq") { ui->videoRateControlCombo->setCurrentIndex(RateControlQuality); videoQuality = preset.get_int("vq"); } else if (name == "qscale") { ui->videoRateControlCombo->setCurrentIndex(RateControlQuality); videoQuality = preset.get_int("qscale"); } else if (name == "crf") { ui->videoRateControlCombo->setCurrentIndex(RateControlQuality); videoQuality = preset.get_int("crf"); } else if (name == "bufsize") { // traditionally this means video only ui->videoRateControlCombo->setCurrentIndex(RateControlConstant); ui->videoBufferSizeSpinner->setValue(getBufferSize(preset, "bufsize")); } else if (name == "vbufsize") { ui->videoRateControlCombo->setCurrentIndex(RateControlConstant); ui->videoBufferSizeSpinner->setValue(getBufferSize(preset, "vbufsize")); } else if (name == "threads") { // TODO: should we save the thread count and restore it if preset is not 1? if (preset.get_int("threads") == 1) ui->videoCodecThreadsSpinner->setValue(1); } else if (name == "meta.preset.extension") { m_extension = preset.get("meta.preset.extension"); } else if (name == "deinterlace_method") { name = preset.get("deinterlace_method"); if (name == "onefield") ui->deinterlacerCombo->setCurrentIndex(0); else if (name == "linearblend") ui->deinterlacerCombo->setCurrentIndex(1); else if (name == "yadif-nospatial") ui->deinterlacerCombo->setCurrentIndex(2); else if (name == "yadif") ui->deinterlacerCombo->setCurrentIndex(3); ui->deinterlacerCombo->setDisabled(true); } else if (name == "rescale") { name = preset.get("rescale"); if (name == "nearest" || name == "neighbor") ui->interpolationCombo->setCurrentIndex(0); else if (name == "bilinear") ui->interpolationCombo->setCurrentIndex(1); else if (name == "bicubic") ui->interpolationCombo->setCurrentIndex(2); else if (name == "hyper" || name == "lanczos") ui->interpolationCombo->setCurrentIndex(3); ui->interpolationCombo->setDisabled(true); } else if (name != "an" && name != "vn" && name != "threads" && !name.startsWith('_') && !name.startsWith("meta.preset.")) { other.append(QString("%1=%2").arg(name).arg(preset.get(i))); } } ui->advancedTextEdit->setPlainText(other.join("\n")); // normalize the quality settings // quality depends on codec if (ui->audioRateControlCombo->currentIndex() == RateControlQuality && audioQuality > -1) { const QString& acodec = ui->audioCodecCombo->currentText(); if (acodec == "libmp3lame") // 0 (best) - 9 (worst) ui->audioQualitySpinner->setValue(TO_RELATIVE(9, 0, audioQuality)); if (acodec == "libvorbis" || acodec == "vorbis") // 0 (worst) - 10 (best) ui->audioQualitySpinner->setValue(TO_RELATIVE(0, 10, audioQuality)); else // aac: 0 (worst) - 500 (best) ui->audioQualitySpinner->setValue(TO_RELATIVE(0, 500, audioQuality)); } if (ui->videoRateControlCombo->currentIndex() == RateControlQuality && videoQuality > -1) { const QString& vcodec = ui->videoCodecCombo->currentText(); //val = min + (max - min) * paramval; if (vcodec == "libx264" || vcodec == "libx265") // 0 (best, 100%) - 51 (worst) ui->videoQualitySpinner->setValue(TO_RELATIVE(51, 0, videoQuality)); else if (vcodec.startsWith("libvpx")) // 0 (best, 100%) - 63 (worst) ui->videoQualitySpinner->setValue(TO_RELATIVE(63, 0, videoQuality)); else // 1 (best, NOT 100%) - 31 (worst) ui->videoQualitySpinner->setValue(TO_RELATIVE(31, 1, videoQuality)); } on_audioRateControlCombo_activated(ui->audioRateControlCombo->currentIndex()); on_videoRateControlCombo_activated(ui->videoRateControlCombo->currentIndex()); }
void BinController::initializeBin(Mlt::Playlist playlist) { // Load folders Mlt::Properties folderProperties; Mlt::Properties playlistProps(playlist.get_properties()); folderProperties.pass_values(playlistProps, "kdenlive:folder."); QMap <QString,QString> foldersData; for (int i = 0; i < folderProperties.count(); i++) { foldersData.insert(folderProperties.get_name(i), folderProperties.get(i)); } emit loadFolders(foldersData); // Read notes QString notes = playlistProps.get("kdenlive:documentnotes"); emit setDocumentNotes(notes); // Fill Controller's list m_binPlaylist = new Mlt::Playlist(playlist); m_binPlaylist->set("id", kPlaylistTrackId); int max = m_binPlaylist->count(); for (int i = 0; i < max; i++) { Mlt::Producer *producer = m_binPlaylist->get_clip(i); if (producer->is_blank() || !producer->is_valid()) continue; QString id = producer->parent().get("id"); if (id.contains(QStringLiteral("_"))) { // This is a track producer QString mainId = id.section(QStringLiteral("_"), 0, 0); QString track = id.section(QStringLiteral("_"), 1, 1); if (m_clipList.contains(mainId)) { // The controller for this track producer already exists } else { // Create empty controller for this track ClipController *controller = new ClipController(this); m_clipList.insert(mainId, controller); } delete producer; } else { if (m_clipList.contains(id) && m_clipList.value(id)) { //Controller was already added by a track producer, add master now m_clipList.value(id)->addMasterProducer(producer->parent()); } else { // Controller has not been created yet ClipController *controller = new ClipController(this, producer->parent()); // fix MLT somehow adding root to color producer's resource (report upstream) if (strcmp(producer->parent().get("mlt_service"), "color") == 0) { QString color = producer->parent().get("resource"); if (color.contains(QStringLiteral("/"))) { color = color.section(QStringLiteral("/"), -1, -1); producer->parent().set("resource", color.toUtf8().constData()); } } m_clipList.insert(id, controller); } } emit loadingBin(i + 1); } // Load markers Mlt::Properties markerProperties; markerProperties.pass_values(playlistProps, "kdenlive:marker."); QMap <QString,QString> markersData; for (int i = 0; i < markerProperties.count(); i++) { QString markerId = markerProperties.get_name(i); QString controllerId = markerId.section(QStringLiteral(":"), 0, 0); ClipController *ctrl = m_clipList.value(controllerId); if (!ctrl) continue; ctrl->loadSnapMarker(markerId.section(QStringLiteral(":"), 1), markerProperties.get(i)); } }