#include <kstandarddirs.h>
#include <krandomsequence.h>
#include <qdatetime.h>
-#include <QProcess>
+#include <QColor>
#include <kdebug.h>
#include <ktempdir.h>
#include <kurl.h>
#define DBG_AREA
//#include "config.h"
-extern "C"
-{
+extern "C" {
KDE_EXPORT ThumbCreator *new_creator() {
- return new WestleyPreview;
+ return new MltPreview;
}
}
-WestleyPreview::WestleyPreview() :
- m_rand(0),
- m_inigoprocess(0)
+MltPreview::MltPreview() :
+ QObject(),
+ ThumbCreator()
{
+ Mlt::Factory::init();
}
-WestleyPreview::~WestleyPreview()
+MltPreview::~MltPreview()
{
- delete m_rand;
- delete m_inigoprocess;
+ Mlt::Factory::close();
}
-bool WestleyPreview::startAndWaitProcess(const QStringList &args)
+
+bool MltPreview::create(const QString &path, int width, int height, QImage &img)
{
- kDebug(DBG_AREA) << "westleypreview: starting process with args: " << args << endl;
- m_inigoprocess->start(args.join(" "));
- if (! m_inigoprocess->waitForStarted()) {
- kDebug(DBG_AREA) << "westleypreview: PROCESS NOT STARTED!!! exiting\n";
+ Mlt::Profile *profile = new Mlt::Profile("dv_pal");
+ Mlt::Producer *producer = new Mlt::Producer(*profile, path.toUtf8().data());
+
+
+ if (producer->is_blank()) {
+ delete producer;
return false;
}
- if (! m_inigoprocess->waitForFinished()) {
- kDebug(DBG_AREA) << "westleypreview: PROCESS DIDN'T FINISH!! exiting\n";
- m_inigoprocess->close();
- return false;
+ int frame = 75;
+ uint variance = 10;
+ int ct = 1;
+
+ //img = getFrame(producer, frame, width, height);
+
+ while (variance <= 40 && ct < 4) {
+ img = getFrame(producer, frame, width, height);
+ variance = imageVariance(img);
+ frame += 100 * ct;
+ ct++;
}
- kDebug() << "westleypreview: process started and ended correctly\n";
- return true;
+
+ delete producer;
+ delete profile;
+ return (img.isNull() == false);
}
-bool WestleyPreview::create(const QString &path, int width, int /*height*/, QImage &img)
+QImage MltPreview::getFrame(Mlt::Producer *producer, int framepos, int /*width*/, int height)
{
- QFileInfo fi(path);
- playerBin = KStandardDirs::findExe("inigo");
- if (playerBin.isEmpty()) {
- kDebug(DBG_AREA) << "westleypreview: inigo not found, exiting.\n";
- return false;
+ QImage result;
+ if (producer == NULL) {
+ return result;
}
- fileinfo.seconds = 0;
- fileinfo.fps = 0;
-
- m_rand = new KRandomSequence(QDateTime::currentDateTime().toTime_t());
- m_inigoprocess = new QProcess();
- KUrl furl(path);
- kDebug(DBG_AREA) << "videopreview: url=" << furl << "; local:" << furl.isLocalFile() << endl;
- fileinfo.towidth = width;
- fileinfo.toheight = width * 3 / 4;
- QImage 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;
-
- const int LASTTRY = 3;
- for (int i = 0; i <= LASTTRY; i++) {
- pix = getFrame(path);
- if (!pix.isNull()) {
- uint variance = imageVariance(pix);
- 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;
+ producer->seek(framepos);
+ Mlt::Frame *frame = producer->get_frame();
+ if (frame == NULL) {
+ return result;
}
- if (pix.depth() != 32)
- img = pix.convertToFormat(QImage::Format_RGB32);
- else img = pix;
- return true;
-}
+ mlt_image_format format = mlt_image_rgb24a;
+ height = 200;
+ double ar = frame->get_double("aspect_ratio");
+ if (ar == 0.0) ar = 1.33;
+ int calculated_width = (int)((double) height * ar);
+ uint8_t *data = frame->get_image(format, calculated_width, height, 0);
+ QImage image((uchar *)data, calculated_width, height, QImage::Format_ARGB32);
-QImage WestleyPreview::getFrame(const QString &path)
-{
- QStringList args;
- const int START = 25;
- const int RANGE = 500;
- args.clear();
- args << playerBin << "\"" + path + "\"";
-
- unsigned long start = (unsigned long)(START + (m_rand->getDouble() * RANGE));
- 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 QImage();
- QImage retpix(temp.fileName());
- temp.close();
- return retpix;
+ if (!image.isNull()) {
+ result = image.rgbSwapped().convertToFormat(QImage::Format_RGB32);
+ }
+
+ delete frame;
+ return result;
}
-uint WestleyPreview::imageVariance(QImage image)
+uint MltPreview::imageVariance(QImage image)
{
+ if (image.isNull()) return 0;
uint delta = 0;
uint avg = 0;
uint bytes = image.numBytes();
uint STEPS = bytes / 2;
QVarLengthArray<uchar> pivot(STEPS);
kDebug(DBG_AREA) << "Using " << STEPS << " steps\n";
- uchar *bits = image.bits();
+ const uchar *bits=image.bits();
// First pass: get pivots and taking average
- for (uint i = 0; i < STEPS ; i++) {
- pivot[i] = bits[i*(bytes/STEPS)];
- avg += pivot[i];
+ for( uint i=0; i<STEPS ; i++ ){
+ pivot[i] = bits[2 * i];
+#if QT_VERSION >= 0x040700
+ avg+=pivot.at(i);
+#else
+ avg+=pivot[i];
+#endif
}
- avg = avg / STEPS;
+ avg=avg/STEPS;
// Second Step: calculate delta (average?)
- for (uint i = 0; i < STEPS; i++) {
- int curdelta = abs(int(avg - pivot[i]));
- delta += curdelta;
+ for (uint i=0; i<STEPS; i++)
+ {
+#if QT_VERSION >= 0x040700
+ int curdelta=abs(int(avg - pivot.at(i)));
+#else
+ int curdelta=abs(int(avg - pivot[i]));
+#endif
+ delta+=curdelta;
}
return delta / STEPS;
}
-ThumbCreator::Flags WestleyPreview::flags() const
+ThumbCreator::Flags MltPreview::flags() const
{
return None;
}
-#include "westleypreview.moc"
-