From a97b0c01710b048ff8e8640378457f410f77321c Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Thu, 28 Aug 2008 17:53:43 +0000 Subject: [PATCH] * new: thumbnailer for preview of kdenlive/westley files in KDE4 apps svn path=/branches/KDE4/; revision=2386 --- CMakeLists.txt | 1 + src/mimetypes/westley.xml | 2 +- thumbnailer/CMakeLists.txt | 17 +++ thumbnailer/westleypreview.cpp | 202 +++++++++++++++++++++++++++++ thumbnailer/westleypreview.desktop | 8 ++ thumbnailer/westleypreview.h | 62 +++++++++ 6 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 thumbnailer/CMakeLists.txt create mode 100644 thumbnailer/westleypreview.cpp create mode 100644 thumbnailer/westleypreview.desktop create mode 100644 thumbnailer/westleypreview.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e9b87f95..00e43f49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ find_program(XGETTEXT_EXECUTABLE xgettext) add_subdirectory(src src/cmake_bindir) add_subdirectory(renderer renderer/cmake_bindir) +add_subdirectory(thumbnailer thumbnailer/cmake_bindir) add_subdirectory(effects ) add_subdirectory(export ) add_subdirectory(icons ) diff --git a/src/mimetypes/westley.xml b/src/mimetypes/westley.xml index 80b99701..f2aa2162 100644 --- a/src/mimetypes/westley.xml +++ b/src/mimetypes/westley.xml @@ -2,7 +2,7 @@ MLT video playlist + - diff --git a/thumbnailer/CMakeLists.txt b/thumbnailer/CMakeLists.txt new file mode 100644 index 00000000..a56b8391 --- /dev/null +++ b/thumbnailer/CMakeLists.txt @@ -0,0 +1,17 @@ + + +########### next target ############### + +set(westleypreview_PART_SRCS westleypreview.cpp) + +kde4_add_plugin(westleypreview ${westleypreview_PART_SRCS}) + +target_link_libraries(westleypreview ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDEUI_LIBS} ${KDE4_KDECORE_LIBS}) + +install(TARGETS westleypreview DESTINATION ${PLUGIN_INSTALL_DIR}) + + +########### install files ############### + +install(FILES westleypreview.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/thumbnailer/westleypreview.cpp b/thumbnailer/westleypreview.cpp new file mode 100644 index 00000000..af1a58c0 --- /dev/null +++ b/thumbnailer/westleypreview.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + Copyright (C) 2006-2008 + by Marco Gulino + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "westleypreview.h" + +#define DBG_AREA + +//#include "config.h" +extern "C" +{ + KDE_EXPORT ThumbCreator *new_creator() + { + return new WestleyPreview; + } +} + +WestleyPreview::WestleyPreview() +{ +} + +WestleyPreview::~WestleyPreview() +{ + delete rand; + delete inigoprocess; +} + +bool WestleyPreview::startAndWaitProcess(const QStringList &args) { + kDebug(DBG_AREA) << "westleypreview: starting process with args: " << args << endl; + inigoprocess->start( args.join(" ") ); + if(! inigoprocess->waitForStarted() ) { + kDebug(DBG_AREA) << "westleypreview: PROCESS NOT STARTED!!! exiting\n"; + return false; + } + if(! inigoprocess->waitForFinished() ) { + kDebug(DBG_AREA) << "westleypreview: PROCESS DIDN'T FINISH!! exiting\n"; + inigoprocess->close(); + return false; + } + kDebug() << "westleypreview: process started and ended correctly\n"; + return true; +} + +bool WestleyPreview::create(const QString &path, int width, int height, QImage &img) +{ + QFileInfo fi(path); + /*if (fi.suffix().trimmed() != "westley" && fi.suffix().trimmed() != "kdenlive") + { + kDebug(DBG_AREA) << "westleypreview: matched extension " << fi.suffix().prepend('.') << "; exiting.\n"; + return false; + }*/ + playerBin=KStandardDirs::findExe("inigo"); + if(playerBin.isEmpty()) + { + kDebug(DBG_AREA) << "westleypreview: inigo not found, exiting.\n"; + return false; + } + + fileinfo.seconds=0; + fileinfo.fps=0; + + rand=new KRandomSequence(QDateTime::currentDateTime().toTime_t()); + inigoprocess=new QProcess(); + KUrl furl(path); + kDebug(DBG_AREA) << "videopreview: url=" << furl << "; local:" << furl.isLocalFile() << endl; + fileinfo.towidth=width; + fileinfo.toheight=height; + QPixmap pix; +// if(furl.isLocalFile()) +// { + QStringList args; + //TODO: modify inigo so that it can return some infos about a westley clip (duration, track number,fps,...) + // without actually playing the file +/* + args << playerBin << QString("\"" + path + "\"") << "-file-info"; + + kDebug(DBG_AREA) << "videopreview: starting process: --_" << " " << args.join(" ") << "_--\n"; + if (! startAndWaitProcess(args) ) return NULL; + + QString information=QString(inigoprocess->readAllStandardOutput() ); + QRegExp findInfos("ID_VIDEO_FPS=([\\d]*).*ID_LENGTH=([\\d]*).*"); + if(findInfos.indexIn( information) == -1 ) + { + kDebug(DBG_AREA) << "videopreview: No information found, exiting\n"; + return NULL; + } + fileinfo.seconds =findInfos.cap(2).toInt(); + fileinfo.fps=findInfos.cap(1).toInt(); + */ + fileinfo.seconds = 250; + fileinfo.fps = 25; + + //kDebug(DBG_AREA) << "videopreview: find length=" << fileinfo.seconds << ", fps=" << fileinfo.fps << endl; + + const int LASTTRY = 3; + for(int i=0; i<=LASTTRY; i++) + { + pix=getFrame(path); + if(!pix.isNull()) { + uint variance=imageVariance(pix.toImage()/*.bits(),( (width+ 7) & ~0x7), width, height, 1 */); + kDebug(DBG_AREA) << "videopreview: " << QFileInfo(path).fileName() << " frame variance: " << variance << "; " << + ((variance<=40 && ( i!=LASTTRY-1))? "!!!DROPPING!!!" : "GOOD :-)" ) << endl; + if(variance>40 || i==LASTTRY-1 ) break; + } + } + if(pix.isNull() ) + { + return false; + } + img = pix.toImage(); + return true; +} + +QPixmap WestleyPreview::getFrame(const QString &path) +{ + QStringList args; + #define START ((fileinfo.seconds*15)/100) + #define END ((fileinfo.seconds*70)/100) + args.clear(); + args << playerBin << "\"" + path + "\""; + if(fileinfo.towidth>fileinfo.toheight) fileinfo.toheight=-2; else fileinfo.towidth=-2; +// switch( flags ){ +// case random +// } + unsigned long start=(unsigned long)(START+(rand->getDouble() * (END - START) ) ); + args << QString("in=%1").arg(start)<< QString("out=%1").arg(start)<<"-consumer"; + + KTemporaryFile temp; + temp.setSuffix(".png"); + temp.open(); + args << QString("avformat:%1").arg(temp.fileName()) << "vframes=1"<< "f=rawvideo"<< "vcodec=png"<< QString("s=%1x%2").arg(fileinfo.towidth).arg(fileinfo.toheight); + if (! startAndWaitProcess(args) ) return NULL; + QPixmap retpix(temp.fileName()); + temp.close(); + return retpix; +} + + +uint WestleyPreview::imageVariance(QImage image ) +{ + uint delta=0; + uint avg=0; + uint bytes=image.numBytes(); + uint STEPS=bytes/2; + QVarLengthArray pivot(STEPS); + kDebug(DBG_AREA) << "Using " << STEPS << " steps\n"; + uchar *bits=image.bits(); + // First pass: get pivots and taking average + for( uint i=0; i + adapted for MLT video preview by Jean-Baptiste Mardelle + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + ***************************************************************************/ + + +#ifndef _westleypreview_H_ +#define _westleypreview_H_ + +#include +#include + +#include +#include + +class QProcess; +class Q3CString; +class KTempDir; +class KRandomSequence; +#include + + + +class WestleyPreview : public QObject, public ThumbCreator +{ +Q_OBJECT + public: + WestleyPreview(); + virtual ~WestleyPreview(); + virtual bool create(const QString &path, int width, int height, QImage &img); + protected: + QPixmap getFrame(const QString &path); + static uint imageVariance(QImage image ); + + private: + QPixmap m_pixmap; + QProcess *inigoprocess; + QStringList customargs; + KRandomSequence *rand; + QString playerBin; + bool startAndWaitProcess(const QStringList &args); + enum frameflags { framerandom=0x1, framestart=0x2, frameend=0x4 }; + struct { int towidth; int toheight; int fps; int seconds; } fileinfo; +}; + +#endif -- 2.39.2