From 1c5d55012babd33c9da2feda9ffd36c3f2d7e477 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 12 Jan 2020 01:14:56 +1100 Subject: [PATCH] video renderer will always render frames closest to the playhead first A few commits ago, the render behavior was changed to only render within a user-specified range of the playhead. This works well, but it would still render from the start of the range (usually before the playhead) to the end, meaning it couldn't keep up with the playhead as well as it should. This commit prioritizes frames close to the playhead and renders outwards to address this. --- app/codec/ffmpeg/ffmpegdecoder.cpp | 12 +++-- app/render/backend/videorenderbackend.cpp | 56 ++++++++++++++++++----- app/render/backend/videorenderbackend.h | 2 +- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 04c3ddcf9..1c1d51a08 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -202,7 +202,8 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode) DiskManager::instance()->Accessed(compressed_frame.fileName()); // Read data - QByteArray frame_loader = qUncompress(compressed_frame.readAll()); + //QByteArray frame_loader = qUncompress(compressed_frame.readAll()); + QByteArray frame_loader = compressed_frame.readAll(); // Frame was valid, now we convert it to a native Olive frame FramePtr frame_container = Frame::Create(); @@ -277,8 +278,11 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode) QFile save_frame(GetIndexFilename().append(QString::number(frame_->pts))); if (save_frame.open(QFile::WriteOnly)) { - QByteArray compressed = qCompress(reinterpret_cast(output_frame->data()), output_frame->allocated_size()); - save_frame.write(compressed); + // FIXME: This compression is really slow + //QByteArray compressed = qCompress(reinterpret_cast(output_frame->data()), output_frame->allocated_size()); + //save_frame.write(compressed); + + save_frame.write(output_frame->data(), output_frame->allocated_size()); save_frame.close(); DiskManager::instance()->CreatedFile(save_frame.fileName(), QByteArray()); @@ -374,7 +378,7 @@ int64_t FFmpegDecoder::GetTimestampFromTime(const rational &time) return -1; } - // Convert timecode to AVStream timebase + // Get rough approximation of what the timestamp would be in this timebase int64_t target_ts = Timecode::time_to_timestamp(time, avstream_->time_base); // Adjust target by stream's start time diff --git a/app/render/backend/videorenderbackend.cpp b/app/render/backend/videorenderbackend.cpp index 91b9d4543..8a2eb89e1 100644 --- a/app/render/backend/videorenderbackend.cpp +++ b/app/render/backend/videorenderbackend.cpp @@ -155,7 +155,7 @@ void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, co { TimeRange invalidated(start_range, end_range); - missing_cache_.InsertTimeRange(invalidated); + invalidated_.InsertTimeRange(invalidated); emit RangeInvalidated(invalidated); @@ -226,26 +226,58 @@ bool VideoRenderBackend::CanRender() TimeRange VideoRenderBackend::PopNextFrameFromQueue() { - TimeRange range = cache_queue_.first(); + // Try to find the frame that's closest to the last time requested (the playhead) - // Snap the range to a single discrete frame - rational snapped_in = Timecode::snap_time_to_timebase(range.in(), params_.time_base()); + // Set up playhead frame range to see if the queue contains this frame precisely + TimeRange test_range(last_time_requested_, last_time_requested_ + params_.time_base()); - // Check if the range starts earlier, in which case we should render that frame instead - if (range.in() < snapped_in) { - snapped_in -= params_.time_base(); + // Use this variable to find the closest frame in the range + rational closest_time = -1; + + for (int i=0;i(), last_time_requested_ + Config::Current()["DiskCacheAhead"].value()); - cache_queue_ = missing_cache_.Intersects(queueable_range); + cache_queue_ = invalidated_.Intersects(queueable_range); CacheNext(); } diff --git a/app/render/backend/videorenderbackend.h b/app/render/backend/videorenderbackend.h index 743661b53..394ce72d7 100644 --- a/app/render/backend/videorenderbackend.h +++ b/app/render/backend/videorenderbackend.h @@ -128,7 +128,7 @@ private: VideoRenderFrameCache frame_cache_; - TimeRangeList missing_cache_; + TimeRangeList invalidated_; rational last_time_requested_;