Mercurial > libdvdnav.hg
annotate read_cache.c @ 249:5d643668f1e3 src
I added this code myself a long time ago, but now I am quite convinced that
it is wrong: Why would we filter out SPU stream change events that switch
SPUs off? This breaks watching the trailer on the RC2 of "Girl, interrupted",
because you always get unwanted subtitles.
When I added this code, it fixed a problem with the RC2 of "Terminator", but
I cannot reproduce this problem any more. Back then, the menu highlights would
not show up, but they do now. I assume the problem really got fixed with proper
support for forced subtitles in xine, so this crappy workaround here can go
away.
After all, this way it is more symmetric to audio stream change events,
because these are not filtered.
author | mroi |
---|---|
date | Sun, 12 Sep 2004 15:12:43 +0000 |
parents | f794e1c17947 |
children | ef3b33441db5 |
rev | line source |
---|---|
105 | 1 /* |
0 | 2 * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> |
242
f794e1c17947
porting AMD64 patches from xine (provided by Goetz Waschk and Gwenole Beauchesne
mroi
parents:
230
diff
changeset
|
3 * 2001-2004 the dvdnav project |
105 | 4 * |
0 | 5 * This file is part of libdvdnav, a DVD navigation library. |
105 | 6 * |
0 | 7 * libdvdnav is free software; you can redistribute it and/or modify |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
105 | 11 * |
0 | 12 * libdvdnav is distributed in the hope that it will be useful, |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
105 | 16 * |
0 | 17 * You should have received a copy of the GNU General Public License |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
20 * | |
21 * $Id$ | |
22 * | |
23 */ | |
225 | 24 /* |
25 * There was a multithreaded read ahead cache in here for some time, but | |
26 * it had only been used for a short time. If you want to have a look at it, | |
27 * search the CVS attic. | |
28 */ | |
0 | 29 |
30 #ifdef HAVE_CONFIG_H | |
31 #include "config.h" | |
32 #endif | |
33 | |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
34 #include "dvdnav.h" |
230 | 35 #include "dvdnav_internal.h" |
0 | 36 #include "read_cache.h" |
46 | 37 #include <sys/time.h> |
38 #include <time.h> | |
39 | |
60 | 40 #define READ_CACHE_CHUNKS 10 |
41 | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
42 /* all cache chunks must be memory aligned to allow use of raw devices */ |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
43 #define ALIGNMENT 2048 |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
44 |
105 | 45 #define READ_AHEAD_SIZE_MIN 4 |
46 #define READ_AHEAD_SIZE_MAX 512 | |
47 | |
60 | 48 typedef struct read_cache_chunk_s { |
49 uint8_t *cache_buffer; | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
50 uint8_t *cache_buffer_base; /* used in malloc and free for alignment */ |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
51 int32_t cache_start_sector; /* -1 means cache invalid */ |
103
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
52 int32_t cache_read_count; /* this many sectors are already read */ |
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
53 size_t cache_block_count; /* this many sectors will go in this chunk */ |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
54 size_t cache_malloc_size; |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
55 int cache_valid; |
60 | 56 int usage_count; /* counts how many buffers where issued from this chunk */ |
57 } read_cache_chunk_t; | |
58 | |
59 struct read_cache_s { | |
60 read_cache_chunk_t chunk[READ_CACHE_CHUNKS]; | |
61 int current; | |
62 int freeing; /* is set to one when we are about to dispose the cache */ | |
166 | 63 uint32_t read_ahead_size; |
105 | 64 int read_ahead_incr; |
65 int last_sector; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
66 pthread_mutex_t lock; |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
67 |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
68 /* Bit of strange cross-linking going on here :) -- Gotta love C :) */ |
60 | 69 dvdnav_t *dvd_self; |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
70 }; |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
71 |
105 | 72 /* |
76 | 73 #define READ_CACHE_TRACE 0 |
105 | 74 */ |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
75 |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
76 #ifdef __GNUC__ |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
77 # if READ_CACHE_TRACE |
114 | 78 # define dprintf(fmt, args...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , ## args) |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
79 # else |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
80 # define dprintf(fmt, args...) /* Nowt */ |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
81 # endif |
41
50e0855a2017
Experimental multi-threaded cache now enabled by default so that it can get tested during change from 0.1.1 to 0.1.2
richwareham
parents:
40
diff
changeset
|
82 #else |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
83 # if READ_CACHE_TRACE |
114 | 84 # define dprintf(fmt, ...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , __VA_ARGS__) |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
85 # else |
176 | 86 #ifdef _MSC_VER |
87 # define dprintf(fmt, str) /* Nowt */ | |
88 #else | |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
89 # define dprintf(fmt, ...) /* Nowt */ |
176 | 90 #endif /* _MSC_VER */ |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
91 # endif |
41
50e0855a2017
Experimental multi-threaded cache now enabled by default so that it can get tested during change from 0.1.1 to 0.1.2
richwareham
parents:
40
diff
changeset
|
92 #endif |
50e0855a2017
Experimental multi-threaded cache now enabled by default so that it can get tested during change from 0.1.1 to 0.1.2
richwareham
parents:
40
diff
changeset
|
93 |
40
a049c3753f32
Added some packaging patches from Philipp Matthias Hahn <pmhahn@titan.lahn.de> and an initial (non-working) multi-threaded read-ahead cache.
richwareham
parents:
37
diff
changeset
|
94 |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
95 read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) { |
60 | 96 read_cache_t *self; |
97 int i; | |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
98 |
60 | 99 self = (read_cache_t *)malloc(sizeof(read_cache_t)); |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
100 |
60 | 101 if(self) { |
102 self->current = 0; | |
103 self->freeing = 0; | |
104 self->dvd_self = dvd_self; | |
105 | 105 self->last_sector = 0; |
106 self->read_ahead_size = READ_AHEAD_SIZE_MIN; | |
107 self->read_ahead_incr = 0; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
108 pthread_mutex_init(&self->lock, NULL); |
60 | 109 dvdnav_read_cache_clear(self); |
110 for (i = 0; i < READ_CACHE_CHUNKS; i++) { | |
111 self->chunk[i].cache_buffer = NULL; | |
112 self->chunk[i].usage_count = 0; | |
113 } | |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
114 } |
105 | 115 |
60 | 116 return self; |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
117 } |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
118 |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
119 void dvdnav_read_cache_free(read_cache_t* self) { |
60 | 120 dvdnav_t *tmp; |
121 int i; | |
105 | 122 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
123 pthread_mutex_lock(&self->lock); |
60 | 124 self->freeing = 1; |
125 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
126 if (self->chunk[i].cache_buffer && self->chunk[i].usage_count == 0) { | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
127 free(self->chunk[i].cache_buffer_base); |
60 | 128 self->chunk[i].cache_buffer = NULL; |
129 } | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
130 pthread_mutex_unlock(&self->lock); |
105 | 131 |
60 | 132 for (i = 0; i < READ_CACHE_CHUNKS; i++) |
133 if (self->chunk[i].cache_buffer) return; | |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
134 |
60 | 135 /* all buffers returned, free everything */ |
136 tmp = self->dvd_self; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
137 pthread_mutex_destroy(&self->lock); |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
138 free(self); |
60 | 139 free(tmp); |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
140 } |
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
141 |
0 | 142 /* This function MUST be called whenever self->file changes. */ |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
143 void dvdnav_read_cache_clear(read_cache_t *self) { |
60 | 144 int i; |
145 | |
0 | 146 if(!self) |
147 return; | |
105 | 148 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
149 pthread_mutex_lock(&self->lock); |
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
150 for (i = 0; i < READ_CACHE_CHUNKS; i++) |
60 | 151 self->chunk[i].cache_valid = 0; |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
152 pthread_mutex_unlock(&self->lock); |
0 | 153 } |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
154 |
0 | 155 /* This function is called just after reading the NAV packet. */ |
34
1f29402ef2ef
'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
richwareham
parents:
3
diff
changeset
|
156 void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) { |
103
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
157 int i, use; |
105 | 158 |
0 | 159 if(!self) |
60 | 160 return; |
105 | 161 |
60 | 162 if(!self->dvd_self->use_read_ahead) |
0 | 163 return; |
164 | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
165 pthread_mutex_lock(&self->lock); |
105 | 166 |
60 | 167 /* find a free cache chunk that best fits the required size */ |
168 use = -1; | |
169 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
61
6b7520caf9a1
fix stupid bug: test if the buffer is there before using it
mroi
parents:
60
diff
changeset
|
170 if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer && |
6b7520caf9a1
fix stupid bug: test if the buffer is there before using it
mroi
parents:
60
diff
changeset
|
171 self->chunk[i].cache_malloc_size >= block_count && |
60 | 172 (use == -1 || self->chunk[use].cache_malloc_size > self->chunk[i].cache_malloc_size)) |
173 use = i; | |
105 | 174 |
60 | 175 if (use == -1) { |
176 /* we haven't found a cache chunk, so we try to reallocate an existing one */ | |
177 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
178 if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer && | |
179 (use == -1 || self->chunk[use].cache_malloc_size < self->chunk[i].cache_malloc_size)) | |
180 use = i; | |
181 if (use >= 0) { | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
182 self->chunk[use].cache_buffer_base = realloc(self->chunk[use].cache_buffer_base, |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
183 block_count * DVD_VIDEO_LB_LEN + ALIGNMENT); |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
184 self->chunk[use].cache_buffer = |
242
f794e1c17947
porting AMD64 patches from xine (provided by Goetz Waschk and Gwenole Beauchesne
mroi
parents:
230
diff
changeset
|
185 (uint8_t *)(((uintptr_t)self->chunk[use].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); |
60 | 186 dprintf("pre_cache DVD read realloc happened\n"); |
187 self->chunk[use].cache_malloc_size = block_count; | |
188 } else { | |
189 /* we still haven't found a cache chunk, let's allocate a new one */ | |
190 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
191 if (!self->chunk[i].cache_buffer) { | |
192 use = i; | |
193 break; | |
194 } | |
195 if (use >= 0) { | |
196 /* We start with a sensible figure for the first malloc of 500 blocks. | |
197 * Some DVDs I have seen venture to 450 blocks. | |
198 * This is so that fewer realloc's happen if at all. | |
105 | 199 */ |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
200 self->chunk[i].cache_buffer_base = |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
201 malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT); |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
202 self->chunk[i].cache_buffer = |
242
f794e1c17947
porting AMD64 patches from xine (provided by Goetz Waschk and Gwenole Beauchesne
mroi
parents:
230
diff
changeset
|
203 (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); |
60 | 204 self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500; |
205 dprintf("pre_cache DVD read malloc %d blocks\n", | |
105 | 206 (block_count > 500 ? block_count : 500 )); |
0 | 207 } |
208 } | |
48 | 209 } |
105 | 210 |
60 | 211 if (use >= 0) { |
212 self->chunk[use].cache_start_sector = sector; | |
213 self->chunk[use].cache_block_count = block_count; | |
103
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
214 self->chunk[use].cache_read_count = 0; |
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
215 self->chunk[use].cache_valid = 1; |
60 | 216 self->current = use; |
105 | 217 } else { |
60 | 218 dprintf("pre_caching was impossible, no cache chunk available\n"); |
105 | 219 } |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
220 pthread_mutex_unlock(&self->lock); |
60 | 221 } |
222 | |
223 int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) { | |
224 int i, use; | |
105 | 225 int start; |
226 int size; | |
227 int incr; | |
228 uint8_t *read_ahead_buf; | |
229 int32_t res; | |
230 | |
60 | 231 if(!self) |
232 return 0; | |
105 | 233 |
60 | 234 use = -1; |
105 | 235 |
60 | 236 if(self->dvd_self->use_read_ahead) { |
237 /* first check, if sector is in current chunk */ | |
238 read_cache_chunk_t cur = self->chunk[self->current]; | |
239 if (cur.cache_valid && sector >= cur.cache_start_sector && | |
105 | 240 sector <= (cur.cache_start_sector + cur.cache_read_count) && |
60 | 241 sector + block_count <= cur.cache_start_sector + cur.cache_block_count) |
242 use = self->current; | |
243 else | |
244 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
105 | 245 if (self->chunk[i].cache_valid && |
246 sector >= self->chunk[i].cache_start_sector && | |
247 sector <= (self->chunk[i].cache_start_sector + self->chunk[i].cache_read_count) && | |
248 sector + block_count <= self->chunk[i].cache_start_sector + self->chunk[i].cache_block_count) | |
249 use = i; | |
60 | 250 } |
105 | 251 |
60 | 252 if (use >= 0) { |
108 | 253 read_cache_chunk_t *chunk; |
254 | |
105 | 255 /* Increment read-ahead size if sector follows the last sector */ |
256 if (sector == (self->last_sector + 1)) { | |
225 | 257 if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX) |
258 self->read_ahead_incr++; | |
105 | 259 } else { |
260 self->read_ahead_size = READ_AHEAD_SIZE_MIN; | |
261 self->read_ahead_incr = 0; | |
262 } | |
263 self->last_sector = sector; | |
264 | |
265 /* The following resources need to be protected by a mutex : | |
266 * self->chunk[*].cache_buffer | |
267 * self->chunk[*].cache_malloc_size | |
268 * self->chunk[*].usage_count | |
269 */ | |
270 pthread_mutex_lock(&self->lock); | |
108 | 271 chunk = &self->chunk[use]; |
105 | 272 read_ahead_buf = chunk->cache_buffer + chunk->cache_read_count * DVD_VIDEO_LB_LEN; |
273 *buf = chunk->cache_buffer + (sector - chunk->cache_start_sector) * DVD_VIDEO_LB_LEN; | |
274 chunk->usage_count++; | |
275 pthread_mutex_unlock(&self->lock); | |
276 | |
225 | 277 dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count); |
105 | 278 |
225 | 279 /* read_ahead_size */ |
280 incr = self->read_ahead_incr >> 1; | |
281 if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) { | |
282 self->read_ahead_size = READ_AHEAD_SIZE_MAX; | |
283 } else { | |
284 self->read_ahead_size += incr; | |
285 } | |
105 | 286 |
225 | 287 /* real read size */ |
288 start = chunk->cache_start_sector + chunk->cache_read_count; | |
289 if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) { | |
290 size = chunk->cache_block_count - chunk->cache_read_count; | |
291 } else { | |
292 size = self->read_ahead_size; | |
293 /* ensure that the sector we want will be read */ | |
294 if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size) | |
295 size = sector - chunk->cache_start_sector - chunk->cache_read_count; | |
296 } | |
297 dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size); | |
105 | 298 |
225 | 299 if (size) |
105 | 300 chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file, |
301 start, | |
302 size, | |
303 read_ahead_buf); | |
304 | |
305 res = DVD_VIDEO_LB_LEN * block_count; | |
306 | |
60 | 307 } else { |
105 | 308 |
60 | 309 if (self->dvd_self->use_read_ahead) |
310 dprintf("cache miss on sector %d\n", sector); | |
105 | 311 |
312 res = DVDReadBlocks(self->dvd_self->file, | |
313 sector, | |
314 block_count, | |
315 *buf) * DVD_VIDEO_LB_LEN; | |
60 | 316 } |
105 | 317 |
318 return res; | |
319 | |
60 | 320 } |
321 | |
322 dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) { | |
323 read_cache_t *cache; | |
324 int i; | |
105 | 325 |
60 | 326 if (!self) |
327 return DVDNAV_STATUS_ERR; | |
105 | 328 |
60 | 329 cache = self->cache; |
330 if (!cache) | |
331 return DVDNAV_STATUS_ERR; | |
105 | 332 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
333 pthread_mutex_lock(&cache->lock); |
105 | 334 for (i = 0; i < READ_CACHE_CHUNKS; i++) { |
60 | 335 if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer && |
105 | 336 buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) { |
60 | 337 cache->chunk[i].usage_count--; |
105 | 338 } |
339 } | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
340 pthread_mutex_unlock(&cache->lock); |
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
341 |
60 | 342 if (cache->freeing) |
343 /* when we want to dispose the cache, try freeing it now */ | |
344 dvdnav_read_cache_free(cache); | |
105 | 345 |
60 | 346 return DVDNAV_STATUS_OK; |
0 | 347 } |