Mercurial > mplayer.hg
annotate stream/cache2.c @ 36782:06344efeded3
configure: improve FFmpeg check.
If internal FFmpeg is not available we should fall back to
external automatically instead of trying to build without
(which is currently broken it seems).
Also we can compile without internal copy as long as the
necessary headers can be found.
Two are required that FFmpeg does not install:
libavformat/internal.h
libavutil/x86/asm.h
author | reimar |
---|---|
date | Mon, 17 Feb 2014 23:25:32 +0000 |
parents | 7766530caa76 |
children |
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 |
35025
a11919e51187
Avoid sleeping 0 ms, this can cause sleep to be not called at all.
reimar
parents:
35013
diff
changeset
|
32 #define CONTROL_SLEEP_TIME 1 |
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" |
35712
d206960484fe
Add a number of missing libavutil header #includes.
diego
parents:
35266
diff
changeset
|
43 #include "libavutil/common.h" |
27723
fb67a8f56bfc
Unconditionally #include osdep/shem.h, fixes the warnings on Cygwin:
diego
parents:
27343
diff
changeset
|
44 #include "osdep/shmem.h" |
17012 | 45 #include "osdep/timer.h" |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
46 #if defined(__MINGW32__) |
26077 | 47 #include <windows.h> |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
48 static void ThreadProc( void *s ); |
26077 | 49 #elif defined(__OS2__) |
50 #define INCL_DOS | |
51 #include <os2.h> | |
27756
1266470a5651
Revert declaring ThreadProc as void, it breaks the WINAPI.
diego
parents:
27727
diff
changeset
|
52 static void ThreadProc( void *s ); |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
53 #elif defined(PTHREAD_CACHE) |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
54 #include <pthread.h> |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
55 static void *ThreadProc(void *s); |
26077 | 56 #else |
10242 | 57 #include <sys/wait.h> |
31146 | 58 #define FORKED_CACHE 1 |
59 #endif | |
60 #ifndef FORKED_CACHE | |
61 #define FORKED_CACHE 0 | |
10197 | 62 #endif |
2322 | 63 |
2371 | 64 #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
|
65 #include "help_mp.h" |
2371 | 66 |
2322 | 67 #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
|
68 #include "cache2.h" |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
69 #include "mp_global.h" |
2322 | 70 |
71 typedef struct { | |
72 // constats: | |
31181 | 73 unsigned char *buffer; // base pointer of the allocated buffer memory |
34704 | 74 int64_t buffer_size; // size of the allocated buffer memory |
2352 | 75 int sector_size; // size of a single sector (2048/2324) |
34704 | 76 int64_t back_size; // we should keep back_size amount of old bytes for backward seek |
77 int64_t fill_limit; // we should fill buffer only if space>=fill_limit | |
78 int64_t seek_limit; // keep filling cache if distance is less that seek limit | |
34283
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
79 #if FORKED_CACHE |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
80 pid_t ppid; // parent PID to detect killed parent |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
81 #endif |
2374 | 82 // filler's pointers: |
83 int eof; | |
34705 | 84 int64_t min_filepos; // buffer contain only a part of the file, from min-max pos |
85 int64_t max_filepos; | |
86 int64_t offset; // filepos <-> bufferpos offset value (filepos of the buffer's first byte) | |
2322 | 87 // reader's pointers: |
34705 | 88 int64_t read_filepos; |
2322 | 89 // commands/locking: |
2352 | 90 // int seek_lock; // 1 if we will seek/reset buffer, 2 if we are ready for cmd |
91 // int fifo_flag; // 1 if we should use FIFO to notice cache about buffer reads. | |
2322 | 92 // callback |
93 stream_t* stream; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
94 volatile int control; |
35013 | 95 volatile uint64_t control_uint_arg; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
96 volatile double control_double_arg; |
36428
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
97 volatile char *control_char_p_arg; |
34648
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
98 volatile struct stream_lang_req control_lang_arg; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
99 volatile int control_res; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
100 volatile double stream_time_length; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
101 volatile double stream_time_pos; |
2322 | 102 } cache_vars_t; |
103 | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
104 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
|
105 { |
31146 | 106 #if FORKED_CACHE |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
107 // signal process to wake up immediately |
31167 | 108 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
|
109 #endif |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
110 } |
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
111 |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
112 static void cache_flush(cache_vars_t *s) |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
113 { |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
114 s->offset= // FIXME!? |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
115 s->min_filepos=s->max_filepos=s->read_filepos; // drop cache content :( |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
116 } |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
117 |
30557
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
118 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
|
119 { |
2322 | 120 int total=0; |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
121 int sleep_count = 0; |
34704 | 122 int64_t last_max = s->max_filepos; |
2322 | 123 while(size>0){ |
34704 | 124 int64_t pos,newb,len; |
2352 | 125 |
126 //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
|
127 |
2374 | 128 if(s->read_filepos>=s->max_filepos || s->read_filepos<s->min_filepos){ |
2352 | 129 // eof? |
130 if(s->eof) break; | |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
131 if (s->max_filepos == last_max) { |
31193
f41fda4fe85f
100l, stream_check_for_interrupt argument is not in usec,
reimar
parents:
31190
diff
changeset
|
132 if (sleep_count++ == 10) |
33868
1714e25ded23
Another attempt to make message easier to understand.
reimar
parents:
33867
diff
changeset
|
133 mp_msg(MSGT_CACHE, MSGL_WARN, "Cache empty, consider increasing -cache and/or -cache-min. [performance issue]\n"); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
134 } else { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
135 last_max = s->max_filepos; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
136 sleep_count = 0; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
137 } |
2352 | 138 // waiting for buffer fill... |
31193
f41fda4fe85f
100l, stream_check_for_interrupt argument is not in usec,
reimar
parents:
31190
diff
changeset
|
139 if (stream_check_interrupt(READ_SLEEP_TIME)) { |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
140 s->eof = 1; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
141 break; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
142 } |
2352 | 143 continue; // try again... |
144 } | |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
145 sleep_count = 0; |
2352 | 146 |
2374 | 147 newb=s->max_filepos-s->read_filepos; // new bytes in the buffer |
2322 | 148 |
149 // printf("*** newb: %d bytes ***\n",newb); | |
2352 | 150 |
151 pos=s->read_filepos - s->offset; | |
152 if(pos<0) pos+=s->buffer_size; else | |
153 if(pos>=s->buffer_size) pos-=s->buffer_size; | |
154 | |
2322 | 155 if(newb>s->buffer_size-pos) newb=s->buffer_size-pos; // handle wrap... |
156 if(newb>size) newb=size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
157 |
2352 | 158 // check: |
2371 | 159 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
|
160 |
2322 | 161 // len=write(mem,newb) |
162 //printf("Buffer read: %d bytes\n",newb); | |
163 memcpy(buf,&s->buffer[pos],newb); | |
164 buf+=newb; | |
2352 | 165 len=newb; |
2322 | 166 // ... |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
167 |
2322 | 168 s->read_filepos+=len; |
169 size-=len; | |
170 total+=len; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
171 |
2322 | 172 } |
173 return total; | |
174 } | |
175 | |
30557
74a6c2a3dcce
stream: Mark functions not used outside of their files as static.
diego
parents:
30426
diff
changeset
|
176 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
|
177 { |
34704 | 178 int64_t back,back2,newb,space,len,pos; |
34705 | 179 int64_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
|
180 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
|
181 int wraparound_copy = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
182 |
2352 | 183 if(read<s->min_filepos || read>s->max_filepos){ |
184 // seek... | |
34706 | 185 mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",read); |
31305
7ae56026b7ee
Respect -cache-seek-min also for on-disk files to reduce issues with mov.
reimar
parents:
31195
diff
changeset
|
186 // 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
|
187 // 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
|
188 // 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
|
189 // 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
|
190 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
|
191 { |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
192 cache_flush(s); |
8938
fc21a94f98c6
do not discard cache content at seeking type=STREAMTYPE_STREAM
arpi
parents:
7862
diff
changeset
|
193 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
|
194 stream_seek_internal(s->stream,read); |
17366 | 195 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
|
196 } |
2352 | 197 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
198 |
2322 | 199 // calc number of back-bytes: |
200 back=read - s->min_filepos; | |
201 if(back<0) back=0; // strange... | |
202 if(back>s->back_size) back=s->back_size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
203 |
2322 | 204 // calc number of new bytes: |
205 newb=s->max_filepos - read; | |
206 if(newb<0) newb=0; // strange... | |
207 | |
208 // calc free buffer space: | |
209 space=s->buffer_size - (newb+back); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
210 |
2322 | 211 // calc bufferpos: |
212 pos=s->max_filepos - s->offset; | |
213 if(pos>=s->buffer_size) pos-=s->buffer_size; // wrap-around | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
214 |
2322 | 215 if(space<s->fill_limit){ |
216 // printf("Buffer is full (%d bytes free, limit: %d)\n",space,s->fill_limit); | |
217 return 0; // no fill... | |
218 } | |
219 | |
220 // 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
|
221 |
33033
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
222 // 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
|
223 // 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
|
224 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
|
225 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
|
226 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
|
227 } else { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
228 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
|
229 wraparound_copy = 1; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
230 } |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
231 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
232 |
32468 | 233 // 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
|
234 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
|
235 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
|
236 space = FFMIN(space, read_chunk); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
237 |
2352 | 238 #if 1 |
239 // back+newb+space <= buffer_size | |
240 back2=s->buffer_size-(space+newb); // max back size | |
241 if(s->min_filepos<(read-back2)) s->min_filepos=read-back2; | |
242 #else | |
2322 | 243 s->min_filepos=read-back; // avoid seeking-back to temp area... |
2352 | 244 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
245 |
33033
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
246 if (wraparound_copy) { |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
247 int to_copy; |
1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
reimar
parents:
32731
diff
changeset
|
248 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
|
249 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
|
250 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
|
251 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
|
252 } else |
32472
5d1d67cf8718
Add internal read and seek function to avoid a useless memcpy when using
reimar
parents:
32468
diff
changeset
|
253 len = stream_read_internal(s->stream, &s->buffer[pos], space); |
31169 | 254 s->eof= !len; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
255 |
2322 | 256 s->max_filepos+=len; |
257 if(pos+len>=s->buffer_size){ | |
258 // wrap... | |
259 s->offset+=s->buffer_size; | |
260 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
261 |
2322 | 262 return len; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
263 |
2322 | 264 } |
265 | |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
266 static int cache_execute_control(cache_vars_t *s) { |
33348 | 267 double double_res; |
268 unsigned uint_res; | |
35266
ceb148e1fe31
Change STREAM_CTRL_GET_SIZE argument type from off_t to
reimar
parents:
35169
diff
changeset
|
269 uint64_t uint64_res; |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
270 int needs_flush = 0; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
271 static unsigned last; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
272 int quit = s->control == -2; |
34488
01c19d9b1e83
Print an error when streams behave in a way that the cache cannot handle.
reimar
parents:
34487
diff
changeset
|
273 uint64_t old_pos = s->stream->pos; |
01c19d9b1e83
Print an error when streams behave in a way that the cache cannot handle.
reimar
parents:
34487
diff
changeset
|
274 int old_eof = s->stream->eof; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
275 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
|
276 s->stream_time_length = 0; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
277 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
|
278 s->control_res = STREAM_UNSUPPORTED; |
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
279 s->control = -1; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
280 return !quit; |
26897
23c3741dc490
Handle NULL control function in cache_execute_control, fixes crash with http urls.
reimar
parents:
26847
diff
changeset
|
281 } |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
282 if (GetTimerMS() - last > 99) { |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
283 double len, pos; |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
284 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
|
285 s->stream_time_length = len; |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
286 else |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
287 s->stream_time_length = 0; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
288 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
|
289 s->stream_time_pos = pos; |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
290 else |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
291 s->stream_time_pos = MP_NOPTS_VALUE; |
34283
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
292 #if FORKED_CACHE |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
293 // if parent PID changed, main process was killed -> exit |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
294 if (s->ppid != getppid()) { |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
295 mp_msg(MSGT_CACHE, MSGL_WARN, "Parent process disappeared, exiting cache process.\n"); |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
296 return 0; |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
297 } |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
298 #endif |
26847
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
299 last = GetTimerMS(); |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
300 } |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
301 if (s->control == -1) return 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
302 switch (s->control) { |
33360 | 303 case STREAM_CTRL_SEEK_TO_TIME: |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
304 needs_flush = 1; |
33360 | 305 double_res = s->control_double_arg; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
306 case STREAM_CTRL_GET_CURRENT_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
307 case STREAM_CTRL_GET_ASPECT_RATIO: |
33348 | 308 s->control_res = s->stream->control(s->stream, s->control, &double_res); |
309 s->control_double_arg = double_res; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
310 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
311 case STREAM_CTRL_SEEK_TO_CHAPTER: |
33360 | 312 case STREAM_CTRL_SET_ANGLE: |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
313 needs_flush = 1; |
33360 | 314 uint_res = s->control_uint_arg; |
35164 | 315 case STREAM_CTRL_GET_NUM_TITLES: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
316 case STREAM_CTRL_GET_NUM_CHAPTERS: |
35169
3b2c280da1af
Add new stream control command STREAM_CTRL_GET_CURRENT_TITLE for DVDs.
ib
parents:
35164
diff
changeset
|
317 case STREAM_CTRL_GET_CURRENT_TITLE: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
318 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
319 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
320 case STREAM_CTRL_GET_ANGLE: |
33348 | 321 s->control_res = s->stream->control(s->stream, s->control, &uint_res); |
322 s->control_uint_arg = uint_res; | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
323 break; |
35013 | 324 case STREAM_CTRL_GET_SIZE: |
325 s->control_res = s->stream->control(s->stream, s->control, &uint64_res); | |
326 s->control_uint_arg = uint64_res; | |
327 break; | |
34648
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
328 case STREAM_CTRL_GET_LANG: |
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
329 s->control_res = s->stream->control(s->stream, s->control, (void *)&s->control_lang_arg); |
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
330 break; |
36428
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
331 case STREAM_CTRL_GET_CURRENT_CHANNEL: |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
332 s->control_res = s->stream->control(s->stream, s->control, &s->control_char_p_arg); |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
333 break; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
334 default: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
335 s->control_res = STREAM_UNSUPPORTED; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
336 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
337 } |
34487 | 338 if (s->control_res == STREAM_OK && needs_flush) { |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
339 s->read_filepos = s->stream->pos; |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
340 s->eof = s->stream->eof; |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
341 cache_flush(s); |
34488
01c19d9b1e83
Print an error when streams behave in a way that the cache cannot handle.
reimar
parents:
34487
diff
changeset
|
342 } else if (needs_flush && |
01c19d9b1e83
Print an error when streams behave in a way that the cache cannot handle.
reimar
parents:
34487
diff
changeset
|
343 (old_pos != s->stream->pos || old_eof != s->stream->eof)) |
01c19d9b1e83
Print an error when streams behave in a way that the cache cannot handle.
reimar
parents:
34487
diff
changeset
|
344 mp_msg(MSGT_STREAM, MSGL_ERR, "STREAM_CTRL changed stream pos but returned error, this is not allowed!\n"); |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
345 s->control = -1; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
346 return 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
347 } |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
348 |
34704 | 349 static void *shared_alloc(int64_t size) { |
31147 | 350 #if FORKED_CACHE |
351 return shmem_alloc(size); | |
352 #else | |
353 return malloc(size); | |
354 #endif | |
355 } | |
356 | |
34704 | 357 static void shared_free(void *ptr, int64_t size) { |
31147 | 358 #if FORKED_CACHE |
359 shmem_free(ptr, size); | |
360 #else | |
361 free(ptr); | |
362 #endif | |
363 } | |
364 | |
34704 | 365 static cache_vars_t* cache_init(int64_t size,int sector){ |
366 int64_t num; | |
31147 | 367 cache_vars_t* s=shared_alloc(sizeof(cache_vars_t)); |
12899 | 368 if(s==NULL) return NULL; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
369 |
2322 | 370 memset(s,0,sizeof(cache_vars_t)); |
371 num=size/sector; | |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
372 if(num < 16){ |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
373 num = 16; |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
374 }//32kb min_size |
2322 | 375 s->buffer_size=num*sector; |
376 s->sector_size=sector; | |
31147 | 377 s->buffer=shared_alloc(s->buffer_size); |
12899 | 378 |
379 if(s->buffer == NULL){ | |
31147 | 380 shared_free(s, sizeof(cache_vars_t)); |
12899 | 381 return NULL; |
382 } | |
383 | |
2322 | 384 s->fill_limit=8*sector; |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
385 s->back_size=s->buffer_size/2; |
34283
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
386 #if FORKED_CACHE |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
387 s->ppid = getpid(); |
3a4adac4e9a5
Make cache process detect when the main process disappeared and
reimar
parents:
33868
diff
changeset
|
388 #endif |
2322 | 389 return s; |
390 } | |
391 | |
9915 | 392 void cache_uninit(stream_t *s) { |
393 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
|
394 if(s->cache_pid) { |
31146 | 395 #if !FORKED_CACHE |
30353 | 396 cache_do_control(s, -2, NULL); |
26077 | 397 #else |
30353 | 398 kill(s->cache_pid,SIGKILL); |
399 waitpid(s->cache_pid,NULL,0); | |
10197 | 400 #endif |
30352 | 401 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
|
402 } |
9915 | 403 if(!c) return; |
31147 | 404 shared_free(c->buffer, c->buffer_size); |
30354 | 405 c->buffer = NULL; |
30731
5a1ab9923c3a
Threaded cache fixes: do not free the stream_t struct twice on windows
reimar
parents:
30712
diff
changeset
|
406 c->stream = NULL; |
31147 | 407 shared_free(s->cache_data, sizeof(cache_vars_t)); |
30352 | 408 s->cache_data = NULL; |
9915 | 409 } |
410 | |
33617
c77bf171b354
cache2: Surround conditionally used functions by appropriate #ifdefs.
diego
parents:
33517
diff
changeset
|
411 #if FORKED_CACHE |
2322 | 412 static void exit_sighandler(int x){ |
413 // close stream | |
414 exit(0); | |
415 } | |
416 | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
417 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
|
418 } |
33617
c77bf171b354
cache2: Surround conditionally used functions by appropriate #ifdefs.
diego
parents:
33517
diff
changeset
|
419 #endif |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
420 |
30360
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
421 /** |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
422 * Main loop of the cache process or thread. |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
423 */ |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
424 static void cache_mainloop(cache_vars_t *s) { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
425 int sleep_count = 0; |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
426 #if FORKED_CACHE |
33835
8d3d721a0532
cache2: merge struct declaration and member assignment
diego
parents:
33823
diff
changeset
|
427 struct sigaction sa = { .sa_handler = SIG_IGN }; |
31672
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
428 sigaction(SIGUSR1, &sa, NULL); |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
429 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
430 do { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
431 if (!cache_fill(s)) { |
31167 | 432 #if FORKED_CACHE |
433 // Let signal wake us up, we cannot leave this | |
434 // enabled since we do not handle EINTR in most places. | |
435 // 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
|
436 sa.sa_handler = dummy_sighandler; |
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
437 sigaction(SIGUSR1, &sa, NULL); |
31167 | 438 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
439 if (sleep_count < INITIAL_FILL_USLEEP_COUNT) { |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
440 sleep_count++; |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
441 usec_sleep(INITIAL_FILL_USLEEP_TIME); |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
442 } else |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
443 usec_sleep(FILL_USLEEP_TIME); // idle |
31167 | 444 #if FORKED_CACHE |
31672
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
445 sa.sa_handler = SIG_IGN; |
61eac0d05f20
Use sigaction() instead of signal(), the latter has a unavoidable
reimar
parents:
31311
diff
changeset
|
446 sigaction(SIGUSR1, &sa, NULL); |
31167 | 447 #endif |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
448 } else |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
449 sleep_count = 0; |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
450 } while (cache_execute_control(s)); |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
451 } |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
452 |
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
453 /** |
30360
c74a5f8ffab3
Change code to allow playing a stream even if enabling the cache failed
reimar
parents:
30359
diff
changeset
|
454 * \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
|
455 */ |
34704 | 456 int stream_enable_cache(stream_t *stream,int64_t size,int64_t min,int64_t seek_limit){ |
25445
959fca775f43
Fix stream_cache to use sector_size set in stream_t.
ulion
parents:
24697
diff
changeset
|
457 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
|
458 int res = -1; |
5991 | 459 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
|
460 |
29888
5c39c41f38e8
Deobfuscate the special hack to disable cache for live555.
reimar
parents:
29263
diff
changeset
|
461 if (stream->flags & STREAM_NON_CACHEABLE) { |
7204 | 462 mp_msg(MSGT_CACHE,MSGL_STATUS,"\rThis stream is non-cacheable\n"); |
463 return 1; | |
464 } | |
34704 | 465 if (size > SIZE_MAX) { |
466 mp_msg(MSGT_CACHE, MSGL_FATAL, "Cache size larger than max. allocation size\n"); | |
467 return -1; | |
468 } | |
7006
c0b490505298
disable cache if stream->fd<0 (no regular file/pipe but some special thing)
arpi
parents:
5991
diff
changeset
|
469 |
5991 | 470 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
|
471 if(s == NULL) return -1; |
3562 | 472 stream->cache_data=s; |
473 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
|
474 s->seek_limit=seek_limit; |
12835
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
475 |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
476 |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
477 //make sure that we won't wait from cache_fill |
31181 | 478 //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
|
479 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
|
480 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
|
481 } |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
482 if (min > s->buffer_size - s->fill_limit) { |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
483 min = s->buffer_size - s->fill_limit; |
4235ae5a2d60
cache min fill adjustment, based on patch by Jeremy Huddleston
iive
parents:
10272
diff
changeset
|
484 } |
31189
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
485 // 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
|
486 // before continuing |
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
487 if (min <= 0) |
edfa98275e04
Fix cache process accidentally being killed by SIGUSR1.
reimar
parents:
31181
diff
changeset
|
488 min = 1; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
489 |
31146 | 490 #if FORKED_CACHE |
3562 | 491 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
|
492 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
|
493 stream->cache_pid = 0; |
10197 | 494 #else |
495 { | |
496 stream_t* stream2=malloc(sizeof(stream_t)); | |
497 memcpy(stream2,s->stream,sizeof(stream_t)); | |
498 s->stream=stream2; | |
27894
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
499 #if defined(__MINGW32__) |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
500 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
|
501 #elif defined(__OS2__) |
d06d8e459ae1
Use pthreads for the cache on Cygwin, since _beginthread is not available
reimar
parents:
27876
diff
changeset
|
502 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
|
503 #else |
27896
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
504 { |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
505 pthread_t tid; |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
506 pthread_create(&tid, NULL, ThreadProc, s); |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
507 stream->cache_pid = 1; |
4c2232462353
100l, stream->cache_pid can not be used directly in pthread_create,
reimar
parents:
27894
diff
changeset
|
508 } |
26077 | 509 #endif |
10197 | 510 #endif |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
511 if (!stream->cache_pid) { |
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
512 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
|
513 "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
|
514 goto err_out; |
30351
b985db55e78a
Check for fork failing and make sure cache_uninit always frees the cache data
reimar
parents:
29888
diff
changeset
|
515 } |
3562 | 516 // wait until cache is filled at least prefill_init % |
34704 | 517 mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %"PRId64" [%"PRId64"] %"PRId64" pre:%"PRId64" eof:%d \n", |
34706 | 518 s->min_filepos,s->read_filepos,s->max_filepos,min,s->eof); |
3562 | 519 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
|
520 mp_msg(MSGT_CACHE,MSGL_STATUS,MSGTR_CacheFill, |
3600 | 521 100.0*(float)(s->max_filepos-s->read_filepos)/(float)(s->buffer_size), |
34706 | 522 s->max_filepos-s->read_filepos |
3562 | 523 ); |
524 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
|
525 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
|
526 res = 0; |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
527 goto err_out; |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
528 } |
3562 | 529 } |
16870 | 530 mp_msg(MSGT_CACHE,MSGL_STATUS,"\n"); |
4825
41d2da3bd082
Make blocking call in libmpdemux interuptable (only with new input,
albeu
parents:
3726
diff
changeset
|
531 return 1; // parent exits |
30362
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
532 |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
533 err_out: |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
534 cache_uninit(stream); |
48c51ebbe421
Always call cache_uninit to immediately free everything cache-related if we
reimar
parents:
30360
diff
changeset
|
535 return res; |
3562 | 536 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
537 |
31146 | 538 #if FORKED_CACHE |
2322 | 539 signal(SIGTERM,exit_sighandler); // kill |
31144
c2d5a1f6360b
Extract the cache main loop into a separate function.
reimar
parents:
31142
diff
changeset
|
540 cache_mainloop(s); |
30355
ca3e3df28fe2
Add an exit() to silence a gcc warning and ensure forked code will never
reimar
parents:
30354
diff
changeset
|
541 // 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
|
542 exit(0); |
30712
75903ab49159
Restructure #ifs to be clearer, also ensures that we return from the thread
reimar
parents:
30691
diff
changeset
|
543 #endif |
2322 | 544 } |
545 | |
31146 | 546 #if !FORKED_CACHE |
547 #if defined(__MINGW32__) || defined(__OS2__) | |
548 static void ThreadProc( void *s ){ | |
549 cache_mainloop(s); | |
550 _endthread(); | |
551 } | |
552 #else | |
31145
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
553 static void *ThreadProc( void *s ){ |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
554 cache_mainloop(s); |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
555 return NULL; |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
556 } |
31146 | 557 #endif |
31145
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
558 #endif |
47d2e52f61b4
Try reducing the #ifdef mess for the different cache variants.
reimar
parents:
31144
diff
changeset
|
559 |
2322 | 560 int cache_stream_fill_buffer(stream_t *s){ |
561 int len; | |
31835
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
562 int sector_size; |
2322 | 563 if(!s->cache_pid) return stream_fill_buffer(s); |
564 | |
2371 | 565 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
|
566 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
|
567 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
|
568 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
|
569 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
|
570 } |
2327 | 571 |
31835
73f85fc599e0
Add sanity-check for sector size to avoid strange crashes if it is
reimar
parents:
31828
diff
changeset
|
572 len=cache_read(s->cache_data,s->buffer, sector_size); |
2352 | 573 //printf("cache_stream_fill_buffer->read -> %d\n",len); |
2327 | 574 |
2322 | 575 if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } |
31169 | 576 s->eof=0; |
2322 | 577 s->buf_pos=0; |
578 s->buf_len=len; | |
579 s->pos+=len; | |
580 // printf("[%d]",len);fflush(stdout); | |
32438
faefba58f413
Implement a basic capture feature, available through -capture.
diego
parents:
32037
diff
changeset
|
581 if (s->capture_file) |
faefba58f413
Implement a basic capture feature, available through -capture.
diego
parents:
32037
diff
changeset
|
582 stream_capture_do(s); |
2322 | 583 return len; |
584 | |
585 } | |
586 | |
32731
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
587 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
|
588 cache_vars_t *cv; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
589 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
|
590 return -1; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
591 cv = s->cache_data; |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
592 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
|
593 } |
005b026b1231
Convert cache_fill_status into a function so we always get the latest state,
reimar
parents:
32728
diff
changeset
|
594 |
34705 | 595 int cache_stream_seek_long(stream_t *stream,int64_t pos){ |
2352 | 596 cache_vars_t* s; |
34705 | 597 int64_t newpos; |
2352 | 598 if(!stream->cache_pid) return stream_seek_long(stream,pos); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
599 |
2352 | 600 s=stream->cache_data; |
601 // s->seek_lock=1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28014
diff
changeset
|
602 |
17366 | 603 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 | 604 |
2352 | 605 newpos=pos/s->sector_size; newpos*=s->sector_size; // align |
606 stream->pos=s->read_filepos=newpos; | |
607 s->eof=0; // !!!!!!! | |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
608 cache_wakeup(stream); |
2352 | 609 |
610 cache_stream_fill_buffer(stream); | |
2322 | 611 |
2352 | 612 pos-=newpos; |
613 if(pos>=0 && pos<=stream->buf_len){ | |
614 stream->buf_pos=pos; // byte position in sector | |
615 return 1; | |
616 } | |
617 | |
618 // stream->buf_pos=stream->buf_len=0; | |
619 // return 1; | |
620 | |
34706 | 621 mp_msg(MSGT_CACHE,MSGL_V,"cache_stream_seek: WARNING! Can't seek to 0x%"PRIX64" !\n",pos+newpos); |
2322 | 622 return 0; |
623 } | |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
624 |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
625 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
|
626 int sleep_count = 0; |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
627 int pos_change = 0; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
628 cache_vars_t* s = stream->cache_data; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
629 switch (cmd) { |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
630 case STREAM_CTRL_SEEK_TO_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
631 s->control_double_arg = *(double *)arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
632 s->control = cmd; |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
633 pos_change = 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
634 break; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
635 case STREAM_CTRL_SEEK_TO_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
636 case STREAM_CTRL_SET_ANGLE: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
637 s->control_uint_arg = *(unsigned *)arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
638 s->control = cmd; |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
639 pos_change = 1; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
640 break; |
33517
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
641 // 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
|
642 case STREAM_CTRL_GET_TIME_LENGTH: |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
643 *(double *)arg = s->stream_time_length; |
4f875ae5d538
Emulate STREAM_CTRL_GET_TIME_LENGTH if cache is used.
reimar
parents:
26833
diff
changeset
|
644 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
|
645 case STREAM_CTRL_GET_CURRENT_TIME: |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
646 *(double *)arg = s->stream_time_pos; |
850a3272e10d
Change code to allow STREAM_CTRL_GET_CURRENT_TIME with cache enabled.
reimar
parents:
33512
diff
changeset
|
647 return s->stream_time_pos != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED; |
34648
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
648 case STREAM_CTRL_GET_LANG: |
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
649 s->control_lang_arg = *(struct stream_lang_req *)arg; |
35164 | 650 case STREAM_CTRL_GET_NUM_TITLES: |
26924
ca50c4a72f68
100l, fix wrong order of cases in cache_do_control
reimar
parents:
26897
diff
changeset
|
651 case STREAM_CTRL_GET_NUM_CHAPTERS: |
35169
3b2c280da1af
Add new stream control command STREAM_CTRL_GET_CURRENT_TITLE for DVDs.
ib
parents:
35164
diff
changeset
|
652 case STREAM_CTRL_GET_CURRENT_TITLE: |
26924
ca50c4a72f68
100l, fix wrong order of cases in cache_do_control
reimar
parents:
26897
diff
changeset
|
653 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
654 case STREAM_CTRL_GET_ASPECT_RATIO: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
655 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
656 case STREAM_CTRL_GET_ANGLE: |
35013 | 657 case STREAM_CTRL_GET_SIZE: |
27770
c8d4cace053d
Avoid CreateThread and especially TerminateThread since they cause a memleak.
reimar
parents:
27769
diff
changeset
|
658 case -2: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
659 s->control = cmd; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
660 break; |
36428
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
661 case STREAM_CTRL_GET_CURRENT_CHANNEL: |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
662 s->control_char_p_arg = *(char **)arg; |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
663 s->control = cmd; |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
664 break; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
665 default: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
666 return STREAM_UNSUPPORTED; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
667 } |
31141
3b5e8cc5e128
Add code to wake up cache process when e.g. a seek is needed.
reimar
parents:
30731
diff
changeset
|
668 cache_wakeup(stream); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
669 while (s->control != -1) { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
670 if (sleep_count++ == 1000) |
33867
76b818cbb359
Mark two warnings that usually only indicate a performance issue as such.
reimar
parents:
33835
diff
changeset
|
671 mp_msg(MSGT_CACHE, MSGL_WARN, "Cache not responding! [performance issue]\n"); |
31190
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
672 if (stream_check_interrupt(CONTROL_SLEEP_TIME)) { |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
673 s->eof = 1; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
674 return STREAM_UNSUPPORTED; |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
675 } |
8432358f2d32
Improve handling of cache process/thread hanging/being killed.
reimar
parents:
31189
diff
changeset
|
676 } |
34487 | 677 if (s->control_res != STREAM_OK) |
678 return s->control_res; | |
679 // We cannot do this on failure, since this would cause the | |
680 // stream position to jump when e.g. STREAM_CTRL_SEEK_TO_TIME | |
681 // is unsupported - but in that case we need the old value | |
682 // to do the fallback seek. | |
683 // This unfortunately can lead to slightly different behaviour | |
684 // with and without cache if the protocol changes pos even | |
685 // when an error happened. | |
34373
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
686 if (pos_change) { |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
687 stream->pos = s->read_filepos; |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
688 stream->eof = s->eof; |
7a4dbec9415b
Flush cache and sync stream position/eof after seeking STREAM_CTRLs.
reimar
parents:
34283
diff
changeset
|
689 } |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
690 switch (cmd) { |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
691 case STREAM_CTRL_GET_TIME_LENGTH: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
692 case STREAM_CTRL_GET_CURRENT_TIME: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
693 case STREAM_CTRL_GET_ASPECT_RATIO: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
694 *(double *)arg = s->control_double_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
695 break; |
35164 | 696 case STREAM_CTRL_GET_NUM_TITLES: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
697 case STREAM_CTRL_GET_NUM_CHAPTERS: |
35169
3b2c280da1af
Add new stream control command STREAM_CTRL_GET_CURRENT_TITLE for DVDs.
ib
parents:
35164
diff
changeset
|
698 case STREAM_CTRL_GET_CURRENT_TITLE: |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
699 case STREAM_CTRL_GET_CURRENT_CHAPTER: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
700 case STREAM_CTRL_GET_NUM_ANGLES: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
701 case STREAM_CTRL_GET_ANGLE: |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
702 *(unsigned *)arg = s->control_uint_arg; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
703 break; |
35013 | 704 case STREAM_CTRL_GET_SIZE: |
35266
ceb148e1fe31
Change STREAM_CTRL_GET_SIZE argument type from off_t to
reimar
parents:
35169
diff
changeset
|
705 *(uint64_t *)arg = s->control_uint_arg; |
35013 | 706 break; |
34648
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
707 case STREAM_CTRL_GET_LANG: |
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
708 *(struct stream_lang_req *)arg = s->control_lang_arg; |
26eddbd6353a
Code cleanup: Use a stream_control instead of global functions to
reimar
parents:
34488
diff
changeset
|
709 break; |
36428
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
710 case STREAM_CTRL_GET_CURRENT_CHANNEL: |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
711 *(char **)arg = (char *)s->control_char_p_arg; |
7766530caa76
Add new stream control command STREAM_CTRL_GET_CURRENT_CHANNEL.
ib
parents:
35712
diff
changeset
|
712 break; |
26833
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
713 } |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
714 return s->control_res; |
77003eb2d9a8
Add basic support for stream controls with cache enabled.
reimar
parents:
26326
diff
changeset
|
715 } |