Mercurial > mplayer.hg
annotate stream/stream_file.c @ 25376:382aeacc771f
The buffer used for pread need be aligned, but currently it got an offset 23
to the structure head. This will cause the pread always got random data
on some machines (such as my iMac G5 PPC with 10.5 os) so can not play vcd.
I also tried use DKIOCCDREAD ioctl call, but the result is same -- buffer need
be aligned. It could be a bug of os x or its dev lib.
Now fix this problem by move the buffer to a good aligned position in structure.
author | ulion |
---|---|
date | Sat, 15 Dec 2007 12:17:51 +0000 |
parents | 371a40dcc1cc |
children | 68015115f63a |
rev | line source |
---|---|
9794 | 1 |
2 #include "config.h" | |
3 | |
16748
ec02252fbaa6
we need stdio.h for SEEK_SET on mingw, patch by Zuxy <zuxy.meng at gmail.com>
faust3
parents:
15461
diff
changeset
|
4 #include <stdio.h> |
9794 | 5 #include <sys/types.h> |
6 #include <sys/stat.h> | |
7 #include <fcntl.h> | |
8 #include <unistd.h> | |
9 | |
10 #include "mp_msg.h" | |
11 #include "stream.h" | |
12 #include "help_mp.h" | |
17012 | 13 #include "m_option.h" |
14 #include "m_struct.h" | |
9794 | 15 |
16 static struct stream_priv_s { | |
17 char* filename; | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
18 char *filename2; |
9794 | 19 } stream_priv_dflts = { |
15452 | 20 NULL, NULL |
9794 | 21 }; |
22 | |
23 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) | |
24 /// URL definition | |
25242 | 25 static const m_option_t stream_opts_fields[] = { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
26 {"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
|
27 {"filename", ST_OFF(filename2), CONF_TYPE_STRING, 0, 0 ,0, NULL}, |
9794 | 28 { NULL, NULL, 0, 0, 0, 0, NULL } |
29 }; | |
30 static struct m_struct_st stream_opts = { | |
31 "file", | |
32 sizeof(struct stream_priv_s), | |
33 &stream_priv_dflts, | |
34 stream_opts_fields | |
35 }; | |
36 | |
37 static int fill_buffer(stream_t *s, char* buffer, int max_len){ | |
38 int r = read(s->fd,buffer,max_len); | |
39 return (r <= 0) ? -1 : r; | |
40 } | |
41 | |
42 static int write_buffer(stream_t *s, char* buffer, int len) { | |
43 int r = write(s->fd,buffer,len); | |
44 return (r <= 0) ? -1 : r; | |
45 } | |
46 | |
47 static int seek(stream_t *s,off_t newpos) { | |
48 s->pos = newpos; | |
49 if(lseek(s->fd,s->pos,SEEK_SET)<0) { | |
50 s->eof=1; | |
51 return 0; | |
52 } | |
53 return 1; | |
54 } | |
55 | |
56 static int seek_forward(stream_t *s,off_t newpos) { | |
57 if(newpos<s->pos){ | |
58 mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); | |
59 return 0; | |
60 } | |
61 while(s->pos<newpos){ | |
12018 | 62 int len=s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE); |
63 if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; break; } // EOF | |
64 s->buf_pos=0; | |
65 s->buf_len=len; | |
66 s->pos+=len; | |
9794 | 67 } |
68 return 1; | |
69 } | |
70 | |
21658 | 71 static int control(stream_t *s, int cmd, void *arg) { |
72 switch(cmd) { | |
73 case STREAM_CTRL_GET_SIZE: { | |
74 off_t size; | |
75 | |
76 size = lseek(s->fd, 0, SEEK_END); | |
77 lseek(s->fd, s->pos, SEEK_SET); | |
78 if(size != (off_t)-1) { | |
79 *((off_t*)arg) = size; | |
80 return 1; | |
81 } | |
82 } | |
83 } | |
24257 | 84 return STREAM_UNSUPPORTED; |
21658 | 85 } |
86 | |
9794 | 87 static int open_f(stream_t *stream,int mode, void* opts, int* file_format) { |
88 int f; | |
89 mode_t m = 0; | |
90 off_t len; | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
91 unsigned char *filename; |
9794 | 92 struct stream_priv_s* p = (struct stream_priv_s*)opts; |
93 | |
94 if(mode == STREAM_READ) | |
95 m = O_RDONLY; | |
96 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
|
97 m = O_RDWR|O_CREAT|O_TRUNC; |
9794 | 98 else { |
10608 | 99 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknown open mode %d\n",mode); |
9794 | 100 m_struct_free(&stream_opts,opts); |
24257 | 101 return STREAM_UNSUPPORTED; |
9794 | 102 } |
103 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
104 if(p->filename) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
105 filename = p->filename; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
106 else if(p->filename2) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
107 filename = p->filename2; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
108 else |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
109 filename = NULL; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
110 if(!filename) { |
9849 | 111 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] No filename\n"); |
112 m_struct_free(&stream_opts,opts); | |
113 return STREAM_ERROR; | |
114 } | |
115 | |
9794 | 116 #if defined(__CYGWIN__)|| defined(__MINGW32__) |
117 m |= O_BINARY; | |
118 #endif | |
119 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
120 if(!strcmp(filename,"-")){ |
9794 | 121 if(mode == STREAM_READ) { |
122 // read from stdin | |
123 mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ReadSTDIN); | |
124 f=0; // 0=stdin | |
12921 | 125 #ifdef __MINGW32__ |
126 setmode(fileno(stdin),O_BINARY); | |
127 #endif | |
9794 | 128 } else { |
129 mp_msg(MSGT_OPEN,MSGL_INFO,"Writing to stdout\n"); | |
130 f=1; | |
12921 | 131 #ifdef __MINGW32__ |
132 setmode(fileno(stdout),O_BINARY); | |
133 #endif | |
9794 | 134 } |
135 } else { | |
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
|
136 if(mode == STREAM_READ) |
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
|
137 f=open(filename,m); |
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
|
138 else { |
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
|
139 mode_t openmode = S_IRUSR|S_IWUSR; |
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
|
140 #ifndef __MINGW32__ |
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
|
141 openmode |= S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; |
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
|
142 #endif |
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
|
143 f=open(filename,m, openmode); |
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
|
144 } |
9794 | 145 if(f<0) { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
146 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,filename); |
9794 | 147 m_struct_free(&stream_opts,opts); |
9827 | 148 return STREAM_ERROR; |
9794 | 149 } |
150 } | |
151 | |
152 len=lseek(f,0,SEEK_END); lseek(f,0,SEEK_SET); | |
12921 | 153 #ifdef __MINGW32__ |
154 if(f==0 || len == -1) { | |
155 #else | |
9794 | 156 if(len == -1) { |
12921 | 157 #endif |
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
|
158 if(mode == STREAM_READ) stream->seek = seek_forward; |
9794 | 159 stream->type = STREAMTYPE_STREAM; // Must be move to STREAMTYPE_FILE |
160 stream->flags |= STREAM_SEEK_FW; | |
161 } else if(len >= 0) { | |
162 stream->seek = seek; | |
163 stream->end_pos = len; | |
164 stream->type = STREAMTYPE_FILE; | |
165 } | |
166 | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16748
diff
changeset
|
167 mp_msg(MSGT_OPEN,MSGL_V,"[file] File size is %"PRId64" bytes\n", (int64_t)len); |
9794 | 168 |
169 stream->fd = f; | |
170 stream->fill_buffer = fill_buffer; | |
171 stream->write_buffer = write_buffer; | |
21658 | 172 stream->control = control; |
9794 | 173 |
174 m_struct_free(&stream_opts,opts); | |
175 return STREAM_OK; | |
176 } | |
177 | |
25211 | 178 const stream_info_t stream_info_file = { |
9794 | 179 "File", |
180 "file", | |
181 "Albeu", | |
182 "based on the code from ??? (probably Arpi)", | |
183 open_f, | |
184 { "file", "", NULL }, | |
185 &stream_opts, | |
186 1 // Urls are an option string | |
187 }; |