From: Jean-Baptiste Mardelle Date: Wed, 31 Oct 2012 00:12:59 +0000 (+0100) Subject: Several improvements in DVD wizard, fix menu with background movie (currently only... X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=bf5a5feff2432c0d9be38d0782c2d3ec10cd6739;p=kdenlive Several improvements in DVD wizard, fix menu with background movie (currently only works for 4:3 ratio) --- diff --git a/src/dvdwizard.cpp b/src/dvdwizard.cpp index aa36f604..0a411e65 100644 --- a/src/dvdwizard.cpp +++ b/src/dvdwizard.cpp @@ -196,6 +196,11 @@ void DvdWizard::generateDvd() //temp5.setAutoRemove(false); temp5.open(); + KTemporaryFile temp6; + temp6.setSuffix(".vob"); + //temp6.setAutoRemove(false); + temp6.open(); + m_menuFile.close(); m_menuFile.setSuffix(".xml"); m_menuFile.setAutoRemove(false); @@ -243,16 +248,62 @@ void DvdWizard::generateDvd() args.append(temp4.fileName()); args.append("in=0"); args.append("out=100"); - args << "-consumer" << "avformat:" + temp5.fileName(); - if (m_pageMenu->isPalMenu()) { - args << "f=dvd" << "acodec=ac3" << "ab=192k" << "ar=48000" << "vcodec=mpeg2video" << "vb=5000k" << "maxrate=8000k" << "minrate=0" << "bufsize=1835008" << "mux_packet_s=2048" << "mux_rate=10080000" << "s=720x576" << "g=15" << "me_range=63" << "trellis=1"; + args << "-consumer" << "avformat:" + temp5.fileName()<<"properties=DVD"; + QProcess renderbg; + renderbg.start(KdenliveSettings::rendererpath(), args); + if (renderbg.waitForFinished()) { + if (renderbg.exitStatus() == QProcess::CrashExit) { + kDebug() << "/// RENDERING MENU vob crashed"; + errorMessage(i18n("Rendering menu crashed")); + QByteArray result = renderbg.readAllStandardError(); + vobitem->setIcon(KIcon("dialog-close")); + m_status.error_log->append(result); + m_status.error_box->setHidden(false); + m_status.button_start->setEnabled(true); + m_status.button_abort->setEnabled(false); + return; + } } else { - args << "f=dvd" << "acodec=ac3" << "ab=192k" << "ar=48000" << "vcodec=mpeg2video" << "vb=6000k" << "maxrate=9000k" << "minrate=0" << "bufsize=1835008" << "mux_packet_s=2048" << "mux_rate=10080000" << "s=720x480" << "g=18" << "me_range=63" << "trellis=1"; + kDebug() << "/// RENDERING MENU vob timed out"; + errorMessage(i18n("Rendering job timed out")); + vobitem->setIcon(KIcon("dialog-close")); + m_status.error_log->append("
" + i18n("Rendering job timed out")); + m_status.error_log->scrollToAnchor("result"); + m_status.error_box->setHidden(false); + m_status.button_start->setEnabled(true); + m_status.button_abort->setEnabled(false); + return; } + vobitem->setIcon(KIcon("dialog-ok")); + } else { + // Movie as menu background, do the compositing + QListWidgetItem *vobitem = m_status.job_progress->item(1); + m_status.job_progress->setCurrentRow(1); + vobitem->setIcon(KIcon("system-run")); + qApp->processEvents(); - kDebug() << "MLT ARGS: " << args; + QString std; + if (m_pageMenu->isPalMenu()) std = "dv_pal"; + else std = "dv_ntsc"; + int menuLength = m_pageMenu->menuMovieLength(); + if (menuLength == -1) { + // menu movie is invalid + errorMessage(i18n("Menu movie is invalid")); + m_status.button_start->setEnabled(true); + m_status.button_abort->setEnabled(false); + return; + } + + QStringList args; + args.append("-profile"); + args.append(std); + args.append(m_pageMenu->menuMoviePath()); + args << "-track" << temp4.fileName(); + args << "out=" + QString::number(menuLength); + args << "-transition" << "composite" << "always_active=1"; + args << "-consumer" << "avformat:" + temp6.fileName()<<"properties=DVD"; QProcess renderbg; - renderbg.start(KdenliveSettings::rendererpath(), args); + renderbg.start(KdenliveSettings::rendererpath(), args); if (renderbg.waitForFinished()) { if (renderbg.exitStatus() == QProcess::CrashExit) { kDebug() << "/// RENDERING MENU vob crashed"; @@ -277,7 +328,7 @@ void DvdWizard::generateDvd() return; } vobitem->setIcon(KIcon("dialog-ok")); - } + } kDebug() << "/// STARTING SPUMUX"; // create xml spumux file @@ -353,7 +404,7 @@ void DvdWizard::generateDvd() spumux.setEnvironment(env); #endif - if (m_pageMenu->menuMovie()) spumux.setStandardInputFile(m_pageMenu->menuMoviePath()); + if (m_pageMenu->menuMovie()) spumux.setStandardInputFile(temp6.fileName()); else spumux.setStandardInputFile(temp5.fileName()); spumux.setStandardOutputFile(m_menuVobFile.fileName()); spumux.start("spumux", args); diff --git a/src/dvdwizardmenu.cpp b/src/dvdwizardmenu.cpp index 38ac05a7..fb162c89 100644 --- a/src/dvdwizardmenu.cpp +++ b/src/dvdwizardmenu.cpp @@ -34,7 +34,8 @@ DvdWizardMenu::DvdWizardMenu(const QString &profile, QWidget *parent) : QWizardPage(parent), m_color(NULL), m_safeRect(NULL), - m_finalSize(720, 576) + m_finalSize(720, 576), + m_movieLength(-1) { m_view.setupUi(this); m_view.play_text->setText(i18n("Play")); @@ -329,10 +330,10 @@ void DvdWizardMenu::addButton() #endif //font.setStyleStrategy(QFont::NoAntialias); button->setFont(font); + button->setDefaultTextColor(m_view.text_color->color()); button->setZValue(4); QRectF r = button->sceneBoundingRect(); m_scene->addItem(button); - updateColor(m_view.text_color->color()); button->setPos((m_width - r.width()) / 2, (m_height - r.height()) / 2); button->setSelected(true); } @@ -441,11 +442,16 @@ void DvdWizardMenu::buildImage() pix = pix.scaled(m_width, m_height); } else if (m_view.background_list->currentIndex() == 2) { // video background - int w; - if (m_isPal) w = 768; - else w = 640; - pix = KThumb::getImage(m_view.background_image->url(), 0, w, m_height); - pix = pix.scaled(m_width, m_height); + m_movieLength = -1; + QString standard = "dv_pal"; + if (!m_isPal) standard = "dv_ntsc"; + Mlt::Profile profile(standard.toUtf8().constData()); + Mlt::Producer *producer = new Mlt::Producer(profile, m_view.background_image->url().path().toUtf8().data()); + if (producer && producer->is_valid()) { + pix = QPixmap::fromImage(KThumb::getFrame(producer, 0, m_finalSize.width(), m_width, m_height)); + m_movieLength = producer->get_length(); + } + if (producer) delete producer; } m_background->setPixmap(pix); m_scene->addItem(m_background); @@ -634,7 +640,15 @@ void DvdWizardMenu::createBackgroundImage(const QString &overlayMenu, const QStr { m_scene->clearSelection(); if (m_safeRect->scene() != 0) m_scene->removeItem(m_safeRect); + bool showBg = false; QImage img(m_width, m_height, QImage::Format_ARGB32); + if (menuMovie() && m_background->scene() != 0) { + showBg = true; + m_scene->removeItem(m_background); + if (m_color->scene() != 0) m_scene->removeItem(m_color); + if (m_safeRect->scene() != 0) m_scene->removeItem(m_safeRect); + img.fill(Qt::transparent); + } updateColor(m_view.text_color->color()); QPainter p(&img); p.setRenderHints(QPainter::Antialiasing, true); @@ -643,6 +657,10 @@ void DvdWizardMenu::createBackgroundImage(const QString &overlayMenu, const QStr p.end(); img.save(img1); m_scene->addItem(m_safeRect); + if (showBg) { + m_scene->addItem(m_background); + m_scene->addItem(m_color); + } return; @@ -694,6 +712,11 @@ QString DvdWizardMenu::menuMoviePath() const return m_view.background_image->url().path(); } +int DvdWizardMenu::menuMovieLength() const +{ + return m_movieLength; +} + QMap DvdWizardMenu::buttonsInfo() { diff --git a/src/dvdwizardmenu.h b/src/dvdwizardmenu.h index e8d6f07d..2ecdcae1 100644 --- a/src/dvdwizardmenu.h +++ b/src/dvdwizardmenu.h @@ -140,6 +140,7 @@ public: bool loopMovie() const; bool menuMovie() const; QString menuMoviePath() const; + int menuMovieLength() const; bool isPalMenu() const; void changeProfile(bool isPal); QDomElement toXml() const; @@ -157,6 +158,7 @@ private: int m_width; int m_height; QSize m_finalSize; + int m_movieLength; #if KDE_IS_VERSION(4,7,0) KMessageWidget *m_menuMessage; #endif diff --git a/src/dvdwizardvob.cpp b/src/dvdwizardvob.cpp index 1caae7f8..0dc32551 100644 --- a/src/dvdwizardvob.cpp +++ b/src/dvdwizardvob.cpp @@ -50,6 +50,7 @@ DvdWizardVob::DvdWizardVob(const QString &profile, QWidget *parent) : connect(m_view.button_up, SIGNAL(clicked()), this, SLOT(slotItemUp())); connect(m_view.button_down, SIGNAL(clicked()), this, SLOT(slotItemDown())); connect(m_view.vobs_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotCheckVobList())); + m_view.vobs_list->setIconSize(QSize(60, 45)); if (KStandardDirs::findExe("dvdauthor").isEmpty()) m_errorMessage.append(i18n("Program %1 is required for the DVD wizard.", i18n("dvdauthor"))); @@ -63,15 +64,28 @@ DvdWizardVob::DvdWizardVob(const QString &profile, QWidget *parent) : else if (profile == "dv_ntsc_wide") m_view.dvd_profile->setCurrentIndex(3); connect(m_view.dvd_profile, SIGNAL(activated(int)), this, SLOT(changeFormat())); + connect(m_view.dvd_profile, SIGNAL(activated(int)), this, SLOT(slotCheckProfiles())); m_view.vobs_list->header()->setStretchLastSection(false); m_view.vobs_list->header()->setResizeMode(0, QHeaderView::Stretch); m_view.vobs_list->header()->setResizeMode(1, QHeaderView::Custom); m_view.vobs_list->header()->setResizeMode(2, QHeaderView::Custom); m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this); - QHBoxLayout *layout = new QHBoxLayout; - layout->addWidget(m_capacityBar); - m_view.size_box->setLayout(layout); + QHBoxLayout *lay = new QHBoxLayout; + lay->addWidget(m_capacityBar); + m_view.size_box->setLayout(lay); + + m_view.vobs_list->setItemDelegate(new DvdViewDelegate(m_view.vobs_list)); + +#if KDE_IS_VERSION(4,7,0) + m_warnMessage = new KMessageWidget; + m_warnMessage->setText(i18n("Conflicting video standards, check DVD profile and clips")); + m_warnMessage->setMessageType(KMessageWidget::Warning); + QGridLayout *s = static_cast (layout()); + s->addWidget(m_warnMessage, 3, 0, 1, -1); + m_warnMessage->hide(); +#endif + slotCheckVobList(); } @@ -80,6 +94,25 @@ DvdWizardVob::~DvdWizardVob() delete m_capacityBar; } +void DvdWizardVob::slotCheckProfiles() +{ +#if KDE_IS_VERSION(4,7,0) + bool conflict = false; + int comboProfile = m_view.dvd_profile->currentIndex(); + for (int i = 0; i < m_view.vobs_list->topLevelItemCount(); i++) { + QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i); + if (item->data(0, Qt::UserRole + 1).toInt() != comboProfile) { + conflict = true; + break; + } + } + + if (conflict) { + m_warnMessage->animatedShow(); + } + else m_warnMessage->animatedHide(); +#endif +} void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters) { @@ -103,25 +136,57 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters) break; } - Mlt::Profile profile(profilename.toUtf8().data()); + Mlt::Profile profile(profilename.toUtf8().constData()); + profile.set_explicit(false); QTreeWidgetItem *item = new QTreeWidgetItem(m_view.vobs_list, QStringList() << url.path() << QString() << KIO::convertSize(fileSize)); item->setData(0, Qt::UserRole, fileSize); - item->setIcon(0, KIcon("video-x-generic")); - - QPixmap pix(60, 45); - + item->setData(0, Qt::DecorationRole, KIcon("video-x-generic").pixmap(60, 45)); + item->setToolTip(0, url.path()); + Mlt::Producer *producer = new Mlt::Producer(profile, url.path().toUtf8().data()); - - if (producer->is_blank() == false) { + if (producer && producer->is_valid() && !producer->is_blank()) { + //Mlt::Frame *frame = producer->get_frame(); + //delete frame; + profile.from_producer(*producer); int width = 45.0 * profile.dar(); int swidth = 45.0 * profile.width() / profile.height(); if (width % 2 == 1) width++; - item->setIcon(0, QPixmap::fromImage(KThumb::getFrame(producer, 0, swidth, width, 45))); + item->setData(0, Qt::DecorationRole, QPixmap::fromImage(KThumb::getFrame(producer, 0, swidth, width, 45))); int playTime = producer->get_playtime(); item->setText(1, Timecode::getStringTimecode(playTime, profile.fps())); item->setData(1, Qt::UserRole, playTime); + int standard = -1; + int aspect = profile.dar() * 100; + if (profile.height() == 576) { + if (aspect > 150) standard = 1; + else standard = 0; + } + else if (profile.height() == 480) { + if (aspect > 150) standard = 3; + else standard = 2; + } + QString standardName; + switch (standard) { + case 3: + standardName = i18n("NTSC 16:9"); + break; + case 2: + standardName = i18n("NTSC 4:3"); + break; + case 1: + standardName = i18n("PAL 16:9"); + break; + case 0: + standardName = i18n("PAL 4:3"); + break; + default: + standardName = i18n("Unknown"); + } + item->setData(0, Qt::UserRole, standardName); + item->setData(0, Qt::UserRole + 1, standard); + } - delete producer; + if (producer) delete producer; if (chapters.isEmpty() == false) { item->setData(1, Qt::UserRole + 1, chapters); @@ -147,6 +212,7 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters) item->setData(1, Qt::UserRole + 1, "0"); slotCheckVobList(); + slotCheckProfiles(); } void DvdWizardVob::changeFormat() @@ -168,7 +234,7 @@ void DvdWizardVob::changeFormat() break; } - Mlt::Profile profile(profilename.toUtf8().data()); + Mlt::Profile profile(profilename.toUtf8().constData()); QPixmap pix(180, 135); for (int i = 0; i < max; i++) { @@ -196,6 +262,7 @@ void DvdWizardVob::slotDeleteVobFile() if (item == NULL) return; delete item; slotCheckVobList(); + slotCheckProfiles(); } diff --git a/src/dvdwizardvob.h b/src/dvdwizardvob.h index bc395019..0b634a77 100644 --- a/src/dvdwizardvob.h +++ b/src/dvdwizardvob.h @@ -27,7 +27,53 @@ #include #include +#if KDE_IS_VERSION(4,7,0) +#include +#endif + #include +#include +#include + +class DvdViewDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + DvdViewDelegate(QWidget *parent) : QStyledItemDelegate(parent) {} + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const { + if (index.column() == 0) { + painter->save(); + QStyleOptionViewItemV4 opt(option); + QRect r1 = option.rect; + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + + QPixmap pixmap = qVariantValue(index.data(Qt::DecorationRole)); + QPoint pixmapPoint(r1.left() + textMargin, r1.top() + (r1.height() - pixmap.height()) / 2); + painter->drawPixmap(pixmapPoint, pixmap); + int decoWidth = pixmap.width() + 2 * textMargin; + + QFont font = painter->font(); + font.setBold(true); + painter->setFont(font); + int mid = (int)((r1.height() / 2)); + r1.adjust(decoWidth, 0, 0, -mid); + QRect r2 = option.rect; + r2.adjust(decoWidth, mid, 0, 0); + painter->drawText(r1, Qt::AlignLeft | Qt::AlignBottom, KUrl(index.data().toString()).fileName()); + font.setBold(false); + painter->setFont(font); + QString subText = index.data(Qt::UserRole).toString(); + QRectF bounding; + painter->drawText(r2, Qt::AlignLeft | Qt::AlignVCenter , subText, &bounding); + painter->restore(); + } else QStyledItemDelegate::paint(painter, option, index); + } +}; + class DvdWizardVob : public QWizardPage { @@ -54,9 +100,13 @@ private: Ui::DvdWizardVob_UI m_view; QString m_errorMessage; KCapacityBar *m_capacityBar; +#if KDE_IS_VERSION(4,7,0) + KMessageWidget *m_warnMessage; +#endif public slots: void slotAddVobFile(KUrl url = KUrl(), const QString &chapters = QString()); + void slotCheckProfiles(); private slots: void slotCheckVobList();