Mercurial > libdvdnav.hg
annotate read_cache.c @ 409:9b8bfc56a7fe src
Add dvdnav_program_play & dvdnav_current_title_program
Using title parts w/ dvdnav_part_play and dvdnav_current_title_info
is not reliable for use as chapter marks in files made from
transcoding. The start of a part does not necessarily fall strictly
inside the main title. Parts can have an intro sequence before
getting into the title. So we use program boundaries instead of
part markers to test when we have reached a chapter point during
encoding of the title. The same would apply to displaying the
current chapter during playback. The program boundaries
should be checked instead of looking for a part.
Patch from John Stebbins. Thanks!
author | erik |
---|---|
date | Fri, 30 Jul 2010 23:34:16 +0000 |
parents | 9c5aef10d165 |
children |
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 * |
389
d3c273ced49c
Use consistent license headers everywhere: Fix wrong FSF address.
diego
parents:
388
diff
changeset
|
17 * You should have received a copy of the GNU General Public License along |
d3c273ced49c
Use consistent license headers everywhere: Fix wrong FSF address.
diego
parents:
388
diff
changeset
|
18 * with libdvdnav; if not, write to the Free Software Foundation, Inc., |
d3c273ced49c
Use consistent license headers everywhere: Fix wrong FSF address.
diego
parents:
388
diff
changeset
|
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
0 | 20 */ |
225 | 21 /* |
22 * There was a multithreaded read ahead cache in here for some time, but | |
23 * it had only been used for a short time. If you want to have a look at it, | |
24 * search the CVS attic. | |
25 */ | |
0 | 26 |
27 #ifdef HAVE_CONFIG_H | |
28 #include "config.h" | |
29 #endif | |
30 | |
278 | 31 #include <inttypes.h> |
288
ce4230602517
moved away from dvdnav_internal.h inclusion of various system headers
nicodvb
parents:
285
diff
changeset
|
32 #include <stdlib.h> |
294
2146ff691bcd
include limits.h; it was included in the previous dvdnav_internal.h and without it players segfault
nicodvb
parents:
290
diff
changeset
|
33 #include <limits.h> |
290 | 34 #include <sys/time.h> |
35 #include <time.h> | |
395
9c5aef10d165
Move dvd_types.h, dvdnav_events.h and dvdnav.h into a dvdnav directory.
reimar
parents:
392
diff
changeset
|
36 #include "dvdnav/dvdnav.h" |
386 | 37 #include <dvdread/nav_types.h> |
38 #include <dvdread/ifo_types.h> | |
285
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
39 #include "remap.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
40 #include "vm/decoder.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
41 #include "vm/vm.h" |
230 | 42 #include "dvdnav_internal.h" |
0 | 43 #include "read_cache.h" |
46 | 44 |
60 | 45 #define READ_CACHE_CHUNKS 10 |
46 | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
47 /* 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
|
48 #define ALIGNMENT 2048 |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
49 |
105 | 50 #define READ_AHEAD_SIZE_MIN 4 |
51 #define READ_AHEAD_SIZE_MAX 512 | |
52 | |
60 | 53 typedef struct read_cache_chunk_s { |
54 uint8_t *cache_buffer; | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
55 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
|
56 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
|
57 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
|
58 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
|
59 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
|
60 int cache_valid; |
60 | 61 int usage_count; /* counts how many buffers where issued from this chunk */ |
62 } read_cache_chunk_t; | |
63 | |
64 struct read_cache_s { | |
65 read_cache_chunk_t chunk[READ_CACHE_CHUNKS]; | |
66 int current; | |
67 int freeing; /* is set to one when we are about to dispose the cache */ | |
166 | 68 uint32_t read_ahead_size; |
105 | 69 int read_ahead_incr; |
70 int last_sector; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
71 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
|
72 |
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
|
73 /* Bit of strange cross-linking going on here :) -- Gotta love C :) */ |
60 | 74 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
|
75 }; |
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
|
76 |
105 | 77 /* |
76 | 78 #define READ_CACHE_TRACE 0 |
105 | 79 */ |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
80 |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
81 #ifdef __GNUC__ |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
82 # if READ_CACHE_TRACE |
114 | 83 # 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
|
84 # else |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
85 # define dprintf(fmt, args...) /* Nowt */ |
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
86 # 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
|
87 #else |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
88 # if READ_CACHE_TRACE |
114 | 89 # 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
|
90 # else |
176 | 91 #ifdef _MSC_VER |
92 # define dprintf(fmt, str) /* Nowt */ | |
93 #else | |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
94 # define dprintf(fmt, ...) /* Nowt */ |
176 | 95 #endif /* _MSC_VER */ |
107
b2801805c433
include some fixes done in xine's copy to avoid merging conflicts
mroi
parents:
105
diff
changeset
|
96 # 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
|
97 #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
|
98 |
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
|
99 |
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 read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) { |
60 | 101 read_cache_t *self; |
102 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
|
103 |
60 | 104 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
|
105 |
60 | 106 if(self) { |
107 self->current = 0; | |
108 self->freeing = 0; | |
109 self->dvd_self = dvd_self; | |
105 | 110 self->last_sector = 0; |
111 self->read_ahead_size = READ_AHEAD_SIZE_MIN; | |
112 self->read_ahead_incr = 0; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
113 pthread_mutex_init(&self->lock, NULL); |
60 | 114 dvdnav_read_cache_clear(self); |
115 for (i = 0; i < READ_CACHE_CHUNKS; i++) { | |
116 self->chunk[i].cache_buffer = NULL; | |
117 self->chunk[i].usage_count = 0; | |
118 } | |
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
|
119 } |
105 | 120 |
60 | 121 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
|
122 } |
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
|
123 |
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
|
124 void dvdnav_read_cache_free(read_cache_t* self) { |
60 | 125 dvdnav_t *tmp; |
126 int i; | |
105 | 127 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
128 pthread_mutex_lock(&self->lock); |
60 | 129 self->freeing = 1; |
130 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
131 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
|
132 free(self->chunk[i].cache_buffer_base); |
60 | 133 self->chunk[i].cache_buffer = NULL; |
134 } | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
135 pthread_mutex_unlock(&self->lock); |
105 | 136 |
60 | 137 for (i = 0; i < READ_CACHE_CHUNKS; i++) |
138 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
|
139 |
60 | 140 /* all buffers returned, free everything */ |
141 tmp = self->dvd_self; | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
142 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
|
143 free(self); |
60 | 144 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
|
145 } |
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
|
146 |
0 | 147 /* 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
|
148 void dvdnav_read_cache_clear(read_cache_t *self) { |
60 | 149 int i; |
150 | |
0 | 151 if(!self) |
152 return; | |
105 | 153 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
154 pthread_mutex_lock(&self->lock); |
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
155 for (i = 0; i < READ_CACHE_CHUNKS; i++) |
60 | 156 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
|
157 pthread_mutex_unlock(&self->lock); |
0 | 158 } |
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
|
159 |
0 | 160 /* 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
|
161 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
|
162 int i, use; |
105 | 163 |
0 | 164 if(!self) |
60 | 165 return; |
105 | 166 |
60 | 167 if(!self->dvd_self->use_read_ahead) |
0 | 168 return; |
169 | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
170 pthread_mutex_lock(&self->lock); |
105 | 171 |
60 | 172 /* find a free cache chunk that best fits the required size */ |
173 use = -1; | |
174 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
|
175 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
|
176 self->chunk[i].cache_malloc_size >= block_count && |
60 | 177 (use == -1 || self->chunk[use].cache_malloc_size > self->chunk[i].cache_malloc_size)) |
178 use = i; | |
105 | 179 |
60 | 180 if (use == -1) { |
181 /* we haven't found a cache chunk, so we try to reallocate an existing one */ | |
182 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
183 if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer && | |
184 (use == -1 || self->chunk[use].cache_malloc_size < self->chunk[i].cache_malloc_size)) | |
185 use = i; | |
186 if (use >= 0) { | |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
187 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
|
188 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
|
189 self->chunk[use].cache_buffer = |
242
f794e1c17947
porting AMD64 patches from xine (provided by Goetz Waschk and Gwenole Beauchesne
mroi
parents:
230
diff
changeset
|
190 (uint8_t *)(((uintptr_t)self->chunk[use].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); |
60 | 191 dprintf("pre_cache DVD read realloc happened\n"); |
192 self->chunk[use].cache_malloc_size = block_count; | |
193 } else { | |
194 /* we still haven't found a cache chunk, let's allocate a new one */ | |
195 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
196 if (!self->chunk[i].cache_buffer) { | |
197 use = i; | |
198 break; | |
199 } | |
200 if (use >= 0) { | |
201 /* We start with a sensible figure for the first malloc of 500 blocks. | |
202 * Some DVDs I have seen venture to 450 blocks. | |
203 * This is so that fewer realloc's happen if at all. | |
105 | 204 */ |
74
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
205 self->chunk[i].cache_buffer_base = |
bf89c194f781
align read cache chunks in memory to allow use of raw devices
mroi
parents:
65
diff
changeset
|
206 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
|
207 self->chunk[i].cache_buffer = |
242
f794e1c17947
porting AMD64 patches from xine (provided by Goetz Waschk and Gwenole Beauchesne
mroi
parents:
230
diff
changeset
|
208 (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); |
60 | 209 self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500; |
210 dprintf("pre_cache DVD read malloc %d blocks\n", | |
105 | 211 (block_count > 500 ? block_count : 500 )); |
0 | 212 } |
213 } | |
48 | 214 } |
105 | 215 |
60 | 216 if (use >= 0) { |
217 self->chunk[use].cache_start_sector = sector; | |
218 self->chunk[use].cache_block_count = block_count; | |
103
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
219 self->chunk[use].cache_read_count = 0; |
8905d8de7e91
changes to read cache behaviour inspired by Thibaut Mattern:
mroi
parents:
76
diff
changeset
|
220 self->chunk[use].cache_valid = 1; |
60 | 221 self->current = use; |
105 | 222 } else { |
60 | 223 dprintf("pre_caching was impossible, no cache chunk available\n"); |
105 | 224 } |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
225 pthread_mutex_unlock(&self->lock); |
60 | 226 } |
227 | |
228 int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) { | |
229 int i, use; | |
105 | 230 int start; |
231 int size; | |
232 int incr; | |
233 uint8_t *read_ahead_buf; | |
234 int32_t res; | |
235 | |
60 | 236 if(!self) |
237 return 0; | |
105 | 238 |
60 | 239 use = -1; |
105 | 240 |
60 | 241 if(self->dvd_self->use_read_ahead) { |
242 /* first check, if sector is in current chunk */ | |
243 read_cache_chunk_t cur = self->chunk[self->current]; | |
244 if (cur.cache_valid && sector >= cur.cache_start_sector && | |
105 | 245 sector <= (cur.cache_start_sector + cur.cache_read_count) && |
60 | 246 sector + block_count <= cur.cache_start_sector + cur.cache_block_count) |
247 use = self->current; | |
248 else | |
249 for (i = 0; i < READ_CACHE_CHUNKS; i++) | |
105 | 250 if (self->chunk[i].cache_valid && |
251 sector >= self->chunk[i].cache_start_sector && | |
252 sector <= (self->chunk[i].cache_start_sector + self->chunk[i].cache_read_count) && | |
253 sector + block_count <= self->chunk[i].cache_start_sector + self->chunk[i].cache_block_count) | |
254 use = i; | |
60 | 255 } |
105 | 256 |
60 | 257 if (use >= 0) { |
108 | 258 read_cache_chunk_t *chunk; |
388 | 259 |
105 | 260 /* Increment read-ahead size if sector follows the last sector */ |
261 if (sector == (self->last_sector + 1)) { | |
225 | 262 if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX) |
263 self->read_ahead_incr++; | |
105 | 264 } else { |
265 self->read_ahead_size = READ_AHEAD_SIZE_MIN; | |
266 self->read_ahead_incr = 0; | |
267 } | |
268 self->last_sector = sector; | |
269 | |
270 /* The following resources need to be protected by a mutex : | |
271 * self->chunk[*].cache_buffer | |
272 * self->chunk[*].cache_malloc_size | |
273 * self->chunk[*].usage_count | |
274 */ | |
275 pthread_mutex_lock(&self->lock); | |
108 | 276 chunk = &self->chunk[use]; |
105 | 277 read_ahead_buf = chunk->cache_buffer + chunk->cache_read_count * DVD_VIDEO_LB_LEN; |
278 *buf = chunk->cache_buffer + (sector - chunk->cache_start_sector) * DVD_VIDEO_LB_LEN; | |
279 chunk->usage_count++; | |
280 pthread_mutex_unlock(&self->lock); | |
281 | |
225 | 282 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 | 283 |
225 | 284 /* read_ahead_size */ |
285 incr = self->read_ahead_incr >> 1; | |
286 if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) { | |
287 self->read_ahead_size = READ_AHEAD_SIZE_MAX; | |
288 } else { | |
289 self->read_ahead_size += incr; | |
290 } | |
105 | 291 |
225 | 292 /* real read size */ |
293 start = chunk->cache_start_sector + chunk->cache_read_count; | |
294 if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) { | |
295 size = chunk->cache_block_count - chunk->cache_read_count; | |
296 } else { | |
297 size = self->read_ahead_size; | |
298 /* ensure that the sector we want will be read */ | |
299 if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size) | |
300 size = sector - chunk->cache_start_sector - chunk->cache_read_count; | |
301 } | |
302 dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size); | |
105 | 303 |
225 | 304 if (size) |
105 | 305 chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file, |
306 start, | |
307 size, | |
308 read_ahead_buf); | |
309 | |
310 res = DVD_VIDEO_LB_LEN * block_count; | |
311 | |
60 | 312 } else { |
105 | 313 |
60 | 314 if (self->dvd_self->use_read_ahead) |
315 dprintf("cache miss on sector %d\n", sector); | |
105 | 316 |
317 res = DVDReadBlocks(self->dvd_self->file, | |
318 sector, | |
319 block_count, | |
320 *buf) * DVD_VIDEO_LB_LEN; | |
60 | 321 } |
105 | 322 |
323 return res; | |
324 | |
60 | 325 } |
326 | |
327 dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) { | |
328 read_cache_t *cache; | |
329 int i; | |
105 | 330 |
60 | 331 if (!self) |
332 return DVDNAV_STATUS_ERR; | |
105 | 333 |
60 | 334 cache = self->cache; |
335 if (!cache) | |
336 return DVDNAV_STATUS_ERR; | |
105 | 337 |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
338 pthread_mutex_lock(&cache->lock); |
105 | 339 for (i = 0; i < READ_CACHE_CHUNKS; i++) { |
60 | 340 if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer && |
105 | 341 buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) { |
60 | 342 cache->chunk[i].usage_count--; |
105 | 343 } |
344 } | |
65
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
345 pthread_mutex_unlock(&cache->lock); |
dcde6d9cea7a
ensure serialized access to the cache to avoid concurrent access on the
mroi
parents:
62
diff
changeset
|
346 |
60 | 347 if (cache->freeing) |
348 /* when we want to dispose the cache, try freeing it now */ | |
349 dvdnav_read_cache_free(cache); | |
105 | 350 |
60 | 351 return DVDNAV_STATUS_OK; |
0 | 352 } |