Mercurial > mplayer.hg
annotate stream/stream_file.c @ 36406:c918845d0d9a
mplayer: Fix a crash seeking with -chapter and -ass
When seeking to chapter on startup the mpctx->d_sub member
is not yet initialized. Do not access it in that case.
The commit r31293 that introduced that code explains that
it is for handling backward seeking correctly. So it should
not be needed on startup forward seek situation.
author | al |
---|---|
date | Fri, 08 Nov 2013 21:06:40 +0000 |
parents | 5c8339df2496 |
children | cb25e73ac822 |
rev | line source |
---|---|
30426
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
1 /* |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
2 * This file is part of MPlayer. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
3 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
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:
29920
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:
29920
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:
29920
diff
changeset
|
7 * (at your option) any later version. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
8 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
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:
29920
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:
29920
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:
29920
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:
29920
diff
changeset
|
13 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
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:
29920
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:
29920
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:
29920
diff
changeset
|
17 */ |
9794 | 18 |
19 #include "config.h" | |
20 | |
16748
ec02252fbaa6
we need stdio.h for SEEK_SET on mingw, patch by Zuxy <zuxy.meng at gmail.com>
faust3
parents:
15461
diff
changeset
|
21 #include <stdio.h> |
9794 | 22 #include <sys/types.h> |
23 #include <sys/stat.h> | |
24 #include <fcntl.h> | |
25 #include <unistd.h> | |
33759 | 26 #if HAVE_SETMODE |
27 #include <io.h> | |
28 #endif | |
35868
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
29 #ifdef __MINGW32__ |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
30 #include <windows.h> |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
31 #include <share.h> |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
32 #endif |
9794 | 33 |
34 #include "mp_msg.h" | |
35 #include "stream.h" | |
36 #include "help_mp.h" | |
17012 | 37 #include "m_option.h" |
38 #include "m_struct.h" | |
36253 | 39 #include "osdep/osdep.h" |
9794 | 40 |
41 static struct stream_priv_s { | |
42 char* filename; | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
43 char *filename2; |
9794 | 44 } stream_priv_dflts = { |
15452 | 45 NULL, NULL |
9794 | 46 }; |
47 | |
48 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) | |
49 /// URL definition | |
25242 | 50 static const m_option_t stream_opts_fields[] = { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
51 {"string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL}, |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
52 {"filename", ST_OFF(filename2), CONF_TYPE_STRING, 0, 0 ,0, NULL}, |
9794 | 53 { NULL, NULL, 0, 0, 0, 0, NULL } |
54 }; | |
25691 | 55 static const struct m_struct_st stream_opts = { |
9794 | 56 "file", |
57 sizeof(struct stream_priv_s), | |
58 &stream_priv_dflts, | |
59 stream_opts_fields | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27727
diff
changeset
|
60 }; |
9794 | 61 |
62 static int fill_buffer(stream_t *s, char* buffer, int max_len){ | |
63 int r = read(s->fd,buffer,max_len); | |
35018
5f3501f7f4d9
Explicitly signal EOF when reaching the end of a file/pipe.
reimar
parents:
33759
diff
changeset
|
64 // We are certain this is EOF, do not retry |
5f3501f7f4d9
Explicitly signal EOF when reaching the end of a file/pipe.
reimar
parents:
33759
diff
changeset
|
65 if (max_len && r == 0) s->eof = 1; |
9794 | 66 return (r <= 0) ? -1 : r; |
67 } | |
68 | |
69 static int write_buffer(stream_t *s, char* buffer, int len) { | |
32794
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
70 int r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
71 int wr = 0; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
72 while (wr < len) { |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
73 r = write(s->fd,buffer,len); |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
74 if (r <= 0) |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
75 return -1; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
76 wr += r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
77 buffer += r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
78 } |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
79 return len; |
9794 | 80 } |
81 | |
35885
3389262720da
Fix previous commit, off_t must be replaced by int64_t
reimar
parents:
35881
diff
changeset
|
82 static int seek(stream_t *s, int64_t newpos) { |
9794 | 83 s->pos = newpos; |
84 if(lseek(s->fd,s->pos,SEEK_SET)<0) { | |
85 s->eof=1; | |
86 return 0; | |
87 } | |
88 return 1; | |
89 } | |
90 | |
35885
3389262720da
Fix previous commit, off_t must be replaced by int64_t
reimar
parents:
35881
diff
changeset
|
91 static int seek_forward(stream_t *s, int64_t newpos) { |
9794 | 92 if(newpos<s->pos){ |
93 mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); | |
94 return 0; | |
95 } | |
96 while(s->pos<newpos){ | |
12018 | 97 int len=s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE); |
98 if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; break; } // EOF | |
99 s->buf_pos=0; | |
100 s->buf_len=len; | |
101 s->pos+=len; | |
9794 | 102 } |
103 return 1; | |
104 } | |
105 | |
21658 | 106 static int control(stream_t *s, int cmd, void *arg) { |
107 switch(cmd) { | |
108 case STREAM_CTRL_GET_SIZE: { | |
109 off_t size; | |
110 | |
111 size = lseek(s->fd, 0, SEEK_END); | |
112 lseek(s->fd, s->pos, SEEK_SET); | |
113 if(size != (off_t)-1) { | |
35266
ceb148e1fe31
Change STREAM_CTRL_GET_SIZE argument type from off_t to
reimar
parents:
35018
diff
changeset
|
114 *(uint64_t*)arg = size; |
21658 | 115 return 1; |
116 } | |
117 } | |
118 } | |
24257 | 119 return STREAM_UNSUPPORTED; |
21658 | 120 } |
121 | |
35868
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
122 #ifdef __MINGW32__ |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
123 static int win32_open(const char *fname, int m, int omode) |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
124 { |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
125 int cnt; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
126 int fd = -1; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
127 wchar_t fname_w[MAX_PATH]; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
128 int WINAPI (*mb2wc)(UINT, DWORD, LPCSTR, int, LPWSTR, int) = NULL; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
129 HMODULE kernel32 = GetModuleHandle("Kernel32.dll"); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
130 if (!kernel32) goto fallback; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
131 mb2wc = GetProcAddress(kernel32, "MultiByteToWideChar"); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
132 if (!mb2wc) goto fallback; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
133 cnt = mb2wc(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, fname_w, sizeof(fname_w) / sizeof(*fname_w)); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
134 if (cnt <= 0) goto fallback; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
135 fd = _wsopen(fname_w, m, SH_DENYNO, omode); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
136 if (fd != -1 || (m & O_CREAT)) |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
137 return fd; |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
138 |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
139 fallback: |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
140 return _sopen(fname, m, SH_DENYNO, omode); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
141 } |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
142 #endif |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
143 |
9794 | 144 static int open_f(stream_t *stream,int mode, void* opts, int* file_format) { |
145 int f; | |
146 mode_t m = 0; | |
35885
3389262720da
Fix previous commit, off_t must be replaced by int64_t
reimar
parents:
35881
diff
changeset
|
147 int64_t len; |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
148 unsigned char *filename; |
9794 | 149 struct stream_priv_s* p = (struct stream_priv_s*)opts; |
150 | |
151 if(mode == STREAM_READ) | |
152 m = O_RDONLY; | |
153 else if(mode == STREAM_WRITE) | |
22451
86f7b9cab33b
truncate mencoder's output file if it exists, instead of overwriting just part of it.
lorenm
parents:
21705
diff
changeset
|
154 m = O_RDWR|O_CREAT|O_TRUNC; |
9794 | 155 else { |
10608 | 156 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknown open mode %d\n",mode); |
9794 | 157 m_struct_free(&stream_opts,opts); |
24257 | 158 return STREAM_UNSUPPORTED; |
9794 | 159 } |
160 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
161 if(p->filename) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
162 filename = p->filename; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
163 else if(p->filename2) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
164 filename = p->filename2; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
165 else |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
166 filename = NULL; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
167 if(!filename) { |
9849 | 168 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] No filename\n"); |
169 m_struct_free(&stream_opts,opts); | |
170 return STREAM_ERROR; | |
171 } | |
172 | |
30608
c05fbacce55f
Replace platform preprocessor check by HAVE_DOS_PATHS.
komh
parents:
30426
diff
changeset
|
173 #if HAVE_DOS_PATHS |
26005 | 174 // extract '/' from '/x:/path' |
175 if( filename[ 0 ] == '/' && filename[ 1 ] && filename[ 2 ] == ':' ) | |
176 filename++; | |
177 #endif | |
178 | |
9794 | 179 m |= O_BINARY; |
180 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
181 if(!strcmp(filename,"-")){ |
9794 | 182 if(mode == STREAM_READ) { |
183 // read from stdin | |
184 mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ReadSTDIN); | |
185 f=0; // 0=stdin | |
30787
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
186 #if HAVE_SETMODE |
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
187 setmode(fileno(stdin),O_BINARY); |
12921 | 188 #endif |
9794 | 189 } else { |
190 mp_msg(MSGT_OPEN,MSGL_INFO,"Writing to stdout\n"); | |
191 f=1; | |
30787
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
192 #if HAVE_SETMODE |
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
193 setmode(fileno(stdout),O_BINARY); |
12921 | 194 #endif |
9794 | 195 } |
196 } else { | |
21705
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
197 mode_t openmode = S_IRUSR|S_IWUSR; |
35868
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
198 #ifdef __MINGW32__ |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
199 f = win32_open(filename, m, openmode); |
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
200 #else |
21705
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
201 openmode |= S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; |
35868
3edaed3c1d60
Win32: support file names with characters outside system code-page
reimar
parents:
35266
diff
changeset
|
202 f=open(filename,m, openmode); |
21705
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
203 #endif |
9794 | 204 if(f<0) { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
205 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,filename); |
9794 | 206 m_struct_free(&stream_opts,opts); |
9827 | 207 return STREAM_ERROR; |
9794 | 208 } |
209 } | |
210 | |
211 len=lseek(f,0,SEEK_END); lseek(f,0,SEEK_SET); | |
12921 | 212 #ifdef __MINGW32__ |
31883 | 213 // seeks on stdin incorrectly succeed on MinGW |
214 if(f==0) | |
215 len = -1; | |
216 #endif | |
9794 | 217 if(len == -1) { |
21656
32c50eb3ff18
in STREAM_WRITE mode open the stream with O_RDWR|O_CREAT, S_IRUSR|S_IWUSR and disable seek_forward for pipes
nicodvb
parents:
19271
diff
changeset
|
218 if(mode == STREAM_READ) stream->seek = seek_forward; |
9794 | 219 stream->type = STREAMTYPE_STREAM; // Must be move to STREAMTYPE_FILE |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29304
diff
changeset
|
220 stream->flags |= MP_STREAM_SEEK_FW; |
9794 | 221 } else if(len >= 0) { |
222 stream->seek = seek; | |
223 stream->end_pos = len; | |
224 stream->type = STREAMTYPE_FILE; | |
225 } | |
226 | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16748
diff
changeset
|
227 mp_msg(MSGT_OPEN,MSGL_V,"[file] File size is %"PRId64" bytes\n", (int64_t)len); |
9794 | 228 |
229 stream->fd = f; | |
230 stream->fill_buffer = fill_buffer; | |
231 stream->write_buffer = write_buffer; | |
21658 | 232 stream->control = control; |
32529
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
31883
diff
changeset
|
233 stream->read_chunk = 64*1024; |
9794 | 234 |
235 m_struct_free(&stream_opts,opts); | |
236 return STREAM_OK; | |
237 } | |
238 | |
25211 | 239 const stream_info_t stream_info_file = { |
9794 | 240 "File", |
241 "file", | |
242 "Albeu", | |
243 "based on the code from ??? (probably Arpi)", | |
244 open_f, | |
245 { "file", "", NULL }, | |
246 &stream_opts, | |
247 1 // Urls are an option string | |
248 }; |