+ overlayargs << "data_show:" + filterFile << "_loader=1" << "dynamic=1";
+ }
+
+ QStringList render_process_args;
+
+ if (!scriptExport) render_process_args << "-erase";
+ if (KdenliveSettings::usekuiserver()) render_process_args << "-kuiserver";
+
+ double guideStart = 0;
+ double guideEnd = 0;
+
+ if (m_view.render_zone->isChecked()) render_process_args << "in=" + QString::number(zoneIn) << "out=" + QString::number(zoneOut);
+ else if (m_view.render_guide->isChecked()) {
+ double fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
+ guideStart = m_view.guide_start->itemData(m_view.guide_start->currentIndex()).toDouble();
+ guideEnd = m_view.guide_end->itemData(m_view.guide_end->currentIndex()).toDouble();
+ render_process_args << "in=" + QString::number(GenTime(guideStart).frames(fps)) << "out=" + QString::number(GenTime(guideEnd).frames(fps));
+ }
+
+ if (!overlayargs.isEmpty()) render_process_args << "preargs=" + overlayargs.join(" ");
+
+ render_process_args << KdenliveSettings::rendererpath() << m_profile.path << item->data(RenderRole).toString();
+ if (m_view.play_after->isChecked()) render_process_args << KdenliveSettings::KdenliveSettings::defaultplayerapp();
+ else render_process_args << "-";
+
+ QString renderArgs = m_view.advanced_params->toPlainText().simplified();
+
+ // Adjust frame scale
+ int width;
+ int height;
+ if (m_view.rescale->isChecked() && m_view.rescale->isEnabled()) {
+ width = m_view.rescale_width->value();
+ height = m_view.rescale_height->value();
+ } else {
+ width = m_profile.width;
+ height = m_profile.height;
+ }
+ renderArgs.replace("%dar", '@' + QString::number(m_profile.display_aspect_num) + '/' + QString::number(m_profile.display_aspect_den));
+
+ // Adjust scanning
+ if (m_view.scanning_list->currentIndex() == 1) renderArgs.append(" progressive=1");
+ else if (m_view.scanning_list->currentIndex() == 2) renderArgs.append(" progressive=0");
+
+ // disable audio if requested
+ if (!exportAudio) renderArgs.append(" an=1 ");
+
+ // Check if the rendering profile is different from project profile,
+ // in which case we need to use the producer_comsumer from MLT
+ QString std = renderArgs;
+ QString destination = m_view.destination_list->itemData(m_view.destination_list->currentIndex()).toString();
+ const QString currentSize = QString::number(width) + 'x' + QString::number(height);
+ QString subsize = currentSize;
+ if (std.startsWith("s=")) {
+ subsize = std.section(' ', 0, 0).toLower();
+ subsize = subsize.section("=", 1, 1);
+ } else if (std.contains(" s=")) {
+ subsize = std.section(" s=", 1, 1);
+ subsize = subsize.section(' ', 0, 0).toLower();
+ } else if (destination != "audioonly" && m_view.rescale->isChecked() && m_view.rescale->isEnabled()) {
+ subsize = QString(" s=%1x%2").arg(width).arg(height);
+ // Add current size parameter
+ renderArgs.append(subsize);
+ }
+ bool resizeProfile = (subsize != currentSize);
+ QStringList paramsList = renderArgs.split(" ", QString::SkipEmptyParts);
+ for (int i = 0; i < paramsList.count(); i++) {
+ if (paramsList.at(i).startsWith("profile=")) {
+ if (paramsList.at(i).section('=', 1) != m_profile.path) resizeProfile = true;
+ break;
+ }
+ }
+
+ if (resizeProfile) render_process_args << "consumer:" + playlistPath;
+ else render_process_args << playlistPath;
+ render_process_args << dest;
+ render_process_args << paramsList;
+
+ QString group = m_view.size_list->currentItem()->data(MetaGroupRole).toString();
+
+ QStringList renderParameters;
+ renderParameters << dest << item->data(RenderRole).toString() << renderArgs.simplified();
+ renderParameters << QString::number(zoneIn) << QString::number(zoneOut) << QString::number(m_view.play_after->isChecked());
+ renderParameters << QString::number(guideStart) << QString::number(guideEnd) << QString::number(resizeProfile);
+
+ QString scriptName;
+ if (scriptExport) {
+ // Generate script file
+ QFile file(scriptPath);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ KMessageBox::error(this, i18n("Cannot write to file %1", scriptPath));
+ return;
+ }
+ QTextStream outStream(&file);
+ outStream << "#! /bin/sh" << "\n" << "\n";
+ outStream << "SOURCE=" << "\"" + playlistPath + "\"" << "\n";
+ outStream << "TARGET=" << "\"" + dest + "\"" << "\n";
+ outStream << "RENDERER=" << "\"" + m_renderer + "\"" << "\n";
+ outStream << "MELT=" << "\"" + render_process_args.takeFirst() + "\"" << "\n";
+ outStream << "PARAMETERS=" << "\"" + render_process_args.join(" ") + "\"" << "\n";
+ outStream << "$RENDERER $MELT $PARAMETERS" << "\n" << "\n";
+ if (file.error() != QFile::NoError) {
+ KMessageBox::error(this, i18n("Cannot write to file %1", scriptPath));
+ file.close();
+ return;
+ }
+ file.close();
+ QFile::setPermissions(scriptPath, file.permissions() | QFile::ExeUser);
+
+ QTimer::singleShot(400, this, SLOT(parseScriptFiles()));
+ m_view.tabWidget->setCurrentIndex(2);
+ return;
+ }
+ renderParameters << scriptName;
+
+ // Save rendering profile to document
+ QMap <QString, QString> renderProps;
+ renderProps.insert("renderdestination", m_view.size_list->currentItem()->data(MetaGroupRole).toString());
+ renderProps.insert("rendercategory", m_view.size_list->currentItem()->data(GroupRole).toString());
+ renderProps.insert("renderprofile", m_view.size_list->currentItem()->text());
+ renderProps.insert("renderurl", dest);
+ renderProps.insert("renderzone", QString::number(m_view.render_zone->isChecked()));
+ renderProps.insert("renderguide", QString::number(m_view.render_guide->isChecked()));
+ renderProps.insert("renderstartguide", QString::number(m_view.guide_start->currentIndex()));
+ renderProps.insert("renderendguide", QString::number(m_view.guide_end->currentIndex()));
+ renderProps.insert("renderendguide", QString::number(m_view.guide_end->currentIndex()));
+ renderProps.insert("renderscanning", QString::number(m_view.scanning_list->currentIndex()));
+ int export_audio = 0;
+ if (m_view.export_audio->checkState() == Qt::Checked) export_audio = 2;
+ else if (m_view.export_audio->checkState() == Qt::Unchecked) export_audio = 1;
+ renderProps.insert("renderexportaudio", QString::number(export_audio));
+ renderProps.insert("renderrescale", QString::number(m_view.rescale->isChecked()));
+ renderProps.insert("renderrescalewidth", QString::number(m_view.rescale_width->value()));
+ renderProps.insert("renderrescaleheight", QString::number(m_view.rescale_height->value()));
+ renderProps.insert("rendertcoverlay", QString::number(m_view.tc_overlay->isChecked()));
+ renderProps.insert("renderratio", QString::number(m_view.rescale_keep->isChecked()));
+ renderProps.insert("renderplay", QString::number(m_view.play_after->isChecked()));
+
+ emit selectedRenderProfile(renderProps);
+
+ // insert item in running jobs list
+ QTreeWidgetItem *renderItem;
+ QList<QTreeWidgetItem *> existing = m_view.running_jobs->findItems(dest, Qt::MatchExactly, 1);
+ if (!existing.isEmpty()) {
+ renderItem = existing.at(0);
+ if (renderItem->data(1, Qt::UserRole + 2).toInt() == RUNNINGJOB) {
+ KMessageBox::information(this, i18n("There is already a job writing file:<br /><b>%1</b><br />Abort the job if you want to overwrite it...", dest), i18n("Already running"));
+ return;
+ }
+ renderItem->setData(1, Qt::UserRole + 4, QString());
+ } else {
+ renderItem = new QTreeWidgetItem(m_view.running_jobs, QStringList() << QString() << dest << QString());
+ }
+ renderItem->setData(1, Qt::UserRole + 2, WAITINGJOB);
+ renderItem->setIcon(0, KIcon("media-playback-pause"));
+ renderItem->setData(1, Qt::UserRole, i18n("Waiting..."));
+ renderItem->setSizeHint(1, QSize(m_view.running_jobs->columnWidth(1), fontMetrics().height() * 2));
+ renderItem->setData(1, Qt::UserRole + 1, QTime::currentTime());
+
+ // Set rendering type
+ if (group == "dvd") {
+ if (m_view.open_dvd->isChecked()) {
+ renderItem->setData(0, Qt::UserRole, group);
+ if (renderArgs.contains("profile=")) {
+ // rendering profile contains an MLT profile, so pass it to the running jog item, useful for dvd
+ QString prof = renderArgs.section("profile=", 1, 1);
+ prof = prof.section(' ', 0, 0);
+ kDebug() << "// render profile: " << prof;
+ renderItem->setData(0, Qt::UserRole + 1, prof);
+ }
+ }
+ } else {
+ if (group == "websites" && m_view.open_browser->isChecked()) {
+ renderItem->setData(0, Qt::UserRole, group);
+ // pass the url
+ QString url = m_view.size_list->currentItem()->data(ExtraRole).toString();
+ renderItem->setData(0, Qt::UserRole + 1, url);
+ }
+ }
+ renderItem->setData(1, Qt::UserRole + 3, render_process_args);
+ if (exportAudio == false) renderItem->setData(1, Qt::UserRole + 5, i18n("Video without audio track"));
+ else renderItem->setData(1, Qt::UserRole + 5, QString());
+ m_view.running_jobs->setCurrentItem(renderItem);
+ m_view.tabWidget->setCurrentIndex(1);
+ checkRenderStatus();
+}
+
+void RenderWidget::checkRenderStatus()
+{
+ // check if we have a job waiting to render
+ if (m_blockProcessing) return;
+ QTreeWidgetItem *item = m_view.running_jobs->topLevelItem(0);
+ while (item) {
+ if (item->data(1, Qt::UserRole + 2).toInt() == RUNNINGJOB) return;
+ item = m_view.running_jobs->itemBelow(item);
+ }
+ item = m_view.running_jobs->topLevelItem(0);
+ bool waitingJob = false;
+ while (item) {
+ if (item->data(1, Qt::UserRole + 2).toInt() == WAITINGJOB) {
+ item->setData(1, Qt::UserRole + 1, QTime::currentTime());
+ waitingJob = true;
+ startRendering(item);
+ break;
+ }
+ item = m_view.running_jobs->itemBelow(item);