Mercurial > mplayer.hg
annotate stream/cache2.c @ 33526:140525bcc32f
Fix GUI icon bug.
The GUI icon did not display properly but showed up with various distortions.
The reason was the icon mask which hadn't been put to the X server yet when
used.
The icon itself was okay, but is rendered now in a way that doesn't need a
drawable which spares creating a GTK window and destroying it right after.
The locally used GDK variables have been moved inside the function where
they are needed.
Patch with grateful support by Steaphan Greene, sgreene cs.binghamton edu.
This closes Bugzilla #582.
author | ib |
---|---|
date | Tue, 14 Jun 2011 17:51:17 +0000 |
parents | 850a3272e10d |
children | c77bf171b354 |
rev | line source |
---|---|
30426
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
1 /* |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
2 * This file is part of MPlayer. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
3 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
7 * (at your option) any later version. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
8 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
12 * GNU General Public License for more details. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
13 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
17 */ |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
30362
diff
changeset
|
18 |
2324 | 19 #include "config.h" |
20 | |
2322 | 21 // Initial draft of my new cache system... |
31181 | 22 // Note it runs in 2 processes (using fork()), but doesn't require locking!! |
2322 | 23 // TODO: seeking, data consistency checking |
24 | |
31193
f41fda4fe85f
100l, stream_check_for_interrupt argument is not in usec,
reimar
parents:
31190
diff
changeset
|
25 #define READ_SLEEP_TIME 10 |
31181 | 26 // These defines are used to reduce the cost of many successive |
31142
355302f83219
Optimize cache behaviour for the many-consecutive-seeks case.
reimar
parents:
31141
diff
changeset
|
27 // seeks (e.g. when a file has no index) by spinning quickly at first. |
355302f83219
Optimize cache behaviour for the many-consecutive-seeks case.
reimar
parents:
31141
diff
changeset
|
28 #define INITIAL_FILL_USLEEP_TIME 1000 |
355302f83219
Optimize cache behaviour for the many-consecutive-seeks case.
reimar
parents:
31141
diff
changeset
|
29 #define INITIAL_FILL_USLEEP_COUNT 10 |
2352 | 30 #define FILL_USLEEP_TIME 50000 |
4825
41d2da3bd082
Make blocking call in libmpdemux interuptable (only with new input,
albeu
parents:
3726
diff
changeset
|
31 #define PREFILL_SLEEP_TIME 200 |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
32 #define CONTROL_SLEEP_TIME 0 |
2322 | 33 |
34 #include <stdio.h> | |
35 #include <stdlib.h> | |
36 #include <string.h> | |
37 #include <signal.h> | |
3726 | 38 #include <sys/types.h> |
39 #include <unistd.h> | |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
40 #include <errno.h> |
2322 | 41 |
32529
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
32472
diff
changeset
|
42 #include "libavutil/avutil.h" |
27723
fb67a8f56bfc
Unconditionally #include osdep/shem.h, fixes the warnings on Cygwin:
diego
parents:
27343
diff
changeset
|
43 #include "osdep/shmem.h" |
17012 | 44 #include "osdep/timer.h" |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
45 #if defined(__MINGW32__) |
26077 | 46 #include <windows.h> |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
47 static void ThreadProc( void *s ); |
26077 | 48 #elif defined(__OS2__) |
49 #define INCL_DOS | |
50 #include <os2.h> | |
27756
1266470a5651
Revert declaring ThreadProc as void, it breaks the WINAPI.
diego
parents:
27727
diff
changeset
|
51 static void ThreadProc( void *s ); |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
52 #elif defined(PTHREAD_CACHE) |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
53 #include <pthread.h> |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
54 static void *ThreadProc(void *s); |
26077 | 55 #else |
10242 | 56 #include <sys/wait.h> |
31146 | 57 #define FORKED_CACHE 1 |
58 #endif | |
59 #ifndef FORKED_CACHE | |
60 #define FORKED_CACHE 0 | |
10197 | 61 #endif |
2322 | 62 |
2371 | 63 #include "mp_msg.h" |
16793
8d4fb5469efb
Make a few more messages translatable by moving them into help_mp-en.h.
diego
parents:
16750
diff
changeset
|
64 #include "help_mp.h" |
2371 | 65 |
2322 | 66 #include "stream.h" |
27876
298a3cd86bbb
Include cache2.h in cache2.c, fixes an implicit declaration warning for cache_do_control
reimar
parents:
27770
diff
changeset
|
67 #include "cache2.h" |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
68 #include "mp_global.h" |
2322 | 69 |
70 typedef struct { | |
71 // constats: | |
31181 | 72 unsigned char *buffer; // base pointer of the allocated buffer memory |
73 int buffer_size; // size of the allocated buffer memory | |
2352 | 74 int sector_size; // size of a single sector (2048/2324) |
75 int back_size; // we should keep back_size amount of old bytes for backward seek | |
76 int fill_limit; // we should fill buffer only if space>=fill_limit | |
31181 | 77 int seek_limit; // keep filling cache if distance is less that seek limit |
2374 | 78 // filler's pointers: |
79 int eof; | |
80 off_t min_filepos; // buffer contain only a part of the file, from min-max pos | |
81 off_t max_filepos; | |
82 off_t offset; // filepos <-> bufferpos offset value (filepos of the buffer's first byte) | |
2322 | 83 // reader's pointers: |
2374 | 84 off_t read_filepos; |
2322 | 85 // commands/locking: |
2352 | 86 // int seek_lock; // 1 if we will seek/reset buffer, 2 if we are ready for cmd |
87 // int fifo_flag; // 1 if we should use FIFO to notice cache about buffer reads. | |
2322 | 88 // callback |
89 stream_t* stream; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
90 volatile int control; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
91 volatile unsigned control_uint_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
92 volatile double control_double_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
93 volatile int control_res; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
94 volatile off_t control_new_pos; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
95 volatile double stream_time_length; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
96 volatile double stream_time_pos; |
2322 | 97 } cache_vars_t; |
98 | |
2352 | 99 static int min_fill=0; |
100 | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
101 static void cache_wakeup(stream_t *s) |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
102 { |
31146 | 103 #if FORKED_CACHE |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
104 // signal process to wake up immediately |
31167 | 105 kill(s->cache_pid, SIGUSR1); |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
106 #endif |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
107 } |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
108 |
30557
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
109 static int cache_read(cache_vars_t *s, unsigned char *buf, int size) |
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
110 { |
2322 | 111 int total=0; |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
112 int sleep_count = 0; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
113 int last_max = s->max_filepos; |
2322 | 114 while(size>0){ |
115 int pos,newb,len; | |
2352 | 116 |
117 //printf("CACHE2_READ: 0x%X <= 0x%X <= 0x%X \n",s->min_filepos,s->read_filepos,s->max_filepos); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
118 |
2374 | 119 if(s->read_filepos>=s->max_filepos || s->read_filepos<s->min_filepos){ |
2352 | 120 // eof? |
121 if(s->eof) break; | |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
122 if (s->max_filepos == last_max) { |
31193
f41fda4fe85f
100l, stream_check_for_interrupt argument is not in usec,
reimar
parents:
31190
diff
changeset
|
123 if (sleep_count++ == 10) |
32728
ce80aa247b4b
Change "cache not filling" warning to include a hint to increase the cache size.
reimar
parents:
32529
diff
changeset
|
124 mp_msg(MSGT_CACHE, MSGL_WARN, "Cache not filling, consider increasing -cache and/or -cache-min!\n"); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
125 } else { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
126 last_max = s->max_filepos; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
127 sleep_count = 0; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
128 } |
2352 | 129 // waiting for buffer fill... |
31193
f41fda4fe85f
100l, stream_check_for_interrupt argument is not in usec,
reimar
parents:
31190
diff
changeset
|
130 if (stream_check_interrupt(READ_SLEEP_TIME)) { |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
131 s->eof = 1; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
132 break; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
133 } |
2352 | 134 continue; // try again... |
135 } | |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
136 sleep_count = 0; |
2352 | 137 |
2374 | 138 newb=s->max_filepos-s->read_filepos; // new bytes in the buffer |
2322 | 139 if(newb<min_fill) min_fill=newb; // statistics... |
140 | |
141 // printf("*** newb: %d bytes ***\n",newb); | |
2352 | 142 |
143 pos=s->read_filepos - s->offset; | |
144 if(pos<0) pos+=s->buffer_size; else | |
145 if(pos>=s->buffer_size) pos-=s->buffer_size; | |
146 | |
2322 | 147 if(newb>s->buffer_size-pos) newb=s->buffer_size-pos; // handle wrap... |
148 if(newb>size) newb=size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
149 |
2352 | 150 // check: |
2371 | 151 if(s->read_filepos<s->min_filepos) mp_msg(MSGT_CACHE,MSGL_ERR,"Ehh. s->read_filepos<s->min_filepos !!! Report bug...\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
152 |
2322 | 153 // len=write(mem,newb) |
154 //printf("Buffer read: %d bytes\n",newb); | |
155 memcpy(buf,&s->buffer[pos],newb); | |
156 buf+=newb; | |
2352 | 157 len=newb; |
2322 | 158 // ... |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
159 |
2322 | 160 s->read_filepos+=len; |
161 size-=len; | |
162 total+=len; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
163 |
2322 | 164 } |
165 return total; | |
166 } | |
167 | |
30557
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
168 static int cache_fill(cache_vars_t *s) |
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
169 { |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7204
diff
changeset
|
170 int back,back2,newb,space,len,pos; |
2374 | 171 off_t read=s->read_filepos; |
32529
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
32472
diff
changeset
|
172 int read_chunk; |
33033
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
173 int wraparound_copy = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
174 |
2352 | 175 if(read<s->min_filepos || read>s->max_filepos){ |
176 // seek... | |
17366 | 177 mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",(int64_t)read); |
31305
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
178 // drop cache contents only if seeking backward or too much fwd. |
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
179 // This is also done for on-disk files, since it loses the backseek cache. |
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
180 // That in turn can cause major bandwidth increase and performance |
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
181 // issues with e.g. mov or badly interleaved files |
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
182 if(read<s->min_filepos || read>=s->max_filepos+s->seek_limit) |
8938
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
183 { |
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
184 s->offset= // FIXME!? |
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
185 s->min_filepos=s->max_filepos=read; // drop cache content :( |
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
186 if(s->stream->eof) stream_reset(s->stream); |
32472
5d1d67cf8718
Add internal read and seek function to avoid a useless memcpy when using
reimar
parents:
32468
diff
changeset
|
187 stream_seek_internal(s->stream,read); |
17366 | 188 mp_msg(MSGT_CACHE,MSGL_DBG2,"Seek done. new pos: 0x%"PRIX64" \n",(int64_t)stream_tell(s->stream)); |
8938
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
189 } |
2352 | 190 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
191 |
2322 | 192 // calc number of back-bytes: |
193 back=read - s->min_filepos; | |
194 if(back<0) back=0; // strange... | |
195 if(back>s->back_size) back=s->back_size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
196 |
2322 | 197 // calc number of new bytes: |
198 newb=s->max_filepos - read; | |
199 if(newb<0) newb=0; // strange... | |
200 | |
201 // calc free buffer space: | |
202 space=s->buffer_size - (newb+back); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
203 |
2322 | 204 // calc bufferpos: |
205 pos=s->max_filepos - s->offset; | |
206 if(pos>=s->buffer_size) pos-=s->buffer_size; // wrap-around | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
207 |
2322 | 208 if(space<s->fill_limit){ |
209 // printf("Buffer is full (%d bytes free, limit: %d)\n",space,s->fill_limit); | |
210 return 0; // no fill... | |
211 } | |
212 | |
213 // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
214 |
33033
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
215 // try to avoid wrap-around. If not possible due to sector size |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
216 // do an extra copy. |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
217 if(space>s->buffer_size-pos) { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
218 if (s->buffer_size-pos >= s->sector_size) { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
219 space=s->buffer_size-pos; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
220 } else { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
221 space = s->sector_size; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
222 wraparound_copy = 1; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
223 } |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
224 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
225 |
32468 | 226 // limit one-time block size |
32529
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
32472
diff
changeset
|
227 read_chunk = s->stream->read_chunk; |
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
32472
diff
changeset
|
228 if (!read_chunk) read_chunk = 4*s->sector_size; |
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
32472
diff
changeset
|
229 space = FFMIN(space, read_chunk); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
230 |
2352 | 231 #if 1 |
232 // back+newb+space <= buffer_size | |
233 back2=s->buffer_size-(space+newb); // max back size | |
234 if(s->min_filepos<(read-back2)) s->min_filepos=read-back2; | |
235 #else | |
2322 | 236 s->min_filepos=read-back; // avoid seeking-back to temp area... |
2352 | 237 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
238 |
33033
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
239 if (wraparound_copy) { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
240 int to_copy; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
241 len = stream_read_internal(s->stream, s->stream->buffer, space); |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
242 to_copy = FFMIN(len, s->buffer_size-pos); |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
243 memcpy(s->buffer + pos, s->stream->buffer, to_copy); |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
244 memcpy(s->buffer, s->stream->buffer + to_copy, len - to_copy); |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
245 } else |
32472
5d1d67cf8718
Add internal read and seek function to avoid a useless memcpy when using
reimar
parents:
32468
diff
changeset
|
246 len = stream_read_internal(s->stream, &s->buffer[pos], space); |
31169 | 247 s->eof= !len; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
248 |
2322 | 249 s->max_filepos+=len; |
250 if(pos+len>=s->buffer_size){ | |
251 // wrap... | |
252 s->offset+=s->buffer_size; | |
253 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
254 |
2322 | 255 return len; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
256 |
2322 | 257 } |
258 | |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
259 static int cache_execute_control(cache_vars_t *s) { |
33348 | 260 double double_res; |
261 unsigned uint_res; | |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
262 static unsigned last; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
263 int quit = s->control == -2; |
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
264 if (quit || !s->stream->control) { |
26897
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
265 s->stream_time_length = 0; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
266 s->stream_time_pos = MP_NOPTS_VALUE; |
26897
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
267 s->control_new_pos = 0; |
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
268 s->control_res = STREAM_UNSUPPORTED; |
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
269 s->control = -1; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
270 return !quit; |
26897
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
271 } |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
272 if (GetTimerMS() - last > 99) { |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
273 double len, pos; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
274 if (s->stream->control(s->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) == STREAM_OK) |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
275 s->stream_time_length = len; |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
276 else |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
277 s->stream_time_length = 0; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
278 if (s->stream->control(s->stream, STREAM_CTRL_GET_CURRENT_TIME, &pos) == STREAM_OK) |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
279 s->stream_time_pos = pos; |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
280 else |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
281 s->stream_time_pos = MP_NOPTS_VALUE; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
282 last = GetTimerMS(); |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
283 } |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
284 if (s->control == -1) return 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
285 switch (s->control) { |
33360 | 286 case STREAM_CTRL_SEEK_TO_TIME: |
287 double_res = s->control_double_arg; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
288 case STREAM_CTRL_GET_CURRENT_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
289 case STREAM_CTRL_GET_ASPECT_RATIO: |
33348 | 290 s->control_res = s->stream->control(s->stream, s->control, &double_res); |
291 s->control_double_arg = double_res; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
292 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
293 case STREAM_CTRL_SEEK_TO_CHAPTER: |
33360 | 294 case STREAM_CTRL_SET_ANGLE: |
295 uint_res = s->control_uint_arg; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
296 case STREAM_CTRL_GET_NUM_CHAPTERS: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
297 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
298 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
299 case STREAM_CTRL_GET_ANGLE: |
33348 | 300 s->control_res = s->stream->control(s->stream, s->control, &uint_res); |
301 s->control_uint_arg = uint_res; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
302 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
303 default: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
304 s->control_res = STREAM_UNSUPPORTED; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
305 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
306 } |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
307 s->control_new_pos = s->stream->pos; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
308 s->control = -1; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
309 return 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
310 } |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
311 |
31147 | 312 static void *shared_alloc(int size) { |
313 #if FORKED_CACHE | |
314 return shmem_alloc(size); | |
315 #else | |
316 return malloc(size); | |
317 #endif | |
318 } | |
319 | |
320 static void shared_free(void *ptr, int size) { | |
321 #if FORKED_CACHE | |
322 shmem_free(ptr, size); | |
323 #else | |
324 free(ptr); | |
325 #endif | |
326 } | |
327 | |
30359
44b8f698fd15
Make cache_init static, it is not used outside this file
reimar
parents:
30355
diff
changeset
|
328 static cache_vars_t* cache_init(int size,int sector){ |
2322 | 329 int num; |
31147 | 330 cache_vars_t* s=shared_alloc(sizeof(cache_vars_t)); |
12899 | 331 if(s==NULL) return NULL; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
332 |
2322 | 333 memset(s,0,sizeof(cache_vars_t)); |
334 num=size/sector; | |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
335 if(num < 16){ |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
336 num = 16; |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
337 }//32kb min_size |
2322 | 338 s->buffer_size=num*sector; |
339 s->sector_size=sector; | |
31147 | 340 s->buffer=shared_alloc(s->buffer_size); |
12899 | 341 |
342 if(s->buffer == NULL){ | |
31147 | 343 shared_free(s, sizeof(cache_vars_t)); |
12899 | 344 return NULL; |
345 } | |
346 | |
2322 | 347 s->fill_limit=8*sector; |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
348 s->back_size=s->buffer_size/2; |
2322 | 349 return s; |
350 } | |
351 | |
9915 | 352 void cache_uninit(stream_t *s) { |
353 cache_vars_t* c = s->cache_data; | |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
354 if(s->cache_pid) { |
31146 | 355 #if !FORKED_CACHE |
30353 | 356 cache_do_control(s, -2, NULL); |
26077 | 357 #else |
30353 | 358 kill(s->cache_pid,SIGKILL); |
359 waitpid(s->cache_pid,NULL,0); | |
10197 | 360 #endif |
30352 | 361 s->cache_pid = 0; |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
362 } |
9915 | 363 if(!c) return; |
31147 | 364 shared_free(c->buffer, c->buffer_size); |
30354 | 365 c->buffer = NULL; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
366 c->stream = NULL; |
31147 | 367 shared_free(s->cache_data, sizeof(cache_vars_t)); |
30352 | 368 s->cache_data = NULL; |
9915 | 369 } |
370 | |
2322 | 371 static void exit_sighandler(int x){ |
372 // close stream | |
373 exit(0); | |
374 } | |
375 | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
376 static void dummy_sighandler(int x) { |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
377 } |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
378 |
30360
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
379 /** |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
380 * Main loop of the cache process or thread. |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
381 */ |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
382 static void cache_mainloop(cache_vars_t *s) { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
383 int sleep_count = 0; |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
384 #if FORKED_CACHE |
31940
f1e3d7471ac8
Fix compilation with gcc 2.95.3 with some help by Reimar.
cehoyos
parents:
31835
diff
changeset
|
385 struct sigaction sa = { 0 }; |
f1e3d7471ac8
Fix compilation with gcc 2.95.3 with some help by Reimar.
cehoyos
parents:
31835
diff
changeset
|
386 sa.sa_handler = SIG_IGN; |
31672
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
387 sigaction(SIGUSR1, &sa, NULL); |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
388 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
389 do { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
390 if (!cache_fill(s)) { |
31167 | 391 #if FORKED_CACHE |
392 // Let signal wake us up, we cannot leave this | |
393 // enabled since we do not handle EINTR in most places. | |
394 // This might need extra code to work on BSD. | |
31672
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
395 sa.sa_handler = dummy_sighandler; |
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
396 sigaction(SIGUSR1, &sa, NULL); |
31167 | 397 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
398 if (sleep_count < INITIAL_FILL_USLEEP_COUNT) { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
399 sleep_count++; |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
400 usec_sleep(INITIAL_FILL_USLEEP_TIME); |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
401 } else |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
402 usec_sleep(FILL_USLEEP_TIME); // idle |
31167 | 403 #if FORKED_CACHE |
31672
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
404 sa.sa_handler = SIG_IGN; |
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
405 sigaction(SIGUSR1, &sa, NULL); |
31167 | 406 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
407 } else |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
408 sleep_count = 0; |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
409 } while (cache_execute_control(s)); |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
410 } |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
411 |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
412 /** |
30360
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
413 * \return 1 on success, 0 if the function was interrupted and -1 on error |
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
414 */ |
16152
10a69a812eff
remove unused cache-prefill and create cache-seek-min that controls when seek_long is prefered over waiting for cache to fill
iive
parents:
12899
diff
changeset
|
415 int stream_enable_cache(stream_t *stream,int size,int min,int seek_limit){ |
25445
959fca775f43
Fix stream_cache to use sector_size set in stream_t.
ulion
parents:
24697
diff
changeset
|
416 int ss = stream->sector_size ? stream->sector_size : STREAM_BUFFER_SIZE; |
30362
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
417 int res = -1; |
5991 | 418 cache_vars_t* s; |
7006
c0b490505298
disable cache if stream->fd<0 (no regular file/pipe but some special thing)
arpi
parents:
5991
diff
changeset
|
419 |
29888
5c39c41f38e8
Deobfuscate the special hack to disable cache for live555.
reimar
parents:
29263
diff
changeset
|
420 if (stream->flags & STREAM_NON_CACHEABLE) { |
7204 | 421 mp_msg(MSGT_CACHE,MSGL_STATUS,"\rThis stream is non-cacheable\n"); |
422 return 1; | |
423 } | |
7006
c0b490505298
disable cache if stream->fd<0 (no regular file/pipe but some special thing)
arpi
parents:
5991
diff
changeset
|
424 |
5991 | 425 s=cache_init(size,ss); |
30360
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
426 if(s == NULL) return -1; |
3562 | 427 stream->cache_data=s; |
428 s->stream=stream; // callback | |
16152
10a69a812eff
remove unused cache-prefill and create cache-seek-min that controls when seek_long is prefered over waiting for cache to fill
iive
parents:
12899
diff
changeset
|
429 s->seek_limit=seek_limit; |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
430 |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
431 |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
432 //make sure that we won't wait from cache_fill |
31181 | 433 //more data than it is allowed to fill |
16152
10a69a812eff
remove unused cache-prefill and create cache-seek-min that controls when seek_long is prefered over waiting for cache to fill
iive
parents:
12899
diff
changeset
|
434 if (s->seek_limit > s->buffer_size - s->fill_limit ){ |
10a69a812eff
remove unused cache-prefill and create cache-seek-min that controls when seek_long is prefered over waiting for cache to fill
iive
parents:
12899
diff
changeset
|
435 s->seek_limit = s->buffer_size - s->fill_limit; |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
436 } |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
437 if (min > s->buffer_size - s->fill_limit) { |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
438 min = s->buffer_size - s->fill_limit; |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
439 } |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
440 // to make sure we wait for the cache process/thread to be active |
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
441 // before continuing |
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
442 if (min <= 0) |
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
443 min = 1; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
444 |
31146 | 445 #if FORKED_CACHE |
3562 | 446 if((stream->cache_pid=fork())){ |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
447 if ((pid_t)stream->cache_pid == -1) |
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
448 stream->cache_pid = 0; |
10197 | 449 #else |
450 { | |
451 stream_t* stream2=malloc(sizeof(stream_t)); | |
452 memcpy(stream2,s->stream,sizeof(stream_t)); | |
453 s->stream=stream2; | |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
454 #if defined(__MINGW32__) |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
455 stream->cache_pid = _beginthread( ThreadProc, 0, s ); |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
456 #elif defined(__OS2__) |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
457 stream->cache_pid = _beginthread( ThreadProc, NULL, 256 * 1024, s ); |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
458 #else |
27896
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
459 { |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
460 pthread_t tid; |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
461 pthread_create(&tid, NULL, ThreadProc, s); |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
462 stream->cache_pid = 1; |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
463 } |
26077 | 464 #endif |
10197 | 465 #endif |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
466 if (!stream->cache_pid) { |
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
467 mp_msg(MSGT_CACHE, MSGL_ERR, |
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
468 "Starting cache process/thread failed: %s.\n", strerror(errno)); |
30362
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
469 goto err_out; |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
470 } |
3562 | 471 // wait until cache is filled at least prefill_init % |
17366 | 472 mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %"PRId64" [%"PRId64"] %"PRId64" pre:%d eof:%d \n", |
17384 | 473 (int64_t)s->min_filepos,(int64_t)s->read_filepos,(int64_t)s->max_filepos,min,s->eof); |
3562 | 474 while(s->read_filepos<s->min_filepos || s->max_filepos-s->read_filepos<min){ |
16793
8d4fb5469efb
Make a few more messages translatable by moving them into help_mp-en.h.
diego
parents:
16750
diff
changeset
|
475 mp_msg(MSGT_CACHE,MSGL_STATUS,MSGTR_CacheFill, |
3600 | 476 100.0*(float)(s->max_filepos-s->read_filepos)/(float)(s->buffer_size), |
17366 | 477 (int64_t)s->max_filepos-s->read_filepos |
3562 | 478 ); |
479 if(s->eof) break; // file is smaller than prefill size | |
30362
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
480 if(stream_check_interrupt(PREFILL_SLEEP_TIME)) { |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
481 res = 0; |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
482 goto err_out; |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
483 } |
3562 | 484 } |
16870 | 485 mp_msg(MSGT_CACHE,MSGL_STATUS,"\n"); |
4825
41d2da3bd082
Make blocking call in libmpdemux interuptable (only with new input,
albeu
parents:
3726
diff
changeset
|
486 return 1; // parent exits |
30362
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
487 |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
488 err_out: |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
489 cache_uninit(stream); |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
490 return res; |
3562 | 491 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
492 |
31146 | 493 #if FORKED_CACHE |
2322 | 494 signal(SIGTERM,exit_sighandler); // kill |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
495 cache_mainloop(s); |
30355
ca3e3df28fe2
Add an exit() to silence a gcc warning and ensure forked code will never
reimar
parents:
30354
diff
changeset
|
496 // make sure forked code never leaves this function |
ca3e3df28fe2
Add an exit() to silence a gcc warning and ensure forked code will never
reimar
parents:
30354
diff
changeset
|
497 exit(0); |
30712
75903ab49159
Restructure #ifs to be clearer, also ensures that we return from the thread
reimar
parents:
30691
diff
changeset
|
498 #endif |
2322 | 499 } |
500 | |
31146 | 501 #if !FORKED_CACHE |
502 #if defined(__MINGW32__) || defined(__OS2__) | |
503 static void ThreadProc( void *s ){ | |
504 cache_mainloop(s); | |
505 _endthread(); | |
506 } | |
507 #else | |
31145
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
508 static void *ThreadProc( void *s ){ |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
509 cache_mainloop(s); |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
510 return NULL; |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
511 } |
31146 | 512 #endif |
31145
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
513 #endif |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
514 |
2322 | 515 int cache_stream_fill_buffer(stream_t *s){ |
516 int len; | |
31835
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
517 int sector_size; |
2322 | 518 if(!s->cache_pid) return stream_fill_buffer(s); |
519 | |
2371 | 520 if(s->pos!=((cache_vars_t*)s->cache_data)->read_filepos) mp_msg(MSGT_CACHE,MSGL_ERR,"!!! read_filepos differs!!! report this bug...\n"); |
31835
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
521 sector_size = ((cache_vars_t*)s->cache_data)->sector_size; |
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
522 if (sector_size > STREAM_MAX_SECTOR_SIZE) { |
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
523 mp_msg(MSGT_CACHE, MSGL_ERR, "Sector size %i larger than maximum %i\n", sector_size, STREAM_MAX_SECTOR_SIZE); |
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
524 sector_size = STREAM_MAX_SECTOR_SIZE; |
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
525 } |
2327 | 526 |
31835
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
527 len=cache_read(s->cache_data,s->buffer, sector_size); |
2352 | 528 //printf("cache_stream_fill_buffer->read -> %d\n",len); |
2327 | 529 |
2322 | 530 if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } |
31169 | 531 s->eof=0; |
2322 | 532 s->buf_pos=0; |
533 s->buf_len=len; | |
534 s->pos+=len; | |
535 // printf("[%d]",len);fflush(stdout); | |
32438
faefba58f413
Implement a basic capture feature, available through -capture.
diego
parents:
32037
diff
changeset
|
536 if (s->capture_file) |
faefba58f413
Implement a basic capture feature, available through -capture.
diego
parents:
32037
diff
changeset
|
537 stream_capture_do(s); |
2322 | 538 return len; |
539 | |
540 } | |
541 | |
32731
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
542 int cache_fill_status(stream_t *s) { |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
543 cache_vars_t *cv; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
544 if (!s || !s->cache_data) |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
545 return -1; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
546 cv = s->cache_data; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
547 return (cv->max_filepos-cv->read_filepos)/(cv->buffer_size / 100); |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
548 } |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
549 |
2352 | 550 int cache_stream_seek_long(stream_t *stream,off_t pos){ |
551 cache_vars_t* s; | |
552 off_t newpos; | |
553 if(!stream->cache_pid) return stream_seek_long(stream,pos); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
554 |
2352 | 555 s=stream->cache_data; |
556 // s->seek_lock=1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
557 |
17366 | 558 mp_msg(MSGT_CACHE,MSGL_DBG2,"CACHE2_SEEK: 0x%"PRIX64" <= 0x%"PRIX64" (0x%"PRIX64") <= 0x%"PRIX64" \n",s->min_filepos,pos,s->read_filepos,s->max_filepos); |
2322 | 559 |
2352 | 560 newpos=pos/s->sector_size; newpos*=s->sector_size; // align |
561 stream->pos=s->read_filepos=newpos; | |
562 s->eof=0; // !!!!!!! | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
563 cache_wakeup(stream); |
2352 | 564 |
565 cache_stream_fill_buffer(stream); | |
2322 | 566 |
2352 | 567 pos-=newpos; |
568 if(pos>=0 && pos<=stream->buf_len){ | |
569 stream->buf_pos=pos; // byte position in sector | |
570 return 1; | |
571 } | |
572 | |
573 // stream->buf_pos=stream->buf_len=0; | |
574 // return 1; | |
575 | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16152
diff
changeset
|
576 mp_msg(MSGT_CACHE,MSGL_V,"cache_stream_seek: WARNING! Can't seek to 0x%"PRIX64" !\n",(int64_t)(pos+newpos)); |
2322 | 577 return 0; |
578 } | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
579 |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
580 int cache_do_control(stream_t *stream, int cmd, void *arg) { |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
581 int sleep_count = 0; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
582 cache_vars_t* s = stream->cache_data; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
583 switch (cmd) { |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
584 case STREAM_CTRL_SEEK_TO_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
585 s->control_double_arg = *(double *)arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
586 s->control = cmd; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
587 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
588 case STREAM_CTRL_SEEK_TO_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
589 case STREAM_CTRL_SET_ANGLE: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
590 s->control_uint_arg = *(unsigned *)arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
591 s->control = cmd; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
592 break; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
593 // the core might call these every frame, so cache them... |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
594 case STREAM_CTRL_GET_TIME_LENGTH: |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
595 *(double *)arg = s->stream_time_length; |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
596 return s->stream_time_length ? STREAM_OK : STREAM_UNSUPPORTED; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
597 case STREAM_CTRL_GET_CURRENT_TIME: |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
598 *(double *)arg = s->stream_time_pos; |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
599 return s->stream_time_pos != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED; |
26924
ca50c4a72f68
100l, fix wrong order of cases in cache_do_control
reimar
parents:
26897
diff
changeset
|
600 case STREAM_CTRL_GET_NUM_CHAPTERS: |
ca50c4a72f68
100l, fix wrong order of cases in cache_do_control
reimar
parents:
26897
diff
changeset
|
601 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
602 case STREAM_CTRL_GET_ASPECT_RATIO: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
603 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
604 case STREAM_CTRL_GET_ANGLE: |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
605 case -2: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
606 s->control = cmd; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
607 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
608 default: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
609 return STREAM_UNSUPPORTED; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
610 } |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
611 cache_wakeup(stream); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
612 while (s->control != -1) { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
613 if (sleep_count++ == 1000) |
31195 | 614 mp_msg(MSGT_CACHE, MSGL_WARN, "Cache not responding!\n"); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
615 if (stream_check_interrupt(CONTROL_SLEEP_TIME)) { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
616 s->eof = 1; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
617 return STREAM_UNSUPPORTED; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
618 } |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
619 } |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
620 switch (cmd) { |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
621 case STREAM_CTRL_GET_TIME_LENGTH: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
622 case STREAM_CTRL_GET_CURRENT_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
623 case STREAM_CTRL_GET_ASPECT_RATIO: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
624 *(double *)arg = s->control_double_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
625 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
626 case STREAM_CTRL_GET_NUM_CHAPTERS: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
627 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
628 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
629 case STREAM_CTRL_GET_ANGLE: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
630 *(unsigned *)arg = s->control_uint_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
631 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
632 case STREAM_CTRL_SEEK_TO_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
633 case STREAM_CTRL_SEEK_TO_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
634 case STREAM_CTRL_SET_ANGLE: |
31828
ba740e64ba01
Avoid STREAM_CTRL_SEEK_TO_TIME messing up the current position for stream
reimar
parents:
31672
diff
changeset
|
635 if (s->control_res != STREAM_UNSUPPORTED) |
ba740e64ba01
Avoid STREAM_CTRL_SEEK_TO_TIME messing up the current position for stream
reimar
parents:
31672
diff
changeset
|
636 stream->pos = s->read_filepos = s->control_new_pos; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
637 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
638 } |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
639 return s->control_res; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
640 } |