Commit b48d49b6 authored by jan.koester's avatar jan.koester
Browse files

test



Co-authored-by: default avatarCopilot <copilot@github.com>
parent 3d685aef
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
mediadb (20260424+82) unstable; urgency=medium

  * Bulk-prefetch entire file (≤64 MB) in one parity round-trip before FFmpeg
    decode, instead of 52+ small range requests that each reconstruct the full
    parity group.  Reduces preview render from ~30s to ~2s for typical images.

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 00:00:00 +0200

mediadb (20260424+81) unstable; urgency=medium

  * Fix preview inflight coalescing: use predicate-based wait_until to prevent
+24 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ static std::string ff_err2str(int err) {
struct PrefetchBuffer {
    static constexpr std::size_t BLOCK_SIZE   = 64 * 1024;   // 64 KB — small blocks for fast initial decode
    static constexpr std::size_t AHEAD_BLOCKS = 4;           // 4 blocks ahead = 256 KB look-ahead
    // Files up to this size are fetched in a single cluster round-trip
    // instead of many small range requests (avoids repeated parity reconstruction).
    static constexpr std::size_t BULK_FETCH_LIMIT = 64ULL * 1024 * 1024; // 64 MB

    MediaBackendApi* db;
    ThreadPool*      io_pool;   // bounded I/O pool (separate from render pool)
@@ -32,6 +35,7 @@ struct PrefetchBuffer {
    std::uint64_t    total_size;
    std::uint64_t    pos = 0;
    bool             premature_eof = false;  // set when read returns empty before total_size
    std::vector<uint8_t> bulk_data_;         // pre-fetched full file (empty if not used)

    // prefetch ring — holds in-flight async reads
    struct PendingBlock {
@@ -53,6 +57,16 @@ struct PrefetchBuffer {
        }
    }

    // Fetch the entire file in a single cluster round-trip.
    // Call once after setting up db/media_id/total_size.
    void bulk_prefetch() {
        if (total_size == 0 || total_size > BULK_FETCH_LIMIT) return;
        bulk_data_ = db->read_media_data(media_id);
        if (!bulk_data_.empty()) {
            total_size = bulk_data_.size(); // align with actual bytes
        }
    }

    static std::string make_key(const std::string& mid, std::uint64_t off, std::uint64_t len) {
        return "prefetch:" + mid + ":" + std::to_string(off) + ":" + std::to_string(len);
    }
@@ -119,6 +133,15 @@ struct PrefetchBuffer {
    int read(uint8_t* buf, int want) {
        if (pos >= total_size) return AVERROR_EOF;

        // Fast path: serve from bulk-prefetched data
        if (!bulk_data_.empty()) {
            std::uint64_t avail = bulk_data_.size() - pos;
            std::uint64_t n = std::min<std::uint64_t>(want, avail);
            std::memcpy(buf, bulk_data_.data() + pos, n);
            pos += n;
            return static_cast<int>(n);
        }

        kick_prefetch();

        // drop blocks entirely before pos (after a seek)
@@ -825,6 +848,7 @@ std::optional<PreviewResult> FFmpegPreviewer::render_streaming(MediaBackendApi&
    prefetch_buf.cache      = &cache;
    prefetch_buf.media_id   = media_id;
    prefetch_buf.total_size = media_size;
    prefetch_buf.bulk_prefetch();  // single round-trip for files ≤ 64 MB

    constexpr size_t avio_buf_size = 32768;
    auto* avio_buf = static_cast<uint8_t*>(av_malloc(avio_buf_size));