static int cache_read(URLContext *h, unsigned char *buf, int size) { Context *c= h->priv_data; CacheEntry *entry, *next[2] = {NULL, NULL}; int r; entry = av_tree_find(c->root, &c->logical_pos, cmp, (void**)next); if (!entry) entry = next[0]; if (entry) { int64_t in_block_pos = c->logical_pos - entry->logical_pos; av_assert0(entry->logical_pos <= c->logical_pos); if (in_block_pos < entry->size) { int64_t physical_target = entry->physical_pos + in_block_pos; if (c->cache_pos != physical_target) { r = lseek(c->fd, physical_target, SEEK_SET); } else r = c->cache_pos; if (r >= 0) { c->cache_pos = r; r = read(c->fd, buf, FFMIN(size, entry->size - in_block_pos)); } if (r > 0) { c->cache_pos += r; c->logical_pos += r; c->cache_hit ++; return r; } } } // Cache miss or some kind of fault with the cache if (c->logical_pos != c->inner_pos) { r = ffurl_seek(c->inner, c->logical_pos, SEEK_SET); if (r<0) { av_log(h, AV_LOG_ERROR, "Failed to perform internal seek\n"); return r; } c->inner_pos = r; } r = ffurl_read(c->inner, buf, size); if (r == 0 && size>0) { c->is_true_eof = 1; av_assert0(c->end >= c->logical_pos); } if (r<=0) return r; c->inner_pos += r; c->cache_miss ++; add_entry(h, buf, r); c->logical_pos += r; c->end = FFMAX(c->end, c->logical_pos); return r; }