diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-07-15 17:56:18 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-07-23 15:58:55 -0700 |
commit | b3feaa80e26510928c73e92049ec346841f6093a (patch) | |
tree | 1a1f002959ea09aa5a16a5cc04ace06326941377 /core | |
parent | c7428859840bfcf973a14f27c6376e39e915cb29 (diff) | |
download | subsurface-b3feaa80e26510928c73e92049ec346841f6093a.tar.gz |
Dive video: paint duration-bar above thumbnail in profile plot
Paint a rectangle on top of thumbnails indicating the run-time
of the video.
Use the z=100.0-101.0 range for painting the thumbnails, whereby
the z-value increases uniformly from first to last thumbnail
(sorted by timestamp). The duration-bars are placed at z-values
midway between those of the thumbnails.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core')
-rw-r--r-- | core/imagedownloader.cpp | 90 | ||||
-rw-r--r-- | core/imagedownloader.h | 8 |
2 files changed, 48 insertions, 50 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index fd155bec6..7dc35695d 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -93,40 +93,36 @@ Thumbnailer::Thumbnail Thumbnailer::fetchImage(const QString &filename, const QS mediatype_t type = get_metadata(qPrintable(filename), &md); // For io error or video, return early with the appropriate dummy-icon. - if (type == MEDIATYPE_IO_ERROR) { - return { failImage, MEDIATYPE_IO_ERROR }; - } else if (type == MEDIATYPE_VIDEO) { - addVideoThumbnailToCache(originalFilename, md.duration); - return { videoImage, MEDIATYPE_VIDEO }; - } + if (type == MEDIATYPE_IO_ERROR) + return { failImage, MEDIATYPE_IO_ERROR, 0 }; + else if (type == MEDIATYPE_VIDEO) + return addVideoThumbnailToCache(originalFilename, md.duration); // Try if Qt can parse this image. If it does, use this as a thumbnail. QImage thumb(filename); if (!thumb.isNull()) { - addPictureThumbnailToCache(originalFilename, thumb); - return { thumb, MEDIATYPE_PICTURE }; + int size = maxThumbnailSize(); + thumb = thumb.scaled(size, size, Qt::KeepAspectRatio); + return addPictureThumbnailToCache(originalFilename, thumb); } // Neither our code, nor Qt could determine the type of this object from looking at the data. // Try to check for a video-file extension. Since we couldn't parse the video file, // we pass 0 as the duration. - if (hasVideoFileExtension(filename)) { - addVideoThumbnailToCache(originalFilename, {0} ); - return { videoImage, MEDIATYPE_VIDEO }; - } + if (hasVideoFileExtension(filename)) + return addVideoThumbnailToCache(originalFilename, {0} ); // Give up: we simply couldn't determine what this thing is. // But since we managed to read this file, mark this file in the cache as unknown. - addUnknownThumbnailToCache(originalFilename); - return { unknownImage, MEDIATYPE_UNKNOWN }; + return addUnknownThumbnailToCache(originalFilename); } else if (tryDownload) { // This has to be done in UI main thread, because QNetworkManager refuses // to treat requests from other threads. invokeMethod() is Qt's way of calling a // function in a different thread, namely the thread the called object is associated to. QMetaObject::invokeMethod(ImageDownloader::instance(), "load", Qt::AutoConnection, Q_ARG(QUrl, url), Q_ARG(QString, originalFilename)); - return { QImage(), MEDIATYPE_STILL_LOADING }; + return { QImage(), MEDIATYPE_STILL_LOADING, 0 }; } - return { QImage(), MEDIATYPE_IO_ERROR }; + return { QImage(), MEDIATYPE_IO_ERROR, 0 }; } // Fetch a picture based on its original filename. If there is a translated filename (obtained either @@ -142,7 +138,7 @@ Thumbnailer::Thumbnail Thumbnailer::getHashedImage(const QString &filename, bool // If there is a translated filename, try that first. // Note that we set the default type to io-error, so that if we didn't try // the local filename first, we will load the file from the canonical filename. - Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR }; + Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR, 0 }; if (localFilename != filename) thumbnail = fetchImage(localFilename, filename, tryDownload); @@ -199,7 +195,9 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str // If reading did not succeed, schedule for recalculation - this thumbnail might // have been written by an older version, which couldn't extract the duration. - if (stream.status() != QDataStream::Ok) + // Likewise test the duration and number of pictures for sanity (no videos longer than 10 h, + // no more than 10000 pictures). + if (stream.status() != QDataStream::Ok || duration > 36000 || numPics > 10000) return { QImage(), MEDIATYPE_VIDEO, 0 }; // Currently, we support only one picture @@ -211,7 +209,7 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str } // No picture -> show dummy-icon - return { res.isNull() ? videoImage : res, MEDIATYPE_VIDEO, {(int32_t)duration} }; + return { res.isNull() ? videoImage : res, MEDIATYPE_VIDEO, (int32_t)duration }; } // Fetch a thumbnail from cache. @@ -220,7 +218,7 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture { QString filename = thumbnailFileName(picture_filename); if (filename.isEmpty()) - return { QImage(), MEDIATYPE_UNKNOWN }; + return { QImage(), MEDIATYPE_UNKNOWN, 0 }; QFile file(filename); if (prefs.auto_recalculate_thumbnails) { @@ -256,7 +254,7 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture } } -void Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, duration_t duration) +Thumbnailer::Thumbnail Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, duration_t duration) { // The format of video thumbnails: // uint32 MEDIATYPE_VIDEO @@ -267,43 +265,43 @@ void Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, dura // QImage frame QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); - stream << (quint32)MEDIATYPE_VIDEO; - stream << (quint32)duration.seconds; - stream << (quint32)0; // Currently, we don't support extraction of images - file.commit(); + stream << (quint32)MEDIATYPE_VIDEO; + stream << (quint32)duration.seconds; + stream << (quint32)0; // Currently, we don't support extraction of images + file.commit(); + } + return { videoImage, MEDIATYPE_VIDEO, duration }; } -void Thumbnailer::addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail) +Thumbnailer::Thumbnail Thumbnailer::addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail) { - if (thumbnail.isNull()) - return; - // The format of a picture-thumbnail is very simple: // uint32 MEDIATYPE_PICTURE // QImage thumbnail QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); - stream << (quint32)MEDIATYPE_PICTURE; - stream << thumbnail; - file.commit(); + stream << (quint32)MEDIATYPE_PICTURE; + stream << thumbnail; + file.commit(); + } + return { thumbnail, MEDIATYPE_PICTURE, 0 }; } -void Thumbnailer::addUnknownThumbnailToCache(const QString &picture_filename) +Thumbnailer::Thumbnail Thumbnailer::addUnknownThumbnailToCache(const QString &picture_filename) { QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); - stream << (quint32)MEDIATYPE_UNKNOWN; + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); + stream << (quint32)MEDIATYPE_UNKNOWN; + } + return { unknownImage, MEDIATYPE_UNKNOWN, 0 }; } void Thumbnailer::recalculate(QString filename) @@ -317,7 +315,7 @@ void Thumbnailer::recalculate(QString filename) return; QMutexLocker l(&lock); - emit thumbnailChanged(filename, thumbnail.img); + emit thumbnailChanged(filename, thumbnail.img, thumbnail.duration); workingOn.remove(filename); } @@ -339,7 +337,7 @@ void Thumbnailer::processItem(QString filename, bool tryDownload) } QMutexLocker l(&lock); - emit thumbnailChanged(filename, thumbnail.img); + emit thumbnailChanged(filename, thumbnail.img, thumbnail.duration); workingOn.remove(filename); } @@ -352,7 +350,7 @@ void Thumbnailer::imageDownloaded(QString filename) void Thumbnailer::imageDownloadFailed(QString filename) { - emit thumbnailChanged(filename, failImage); + emit thumbnailChanged(filename, failImage, duration_t{ 0 }); QMutexLocker l(&lock); workingOn.remove(filename); } diff --git a/core/imagedownloader.h b/core/imagedownloader.h index dcdf08d20..cab945e5f 100644 --- a/core/imagedownloader.h +++ b/core/imagedownloader.h @@ -47,7 +47,7 @@ public slots: void imageDownloaded(QString filename); void imageDownloadFailed(QString filename); signals: - void thumbnailChanged(QString filename, QImage thumbnail); + void thumbnailChanged(QString filename, QImage thumbnail, duration_t duration); private: struct Thumbnail { QImage img; @@ -56,9 +56,9 @@ private: }; Thumbnailer(); - static void addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail); - static void addVideoThumbnailToCache(const QString &picture_filename, duration_t duration); - static void addUnknownThumbnailToCache(const QString &picture_filename); + Thumbnail addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail); + Thumbnail addVideoThumbnailToCache(const QString &picture_filename, duration_t duration); + Thumbnail addUnknownThumbnailToCache(const QString &picture_filename); void recalculate(QString filename); void processItem(QString filename, bool tryDownload); Thumbnail getThumbnailFromCache(const QString &picture_filename); |