X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frenderwidget.cpp;h=99eacdb13ed9712c57da7816cd7847737365430e;hb=d31d2e77667b3e3c30be16cfc462b8a44030beb1;hp=e1c6ddad83a2fab84ed6ef423c06fe90cbb6eb4a;hpb=dc2ee8838848f4ef4cb16866f72d3704e018948e;p=kdenlive diff --git a/src/renderwidget.cpp b/src/renderwidget.cpp index e1c6ddad..99eacdb1 100644 --- a/src/renderwidget.cpp +++ b/src/renderwidget.cpp @@ -19,6 +19,9 @@ #include +#include +#include +#include #include #include @@ -55,12 +58,18 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) { m_view.buttonInfo->setDown(true); } else m_view.advanced_params->hide(); + m_view.experimentalrender->setChecked(KdenliveSettings::experimentalrender()); + + m_view.experimentalrender->setToolTip(i18n("Changing the size of video when rendering\nis not fully supported, you may have problems\nwith some effects or title clips, so the export\nprofiles that resize your video are marked as\nexperimental")); + connect(m_view.buttonInfo, SIGNAL(clicked()), this, SLOT(showInfoPanel())); connect(m_view.buttonSave, SIGNAL(clicked()), this, SLOT(slotSaveProfile())); connect(m_view.buttonEdit, SIGNAL(clicked()), this, SLOT(slotEditProfile())); connect(m_view.buttonDelete, SIGNAL(clicked()), this, SLOT(slotDeleteProfile())); connect(m_view.buttonStart, SIGNAL(clicked()), this, SLOT(slotExport())); + connect(m_view.buttonClose, SIGNAL(clicked()), this, SLOT(hide())); + connect(m_view.buttonClose2, SIGNAL(clicked()), this, SLOT(hide())); connect(m_view.out_file, SIGNAL(textChanged(const QString &)), this, SLOT(slotUpdateButtons())); connect(m_view.format_list, SIGNAL(currentRowChanged(int)), this, SLOT(refreshView())); connect(m_view.size_list, SIGNAL(currentRowChanged(int)), this, SLOT(refreshParams())); @@ -73,6 +82,7 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) { connect(m_view.guide_start, SIGNAL(activated(int)), this, SLOT(slotCheckEndGuidePosition())); connect(m_view.format_selection, SIGNAL(activated(int)), this, SLOT(refreshView())); + connect(m_view.experimentalrender, SIGNAL(stateChanged(int)), this, SLOT(slotUpdateExperimentalRendering())); m_view.buttonStart->setEnabled(false); m_view.guides_box->setVisible(false); @@ -80,9 +90,28 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) { m_view.splitter->setStretchFactor(1, 5); m_view.splitter->setStretchFactor(0, 2); + m_view.out_file->setMode(KFile::File); + + m_view.running_jobs->setItemDelegate(new RenderViewDelegate(this)); + QHeaderView *header = m_view.running_jobs->header(); + QFontMetrics fm = fontMetrics(); + //header->resizeSection(0, fm.width("typical-name-for-a-torrent.torrent")); + header->setResizeMode(0, QHeaderView::Interactive); + header->resizeSection(0, fm.width("typical-name-for-a-file.torrent")); + header->setResizeMode(1, QHeaderView::Fixed); + header->resizeSection(0, width() * 2 / 3); + header->setResizeMode(1, QHeaderView::Interactive); + //header->setResizeMode(1, QHeaderView::Fixed); + focusFirstVisibleItem(); } +void RenderWidget::slotUpdateExperimentalRendering() { + KdenliveSettings::setExperimentalrender(m_view.experimentalrender->isChecked()); + refreshView(); +} + + void RenderWidget::showInfoPanel() { if (m_view.advanced_params->isVisible()) { m_view.advanced_params->setVisible(false); @@ -328,8 +357,29 @@ void RenderWidget::slotDeleteProfile() { focusFirstVisibleItem(); } +void RenderWidget::updateButtons() { + if (!m_view.size_list->currentItem() || m_view.size_list->currentItem()->isHidden()) { + m_view.buttonSave->setEnabled(false); + m_view.buttonDelete->setEnabled(false); + m_view.buttonEdit->setEnabled(false); + } else { + m_view.buttonSave->setEnabled(true); + if (m_view.size_list->currentItem()->data(EditableRole).toString().isEmpty()) { + m_view.buttonDelete->setEnabled(false); + m_view.buttonEdit->setEnabled(false); + } else { + m_view.buttonDelete->setEnabled(true); + m_view.buttonEdit->setEnabled(true); + } + } +} + + void RenderWidget::focusFirstVisibleItem() { - if (m_view.size_list->currentItem() && !m_view.size_list->currentItem()->isHidden()) return; + if (m_view.size_list->currentItem() && !m_view.size_list->currentItem()->isHidden()) { + updateButtons(); + return; + } for (uint ix = 0; ix < m_view.size_list->count(); ix++) { QListWidgetItem *item = m_view.size_list->item(ix); if (item && !item->isHidden()) { @@ -338,6 +388,7 @@ void RenderWidget::focusFirstVisibleItem() { } } if (!m_view.size_list->currentItem()) m_view.size_list->setCurrentRow(0); + updateButtons(); } void RenderWidget::slotExport() { @@ -365,9 +416,24 @@ void RenderWidget::slotExport() { renderArgs.replace("%width", QString::number(m_profile.width)); renderArgs.replace("%height", QString::number(m_profile.height)); renderArgs.replace("%dar", "@" + QString::number(m_profile.display_aspect_num) + "/" + QString::number(m_profile.display_aspect_den)); - if (m_view.force_progressive->isChecked()) renderArgs.append(" progressive=1"); - else renderArgs.append(" progressive=0"); - emit doRender(m_view.out_file->url().path(), item->data(RenderRole).toString(), overlayargs, renderArgs.simplified().split(' '), m_view.render_zone->isChecked(), m_view.play_after->isChecked(), startPos, endPos); + if (m_view.force_progressive->checkState() == Qt::Checked) renderArgs.append(" progressive=1"); + else if (m_view.force_progressive->checkState() == Qt::Unchecked) renderArgs.append(" progressive=0"); + + // Check if the rendering profile is different from project profile, + // in which case we need to use the producer_comsumer from MLT + bool resizeProfile = false; + + QString std = item->data(ParamsRole).toString(); + if (resizeProfile == false && std.contains(" s=")) { + QString subsize = std.section(" s=", 1, 1); + subsize = subsize.section(' ', 0, 0).toLower(); + if (subsize != "%widthx%height") { + const QString currentSize = QString::number(m_profile.width) + 'x' + QString::number(m_profile.height); + if (subsize != currentSize) resizeProfile = true; + } + } + + emit doRender(m_view.out_file->url().path(), item->data(RenderRole).toString(), overlayargs, renderArgs.simplified().split(' '), m_view.render_zone->isChecked(), m_view.play_after->isChecked(), startPos, endPos, resizeProfile); } void RenderWidget::setProfile(MltVideoProfile profile) { @@ -375,11 +441,12 @@ void RenderWidget::setProfile(MltVideoProfile profile) { //WARNING: this way to tell the video standard is a bit hackish... if (m_profile.description.contains("pal", Qt::CaseInsensitive) || m_profile.description.contains("25", Qt::CaseInsensitive) || m_profile.description.contains("50", Qt::CaseInsensitive)) m_view.format_selection->setCurrentIndex(0); else m_view.format_selection->setCurrentIndex(1); - m_view.force_progressive->setChecked(m_profile.progressive); + m_view.force_progressive->setCheckState(Qt::PartiallyChecked); refreshView(); } void RenderWidget::refreshView() { + m_view.size_list->blockSignals(true); QListWidgetItem *item = m_view.format_list->currentItem(); if (!item) { m_view.format_list->setCurrentRow(0); @@ -390,10 +457,13 @@ void RenderWidget::refreshView() { QString group = item->text(); QListWidgetItem *sizeItem; bool firstSelected = false; + const QStringList formatsList = KdenliveSettings::supportedformats(); + const QStringList vcodecsList = KdenliveSettings::videocodecs(); + const QStringList acodecsList = KdenliveSettings::audiocodecs(); for (int i = 0; i < m_view.size_list->count(); i++) { sizeItem = m_view.size_list->item(i); - std = sizeItem->data(StandardRole).toString(); if (sizeItem->data(GroupRole) == group) { + std = sizeItem->data(StandardRole).toString(); if (!std.isEmpty()) { if (std.contains("PAL", Qt::CaseInsensitive)) sizeItem->setHidden(m_view.format_selection->currentIndex() != 0); else if (std.contains("NTSC", Qt::CaseInsensitive)) sizeItem->setHidden(m_view.format_selection->currentIndex() != 1); @@ -402,15 +472,73 @@ void RenderWidget::refreshView() { if (!firstSelected) m_view.size_list->setCurrentItem(sizeItem); firstSelected = true; } + if (!KdenliveSettings::experimentalrender() && !sizeItem->isHidden()) { + // hide experimental codecs (which do resize the video) + std = sizeItem->data(ParamsRole).toString(); + if (std.contains(" s=")) { + QString subsize = std.section(" s=", 1, 1); + subsize = subsize.section(' ', 0, 0).toLower(); + if (subsize != "%widthx%height") { + const QString currentSize = QString::number(m_profile.width) + 'x' + QString::number(m_profile.height); + if (subsize != currentSize) sizeItem->setHidden(true); + } + } + } + if (!sizeItem->isHidden()) { + // Make sure the selected profile uses an installed avformat codec / format + std = sizeItem->data(ParamsRole).toString(); + + if (!formatsList.isEmpty()) { + QString format; + if (std.startsWith("f=")) format = std.section("f=", 1, 1); + else if (std.contains(" f=")) format = std.section(" f=", 1, 1); + if (!format.isEmpty()) { + format = format.section(' ', 0, 0).toLower(); + if (!formatsList.contains(format)) { + kDebug() << "***** UNSUPPORTED F: " << format; + sizeItem->setHidden(true); + } + } + } + if (!acodecsList.isEmpty() && !sizeItem->isHidden()) { + QString format; + if (std.startsWith("acodec=")) format = std.section("acodec=", 1, 1); + else if (std.contains(" acodec=")) format = std.section(" acodec=", 1, 1); + if (!format.isEmpty()) { + format = format.section(' ', 0, 0).toLower(); + if (!acodecsList.contains(format)) { + kDebug() << "***** UNSUPPORTED ACODEC: " << format; + sizeItem->setHidden(true); + } + } + } + if (!vcodecsList.isEmpty() && !sizeItem->isHidden()) { + QString format; + if (std.startsWith("vcodec=")) format = std.section("vcodec=", 1, 1); + else if (std.contains(" vcodec=")) format = std.section(" vcodec=", 1, 1); + if (!format.isEmpty()) { + format = format.section(' ', 0, 0).toLower(); + if (!vcodecsList.contains(format)) { + kDebug() << "***** UNSUPPORTED VCODEC: " << format; + sizeItem->setHidden(true); + } + } + } + } } else sizeItem->setHidden(true); } focusFirstVisibleItem(); - + m_view.size_list->blockSignals(false); + refreshParams(); } void RenderWidget::refreshParams() { QListWidgetItem *item = m_view.size_list->currentItem(); - if (!item) return; + if (!item || item->isHidden()) { + m_view.advanced_params->clear(); + m_view.buttonStart->setEnabled(false); + return; + } QString params = item->data(ParamsRole).toString(); QString extension = item->data(ExtensionRole).toString(); m_view.advanced_params->setPlainText(params); @@ -425,6 +553,7 @@ void RenderWidget::refreshParams() { } else { m_view.out_file->setUrl(KUrl(QDir::homePath() + "/untitled." + extension)); } + m_view.out_file->setFilter("*." + extension); if (item->data(EditableRole).toString().isEmpty()) { m_view.buttonDelete->setEnabled(false); @@ -433,6 +562,7 @@ void RenderWidget::refreshParams() { m_view.buttonDelete->setEnabled(true); m_view.buttonEdit->setEnabled(true); } + m_view.buttonStart->setEnabled(true); } void RenderWidget::parseProfiles(QString group, QString profile) { @@ -503,8 +633,31 @@ void RenderWidget::parseFile(QString exportFile, bool editable) { } } +void RenderWidget::setRenderJob(const QString &dest, int progress) { + QList existing = m_view.running_jobs->findItems(dest, Qt::MatchExactly); + if (!existing.isEmpty()) { + if (progress == -1) { + // Job finished successfully + existing.at(0)->setIcon(0, KIcon("dialog-ok")); + existing.at(0)->setData(1, Qt::UserRole, 100); + } else if (progress == -2) { + // Rendering crashed + existing.at(0)->setIcon(0, KIcon("dialog-close")); + existing.at(0)->setData(1, Qt::UserRole, 0); + } else existing.at(0)->setData(1, Qt::UserRole, progress); + return; + } + QTreeWidgetItem *item = new QTreeWidgetItem(m_view.running_jobs, QStringList() << dest << QString()); + if (progress == -1) { + // Job finished successfully + item->setIcon(0, KIcon("dialog-ok")); + item->setData(1, Qt::UserRole, 100); + } else if (progress == -2) { + // Rendering crashed + item->setIcon(0, KIcon("dialog-close")); + item->setData(1, Qt::UserRole, 0); + } else item->setData(1, Qt::UserRole, progress); +} #include "renderwidget.moc" - -