File indexing completed on 2024-05-05 04:22:01
0001 // SPDX-FileCopyrightText: 2012-2022 The KPhotoAlbum Development Team 0002 // 0003 // SPDX-License-Identifier: GPL-2.0-or-later 0004 0005 #include "VideoThumbnails.h" 0006 0007 #include "VideoLengthExtractor.h" 0008 0009 #include <BackgroundJobs/ExtractOneThumbnailJob.h> 0010 #include <BackgroundJobs/HandleVideoThumbnailRequestJob.h> 0011 #include <BackgroundJobs/ReadVideoLengthJob.h> 0012 #include <BackgroundTaskManager/JobManager.h> 0013 #include <MainWindow/FeatureDialog.h> 0014 0015 ImageManager::VideoThumbnails::VideoThumbnails(QObject *parent) 0016 : QObject(parent) 0017 , m_pendingRequest(false) 0018 , m_index(0) 0019 { 0020 m_cache.resize(10); 0021 m_activeRequests.reserve(10); 0022 } 0023 0024 void ImageManager::VideoThumbnails::setVideoFile(const DB::FileName &fileName) 0025 { 0026 m_index = 0; 0027 m_videoFile = fileName; 0028 if (loadFramesFromCache(fileName)) 0029 return; 0030 0031 // no video thumbnails without ffmpeg: 0032 if (!MainWindow::FeatureDialog::hasVideoThumbnailer()) 0033 return; 0034 0035 if (!fileName.exists()) 0036 return; 0037 0038 cancelPreviousJobs(); 0039 m_pendingRequest = false; 0040 for (int i = 0; i < 10; ++i) 0041 m_cache[i] = QImage(); 0042 0043 BackgroundJobs::ReadVideoLengthJob *lengthJob = new BackgroundJobs::ReadVideoLengthJob(fileName, BackgroundTaskManager::ForegroundCycleRequest); 0044 0045 for (int i = 0; i < 10; ++i) { 0046 BackgroundJobs::ExtractOneThumbnailJob *extractJob = new BackgroundJobs::ExtractOneThumbnailJob(fileName, i, BackgroundTaskManager::ForegroundCycleRequest); 0047 extractJob->addDependency(lengthJob); 0048 connect(extractJob, &BackgroundJobs::ExtractOneThumbnailJob::completed, this, &VideoThumbnails::gotFrame); 0049 m_activeRequests.append(QPointer<BackgroundJobs::ExtractOneThumbnailJob>(extractJob)); 0050 } 0051 BackgroundTaskManager::JobManager::instance()->addJob(lengthJob); 0052 } 0053 0054 void ImageManager::VideoThumbnails::requestNext() 0055 { 0056 for (int i = 0; i < 10; ++i) { 0057 m_index = (m_index + 1) % 10; 0058 if (!m_cache[m_index].isNull()) { 0059 Q_EMIT frameLoaded(m_cache[m_index]); 0060 m_pendingRequest = false; 0061 return; 0062 } 0063 } 0064 m_pendingRequest = true; 0065 } 0066 0067 void ImageManager::VideoThumbnails::gotFrame() 0068 { 0069 const BackgroundJobs::ExtractOneThumbnailJob *job = qobject_cast<BackgroundJobs::ExtractOneThumbnailJob *>(sender()); 0070 const int index = job->index(); 0071 const DB::FileName thumbnailFile = BackgroundJobs::HandleVideoThumbnailRequestJob::frameName(m_videoFile, index); 0072 m_cache[index] = QImage(thumbnailFile.absolute()); 0073 0074 if (m_pendingRequest) { 0075 m_index = index; 0076 Q_EMIT frameLoaded(m_cache[index]); 0077 } 0078 } 0079 0080 bool ImageManager::VideoThumbnails::loadFramesFromCache(const DB::FileName &fileName) 0081 { 0082 for (int i = 0; i < 10; ++i) { 0083 const DB::FileName thumbnailFile = BackgroundJobs::HandleVideoThumbnailRequestJob::frameName(fileName, i); 0084 if (!thumbnailFile.exists()) 0085 return false; 0086 0087 QImage image(thumbnailFile.absolute()); 0088 if (image.isNull()) 0089 return false; 0090 0091 m_cache[i] = image; 0092 } 0093 return true; 0094 } 0095 0096 void ImageManager::VideoThumbnails::cancelPreviousJobs() 0097 { 0098 for (const QPointer<BackgroundJobs::ExtractOneThumbnailJob> &job : m_activeRequests) { 0099 if (!job.isNull()) 0100 job->cancel(); 0101 } 0102 m_activeRequests.clear(); 0103 } 0104 // vi:expandtab:tabstop=4 shiftwidth=4: 0105 0106 #include "moc_VideoThumbnails.cpp"