1 /***************************************************************************
2 Copyright (C) 2006-2008
3 by Marco Gulino <marco@kmobiletools.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 ***************************************************************************/
24 #include <QtCore/QVarLengthArray>
26 #include <kstandarddirs.h>
27 #include <kmimetype.h>
30 #include <krandomsequence.h>
31 #include <qdatetime.h>
38 #include <qfileinfo.h>
40 #include <KTemporaryFile>
44 #include "westleypreview.h"
51 KDE_EXPORT ThumbCreator *new_creator()
53 return new WestleyPreview;
57 WestleyPreview::WestleyPreview()
61 WestleyPreview::~WestleyPreview()
67 bool WestleyPreview::startAndWaitProcess(const QStringList &args) {
68 kDebug(DBG_AREA) << "westleypreview: starting process with args: " << args << endl;
69 inigoprocess->start( args.join(" ") );
70 if(! inigoprocess->waitForStarted() ) {
71 kDebug(DBG_AREA) << "westleypreview: PROCESS NOT STARTED!!! exiting\n";
74 if(! inigoprocess->waitForFinished() ) {
75 kDebug(DBG_AREA) << "westleypreview: PROCESS DIDN'T FINISH!! exiting\n";
76 inigoprocess->close();
79 kDebug() << "westleypreview: process started and ended correctly\n";
83 bool WestleyPreview::create(const QString &path, int width, int height, QImage &img)
86 /*if (fi.suffix().trimmed() != "westley" && fi.suffix().trimmed() != "kdenlive")
88 kDebug(DBG_AREA) << "westleypreview: matched extension " << fi.suffix().prepend('.') << "; exiting.\n";
91 playerBin=KStandardDirs::findExe("inigo");
92 if(playerBin.isEmpty())
94 kDebug(DBG_AREA) << "westleypreview: inigo not found, exiting.\n";
101 rand=new KRandomSequence(QDateTime::currentDateTime().toTime_t());
102 inigoprocess=new QProcess();
104 kDebug(DBG_AREA) << "videopreview: url=" << furl << "; local:" << furl.isLocalFile() << endl;
105 fileinfo.towidth=width;
106 fileinfo.toheight=height;
108 // if(furl.isLocalFile())
111 //TODO: modify inigo so that it can return some infos about a westley clip (duration, track number,fps,...)
112 // without actually playing the file
114 args << playerBin << QString("\"" + path + "\"") << "-file-info";
116 kDebug(DBG_AREA) << "videopreview: starting process: --_" << " " << args.join(" ") << "_--\n";
117 if (! startAndWaitProcess(args) ) return NULL;
119 QString information=QString(inigoprocess->readAllStandardOutput() );
120 QRegExp findInfos("ID_VIDEO_FPS=([\\d]*).*ID_LENGTH=([\\d]*).*");
121 if(findInfos.indexIn( information) == -1 )
123 kDebug(DBG_AREA) << "videopreview: No information found, exiting\n";
126 fileinfo.seconds =findInfos.cap(2).toInt();
127 fileinfo.fps=findInfos.cap(1).toInt();
129 fileinfo.seconds = 250;
132 //kDebug(DBG_AREA) << "videopreview: find length=" << fileinfo.seconds << ", fps=" << fileinfo.fps << endl;
134 const int LASTTRY = 3;
135 for(int i=0; i<=LASTTRY; i++)
139 uint variance=imageVariance(pix.toImage()/*.bits(),( (width+ 7) & ~0x7), width, height, 1 */);
140 kDebug(DBG_AREA) << "videopreview: " << QFileInfo(path).fileName() << " frame variance: " << variance << "; " <<
141 ((variance<=40 && ( i!=LASTTRY-1))? "!!!DROPPING!!!" : "GOOD :-)" ) << endl;
142 if(variance>40 || i==LASTTRY-1 ) break;
153 QPixmap WestleyPreview::getFrame(const QString &path)
156 #define START ((fileinfo.seconds*15)/100)
157 #define END ((fileinfo.seconds*70)/100)
159 args << playerBin << "\"" + path + "\"";
160 if(fileinfo.towidth>fileinfo.toheight) fileinfo.toheight=-2; else fileinfo.towidth=-2;
164 unsigned long start=(unsigned long)(START+(rand->getDouble() * (END - START) ) );
165 args << QString("in=%1").arg(start)<< QString("out=%1").arg(start)<<"-consumer";
168 temp.setSuffix(".png");
170 args << QString("avformat:%1").arg(temp.fileName()) << "vframes=1"<< "f=rawvideo"<< "vcodec=png"<< QString("s=%1x%2").arg(fileinfo.towidth).arg(fileinfo.toheight);
171 if (! startAndWaitProcess(args) ) return NULL;
172 QPixmap retpix(temp.fileName());
178 uint WestleyPreview::imageVariance(QImage image )
182 uint bytes=image.numBytes();
184 QVarLengthArray<uchar> pivot(STEPS);
185 kDebug(DBG_AREA) << "Using " << STEPS << " steps\n";
186 uchar *bits=image.bits();
187 // First pass: get pivots and taking average
188 for( uint i=0; i<STEPS ; i++ ){
189 pivot[i]=bits[i*(bytes/STEPS)];
193 // Second Step: calculate delta (average?)
194 for (uint i=0; i<STEPS; i++)
196 int curdelta=abs(int(avg-pivot[i]));
201 #include "westleypreview.moc"