]> git.sesse.net Git - kdenlive/commitdiff
Fix dropframe timecode, patch from John T. Mertz
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 24 Mar 2010 07:59:07 +0000 (07:59 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 24 Mar 2010 07:59:07 +0000 (07:59 +0000)
http://kdenlive.org/mantis/view.php?id=1033

svn path=/trunk/kdenlive/; revision=4353

13 files changed:
src/clipdurationdialog.cpp
src/clipproperties.cpp
src/dvdwizardchapters.cpp
src/mainwindow.cpp
src/markerdialog.cpp
src/monitor.cpp
src/monitormanager.cpp
src/projectlist.cpp
src/projectlist.h
src/slideshowclip.cpp
src/timecode.cpp
src/timecode.h
src/titlewidget.cpp

index 273b2f083bd87cab7c3eedd44232da2cf9f28ae5..91ced7ca7da5205cdf1e8c18194ea7118bbed7ba 100644 (file)
@@ -69,6 +69,11 @@ ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, GenT
         m_view.clip_position->setValidator(valid);
         m_view.end_position->setInputMask("");
         m_view.clip_position->setValidator(valid);
+    } else {
+        m_view.clip_position->setInputMask(m_tc.inputMask());
+        m_view.crop_position->setInputMask(m_tc.inputMask());
+        m_view.clip_duration->setInputMask(m_tc.inputMask());
+        m_view.end_position->setInputMask(m_tc.inputMask());
     }
     m_view.clip_position->setText(tc.getDisplayTimecode(m_clip->startPos(), m_framesDisplay));
     m_view.crop_position->setText(tc.getDisplayTimecode(m_clip->cropStart(), m_framesDisplay));
index 89dcc6dc39978238d10a4a7780fc037ba5885dee..4b8c9dc509da218d68670de05030740a7383b93c 100644 (file)
@@ -265,6 +265,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
         m_view.clip_filesize->setHidden(true);
         m_view.label_size->setHidden(true);
     }
+    m_view.clip_duration->setInputMask(tc.inputMask());
     m_view.clip_duration->setText(tc.getTimecode(m_clip->duration()));
     if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
     else connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
index e0749817a1d0474e893c8debc2be6116465bd796..2b4aa3bc76f0103098343ce981a54e59cd88d50f 100644 (file)
@@ -131,7 +131,7 @@ void DvdWizardChapters::slotRemoveChapter()
 
 void DvdWizardChapters::slotGoToChapter()
 {
-    m_monitor->setTimePos(m_view.chapters_list->currentItem()->text() + ":00");
+    m_monitor->setTimePos(m_tc.reformatSeparators(m_view.chapters_list->currentItem()->text() + ":00"));
 }
 
 void DvdWizardChapters::setVobFiles(bool isPal, bool isWide, const QStringList movies, const QStringList durations, const QStringList chapters)
index 4a1a0c670d46e5b628c5337125f13e86c3db3c7d..84a74679bf9758b9cf77adef707b036920e96b52 100644 (file)
@@ -1844,6 +1844,7 @@ void MainWindow::slotEditProjectSettings()
 
             m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeDocument->tracksList());
             m_effectStack->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode());
+            m_projectList->updateProjectFormat(m_activeDocument->timecode());
             if (m_renderWidget) m_renderWidget->setProfile(m_activeDocument->mltProfile());
             m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
             //m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList());
@@ -1851,6 +1852,8 @@ void MainWindow::slotEditProjectSettings()
             if (updateFps) m_activeTimeline->updateProjectFps();
             m_activeDocument->setModified(true);
             m_commandStack->activeStack()->clear();
+            //Update the mouse position display so it will display in DF/NDF format by default based on the project setting.
+            slotUpdateMousePosition(0);
             // We need to desactivate & reactivate monitors to get a refresh
             //m_monitorManager->switchMonitors();
         }
@@ -2082,7 +2085,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     m_activeTimeline->updateProjectFps();
     m_activeDocument->checkProjectClips();
     if (KdenliveSettings::dropbframes()) slotUpdatePreviewSettings();
-
+    //Update the mouse position display so it will display in DF/NDF format by default based on the project setting.
+    slotUpdateMousePosition(0);
     // set tool to select tool
     m_buttonSelectTool->setChecked(true);
 }
index 64bc1ee9eeeb8eca84cc4f30a57c62f1bb2f83fc..2f9ff112928e55f7f144f3fbc9c7d60a9e39ec3b 100644 (file)
@@ -87,7 +87,7 @@ MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, cons
         QValidator *valid = new QIntValidator(this);
         marker_position->setInputMask("");
         marker_position->setValidator(valid);
-    }
+    } else marker_position->setInputMask(tc.inputMask());
     marker_position->setText(tc.getDisplayTimecode(t.time(), m_frameDisplay));
 
     marker_comment->setText(t.comment());
index 912df46e763d7807ecef0a5888d3e2ba6f2b0977..9504ec4fcc1147e78a36e226f1541ac581389693 100644 (file)
@@ -118,7 +118,8 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget
     if (m_frametimecode) {
         m_timePos->setInputMask(QString());
         m_timePos->setValidator(new QIntValidator(this));
-    } else m_timePos->setInputMask("99:99:99:99");
+    } else m_timePos->setInputMask(m_monitorManager->timecode().inputMask());
+    
     toolbar->addWidget(m_timePos);
 
     connect(m_timePos, SIGNAL(editingFinished()), this, SLOT(slotSeek()));
@@ -844,7 +845,7 @@ void Monitor::updateTimecodeFormat()
     } else {
         int pos = m_timePos->text().toInt();
         m_timePos->setValidator(0);
-        m_timePos->setInputMask("99:99:99:99");
+        m_timePos->setInputMask(m_monitorManager->timecode().inputMask());
         m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(pos));
     }
 }
index 968de22e77b26f6962f0b9c3893d210ee16a7347..9348c9de88e1a1026d0b53c299404cf3092bcebc 100644 (file)
@@ -165,8 +165,10 @@ void MonitorManager::slotResetProfiles()
     if (m_projectMonitor == NULL || m_clipMonitor == NULL) return;
     activateMonitor("clip");
     m_clipMonitor->resetProfile(KdenliveSettings::current_profile());
+    m_clipMonitor->updateTimecodeFormat();
     activateMonitor("project");
     m_projectMonitor->resetProfile(KdenliveSettings::current_profile());
+    m_projectMonitor->updateTimecodeFormat();
     //m_projectMonitor->refreshMonitor(true);
 }
 
index a0618d18cf7d13098c98ff7f2215ce014825030a..2c33398a9aaec6ef929a3705d25b86589a0c31bd 100644 (file)
@@ -202,6 +202,11 @@ void ProjectList::setHeaderInfo(const QByteArray &state)
     m_listView->header()->restoreState(state);
 }
 
+void ProjectList::updateProjectFormat(Timecode t)
+{
+    m_timecode = t;
+}
+
 void ProjectList::slotEditClip()
 {
     QList<QTreeWidgetItem *> list = m_listView->selectedItems();
@@ -978,7 +983,8 @@ void ProjectList::slotAddColorClip()
     dia_ui.setupUi(dia);
     dia->setWindowTitle(i18n("Color Clip"));
     dia_ui.clip_name->setText(i18n("Color Clip"));
-    dia_ui.clip_duration->setText(KdenliveSettings::color_duration());
+    dia_ui.clip_duration->setInputMask(m_timecode.inputMask());
+    dia_ui.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::color_duration()));
     if (dia->exec() == QDialog::Accepted) {
         QString color = dia_ui.clip_color->color().name();
         color = color.replace(0, 1, "0x") + "ff";
index a3e31063cb9102d8d30b815c2415dc2eb2eb1568..ac8c509a8c579aaf3ce98575f0f0e9e575cb7364 100644 (file)
@@ -140,6 +140,7 @@ public:
     void slotUpdateClipProperties(const QString &id, QMap <QString, QString> properties);
     QByteArray headerInfo() const;
     void setHeaderInfo(const QByteArray &state);
+    void updateProjectFormat(Timecode t);
     void setupMenu(QMenu *addMenu, QAction *defaultAction);
     void setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu);
     QString currentClipUrl() const;
index 620cc4cbb6261adcac023a768a874c6d4a294524..04c2914d7db9a84833573dfa04a804759fea3888 100644 (file)
@@ -52,8 +52,11 @@ SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) :
     m_view.image_type->addItem("TGA (*.tga)", "tga");
     m_view.image_type->addItem("TIFF (*.tiff)", "tiff");
     m_view.image_type->addItem("Open EXR (*.exr)", "exr");
-    m_view.clip_duration->setText(KdenliveSettings::image_duration());
-    m_view.luma_duration->setText("00:00:00:24");
+    
+    m_view.clip_duration->setInputMask(m_timecode.inputMask());
+    m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::image_duration()));
+    m_view.luma_duration->setInputMask(m_timecode.inputMask());
+    m_view.luma_duration->setText(m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))));
     m_view.folder_url->setUrl(QDir::homePath());
 
     m_view.clip_duration_format->addItem(i18n("hh:mm:ss::ff"));
@@ -225,7 +228,9 @@ void SlideshowClip::slotUpdateDurationFormat(int ix)
         m_view.luma_duration_frames->setValue(m_timecode.getFrameCount(m_view.luma_duration->text()));
     } else {
         // switching to timecode format
+        m_view.clip_duration->setInputMask(m_timecode.inputMask());
         m_view.clip_duration->setText(m_timecode.getTimecodeFromFrames(m_view.clip_duration_frames->value()));
+        m_view.luma_duration->setInputMask(m_timecode.inputMask());
         m_view.luma_duration->setText(m_timecode.getTimecodeFromFrames(m_view.luma_duration_frames->value()));
     }
     m_view.clip_duration_frames->setHidden(!framesFormat);
index 1b25df21f13adaf5a5de50bd488ab890d36c4cab..5be3c3f6fdeb4f9341809382dac544e27e73c835 100644 (file)
@@ -36,6 +36,24 @@ double Timecode::fps() const
     return m_realFps; //m_displayedFramesPerSecond;
 }
 
+bool Timecode::df() const
+{
+    return m_dropFrame;
+}
+
+QString Timecode::inputMask() const
+{
+    if (m_dropFrame) return "99:99.99:99";
+    return "99:99:99:99";
+}
+
+QString Timecode::reformatSeparators(QString duration) const
+{
+    if (m_dropFrame) {
+        return duration.replace(5, 1, '.');
+    }
+    return duration.replace(5, 1, ':');
+}
 
 int Timecode::getDisplayFrameCount(const QString duration, bool frameDisplay) const
 {
@@ -46,30 +64,25 @@ int Timecode::getDisplayFrameCount(const QString duration, bool frameDisplay) co
 int Timecode::getFrameCount(const QString duration) const
 {
     if (m_dropFrame) {
-        // calculate how many frames need to be dropped every minute.
-        int frames;
-        int toDrop = (int) floor(600.0 * (m_displayedFramesPerSecond - m_realFps)  + 0.5);
-
-        int perMinute = toDrop / 9;
-        int tenthMinute = toDrop % 9;
-
-        // calculate how many frames are in a normal minute, and how many are in a tenth minute.
-        int normalMinuteFrames = (m_displayedFramesPerSecond * 60) - perMinute;
-        int tenthMinuteFrames = (m_displayedFramesPerSecond * 60) - tenthMinute;;
-
-        // Number of actual frames in a 10 minute interval :
-        int tenMinutes = (normalMinuteFrames * 9) + tenthMinuteFrames;
-        frames = 6 * duration.section(':', 0, 0).toInt() * tenMinutes;
-        int minutes = duration.section(':', 1, 1).toInt();
-        frames += ((int) minutes / 10) * tenMinutes;
-        int mins = minutes % 10;
-        if (mins > 0) {
-            frames += tenthMinuteFrames;
-            mins--;
-            if (mins > 0) frames += mins * normalMinuteFrames;
+        //Get Hours, Minutes, Seconds, Frames from timecode
+        int hours, minutes, seconds, frames;
+        
+        hours = duration.section(':', 0, 0).toInt();
+        if (duration.contains('.')) {
+            minutes = duration.section('.', 0, 0).section(':', 1, 1).toInt();
+            seconds = duration.section('.', 1, 1).section(':', 0, 0).toInt();
+            frames = duration.section('.', 1, 1).section(':', 1, 1).toInt();
+        } else {
+            //Handle Drop Frame timecode frame calculations, even if the timecode supplied uses incorrect "99:99:99:99" format instead of "99:99.99:99"
+            minutes = duration.section(':', 1, 1).toInt();
+            seconds = duration.section(':', 2, 2).toInt();
+            frames = duration.section(':', 3, 3).toInt();
         }
-        if (minutes % 10 > 0) frames -= perMinute;
-        frames += duration.section(':', 2, 2).toInt() * m_displayedFramesPerSecond + duration.section(':', 3, 3).toInt();
+        
+        //Calculate the frame count
+        int dropRate = (int) ((ceil(m_displayedFramesPerSecond) / 30) * 2);
+        frames += ((hours * 60 + minutes) * 60 + seconds) * m_displayedFramesPerSecond;
+        frames -= dropRate * ((hours * 60 + minutes) - (floor((hours * 60 + minutes) / 10)));
         return frames;
     }
     return (int)((duration.section(':', 0, 0).toInt()*3600.0 + duration.section(':', 1, 1).toInt()*60.0 + duration.section(':', 2, 2).toInt()) * m_realFps + duration.section(':', 3, 3).toInt());
@@ -229,9 +242,13 @@ QString Timecode::getTimecodeHH_MM_SS_HH(const GenTime & time) const
     text.append(QString::number(hours).rightJustified(2, '0', false));
     text.append(':');
     text.append(QString::number(minutes).rightJustified(2, '0', false));
-    text.append(':');
+    if (m_dropFrame) {
+           text.append('.');
+    } else {
+        text.append(':');
+    }
     text.append(QString::number(seconds).rightJustified(2, '0', false));
-    text.append(':');
+       text.append(':');
     text.append(QString::number(hundredths).rightJustified(2, '0', false));
 
     return text;
@@ -258,14 +275,14 @@ QString Timecode::getTimecodeDropFrame(int frames) const
     // for NTSC times, but is untested for any others - it is in no way an "official" algorithm, unless it's by fluke.
 
     // calculate how many frames need to be dropped every minute.
-    int toDrop = (int) floor(600.0 * (m_displayedFramesPerSecond - m_realFps)  + 0.5);
-
-    int perMinute = toDrop / 9;
-    int tenthMinute = toDrop % 9;
+    int dropRate = 0;
+    if (m_dropFrame) {
+        dropRate = (int) ((ceil(m_displayedFramesPerSecond) / 30) * 2);
+    }
 
     // calculate how many frames are in a normal minute, and how many are in a tenth minute.
-    int normalMinuteFrames = (m_displayedFramesPerSecond * 60) - perMinute;
-    int tenthMinuteFrames = (m_displayedFramesPerSecond * 60) - tenthMinute;;
+    int normalMinuteFrames = (m_displayedFramesPerSecond * 60) - dropRate;
+    int tenthMinuteFrames = (m_displayedFramesPerSecond * 60);
 
     // Number of actual frames in a 10 minute interval :
     int tenMinutes = (normalMinuteFrames * 9) + tenthMinuteFrames;
@@ -287,7 +304,7 @@ QString Timecode::getTimecodeDropFrame(int frames) const
         // normal minute logic applies.
         numMinutes = 1 + (frames - tenthMinuteFrames) / normalMinuteFrames;
         frames = (frames - tenthMinuteFrames) % normalMinuteFrames;
-        frames +=  tenthMinute + perMinute;
+        frames +=  dropRate;
     }
     // We now have HH:MM:??:??
 
@@ -303,9 +320,13 @@ QString Timecode::getTimecodeDropFrame(int frames) const
     text.append(':');
     text.append(QString::number(tenMinuteIntervals));
     text.append(QString::number(numMinutes));
-    text.append(':');
+    if (m_dropFrame) {
+           text.append('.');
+    } else {
+        text.append(':');
+    }
     text.append(QString::number(seconds).rightJustified(2, '0', false));
-    text.append(':');
+       text.append(':');
     text.append(QString::number(frames).rightJustified(2, '0', false));
 
     return text;
index e10ae4af767ba4a10b8c55408113678f6a55c24c..3fac06441cbaccbeafa7037c4f543322f766955e 100644 (file)
@@ -58,6 +58,9 @@ public:
     const QString getDisplayTimecodeFromFrames(int frames, bool frameDisplay) const;
     const QString getTimecodeFromFrames(int frames) const;
     double fps() const;
+    bool df() const;
+    QString inputMask() const;
+    QString reformatSeparators(QString duration) const;
 
 private:
     Formats m_format;
index 7872fff89b6ccb156afb3a2209df494b85b8b9ae..05c5ad72e29cffa7d4e69193738aeb0a77bec81e 100644 (file)
@@ -142,6 +142,9 @@ TitleWidget::TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render
     m_frameHeight = render->renderHeight();
     showToolbars(TITLE_SELECT);
 
+    //If project is drop frame, set the input mask as such.
+    title_duration->setInputMask(m_tc.inputMask());
+
     //TODO: get default title duration instead of hardcoded one
     title_duration->setText(m_tc.getTimecode(GenTime(5000 / 1000.0)));