]> git.sesse.net Git - kdenlive/blobdiff - src/kthumb.cpp
Merge branch 'master' into next
[kdenlive] / src / kthumb.cpp
index d8a91e80671289bf0d00e3c729e4383515c699c1..c6189ae7c88b35fb6292550664f88335e73de4e9 100644 (file)
@@ -57,38 +57,36 @@ KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QStr
 
 KThumb::~KThumb()
 {
-    m_requestedThumbs.clear();
+    if (m_producer) m_clipManager->stopThumbs(m_id);
     m_intraFramesQueue.clear();
     if (m_audioThumbProducer.isRunning()) {
         m_stopAudioThumbs = true;
         m_audioThumbProducer.waitForFinished();
         slotAudioThumbOver();
     }
-    m_future.waitForFinished();
     m_intra.waitForFinished();
 }
 
 void KThumb::setProducer(Mlt::Producer *producer)
 {
-    m_requestedThumbs.clear();
+    if (m_producer) m_clipManager->stopThumbs(m_id);
     m_intraFramesQueue.clear();
-    m_future.waitForFinished();
     m_intra.waitForFinished();
     m_mutex.lock();
     m_producer = producer;
-    m_mutex.unlock();
     // FIXME: the profile() call leaks an object, but trying to free
     // it leads to a double-free in Profile::~Profile()
     if (producer) {
-        m_dar = producer->profile()->dar();
-        m_ratio = (double) producer->profile()->width() / producer->profile()->height();
+        Mlt::Profile *profile = producer->profile();
+        m_dar = profile->dar();
+        m_ratio = (double) profile->width() / profile->height();
     }
-        
+    m_mutex.unlock();
 }
 
 void KThumb::clearProducer()
 {
-    setProducer(NULL);
+    if (m_producer) setProducer(NULL);
 }
 
 bool KThumb::hasProducer() const
@@ -104,8 +102,6 @@ void KThumb::updateThumbUrl(const QString &hash)
 void KThumb::updateClipUrl(KUrl url, const QString &hash)
 {
     m_url = url;
-    //if (m_producer)
-        //m_producer->set("resource", url.path().toUtf8().constData());
     m_thumbFile = m_clipManager->projectFolder() + "/thumbs/" + hash + ".thumb";
 }
 
@@ -116,33 +112,31 @@ QPixmap KThumb::getImage(KUrl url, int width, int height)
     return getImage(url, 0, width, height);
 }
 
-void KThumb::extractImage(int frame, int frame2)
+void KThumb::extractImage(QList <int>frames)
 {
     if (!KdenliveSettings::videothumbnails() || m_producer == NULL) return;
-    if (frame != -1 && !m_requestedThumbs.contains(frame)) m_requestedThumbs.append(frame);
-    if (frame2 != -1 && !m_requestedThumbs.contains(frame2)) m_requestedThumbs.append(frame2);
-    if (!m_future.isRunning()) m_future = QtConcurrent::run(this, &KThumb::doGetThumbs);
+    m_clipManager->requestThumbs(m_id, frames);
 }
 
-void KThumb::doGetThumbs()
+
+void KThumb::getThumb(int frame)
 {
     const int theight = KdenliveSettings::trackheight();
     const int swidth = (int)(theight * m_ratio + 0.5);
     const int dwidth = (int)(theight * m_dar + 0.5);
 
-    while (!m_requestedThumbs.isEmpty()) {
-        int frame = m_requestedThumbs.takeFirst();
-        if (frame != -1) {
-            emit thumbReady(frame, getFrame(m_producer, frame, swidth, dwidth, theight));
-        }
-    }
+    QImage img = getProducerFrame(frame, swidth, dwidth, theight);
+    emit thumbReady(frame, img);
 }
 
 QPixmap KThumb::extractImage(int frame, int width, int height)
 {
-    m_mutex.lock();
-    QImage img = getFrame(m_producer, frame, (int) (height * m_ratio + 0.5), width, height);
-    m_mutex.unlock();
+    if (m_producer == NULL) {
+        QPixmap p(width, height);
+        p.fill(Qt::black);
+        return p;
+    }
+    QImage img = getProducerFrame(frame, (int) (height * m_ratio + 0.5), width, height);
     return QPixmap::fromImage(img);
 }
 
@@ -162,23 +156,45 @@ QPixmap KThumb::getImage(KUrl url, int frame, int width, int height)
     return pix;
 }
 
+
+QImage KThumb::getProducerFrame(int framepos, int frameWidth, int displayWidth, int height)
+{
+    if (m_producer == NULL || !m_producer->is_valid()) {
+        QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
+        p.fill(QColor(Qt::red).rgb());
+        return p;
+    }
+    if (m_producer->is_blank()) {
+        QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
+        p.fill(QColor(Qt::black).rgb());
+        return p;
+    }
+    m_mutex.lock();
+    m_producer->seek(framepos);
+    Mlt::Frame *frame = m_producer->get_frame();
+    QImage p = getFrame(frame, frameWidth, displayWidth, height);
+    delete frame;
+    m_mutex.unlock();
+    return p;
+}
+
 //static
 QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int frameWidth, int displayWidth, int height)
 {
-    QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
     if (producer == NULL || !producer->is_valid()) {
-        p.fill(Qt::red);
+        QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
+        p.fill(QColor(Qt::red).rgb());
         return p;
     }
-
     if (producer->is_blank()) {
-        p.fill(Qt::black);
+        QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
+        p.fill(QColor(Qt::black).rgb());
         return p;
     }
 
     producer->seek(framepos);
     Mlt::Frame *frame = producer->get_frame();
-    p = getFrame(frame, frameWidth, displayWidth, height);
+    QImage p = getFrame(frame, frameWidth, displayWidth, height);
     delete frame;
     return p;
 }
@@ -189,30 +205,34 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int
 {
     QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied);
     if (frame == NULL || !frame->is_valid()) {
-        p.fill(Qt::red);
+        p.fill(QColor(Qt::red).rgb());
         return p;
     }
 
     int ow = frameWidth;
     int oh = height;
     mlt_image_format format = mlt_image_rgb24a;
-    uint8_t *data = frame->get_image(format, ow, oh, 0);
-    QImage image((uchar *)data, ow, oh, QImage::Format_ARGB32_Premultiplied);
+
+    const uchar* imagedata = frame->get_image(format, ow, oh);
+    QImage image(ow, oh, QImage::Format_ARGB32_Premultiplied);
+    memcpy(image.bits(), imagedata, ow * oh * 4);//.byteCount());
+    
+    //const uchar* imagedata = frame->get_image(format, ow, oh);
+    //QImage image(imagedata, ow, oh, QImage::Format_ARGB32_Premultiplied);
+    
     if (!image.isNull()) {
         if (ow > (2 * displayWidth)) {
             // there was a scaling problem, do it manually
-            QImage scaled = image.scaled(displayWidth, height);
-            image = scaled.rgbSwapped();
+            image = image.scaled(displayWidth, height).rgbSwapped();
         } else {
             image = image.scaled(displayWidth, height, Qt::IgnoreAspectRatio).rgbSwapped();
         }
+        p.fill(QColor(Qt::black).rgb());
         QPainter painter(&p);
-        painter.fillRect(p.rect(), Qt::black);
-        painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
         painter.drawImage(p.rect(), image);
         painter.end();
     } else
-        p.fill(Qt::red);
+        p.fill(QColor(Qt::red).rgb());
     return p;
 }
 
@@ -346,7 +366,7 @@ void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int a
         return;
     }
 
-    QMap <int, QMap <int, QByteArray> > storeIn;
+    audioByteArray storeIn;
     //FIXME: Hardcoded!!!
     m_frequency = 48000;
     m_channels = channel;
@@ -396,8 +416,8 @@ void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int a
 
 void KThumb::slotCreateAudioThumbs()
 {
-    Mlt::Profile prof((char*) KdenliveSettings::current_profile().toUtf8().data());
-    Mlt::Producer producer(prof, m_url.path().toUtf8().data());
+    Mlt::Profile prof((char*) KdenliveSettings::current_profile().toUtf8().constData());
+    Mlt::Producer producer(prof, m_url.path().toUtf8().constData());
     if (!producer.is_valid()) {
         kDebug() << "++++++++  INVALID CLIP: " << m_url.path();
         return;
@@ -417,7 +437,10 @@ void KThumb::slotCreateAudioThumbs()
 
     int last_val = 0;
     int val = 0;
-    //kDebug() << "for " << m_frame << " " << m_frameLength << " " << m_producer.is_valid();
+    mlt_audio_format m_audioFormat = mlt_audio_pcm;
+    double framesPerSecond = mlt_producer_get_fps(producer.get_producer());
+    Mlt::Frame *mlt_frame;
+    
     for (int z = (int) m_frame; z < (int)(m_frame + m_frameLength) && producer.is_valid(); z++) {
         if (m_stopAudioThumbs) break;
         val = (int)((z - m_frame) / (m_frame + m_frameLength) * 100.0);
@@ -426,13 +449,10 @@ void KThumb::slotCreateAudioThumbs()
             last_val = val;
         }
         producer.seek(z);
-        Mlt::Frame *mlt_frame = producer.get_frame();
+        mlt_frame = producer.get_frame();
         if (mlt_frame && mlt_frame->is_valid()) {
-            double m_framesPerSecond = mlt_producer_get_fps(producer.get_producer());
-            int m_samples = mlt_sample_calculator(m_framesPerSecond, m_frequency, mlt_frame_get_position(mlt_frame->get_frame()));
-            mlt_audio_format m_audioFormat = mlt_audio_pcm;
+            int m_samples = mlt_sample_calculator(framesPerSecond, m_frequency, mlt_frame_get_position(mlt_frame->get_frame()));
             qint16* m_pcm = static_cast<qint16*>(mlt_frame->get_audio(m_audioFormat, m_frequency, m_channels, m_samples));
-
             for (int c = 0; c < m_channels; c++) {
                 QByteArray m_array;
                 m_array.resize(m_arrayWidth);
@@ -473,7 +493,9 @@ void KThumb::queryIntraThumbs(QList <int> missingFrames)
         if (!m_intraFramesQueue.contains(i)) m_intraFramesQueue.append(i);
     }
     qSort(m_intraFramesQueue);
-    if (!m_intra.isRunning()) m_intra = QtConcurrent::run(this, &KThumb::slotGetIntraThumbs);
+    if (!m_intra.isRunning()) {
+        m_intra = QtConcurrent::run(this, &KThumb::slotGetIntraThumbs);
+    }
 }
 
 void KThumb::slotGetIntraThumbs()
@@ -487,7 +509,7 @@ void KThumb::slotGetIntraThumbs()
     while (!m_intraFramesQueue.isEmpty()) {
         int pos = m_intraFramesQueue.takeFirst();
         if (!m_clipManager->pixmapCache->contains(path + QString::number(pos))) {
-            if (m_clipManager->pixmapCache->insertImage(path + QString::number(pos), getFrame(m_producer, pos, frameWidth, displayWidth, theight))) {
+            if (m_clipManager->pixmapCache->insertImage(path + QString::number(pos), getProducerFrame(pos, frameWidth, displayWidth, theight))) {
                 addedThumbs = true;
             }
             else kDebug()<<"// INSERT FAILD FOR: "<<pos;
@@ -497,7 +519,7 @@ void KThumb::slotGetIntraThumbs()
     if (addedThumbs) emit thumbsCached();
 }
 
-QImage KThumb::findCachedThumb(const QString path)
+QImage KThumb::findCachedThumb(const QString &path)
 {
     QImage img;
     m_clipManager->pixmapCache->findImage(path, &img);