moved frame cache saving to our custom thread pool so we can control the priority
This commit is contained in:
@@ -202,13 +202,13 @@ void PreviewAutoCacher::VideoRendered()
|
||||
const QByteArray& hash = video_tasks_.value(watcher);
|
||||
|
||||
// Download frame in another thread
|
||||
QFutureWatcher<bool>* w = new QFutureWatcher<bool>();
|
||||
RenderTicketWatcher* w = new RenderTicketWatcher();
|
||||
video_download_tasks_.insert(w, hash);
|
||||
connect(w, &QFutureWatcher<bool>::finished, this, &PreviewAutoCacher::VideoDownloaded);
|
||||
w->setFuture(QtConcurrent::run(viewer_node_->video_frame_cache(),
|
||||
&FrameHashCache::SaveCacheFrame,
|
||||
hash,
|
||||
watcher->Get().value<FramePtr>()));
|
||||
connect(w, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoDownloaded);
|
||||
w->SetTicket(RenderManager::instance()->SaveFrameToCache(viewer_node_->video_frame_cache(),
|
||||
watcher->Get().value<FramePtr>(),
|
||||
hash,
|
||||
true));
|
||||
}
|
||||
|
||||
video_tasks_.remove(watcher);
|
||||
@@ -224,11 +224,11 @@ void PreviewAutoCacher::VideoRendered()
|
||||
|
||||
void PreviewAutoCacher::VideoDownloaded()
|
||||
{
|
||||
QFutureWatcher<bool>* watcher = static_cast<QFutureWatcher<bool>*>(sender());
|
||||
RenderTicketWatcher* watcher = static_cast<RenderTicketWatcher*>(sender());
|
||||
|
||||
if (video_download_tasks_.contains(watcher)) {
|
||||
if (!watcher->isCanceled()) {
|
||||
if (watcher->result()) {
|
||||
if (!watcher->WasCancelled()) {
|
||||
if (watcher->Get().toBool()) {
|
||||
const QByteArray& hash = video_download_tasks_.value(watcher);
|
||||
|
||||
currently_caching_hashes_.removeOne(hash);
|
||||
@@ -375,12 +375,12 @@ void PreviewAutoCacher::ClearVideoDownloadQueue(bool wait)
|
||||
auto copy = video_download_tasks_;
|
||||
|
||||
for (auto it=copy.cbegin(); it!=copy.cend(); it++) {
|
||||
it.key()->cancel();
|
||||
it.key()->Cancel();
|
||||
}
|
||||
if (wait) {
|
||||
copy = video_download_tasks_;
|
||||
for (auto it=copy.cbegin(); it!=copy.cend(); it++) {
|
||||
it.key()->waitForFinished();
|
||||
it.key()->WaitForFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ private:
|
||||
QList<QFutureWatcher<void>*> hash_tasks_;
|
||||
QMap<RenderTicketWatcher*, TimeRange> audio_tasks_;
|
||||
QMap<RenderTicketWatcher*, QByteArray> video_tasks_;
|
||||
QMap<QFutureWatcher<bool>*, QByteArray> video_download_tasks_;
|
||||
QMap<RenderTicketWatcher*, QByteArray> video_download_tasks_;
|
||||
|
||||
QVector<QByteArray> currently_caching_hashes_;
|
||||
|
||||
|
||||
@@ -98,6 +98,24 @@ RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange
|
||||
return ticket;
|
||||
}
|
||||
|
||||
RenderTicketPtr RenderManager::SaveFrameToCache(FrameHashCache *cache, FramePtr frame, const QByteArray &hash, bool prioritize)
|
||||
{
|
||||
// Create ticket
|
||||
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
|
||||
|
||||
ticket->setProperty("cache", Node::PtrToValue(cache));
|
||||
ticket->setProperty("frame", QVariant::fromValue(frame));
|
||||
ticket->setProperty("hash", hash);
|
||||
ticket->setProperty("type", kTypeVideoDownload);
|
||||
|
||||
// Queue appending the ticket and running the next job on our thread to make this function thread-safe
|
||||
QMetaObject::invokeMethod(this, "AddTicket", Qt::AutoConnection,
|
||||
OLIVE_NS_ARG(RenderTicketPtr, ticket),
|
||||
Q_ARG(bool, prioritize));
|
||||
|
||||
return ticket;
|
||||
}
|
||||
|
||||
void RenderManager::RunTicket(RenderTicketPtr ticket) const
|
||||
{
|
||||
// Depending on the render ticket type, start a job
|
||||
@@ -110,6 +128,9 @@ void RenderManager::RunTicket(RenderTicketPtr ticket) const
|
||||
case kTypeAudio:
|
||||
RenderAudioInternal(ticket);
|
||||
break;
|
||||
case kTypeVideoDownload:
|
||||
SaveFrameToCacheInternal(ticket);
|
||||
break;
|
||||
default:
|
||||
// Fail
|
||||
ticket->Cancel();
|
||||
@@ -144,6 +165,17 @@ void RenderManager::RenderAudioInternal(RenderTicketPtr ticket)
|
||||
ticket->Finish(QVariant::fromValue(SampleBuffer::CreateAllocated(viewer->audio_params(), time.length())), false);
|
||||
}
|
||||
|
||||
void RenderManager::SaveFrameToCacheInternal(RenderTicketPtr ticket)
|
||||
{
|
||||
FrameHashCache* cache = Node::ValueToPtr<FrameHashCache>(ticket->property("cache"));
|
||||
FramePtr frame = ticket->property("frame").value<FramePtr>();
|
||||
QByteArray hash = ticket->property("hash").toByteArray();
|
||||
|
||||
ticket->Start();
|
||||
|
||||
ticket->Finish(cache->SaveCacheFrame(hash, frame), false);
|
||||
}
|
||||
|
||||
void RenderManager::WorkerGeneratedWaveform(RenderTicketPtr ticket, TrackOutput *track, AudioVisualWaveform samples, TimeRange range)
|
||||
{
|
||||
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket->property("viewer"));
|
||||
|
||||
@@ -91,11 +91,14 @@ public:
|
||||
*/
|
||||
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, bool prioritize = false);
|
||||
|
||||
RenderTicketPtr SaveFrameToCache(FrameHashCache* cache, FramePtr frame, const QByteArray& hash, bool prioritize = false);
|
||||
|
||||
virtual void RunTicket(RenderTicketPtr ticket) const override;
|
||||
|
||||
enum TicketType {
|
||||
kTypeVideo,
|
||||
kTypeAudio
|
||||
kTypeAudio,
|
||||
kTypeVideoDownload
|
||||
};
|
||||
|
||||
signals:
|
||||
@@ -105,6 +108,8 @@ private:
|
||||
|
||||
static void RenderAudioInternal(RenderTicketPtr ticket);
|
||||
|
||||
static void SaveFrameToCacheInternal(RenderTicketPtr ticket);
|
||||
|
||||
RenderManager(QObject* parent = nullptr);
|
||||
|
||||
virtual ~RenderManager() override;
|
||||
|
||||
Reference in New Issue
Block a user