diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-12-26 01:36:00 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-12-26 02:21:51 +0100 |
commit | 7c210c442462db78e05569ee23d4dd955c1b1a0b (patch) | |
tree | cf86667d65f34a3765388ef8fe17e6aba8ab8a7d | |
parent | 312151bb9af62a29429821e13871311f670e9d5a (diff) | |
download | ffmpeg-7c210c442462db78e05569ee23d4dd955c1b1a0b.tar.gz |
avformat/cache: Extend cache entries if possible instead of creating new ones
This reduces the number of cache entries and should significantly
reduce memory requirements
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavformat/cache.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/libavformat/cache.c b/libavformat/cache.c index f1e623a04d..f6787ee6cf 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -94,14 +94,9 @@ static int add_entry(URLContext *h, const unsigned char *buf, int size) Context *c= h->priv_data; int64_t pos = -1; int ret; - CacheEntry *entry = av_malloc(sizeof(*entry)); + CacheEntry *entry = NULL, *next[2] = {NULL, NULL}; CacheEntry *entry_ret; - struct AVTreeNode *node = av_tree_node_alloc(); - - if (!entry || !node) { - ret = AVERROR(ENOMEM); - goto fail; - } + struct AVTreeNode *node = NULL; //FIXME avoid lseek pos = lseek(c->fd, 0, SEEK_END); @@ -118,18 +113,35 @@ static int add_entry(URLContext *h, const unsigned char *buf, int size) av_log(h, AV_LOG_ERROR, "write in cache failed\n"); goto fail; } + c->cache_pos += ret; - entry->logical_pos = c->logical_pos; - entry->physical_pos = pos; - entry->size = ret; - c->cache_pos = entry->physical_pos + entry->size; + entry = av_tree_find(c->root, &c->logical_pos, cmp, (void**)next); - entry_ret = av_tree_insert(&c->root, entry, cmp, &node); - if (entry_ret && entry_ret != entry) { - ret = -1; - av_log(h, AV_LOG_ERROR, "av_tree_insert failed\n"); - goto fail; - } + if (!entry) + entry = next[0]; + + if (!entry || + entry->logical_pos + entry->size != c->logical_pos || + entry->physical_pos + entry->size != pos + ) { + entry = av_malloc(sizeof(*entry)); + node = av_tree_node_alloc(); + if (!entry || !node) { + ret = AVERROR(ENOMEM); + goto fail; + } + entry->logical_pos = c->logical_pos; + entry->physical_pos = pos; + entry->size = ret; + + entry_ret = av_tree_insert(&c->root, entry, cmp, &node); + if (entry_ret && entry_ret != entry) { + ret = -1; + av_log(h, AV_LOG_ERROR, "av_tree_insert failed\n"); + goto fail; + } + } else + entry->size += ret; return 0; fail: |