]> git.sesse.net Git - kdenlive/commitdiff
If fetched thumbnail for new clip is not interesting, try to fetch another one (seek...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 15 Mar 2011 15:26:59 +0000 (15:26 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 15 Mar 2011 15:26:59 +0000 (15:26 +0000)
http://kdenlive.org/mantis/view.php?id=2062

svn path=/trunk/kdenlive/; revision=5495

src/kthumb.cpp
src/kthumb.h
src/renderer.cpp

index 90917800b5dcc7cb5ff9f1aa5fbacc08b69f3b6a..809036689a300f4a5de2aef03ab4af4c2dff2950 100644 (file)
@@ -38,7 +38,7 @@
 #include <QImage>
 #include <QApplication>
 #include <QtConcurrentRun>
-
+#include <QVarLengthArray>
 
 KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent, const char */*name*/) :
     QObject(parent),
@@ -193,6 +193,32 @@ QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int he
     delete frame;
     return p;
 }
+
+
+//static
+uint KThumb::imageVariance(QImage image )
+{
+    uint delta=0;
+    uint avg=0;
+    uint bytes=image.numBytes();
+    uint STEPS=bytes/2;
+    QVarLengthArray<uchar> pivot(STEPS);
+    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];
+    }
+    avg=avg/STEPS;
+    // Second Step: calculate delta (average?)
+    for (uint i=0; i<STEPS; i++)
+    {
+        int curdelta=abs(int(avg-pivot[i]));
+        delta+=curdelta;
+    }
+    return delta/STEPS;
+}
+
 /*
 void KThumb::getImage(KUrl url, int frame, int width, int height)
 {
index 63c5df0117b0f4d53dbec4e918e06add563e4a51..598cda56e92e0752da4450894d68404123fee1e2 100644 (file)
@@ -74,6 +74,10 @@ public slots:
     void getAudioThumbs(int channel, double frame, double frameLength, int arrayWidth);
     static QPixmap getImage(KUrl url, int frame, int width, int height);
     static QImage getFrame(Mlt::Producer *producer, int framepos, int width, int height);
+    /** @brief Calculates image variance, useful to know if a thumbnail is interesting. 
+     *  @return an integer between 0 and 100. 0 means no variance, eg. black image while bigger values mean contrasted image
+     * */
+    static uint imageVariance(QImage image);
 
 private slots:
     void slotAudioThumbOver();
index 5d3699d9b21ea801a05f219d5e0321297fb90e63..3d2b2492a6901a9a8432cbb28cc6ecddedc411a0 100644 (file)
@@ -735,22 +735,35 @@ void Render::getFileProperties(const QDomElement xml, const QString &clipId, int
             else
                 filePropertyMap["type"] = "video";
 
+            int variance;
             mlt_image_format format = mlt_image_rgb24a;
             int frame_width = width;
             int frame_height = imageHeight;
-            uint8_t *data = frame->get_image(format, frame_width, frame_height, 0);
-            QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32_Premultiplied);
             QPixmap pix;
-
-            if (!image.isNull()) {
-                if (frame_width > (2 * width)) {
-                    // there was a scaling problem, do it manually
-                    QImage scaled = image.scaled(width, imageHeight);
-                    pix = QPixmap::fromImage(scaled.rgbSwapped());
-                } else pix = QPixmap::fromImage(image.rgbSwapped());
-            } else
-                pix.fill(Qt::black);
-
+            do {
+                variance = 100;
+                uint8_t *data = frame->get_image(format, frame_width, frame_height, 0);
+                QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32_Premultiplied);
+
+                if (!image.isNull()) {
+                    if (frame_width > (2 * width)) {
+                        // there was a scaling problem, do it manually
+                        QImage scaled = image.scaled(width, imageHeight);
+                        pix = QPixmap::fromImage(scaled.rgbSwapped());
+                    } else pix = QPixmap::fromImage(image.rgbSwapped());
+                    variance = KThumb::imageVariance(image);
+                } else
+                    pix.fill(Qt::black);
+                
+                if (frameNumber == 0 && variance < 6) {
+                    // Thumbnail is not interesting (for example all black, seek to fetch better thumb
+                    frameNumber = 100;
+                    producer->seek(frameNumber);
+                    delete frame;
+                    frame = producer->get_frame();
+                    variance = -1;
+                }
+            } while (variance == -1);
             emit replyGetImage(clipId, pix);
 
         } else if (frame->get_int("test_audio") == 0) {