summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-06-01 21:56:24 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commit976ee96e450487e8eb14e7e895d4c39bec14930c (patch)
treee67290d6940dfe150323e196d663f92d3b0ebe78 /etc
parente7db262450d499c7f511e3f7b2aed5af6419527d (diff)
downloadmpv-976ee96e450487e8eb14e7e895d4c39bec14930c.tar.bz2
mpv-976ee96e450487e8eb14e7e895d4c39bec14930c.tar.xz
demux: don't loop over all packets to find forward buffered size on seek
The size of all forward buffered packets is used to control maximum buffering. Until now, this size was incrementally adjusted, but had to be recomputed on seeks within the cache. Doing this was actually pretty expensive. It iterates over a linked list of separate memory allocations (which are probably spread all over the heap due to the allocation behavior), and the demux_packet_estimate_total_size() call touches a lot of further memory locations. I guess this affects the cache rather negatively. In an unscientific test, the recompute_buffers() function (which contained this loop) was responsible for roughly half of the time seeking took. Replace this with a way that computes the buffered size between 2 packets in constant times. The demux_packet.cum_pos field contains the summed sizes of all previous packets, so subtracting cum_pos between two packets yields the size of all packets in between. We can do this because we never remove packets from the middle of the queue. We only add packets to the end, or remove packets at the beginning. The tail_cum_pos field is needed because we don't store the end position of a packet, so the last packet's position would be unknown. We could recompute the "estimated" packet size, or store the estimated size in the packet struct, but I just didn't like this. This also removes the cached fw_bytes fields. It's slightly nicer to just recompute them when needed. Maintaining them incrementally was annoying. total_size stays though, since recomputing it isn't that cheap (would need to loop over all ranges every time). I'm always using uint64_t for sizes. This is certainly needed (a stream could easily burn through more than 4GB of data, even if much less of that is cached). The actual cached amount should always fit into size_t, so it's casted to size_t for printfs (yes, I hate the way you specify stdint.h types in printfs, the less I have to use that crap, the better).
Diffstat (limited to 'etc')
0 files changed, 0 insertions, 0 deletions