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_;