Changeset View
Changeset View
Standalone View
Standalone View
files/0002-stream-file-cache-file-size.patch
- This file was added.
| From c59ca06a0fff432ac4cae012bb0299a8db9a00d3 Mon Sep 17 00:00:00 2001 | |||||
| From: wm4 <wm4@nowhere> | |||||
| Date: Fri, 14 Feb 2020 16:07:13 +0100 | |||||
| Subject: [PATCH] stream_file: cache file size | |||||
| Some cache logic in demux.c queries the raw byte stream size on every | |||||
| packet read. This is because it reports the value to the user. (It has | |||||
| to be polled like this because there is no change notification in most | |||||
| underlying I/O APIs, and also the user can't just block on the demuxer | |||||
| thread to update it explicitly.) | |||||
| This causes a very high number of get_size calls with low packet sizes, | |||||
| so cache the size, and update it on every read. Reads only happen | |||||
| approximately all 64KB read with default settings, which is way less | |||||
| frequent than every packet in such extreme cases. | |||||
| In theory, this could in theory cause problems in some cases. Actually | |||||
| this is whole commit complete non-sense, because why micro-optimize for | |||||
| broken cases like patent troll codecs. I don't need to justify it | |||||
| anyway. | |||||
| As a minor detail, off_t is actually specified as signed, so the off_t | |||||
| cast is never needed. | |||||
| --- | |||||
| stream/stream_file.c | 15 +++++++++++---- | |||||
| 1 file changed, 11 insertions(+), 4 deletions(-) | |||||
| diff --git a/stream/stream_file.c b/stream/stream_file.c | |||||
| index a79ef0e913..6e69f33c94 100644 | |||||
| --- a/stream/stream_file.c | |||||
| +++ b/stream/stream_file.c | |||||
| @@ -64,6 +64,7 @@ struct priv { | |||||
| bool use_poll; | |||||
| bool regular_file; | |||||
| bool appending; | |||||
| + int64_t cached_size; // -2: invalid, -1: unknown | |||||
| int64_t orig_size; | |||||
| struct mp_cancel *cancel; | |||||
| }; | |||||
| @@ -75,15 +76,20 @@ struct priv { | |||||
| static int64_t get_size(stream_t *s) | |||||
| { | |||||
| struct priv *p = s->priv; | |||||
| - off_t size = lseek(p->fd, 0, SEEK_END); | |||||
| - lseek(p->fd, s->pos, SEEK_SET); | |||||
| - return size == (off_t)-1 ? -1 : size; | |||||
| + if (p->cached_size == -2) { | |||||
| + off_t size = lseek(p->fd, 0, SEEK_END); | |||||
| + lseek(p->fd, s->pos, SEEK_SET); | |||||
| + p->cached_size = size < 0 ? -1 : size; | |||||
| + } | |||||
| + return p->cached_size; | |||||
| } | |||||
| static int fill_buffer(stream_t *s, void *buffer, int max_len) | |||||
| { | |||||
| struct priv *p = s->priv; | |||||
| + p->cached_size = -2; // always invalidate cached size | |||||
| + | |||||
| #ifndef __MINGW32__ | |||||
| if (p->use_poll) { | |||||
| int c = mp_cancel_get_fd(p->cancel); | |||||
| @@ -245,7 +251,8 @@ static int open_f(stream_t *stream) | |||||
| { | |||||
| struct priv *p = talloc_ptrtype(stream, p); | |||||
| *p = (struct priv) { | |||||
| - .fd = -1 | |||||
| + .fd = -1, | |||||
| + .cached_size = -2, | |||||
| }; | |||||
| stream->priv = p; | |||||
| stream->is_local_file = true; | |||||
Copyright © 2015-2021 Solus Project. The Solus logo is Copyright © 2016-2021 Solus Project. All Rights Reserved.