diff --git a/app/core.cpp b/app/core.cpp index 1b6b8c74a..fbecb02bf 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -51,7 +51,6 @@ #include "render/diskmanager.h" #include "render/pixelformat.h" #include "render/shaderinfo.h" -#include "task/cache/cache.h" #include "task/project/import/import.h" #include "task/project/load/load.h" #include "task/project/save/save.h" diff --git a/app/render/backend/renderbackend.cpp b/app/render/backend/renderbackend.cpp index 19fcb06f7..762dfeabd 100644 --- a/app/render/backend/renderbackend.cpp +++ b/app/render/backend/renderbackend.cpp @@ -464,8 +464,6 @@ void RenderBackend::TicketFinished() void RenderBackend::WorkerGeneratedWaveform(RenderTicketPtr ticket, TrackOutput *track, AudioVisualWaveform samples, TimeRange range) { - qDebug() << "Hello?"; - QList valid_ranges = viewer_node_->audio_playback_cache()->GetValidRanges(range, ticket->GetJobTime()); if (!valid_ranges.isEmpty()) { diff --git a/app/task/CMakeLists.txt b/app/task/CMakeLists.txt index 02eaab8e4..3498e2910 100644 --- a/app/task/CMakeLists.txt +++ b/app/task/CMakeLists.txt @@ -14,9 +14,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -add_subdirectory(cache) add_subdirectory(conform) add_subdirectory(export) +add_subdirectory(precache) add_subdirectory(project) add_subdirectory(render) diff --git a/app/task/cache/footagecache.cpp b/app/task/cache/footagecache.cpp deleted file mode 100644 index 9a21bc9f8..000000000 --- a/app/task/cache/footagecache.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#include "footagecache.h" - -#include "common/timecodefunctions.h" - -OLIVE_NAMESPACE_ENTER - -FootageCacheTask::FootageCacheTask(VideoStreamPtr footage, Sequence *sequence) : - CacheTask(new ViewerOutput(), sequence->video_params(), sequence->audio_params(), false), - footage_(footage) -{ - viewer()->set_video_params(sequence->video_params()); - viewer()->set_audio_params(sequence->audio_params()); - backend()->SetVideoParams(sequence->video_params()); - backend()->SetAudioParams(sequence->audio_params()); - - video_node_ = new VideoInput(); - video_node_->SetFootage(footage); - - NodeParam::ConnectEdge(video_node_->output(), viewer()->texture_input()); - - SetTitle(tr("Pre-caching %1:%2").arg(footage->footage()->filename(), - QString::number(footage->index()))); - - backend()->ProcessUpdateQueue(); -} - -FootageCacheTask::~FootageCacheTask() -{ - delete viewer(); - delete video_node_; -} - -OLIVE_NAMESPACE_EXIT diff --git a/app/task/cache/footagecache.h b/app/task/cache/footagecache.h deleted file mode 100644 index f48218532..000000000 --- a/app/task/cache/footagecache.h +++ /dev/null @@ -1,48 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#ifndef FOOTAGECACHETASK_H -#define FOOTAGECACHETASK_H - -#include "cache.h" -#include "node/input/media/video/video.h" -#include "project/item/footage/footage.h" -#include "project/item/sequence/sequence.h" - -OLIVE_NAMESPACE_ENTER - -class FootageCacheTask : public CacheTask -{ - Q_OBJECT -public: - FootageCacheTask(VideoStreamPtr footage, Sequence* sequence); - - virtual ~FootageCacheTask() override; - -private: - VideoStreamPtr footage_; - - VideoInput* video_node_; - -}; - -OLIVE_NAMESPACE_EXIT - -#endif // FOOTAGECACHETASK_H diff --git a/app/task/export/export.cpp b/app/task/export/export.cpp index 57f23df6d..bcbdc083b 100644 --- a/app/task/export/export.cpp +++ b/app/task/export/export.cpp @@ -148,8 +148,10 @@ QFuture ExportTask::DownloadFrame(FramePtr frame, const QByteArray &hash) return QtConcurrent::run(FrameColorConvert, color_processor_, frame); } -void ExportTask::FrameDownloaded(const QByteArray &hash, const std::list ×) +void ExportTask::FrameDownloaded(const QByteArray &hash, const std::list ×, qint64 job_time) { + Q_UNUSED(job_time) + FramePtr f = rendered_frame_.value(hash); foreach (const rational& t, times) { @@ -173,8 +175,10 @@ void ExportTask::FrameDownloaded(const QByteArray &hash, const std::list DownloadFrame(FramePtr frame, const QByteArray &hash) override; - virtual void FrameDownloaded(const QByteArray& hash, const std::list& times) override; + virtual void FrameDownloaded(const QByteArray& hash, const std::list& times, qint64 job_time) override; - virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) override; + virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples, qint64 job_time) override; private: QHash rendered_frame_; diff --git a/app/task/cache/CMakeLists.txt b/app/task/precache/CMakeLists.txt similarity index 88% rename from app/task/cache/CMakeLists.txt rename to app/task/precache/CMakeLists.txt index 5557f3f39..872149bae 100644 --- a/app/task/cache/CMakeLists.txt +++ b/app/task/precache/CMakeLists.txt @@ -16,9 +16,7 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} - task/cache/cache.h - task/cache/cache.cpp - task/cache/footagecache.h - task/cache/footagecache.cpp + task/precache/precachetask.h + task/precache/precachetask.cpp PARENT_SCOPE ) diff --git a/app/task/cache/cache.cpp b/app/task/precache/precachetask.cpp similarity index 52% rename from app/task/cache/cache.cpp rename to app/task/precache/precachetask.cpp index 0b8d60279..220fb36f2 100644 --- a/app/task/cache/cache.cpp +++ b/app/task/precache/precachetask.cpp @@ -18,81 +18,80 @@ ***/ -#include "cache.h" - -#include -#include - -#include "project/item/sequence/sequence.h" +#include "precachetask.h" OLIVE_NAMESPACE_ENTER -CacheTask::CacheTask(RenderBackend *backend, bool in_out_only) : - RenderTask(backend), - in_out_only_(in_out_only) +PreCacheTask::PreCacheTask(VideoStreamPtr footage, Sequence* sequence) : + RenderTask(new ViewerOutput(), sequence->video_params(), sequence->audio_params()), + footage_(footage) { - Init(); + viewer()->set_video_params(sequence->video_params()); + viewer()->set_audio_params(sequence->audio_params()); + + // Render fastest quality + backend()->SetRenderMode(RenderMode::kOffline); + + video_node_ = new VideoInput(); + video_node_->SetFootage(footage); + + NodeParam::ConnectEdge(video_node_->output(), viewer()->texture_input()); + + SetTitle(tr("Pre-caching %1:%2").arg(footage->footage()->filename(), + QString::number(footage->index()))); + + backend()->NodeGraphChanged(viewer()->texture_input()); + backend()->ProcessUpdateQueue(); } -CacheTask::CacheTask(ViewerOutput* viewer, const VideoParams& vparams, const AudioParams &aparams, bool in_out_only) : - RenderTask(viewer, vparams, aparams), - in_out_only_(in_out_only) +PreCacheTask::~PreCacheTask() { - Init(); + delete viewer(); + delete video_node_; } -bool CacheTask::Run() +bool PreCacheTask::Run() { // Get list of invalidated ranges TimeRangeList video_range = viewer()->video_frame_cache()->GetInvalidatedRanges(); - TimeRangeList audio_range = viewer()->audio_playback_cache()->GetInvalidatedRanges(); // If we're caching only in-out, limit the range to that + /* if (in_out_only_) { Sequence* s = static_cast(viewer()->parent()); if (s->workarea()->enabled()) { video_range = video_range.Intersects(s->workarea()->range()); - audio_range = audio_range.Intersects(s->workarea()->range()); } } + */ - Render(video_range, audio_range, true); + Render(video_range, TimeRangeList(), true); download_threads_.waitForDone(); return true; } -QFuture CacheTask::DownloadFrame(FramePtr frame, const QByteArray &hash) +QFuture PreCacheTask::DownloadFrame(FramePtr frame, const QByteArray &hash) { return QtConcurrent::run(&download_threads_, FrameHashCache::SaveCacheFrame, hash, frame); } -void CacheTask::FrameDownloaded(const QByteArray &hash, const std::list ×) +void PreCacheTask::FrameDownloaded(const QByteArray &hash, const std::list ×, qint64 job_time) { foreach (const rational& t, times) { - viewer()->video_frame_cache()->SetHash(t, hash, job_time(), true); + viewer()->video_frame_cache()->SetHash(t, hash, job_time, true); } } -void CacheTask::AudioDownloaded(const TimeRange &range, SampleBufferPtr samples) +void PreCacheTask::AudioDownloaded(const TimeRange &range, SampleBufferPtr samples, qint64 job_time) { - if (samples) { - viewer()->audio_playback_cache()->WritePCM(range, samples, job_time()); - } else { - viewer()->audio_playback_cache()->WriteSilence(range); - } -} + // Pre-cache doesn't cache any audio -void CacheTask::Init() -{ - SetTitle(tr("Caching \"%1\"").arg(viewer()->media_name())); - - backend()->EnablePreviewGeneration(job_time()); - - // Render fastest quality - backend()->SetRenderMode(RenderMode::kOffline); + Q_UNUSED(range) + Q_UNUSED(samples) + Q_UNUSED(job_time) } OLIVE_NAMESPACE_EXIT diff --git a/app/task/cache/cache.h b/app/task/precache/precachetask.h similarity index 69% rename from app/task/cache/cache.h rename to app/task/precache/precachetask.h index c17344713..090fedd44 100644 --- a/app/task/cache/cache.h +++ b/app/task/precache/precachetask.h @@ -18,38 +18,36 @@ ***/ -#ifndef CACHETASK_H -#define CACHETASK_H - -#include +#ifndef PRECACHETASK_H +#define PRECACHETASK_H +#include "node/input/media/video/video.h" +#include "project/item/footage/footage.h" +#include "project/item/sequence/sequence.h" #include "task/render/render.h" OLIVE_NAMESPACE_ENTER -class CacheTask : public RenderTask +class PreCacheTask : public RenderTask { - Q_OBJECT public: - CacheTask(RenderBackend* backend, bool in_out_only); - CacheTask(ViewerOutput* viewer, - const VideoParams &vparams, - const AudioParams &aparams, - bool in_out_only); + PreCacheTask(VideoStreamPtr footage, Sequence* sequence); + + virtual ~PreCacheTask() override; protected: virtual bool Run() override; virtual QFuture DownloadFrame(FramePtr frame, const QByteArray &hash) override; - virtual void FrameDownloaded(const QByteArray& hash, const std::list& times) override; + virtual void FrameDownloaded(const QByteArray& hash, const std::list& times, qint64 job_time) override; - virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) override; + virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples, qint64 job_time) override; private: - void Init(); + VideoStreamPtr footage_; - bool in_out_only_; + VideoInput* video_node_; QThreadPool download_threads_; @@ -57,4 +55,4 @@ private: OLIVE_NAMESPACE_EXIT -#endif // CACHETASK_H +#endif // PRECACHETASK_H diff --git a/app/task/render/render.cpp b/app/task/render/render.cpp index 5d81a8643..45bede9e4 100644 --- a/app/task/render/render.cpp +++ b/app/task/render/render.cpp @@ -24,31 +24,17 @@ OLIVE_NAMESPACE_ENTER -RenderTask::RenderTask(RenderBackend *backend) : - backend_(backend) -{ - job_time_ = QDateTime::currentMSecsSinceEpoch(); - - backend_is_ours_ = false; -} - RenderTask::RenderTask(ViewerOutput* viewer, const VideoParams &vparams, const AudioParams &aparams) { - job_time_ = QDateTime::currentMSecsSinceEpoch(); - backend_ = new OpenGLBackend(); backend_->SetViewerNode(viewer); backend_->SetVideoParams(vparams); backend_->SetAudioParams(aparams); - - backend_is_ours_ = true; } RenderTask::~RenderTask() { - if (backend_is_ours_) { - backend_->deleteLater(); - } + delete backend_; } struct TimeHashFuturePair { @@ -74,6 +60,7 @@ struct RangeSampleFuturePair { struct HashDownloadFuturePair { QByteArray hash; QFuture download_future; + qint64 job_time; }; void RenderTask::Render(const TimeRangeList& video_range, @@ -99,16 +86,16 @@ void RenderTask::Render(const TimeRangeList& video_range, QVector times; QVector hashes; std::list frame_queue; + qint64 hash_job_time; if (!video_range.isEmpty()) { - QList existing_hashes; - times = viewer()->video_frame_cache()->GetFrameListFromTimeRange(video_range); total_length += video_frame_sz * times.size(); RenderTicketPtr hash_future = backend_->Hash(times); hashes = hash_future->Get().value >(); + hash_job_time = hash_future->GetJobTime(); if (!hash_future->WasCancelled()) { for (int i=0;iframe_future->Get().value(); // Start multithreaded download here - download_futures.push_back({i->hash, DownloadFrame(f, i->hash)}); + download_futures.push_back({i->hash, DownloadFrame(f, i->hash), i->frame_future->GetJobTime()}); } i = render_lookup_table.erase(i); @@ -215,7 +203,7 @@ void RenderTask::Render(const TimeRangeList& video_range, } } - FrameDownloaded(j->hash, times_with_hash); + FrameDownloaded(j->hash, times_with_hash, j->job_time); existing_hashes.push_back(j->hash); @@ -234,7 +222,9 @@ void RenderTask::Render(const TimeRangeList& video_range, while (!IsCancelled() && k != audio_lookup_table.end()) { if (k->sample_future->IsFinished()) { - AudioDownloaded(k->range, k->sample_future->Get().value()); + AudioDownloaded(k->range, + k->sample_future->Get().value(), + k->sample_future->GetJobTime()); progress_counter += k->range.length().toDouble(); emit ProgressChanged(progress_counter / total_length); @@ -246,15 +236,8 @@ void RenderTask::Render(const TimeRangeList& video_range, } } - if (backend_is_ours_) { - // `Close` will block until all jobs are done making a safe deletion - backend_->Close(); - } -} - -void RenderTask::SetAnchorPoint(const rational &r) -{ - anchor_point_ = r; + // `Close` will block until all jobs are done making a safe deletion + backend_->Close(); } OLIVE_NAMESPACE_EXIT diff --git a/app/task/render/render.h b/app/task/render/render.h index 77b655c24..8571c0894 100644 --- a/app/task/render/render.h +++ b/app/task/render/render.h @@ -32,7 +32,6 @@ OLIVE_NAMESPACE_ENTER class RenderTask : public Task { public: - RenderTask(RenderBackend* backend); RenderTask(ViewerOutput* viewer, const VideoParams &vparams, const AudioParams &aparams); virtual ~RenderTask() override; @@ -44,9 +43,9 @@ protected: virtual QFuture DownloadFrame(FramePtr frame, const QByteArray &hash) = 0; - virtual void FrameDownloaded(const QByteArray& hash, const std::list& times) = 0; + virtual void FrameDownloaded(const QByteArray& hash, const std::list& times, qint64 job_time) = 0; - virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) = 0; + virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples, qint64 job_time) = 0; ViewerOutput* viewer() const { @@ -63,27 +62,14 @@ protected: return backend_->GetAudioParams(); } - void SetAnchorPoint(const rational& r); - - const qint64& job_time() const - { - return job_time_; - } - RenderBackend* backend() { return backend_; } private: - rational anchor_point_; - RenderBackend* backend_; - bool backend_is_ours_; - - qint64 job_time_; - }; OLIVE_NAMESPACE_EXIT diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index c5b4ab690..0a1dd0ab7 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -31,7 +31,7 @@ #include "core.h" #include "dialog/footageproperties/footageproperties.h" #include "dialog/sequence/sequence.h" -#include "task/cache/footagecache.h" +#include "task/precache/precachetask.h" #include "task/taskmanager.h" #include "widget/menu/menu.h" #include "widget/menu/menushared.h" @@ -427,7 +427,7 @@ void ProjectExplorer::ContextMenuStartProxy(QAction *a) // Start a background task for proxying foreach (VideoStreamPtr video_stream, video_streams) { - FootageCacheTask* proxy_task = new FootageCacheTask(video_stream, sequence); + PreCacheTask* proxy_task = new PreCacheTask(video_stream, sequence); TaskManager::instance()->AddTask(proxy_task); } } diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp index d0eb9e4c3..68acb08c7 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.cpp +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -136,7 +136,7 @@ void TimelineViewBase::drawForeground(QPainter *painter, const QRectF &rect) // Get playhead highlight color QColor highlight = palette().text().color(); - highlight.setAlpha(128); + highlight.setAlpha(32); painter->setPen(Qt::NoPen); painter->setBrush(highlight); painter->drawRect(playhead_rect); diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index a1a45e0fc..6e75c8327 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -34,7 +34,6 @@ #include "panel/scope/scope.h" #include "render/backend/opengl/openglbackend.h" #include "render/backend/renderticketwatcher.h" -#include "task/cache/cache.h" #include "viewerdisplay.h" #include "viewerplaybacktimer.h" #include "viewerqueue.h"