summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-14 16:07:13 +0100
committerwm4 <wm4@nowhere>2020-02-14 16:07:13 +0100
commitc59ca06a0fff432ac4cae012bb0299a8db9a00d3 (patch)
treee50b04c632b29a8498b5cdf0206ea567423b965f
parent777c046b358e9e1b82f574875698e650722c0f5e (diff)
downloadmpv-c59ca06a0fff432ac4cae012bb0299a8db9a00d3.tar.bz2
mpv-c59ca06a0fff432ac4cae012bb0299a8db9a00d3.tar.xz
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.
-rw-r--r--stream/stream_file.c15
1 files 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;