]> git.sesse.net Git - kdenlive/commitdiff
Several improvements in DVD wizard, fix menu with background movie (currently only...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 31 Oct 2012 00:12:59 +0000 (01:12 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 31 Oct 2012 00:12:59 +0000 (01:12 +0100)
src/dvdwizard.cpp
src/dvdwizardmenu.cpp
src/dvdwizardmenu.h
src/dvdwizardvob.cpp
src/dvdwizardvob.h

index aa36f6048a497c4a84a3cf767f3e8ea4d59928e3..0a411e659b5d0ba5f30e7823435e4bd532f46418 100644 (file)
@@ -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("<a name=\"result\" /><br /><strong>" + 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);
index 38ac05a719ee74df68a56523817680411d6a3736..fb162c89378850a422ce2ddce584a64d8c6b51c6 100644 (file)
@@ -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 <QString, QRect> DvdWizardMenu::buttonsInfo()
 {
index e8d6f07de258cd063fa1f4c4f8332c7cc73d4382..2ecdcae18b9c41153d5b40bf8680cfd7fe19eb20 100644 (file)
@@ -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
index 1caae7f8180dbfd676da45abc180ee62cc17fdc9..0dc32551e98c0f1dc2369be8e36ac108b8f517ea 100644 (file)
@@ -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("<strong>Program %1 is required for the DVD wizard.</strong>", 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 <QGridLayout*> (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();
 }
 
 
index bc395019071794c744f2f034709be6742bb23874..0b634a7743d04468f5819258aed02ce8c87a137f 100644 (file)
 #include <kcapacitybar.h>
 #include <KUrl>
 
+#if KDE_IS_VERSION(4,7,0)
+#include <KMessageWidget>
+#endif
+
 #include <QWizardPage>
+#include <QStyledItemDelegate>
+#include <QPainter>
+
+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<QPixmap>(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();