Commit 737e798c authored by Boudewijn Rempt's avatar Boudewijn Rempt

Finish implementing the animation renderer

The right extension is now always used, and if the codecs are
there, ffmpeg will render the animation.

For the future, we should probably implement a way to set the
framerate for animation...
parent f2ee040b
......@@ -131,7 +131,7 @@ DlgAnimationRenderer::DlgAnimationRenderer(KisDocument *doc, QWidget *parent)
connect(m_page->grpRender, SIGNAL(toggled(bool)), this, SLOT(toggleSequenceType(bool)));
connect(m_page->bnExportOptions, SIGNAL(clicked()), this, SLOT(sequenceMimeTypeSelected()));
connect(m_page->bnRenderOptions, SIGNAL(clicked()), this, SLOT(selectRenderType()));
connect(m_page->bnRenderOptions, SIGNAL(clicked()), this, SLOT(selectRenderOptions()));
m_page->ffmpegLocation->setFileName(findFFMpeg());
m_page->ffmpegLocation->setMode(KoFileDialog::OpenFile);
......@@ -140,8 +140,7 @@ DlgAnimationRenderer::DlgAnimationRenderer(KisDocument *doc, QWidget *parent)
m_page->grpRender->setChecked(cfg.readEntry<bool>("AnimationRenderer/render_animation", false));
m_page->chkDeleteSequence->setChecked(cfg.readEntry<bool>("AnimationRenderer/delete_sequence", false));
m_page->cmbRenderType->setCurrentIndex(cfg.readEntry<int>("AnimationRenderer/render_type", 0));
connect(m_page->cmbRenderType, SIGNAL(currentIndexChanged(int)), this, SLOT(selectRenderType(int)));
}
DlgAnimationRenderer::~DlgAnimationRenderer()
......@@ -203,6 +202,7 @@ KisPropertiesConfigurationSP DlgAnimationRenderer::getFrameExportConfiguration()
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
cfg->setProperty("ffmpeg_path", m_page->ffmpegLocation->fileName());
return m_frameExportConfigWidget->configuration();
}
......@@ -220,7 +220,12 @@ KisPropertiesConfigurationSP DlgAnimationRenderer::getVideoConfiguration() const
return 0;
}
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
cfg->setProperty("filename", m_page->videoFilename->fileName());
QString filename = m_page->videoFilename->fileName();
if (QFileInfo(filename).completeSuffix().isEmpty()) {
QString mimetype = m_page->cmbRenderType->itemData(m_page->cmbRenderType->currentIndex()).toString();
filename += "." + KisMimeDatabase::suffixesForMimeType(mimetype).first();
}
cfg->setProperty("filename", filename);
cfg->setProperty("delete_sequence", m_page->chkDeleteSequence->isChecked());
return cfg;
}
......@@ -260,7 +265,19 @@ QSharedPointer<KisImportExportFilter> DlgAnimationRenderer::encoderFilter() cons
return QSharedPointer<KisImportExportFilter>(0);
}
void DlgAnimationRenderer::selectRenderType()
void DlgAnimationRenderer::selectRenderType(int index)
{
if (index >= m_renderFilters.size()) return;
QString mimetype = m_page->cmbRenderType->itemData(index).toString();
if (!m_page->videoFilename->fileName().isEmpty() && QFileInfo(m_page->videoFilename->fileName()).completeBaseName() != m_defaultFileName) {
m_defaultFileName = QFileInfo(m_page->videoFilename->fileName()).completeBaseName();
}
m_page->videoFilename->setMimeTypeFilters(QStringList() << mimetype, mimetype);
m_page->videoFilename->setFileName(m_defaultFileName + "." + KisMimeDatabase::suffixesForMimeType(mimetype).first());
}
void DlgAnimationRenderer::selectRenderOptions()
{
int index = m_page->cmbRenderType->currentIndex();
......@@ -273,13 +290,6 @@ void DlgAnimationRenderer::selectRenderType()
QSharedPointer<KisImportExportFilter> filter = m_renderFilters[index];
QString mimetype = m_page->cmbRenderType->itemData(index).toString();
if (!m_page->videoFilename->fileName().isEmpty() && QFileInfo(m_page->videoFilename->fileName()).completeBaseName() != m_defaultFileName) {
m_defaultFileName = QFileInfo(m_page->videoFilename->fileName()).completeBaseName();
}
m_page->videoFilename->setMimeTypeFilters(QStringList() << mimetype, mimetype);
m_page->videoFilename->setFileName(m_defaultFileName + "." + KisMimeDatabase::suffixesForMimeType(mimetype).first());
if (filter) {
m_encoderConfigWidget = filter->createConfigurationWidget(0, KisDocument::nativeFormatMimeType(), mimetype.toLatin1());
if (m_encoderConfigWidget) {
......@@ -298,6 +308,7 @@ void DlgAnimationRenderer::selectRenderType()
else {
m_encoderConfigWidget = 0;
}
}
void DlgAnimationRenderer::toggleSequenceType(bool toggle)
......
......@@ -70,7 +70,8 @@ public:
private Q_SLOTS:
void selectRenderType();
void selectRenderType(int i);
void selectRenderOptions();
void toggleSequenceType(bool toggle);
void sequenceMimeTypeSelected();
void ffmpegLocationChanged(const QString&);
......
......@@ -58,20 +58,29 @@ KisVideoExport::~KisVideoExport()
KisImportExportFilter::ConversionStatus KisVideoExport::convert(KisDocument *document, QIODevice */*io*/, KisPropertiesConfigurationSP configuration)
{
VideoSaver videoSaver(document, batchMode());
if (!videoSaver.hasFFMpeg()) {
const QString warningMessage =
i18n("Could not find \'ffmpeg\' binary. Saving to video formats is impossible.");
if (!batchMode()) {
QMessageBox::critical(KisPart::instance()->currentMainwindow(),
i18n("Video Export Error"),
warningMessage);
QString ffmpegPath = configuration->getString("ffmpeg_path");
if (ffmpegPath.isEmpty()) {
KisConfig cfg;
ffmpegPath = cfg.customFFMpegPath();
if (ffmpegPath.isEmpty()) {
const QString warningMessage =
i18n("Could not find \'ffmpeg\' binary. Saving to video formats is impossible.");
if (!batchMode()) {
QMessageBox::critical(KisPart::instance()->currentMainwindow(),
i18n("Video Export Error"),
warningMessage);
}
else {
qWarning() << warningMessage;
}
return KisImportExportFilter::UsageError;
}
return KisImportExportFilter::UsageError;
}
VideoSaver videoSaver(document, ffmpegPath, batchMode());
KisImageBuilder_Result res = videoSaver.encode(filename(), configuration);
if (res == KisImageBuilder_RESULT_OK) {
......
......@@ -123,6 +123,8 @@ public:
<< "-progress" << progressFile.fileName()
<< specialArgs;
qDebug() << "\t" << m_ffmpegPath << args.join(" ");
m_cancelled = false;
m_process.start(m_ffmpegPath, args);
return waitForFFMpegProcess(actionName, progressFile, m_process, totalFrames);
......@@ -147,7 +149,7 @@ private:
progress.setCancelButton(0);
progress.setMinimumDuration(0);
progress.setValue(0);
progress.setRange(0,100);
progress.setRange(0, 100);
QEventLoop loop;
loop.connect(&watcher, SIGNAL(sigProcessingFinished()), SLOT(quit()));
......@@ -180,12 +182,12 @@ private:
};
VideoSaver::VideoSaver(KisDocument *doc, bool batchMode)
VideoSaver::VideoSaver(KisDocument *doc, const QString &ffmpegPath, bool batchMode)
: m_image(doc->image())
, m_doc(doc)
, m_batchMode(batchMode)
, m_ffmpegPath(findFFMpeg())
, m_runner(new KisFFMpegRunner(m_ffmpegPath))
, m_ffmpegPath(ffmpegPath)
, m_runner(new KisFFMpegRunner(ffmpegPath))
{
}
......@@ -203,47 +205,18 @@ bool VideoSaver::hasFFMpeg() const
return !m_ffmpegPath.isEmpty();
}
QString VideoSaver::findFFMpeg()
KisImageBuilder_Result VideoSaver::encode(const QString &filename, KisPropertiesConfigurationSP configuration)
{
QString result;
QStringList proposedPaths;
QString customPath = KisConfig().customFFMpegPath();
proposedPaths << customPath;
proposedPaths << customPath + QDir::separator() + "ffmpeg";
proposedPaths << "ffmpeg";
proposedPaths << KoResourcePaths::getApplicationRoot() +
QDir::separator() + "bin" + QDir::separator() + "ffmpeg";
dbgFile << "ffmpeg" << m_ffmpegPath << "filename" << filename << "configuration" << configuration->toXML();
Q_FOREACH (const QString &path, proposedPaths) {
if (path.isEmpty()) continue;
QProcess testProcess;
testProcess.start(path, QStringList() << "-version");
testProcess.waitForFinished(1000);
const bool successfulStart =
testProcess.state() == QProcess::NotRunning &&
testProcess.error() == QProcess::UnknownError;
if (successfulStart) {
result = path;
break;
if (m_ffmpegPath.isEmpty()) {
m_ffmpegPath = configuration->getString("ffmpeg_path");
if (!QFileInfo(m_ffmpegPath).exists()) {
return KisImageBuilder_RESULT_FAILURE;
}
}
return result;
}
KisImageBuilder_Result VideoSaver::encode(const QString &filename, KisPropertiesConfigurationSP configuration)
{
//qDebug() << "ffmpeg" << m_ffmpegPath << "filename" << filename << "configuration" << configuration->toXML();
if (m_ffmpegPath.isEmpty()) return KisImageBuilder_RESULT_FAILURE;
KisImageBuilder_Result result = KisImageBuilder_RESULT_OK;
KisImageAnimationInterface *animation = m_image->animationInterface();
......@@ -276,7 +249,7 @@ KisImageBuilder_Result VideoSaver::encode(const QString &filename, KisProperties
framesDir.filePath("log_generate_palette_gif.log"),
clipRange.duration() + clipRange.start());
if (result) {
if (result != KisImageBuilder_RESULT_OK) {
return result;
}
}
......@@ -290,12 +263,14 @@ KisImageBuilder_Result VideoSaver::encode(const QString &filename, KisProperties
<< additionalOptionsList
<< "-y" << resultFile;
dbgFile << "savedFilesMask" << savedFilesMask << "start" << clipRange.start() << "duration" << clipRange.duration();
KisImageBuilder_Result result =
m_runner->runFFMpeg(args, i18n("Encoding frames..."),
framesDir.filePath("log_encode_gif.log"),
clipRange.duration() + clipRange.start());
if (result) {
if (result != KisImageBuilder_RESULT_OK) {
return result;
}
}
......
......@@ -38,7 +38,7 @@ class KRITAVIDEOEXPORT_EXPORT VideoSaver : public QObject {
Q_OBJECT
public:
VideoSaver(KisDocument* doc, bool batchMode);
VideoSaver(KisDocument* doc, const QString &ffmpegPath, bool batchMode);
virtual ~VideoSaver();
KisImageSP image();
......@@ -49,9 +49,6 @@ public:
private Q_SLOTS:
void cancel();
private:
static QString findFFMpeg();
private:
KisImageSP m_image;
KisDocument* m_doc;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment