aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2016-05-25 09:30:18 +0200
committerJean-Baptiste Mardelle <[email protected]>2016-05-25 09:30:18 +0200
commit07b44df26b4f0267a38c72a10c8db419f5374a15 (patch)
treee8cf4df79ff4d1ad686a86ea8105a7a0bc82d8f4
parent814841cb27a24189b054730955ba9a1706cf821f (diff)
Correctly detect and delete preview files if rendering profile is wrong and creates empty files
Fix preview rendering shown as 99 hours whenever it was estimated to 1h add some documentation comments
-rw-r--r--src/mainwindow.cpp37
-rw-r--r--src/timeline/managers/previewmanager.cpp11
-rw-r--r--src/timeline/managers/previewmanager.h29
3 files changed, 53 insertions, 24 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 021dfcd..fde52bc 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -128,7 +128,7 @@ MyToolButton::~MyToolButton()
void MyToolButton::setProgress(int progress)
{
int prog = (width() - 6) * (double) progress / 1000;
- if (m_timer.isValid()) {
+ if (m_timer.isValid() && progress > 0) {
// calculate remaining time
qint64 ms = m_timer.elapsed() * (1000.0 / progress - 1);
if (ms < 60000)
@@ -138,33 +138,34 @@ void MyToolButton::setProgress(int progress)
// xgettext:no-c-format
m_remainingTime = i18nc("m as minutes", "%1m", ms / 60000);
else {
- m_remainingTime = i18nc("h as hours", "%1h", qMax(99, (int) (ms / 3600000)));
+ m_remainingTime = i18nc("h as hours", "%1h", qMin(99, (int) (ms / 3600000)));
}
}
- if (prog == m_progress)
- return;
if (progress < 0) {
if (m_defaultAction)
setDefaultAction(m_defaultAction);
m_remainingTime.clear();
m_timer.invalidate();
m_progress = -1;
- } else {
- if (!m_timer.isValid() || progress == 0) {
- if (!m_defaultAction) {
- m_defaultAction = defaultAction();
- }
- setDefaultAction(m_dummyAction);
- m_timer.start();
- }
- if (progress == 1000) {
- if (m_defaultAction)
- setDefaultAction(m_defaultAction);
- m_remainingTime.clear();
- m_timer.invalidate();
+ update();
+ return;
+ }
+ if (prog == m_progress)
+ return;
+ if (!m_timer.isValid() || progress == 0) {
+ if (!m_defaultAction) {
+ m_defaultAction = defaultAction();
}
- m_progress = prog;
+ setDefaultAction(m_dummyAction);
+ m_timer.start();
+ }
+ if (progress == 1000) {
+ if (m_defaultAction)
+ setDefaultAction(m_defaultAction);
+ m_remainingTime.clear();
+ m_timer.invalidate();
}
+ m_progress = prog;
update();
}
diff --git a/src/timeline/managers/previewmanager.cpp b/src/timeline/managers/previewmanager.cpp
index 7999824..d9b9ae2 100644
--- a/src/timeline/managers/previewmanager.cpp
+++ b/src/timeline/managers/previewmanager.cpp
@@ -208,7 +208,7 @@ void PreviewManager::invalidatePreviews(QList <int> chunks)
}
}
qSort(foundChunks);
- slotReloadChunks(m_cacheDir, foundChunks, m_extension);
+ reloadChunks(foundChunks);
}
m_doc->setModified(true);
if (timer)
@@ -317,7 +317,7 @@ void PreviewManager::doPreviewRender(QString scene)
previewProcess.start(KdenliveSettings::rendererpath(), args);
if (previewProcess.waitForStarted()) {
previewProcess.waitForFinished(-1);
- if (previewProcess.exitStatus() != QProcess::NormalExit) {
+ if (previewProcess.exitStatus() != QProcess::NormalExit || previewProcess.exitCode() != 0) {
// Something went wrong
if (m_abortPreview) {
emit previewRender(0, QString(), 1000);
@@ -330,6 +330,9 @@ void PreviewManager::doPreviewRender(QString scene)
} else {
emit previewRender(i, m_cacheDir.absoluteFilePath(fileName), progress);
}
+ } else {
+ emit previewRender(i, QString(), -1);
+ break;
}
}
QFile::remove(scene);
@@ -389,12 +392,12 @@ void PreviewManager::invalidatePreview(int startFrame, int endFrame)
m_previewGatherTimer.start();
}
-void PreviewManager::slotReloadChunks(QDir cacheDir, QList <int> chunks, const QString ext)
+void PreviewManager::reloadChunks(QList <int> chunks)
{
m_tractor->lock();
foreach(int ix, chunks) {
if (m_previewTrack->is_blank_at(ix)) {
- const QString fileName = cacheDir.absoluteFilePath(QString("%1.%2").arg(ix).arg(ext));
+ const QString fileName = m_cacheDir.absoluteFilePath(QString("%1.%2").arg(ix).arg(m_extension));
Mlt::Producer prod(*m_tractor->profile(), 0, fileName.toUtf8().constData());
if (prod.is_valid()) {
m_ruler->updatePreview(ix, true);
diff --git a/src/timeline/managers/previewmanager.h b/src/timeline/managers/previewmanager.h
index d16ef12..2cc9174 100644
--- a/src/timeline/managers/previewmanager.h
+++ b/src/timeline/managers/previewmanager.h
@@ -38,6 +38,11 @@ namespace Mlt {
/**
* @namespace PreviewManager
* @brief Handles timeline preview.
+ * This manager creates an additionnal video track on top of the current timeline and renders
+ * chunks (small video files of 25 frames) that are added on this track when rendrerd.
+ * This allow us to get a preview with a smooth playback of our project.
+ * Only the preview zone is rendered. Once defined, a preview zone shows as a red line below
+ * the timeline ruler. As chunks are rendered, the zone turns to green.
*/
class PreviewManager : public QObject
@@ -49,14 +54,23 @@ public:
virtual ~PreviewManager();
/** @brief: initialize base variables, return false if error. */
bool initialize();
+ /** @brief: a timeline operation caused changes to frames between startFrame and endFrame. */
+ void invalidatePreview(int startFrame, int endFrame);
+ /** @brief: after a small delay (some operations trigger several invalidatePreview calls), take care of these invalidated chunks. */
void invalidatePreviews(QList <int> chunks);
+ /** @brief: user adds current timeline zone to the preview zone. */
void addPreviewRange(bool add);
+ /** @brief: stops current rendering process. */
void abortRendering();
+ /** @brief: rendering parameters have changed, reload them. */
bool loadParams();
- void invalidatePreview(int startFrame, int endFrame);
+ /** @brief: Create the preview track if not existing. */
bool buildPreviewTrack();
+ /** @brief: Whenever we save or render our project, we remove the preview track so it is not saved. */
void reconnectTrack();
+ /** @brief: After project save or render, re-add our preview track. */
void disconnectTrack();
+ /** @brief: Returns directory currently used to store the preview files. */
const QDir getCacheDir() const;
private:
@@ -64,27 +78,38 @@ private:
CustomRuler *m_ruler;
Mlt::Tractor *m_tractor;
Mlt::Playlist *m_previewTrack;
+ /** @brief: The directory used to store the preview files. */
QDir m_cacheDir;
+ /** @brief: The directory used to store undo history of preview files (child of m_cacheDir). */
QDir m_undoDir;
QMutex m_previewMutex;
QStringList m_consumerParams;
QString m_extension;
+ /** @brief: Timer used to autostart preview rendering. */
QTimer m_previewTimer;
+ /** @brief: Since some timeline operations generate several invalidate calls, use a timer to get them all. */
QTimer m_previewGatherTimer;
bool m_initialized;
bool m_abortPreview;
QList <int> m_waitingThumbs;
QFuture <void> m_previewThread;
+ /** @brief: After an undo/redo, if we have preview history, use it. */
+ void reloadChunks(QList <int> chunks);
private slots:
+ /** @brief: To avoid filling the hard drive, remove preview undo history after 5 steps. */
void doCleanupOldPreviews();
+ /** @brief: Start the real rendering process. */
void doPreviewRender(QString scene);
+ /** @brief: If user does an undo, then makes a new timeline operation, delete undo history of more recent stack . */
void slotRemoveInvalidUndo(int ix);
- void slotReloadChunks(QDir cacheDir, QList <int> chunks, const QString ext);
+ /** @brief: When the timer collecting invalid zones is done, process. */
void slotProcessDirtyChunks();
public slots:
+ /** @brief: Prepare and start rendering. */
void startPreviewRender();
+ /** @brief: A chunk has been created, notify ruler. */
void gotPreviewRender(int frame, const QString &file, int progress);
signals: