X-Git-Url: https://git.sesse.net/?p=kdenlive;a=blobdiff_plain;f=src%2Fkthumb.cpp;h=5a81f5481ad789e159b7fdb8ce449faf0ece0773;hp=bdd6d9689ad240ac90f68243074fba2a167da734;hb=a3eee7be24126f5a3458d488f44cd61c66135e17;hpb=861d83ee58b4d9e1a699097da18610c6b93c639b diff --git a/src/kthumb.cpp b/src/kthumb.cpp index bdd6d968..5a81f548 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -39,8 +39,10 @@ #include #include #include +#include +#include -KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent) : +KThumb::KThumb(ClipManager *clipManager, const KUrl &url, const QString &id, const QString &hash, QObject * parent) : QObject(parent), m_url(url), m_thumbFile(), @@ -66,7 +68,7 @@ void KThumb::setProducer(Mlt::Producer *producer) if (m_producer) m_clipManager->stopThumbs(m_id); m_intraFramesQueue.clear(); m_intra.waitForFinished(); - m_mutex.lock(); + QMutexLocker lock(&m_mutex); m_producer = producer; // FIXME: the profile() call leaks an object, but trying to free // it leads to a double-free in Profile::~Profile() @@ -75,7 +77,6 @@ void KThumb::setProducer(Mlt::Producer *producer) m_dar = profile->dar(); m_ratio = (double) profile->width() / profile->height(); } - m_mutex.unlock(); } void KThumb::clearProducer() @@ -93,55 +94,59 @@ void KThumb::updateThumbUrl(const QString &hash) m_thumbFile = m_clipManager->projectFolder() + "/thumbs/" + hash + ".thumb"; } -void KThumb::updateClipUrl(KUrl url, const QString &hash) +void KThumb::updateClipUrl(const KUrl &url, const QString &hash) { m_url = url; m_thumbFile = m_clipManager->projectFolder() + "/thumbs/" + hash + ".thumb"; } //static -QPixmap KThumb::getImage(KUrl url, int width, int height) +QPixmap KThumb::getImage(const KUrl& url, int width, int height) { if (url.isEmpty()) return QPixmap(); return getImage(url, 0, width, height); } -void KThumb::extractImage(QList frames) +void KThumb::extractImage(const QList &frames) { if (!KdenliveSettings::videothumbnails() || m_producer == NULL) return; - m_clipManager->requestThumbs(m_id, frames); + m_clipManager->slotRequestThumbs(m_id, frames); } void KThumb::getThumb(int frame) { - const int theight = KdenliveSettings::trackheight(); + const int theight = Kdenlive::DefaultThumbHeight; const int swidth = (int)(theight * m_ratio + 0.5); const int dwidth = (int)(theight * m_dar + 0.5); - QImage img = getProducerFrame(frame, swidth, dwidth, theight); emit thumbReady(frame, img); } +void KThumb::getGenericThumb(int frame, int height, int type) +{ + const int swidth = (int)(height * m_ratio + 0.5); + const int dwidth = (int)(height * m_dar + 0.5); + QImage img = getProducerFrame(frame, swidth, dwidth, height); + m_clipManager->projectTreeThumbReady(m_id, frame, img, type); +} + QImage KThumb::extractImage(int frame, int width, int height) { if (m_producer == NULL) { QImage img(width, height, QImage::Format_ARGB32_Premultiplied); - img.fill(Qt::black); + img.fill(QColor(Qt::black).rgb()); return img; } return getProducerFrame(frame, (int) (height * m_ratio + 0.5), width, height); } //static -QPixmap KThumb::getImage(KUrl url, int frame, int width, int height) +QPixmap KThumb::getImage(const KUrl& url, int frame, int width, int height) { Mlt::Profile profile(KdenliveSettings::current_profile().toUtf8().constData()); QPixmap pix(width, height); if (url.isEmpty()) return pix; - - //""); - //Mlt::Producer producer(profile, "xml-string", tmp); Mlt::Producer *producer = new Mlt::Producer(profile, url.path().toUtf8().constData()); double swidth = (double) profile.width() / profile.height(); pix = QPixmap::fromImage(getFrame(producer, frame, (int) (height * swidth + 0.5), width, height)); @@ -162,12 +167,14 @@ QImage KThumb::getProducerFrame(int framepos, int frameWidth, int displayWidth, p.fill(QColor(Qt::black).rgb()); return p; } - m_mutex.lock(); + QMutexLocker lock(&m_mutex); m_producer->seek(framepos); Mlt::Frame *frame = m_producer->get_frame(); + /*frame->set("rescale.interp", "nearest"); + frame->set("deinterlace_method", "onefield"); + frame->set("top_field_first", -1 );*/ QImage p = getFrame(frame, frameWidth, displayWidth, height); delete frame; - m_mutex.unlock(); return p; } @@ -187,7 +194,10 @@ QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int frameWidth, i producer->seek(framepos); Mlt::Frame *frame = producer->get_frame(); - QImage p = getFrame(frame, frameWidth, displayWidth, height); + frame->set("rescale.interp", "nearest"); + frame->set("deinterlace_method", "onefield"); + frame->set("top_field_first", -1 ); + const QImage p = getFrame(frame, frameWidth, displayWidth, height); delete frame; return p; } @@ -201,15 +211,18 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int p.fill(QColor(Qt::red).rgb()); return p; } - + int ow = frameWidth; int oh = height; mlt_image_format format = mlt_image_rgb24a; - frame->set("rescale.interp", "nearest"); - frame->set("deinterlace_method", "onefield"); - frame->set("progressive", "1"); - const uchar* imagedata = frame->get_image(format, ow, oh); + //frame->set("progressive", "1"); + if (ow % 2 == 1) ow++; QImage image(ow, oh, QImage::Format_ARGB32_Premultiplied); + const uchar* imagedata = frame->get_image(format, ow, oh); + if (imagedata == NULL) { + p.fill(QColor(Qt::red).rgb()); + return p; + } memcpy(image.bits(), imagedata, ow * oh * 4);//.byteCount()); //const uchar* imagedata = frame->get_image(format, ow, oh); @@ -222,8 +235,14 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int } else { image = image.scaled(displayWidth, height, Qt::IgnoreAspectRatio).rgbSwapped(); } - p.fill(QColor(Qt::black).rgb()); +#if QT_VERSION >= 0x040800 + p.fill(QColor(100, 100, 100, 70)); QPainter painter(&p); +#else + p.fill(Qt::transparent); + QPainter painter(&p); + painter.fillRect(p.rect(), QColor(100, 100, 100, 70)); +#endif painter.drawImage(p.rect(), image); painter.end(); } else @@ -232,7 +251,7 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int } //static -uint KThumb::imageVariance(QImage image ) +uint KThumb::imageVariance(const QImage &image ) { uint delta = 0; uint avg = 0; @@ -241,7 +260,7 @@ uint KThumb::imageVariance(QImage image ) QVarLengthArray pivot(STEPS); const uchar *bits=image.bits(); // First pass: get pivots and taking average - for( uint i=0; i= 0x040700 avg+=pivot.at(i); @@ -252,7 +271,7 @@ uint KThumb::imageVariance(QImage image ) if (STEPS) avg=avg/STEPS; // Second Step: calculate delta (average?) - for (uint i=0; i= 0x040700 int curdelta=abs(int(avg - pivot.at(i))); @@ -301,7 +320,7 @@ void KThumb::getThumbs(KUrl url, int startframe, int endframe, int width, int he if (url.isEmpty()) return; QPixmap image(width, height); Mlt::Producer m_producer(url.path().toUtf8().constData()); - image.fill(Qt::black); + image.fill(QColor(Qt::black).rgb()); if (m_producer.is_blank()) { emit thumbReady(startframe, image); @@ -345,7 +364,7 @@ void KThumb::slotCreateAudioThumbs() } #if KDE_IS_VERSION(4,5,0) -void KThumb::queryIntraThumbs(QList missingFrames) +void KThumb::queryIntraThumbs(const QList &missingFrames) { foreach (int i, missingFrames) { if (!m_intraFramesQueue.contains(i)) m_intraFramesQueue.append(i); @@ -358,6 +377,10 @@ void KThumb::queryIntraThumbs(QList missingFrames) void KThumb::slotGetIntraThumbs() { + // We are in a new thread, so we need a new OpenGL context for the remainder of the function. + QGLWidget ctx(0, m_clipManager->getMainContext()); + ctx.makeCurrent(); + const int theight = KdenliveSettings::trackheight(); const int frameWidth = (int)(theight * m_ratio + 0.5); const int displayWidth = (int)(theight * m_dar + 0.5);