Mercurial > libavformat.hg
annotate aviobuf.c @ 5854:3dc78fb78b2a libavformat
Fix erroneous behaviour when format probe hits end of file
If the format probe hits end of file, do not add the error code
to the buffer position. This is obviously wrong, and with a
small input file would cause a negative buffer overflow.
Fixes issue 1818.
author | mru |
---|---|
date | Tue, 16 Mar 2010 21:45:30 +0000 |
parents | a9a36b4f83a2 |
children | a1121e5fa662 |
rev | line source |
---|---|
0 | 1 /* |
2 * Buffered I/O for ffmpeg system | |
3 * Copyright (c) 2000,2001 Fabrice Bellard | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1326
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3286 | 21 |
22 #include "libavutil/crc.h" | |
4233 | 23 #include "libavutil/intreadwrite.h" |
0 | 24 #include "avformat.h" |
64 | 25 #include "avio.h" |
0 | 26 #include <stdarg.h> |
27 | |
28 #define IO_BUFFER_SIZE 32768 | |
29 | |
1326 | 30 static void fill_buffer(ByteIOContext *s); |
5320
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
31 #if LIBAVFORMAT_VERSION_MAJOR >= 53 |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
32 static int url_resetbuf(ByteIOContext *s, int flags); |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
33 #endif |
1326 | 34 |
0 | 35 int init_put_byte(ByteIOContext *s, |
36 unsigned char *buffer, | |
37 int buffer_size, | |
38 int write_flag, | |
39 void *opaque, | |
65 | 40 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), |
554 | 41 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
42 int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
0 | 43 { |
44 s->buffer = buffer; | |
45 s->buffer_size = buffer_size; | |
46 s->buf_ptr = buffer; | |
4127
6afa3d7c206e
Initialize s->opaque before calling url_resetbuf().
cehoyos
parents:
4091
diff
changeset
|
47 s->opaque = opaque; |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
48 url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY); |
0 | 49 s->write_packet = write_packet; |
50 s->read_packet = read_packet; | |
51 s->seek = seek; | |
52 s->pos = 0; | |
53 s->must_flush = 0; | |
54 s->eof_reached = 0; | |
554 | 55 s->error = 0; |
0 | 56 s->is_streamed = 0; |
57 s->max_packet_size = 0; | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
58 s->update_checksum= NULL; |
1403
1973528c6975
move memory reading ByteIOContext init from mov.c to avobuf.c
michael
parents:
1358
diff
changeset
|
59 if(!read_packet && !write_flag){ |
1973528c6975
move memory reading ByteIOContext init from mov.c to avobuf.c
michael
parents:
1358
diff
changeset
|
60 s->pos = buffer_size; |
1973528c6975
move memory reading ByteIOContext init from mov.c to avobuf.c
michael
parents:
1358
diff
changeset
|
61 s->buf_end = s->buffer + buffer_size; |
1973528c6975
move memory reading ByteIOContext init from mov.c to avobuf.c
michael
parents:
1358
diff
changeset
|
62 } |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
63 s->read_pause = NULL; |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
64 s->read_seek = NULL; |
0 | 65 return 0; |
66 } | |
885 | 67 |
2853 | 68 ByteIOContext *av_alloc_put_byte( |
69 unsigned char *buffer, | |
70 int buffer_size, | |
71 int write_flag, | |
72 void *opaque, | |
73 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), | |
74 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), | |
4091 | 75 int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
76 { | |
2853 | 77 ByteIOContext *s = av_mallocz(sizeof(ByteIOContext)); |
78 init_put_byte(s, buffer, buffer_size, write_flag, opaque, | |
79 read_packet, write_packet, seek); | |
80 return s; | |
81 } | |
82 | |
0 | 83 static void flush_buffer(ByteIOContext *s) |
84 { | |
85 if (s->buf_ptr > s->buffer) { | |
554 | 86 if (s->write_packet && !s->error){ |
87 int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); | |
88 if(ret < 0){ | |
89 s->error = ret; | |
90 } | |
91 } | |
421 | 92 if(s->update_checksum){ |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
93 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
94 s->checksum_ptr= s->buffer; |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
95 } |
0 | 96 s->pos += s->buf_ptr - s->buffer; |
97 } | |
98 s->buf_ptr = s->buffer; | |
99 } | |
100 | |
101 void put_byte(ByteIOContext *s, int b) | |
102 { | |
103 *(s->buf_ptr)++ = b; | |
885 | 104 if (s->buf_ptr >= s->buf_end) |
0 | 105 flush_buffer(s); |
106 } | |
107 | |
108 void put_buffer(ByteIOContext *s, const unsigned char *buf, int size) | |
109 { | |
110 while (size > 0) { | |
5275 | 111 int len = FFMIN(s->buf_end - s->buf_ptr, size); |
0 | 112 memcpy(s->buf_ptr, buf, len); |
113 s->buf_ptr += len; | |
114 | |
885 | 115 if (s->buf_ptr >= s->buf_end) |
0 | 116 flush_buffer(s); |
117 | |
118 buf += len; | |
119 size -= len; | |
120 } | |
121 } | |
122 | |
123 void put_flush_packet(ByteIOContext *s) | |
124 { | |
125 flush_buffer(s); | |
126 s->must_flush = 0; | |
127 } | |
128 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
129 int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence) |
0 | 130 { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
131 int64_t offset1; |
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
132 int64_t pos; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
133 |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
134 if(!s) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
135 return AVERROR(EINVAL); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
136 |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
137 pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer)); |
0 | 138 |
139 if (whence != SEEK_CUR && whence != SEEK_SET) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1747
diff
changeset
|
140 return AVERROR(EINVAL); |
885 | 141 |
1323 | 142 if (whence == SEEK_CUR) { |
143 offset1 = pos + (s->buf_ptr - s->buffer); | |
144 if (offset == 0) | |
145 return offset1; | |
146 offset += offset1; | |
147 } | |
148 offset1 = offset - pos; | |
149 if (!s->must_flush && | |
4871
37da30baa62d
seek inside buffer when offset is exactly at the end, fix seeking with memory ByteIOContext
bcoudurier
parents:
4236
diff
changeset
|
150 offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { |
1323 | 151 /* can do the seek inside the buffer */ |
152 s->buf_ptr = s->buffer + offset1; | |
5850
a9a36b4f83a2
Add AVSEEK_FORCE flag to indicate that the code should attempt to seek
michael
parents:
5609
diff
changeset
|
153 } else if(s->is_streamed && !s->write_flag && offset1 >= 0 && |
a9a36b4f83a2
Add AVSEEK_FORCE flag to indicate that the code should attempt to seek
michael
parents:
5609
diff
changeset
|
154 ( offset1 < (s->buf_end - s->buffer) + (1<<16) |
a9a36b4f83a2
Add AVSEEK_FORCE flag to indicate that the code should attempt to seek
michael
parents:
5609
diff
changeset
|
155 || (whence & AVSEEK_FORCE))){ |
1326 | 156 while(s->pos < offset && !s->eof_reached) |
157 fill_buffer(s); | |
2816
1523342b58b3
return error when url_fseek could not read until desired offset in streamed mode
bcoudurier
parents:
2783
diff
changeset
|
158 if (s->eof_reached) |
1523342b58b3
return error when url_fseek could not read until desired offset in streamed mode
bcoudurier
parents:
2783
diff
changeset
|
159 return AVERROR(EPIPE); |
1326 | 160 s->buf_ptr = s->buf_end + offset - s->pos; |
1323 | 161 } else { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
162 int64_t res = AVERROR(EPIPE); |
1747
fa70e732d2db
Fix misbehaviour in url_fseek() when seeking fails.
gpoirier
parents:
1741
diff
changeset
|
163 |
4206 | 164 #if CONFIG_MUXERS || CONFIG_NETWORK |
1323 | 165 if (s->write_flag) { |
0 | 166 flush_buffer(s); |
167 s->must_flush = 1; | |
3614
71fdc3f7c771
Only reset buffer state if seeking is successful; update seek reg ref.
bcoudurier
parents:
3286
diff
changeset
|
168 } |
4206 | 169 #endif /* CONFIG_MUXERS || CONFIG_NETWORK */ |
1747
fa70e732d2db
Fix misbehaviour in url_fseek() when seeking fails.
gpoirier
parents:
1741
diff
changeset
|
170 if (!s->seek || (res = s->seek(s->opaque, offset, SEEK_SET)) < 0) |
fa70e732d2db
Fix misbehaviour in url_fseek() when seeking fails.
gpoirier
parents:
1741
diff
changeset
|
171 return res; |
3614
71fdc3f7c771
Only reset buffer state if seeking is successful; update seek reg ref.
bcoudurier
parents:
3286
diff
changeset
|
172 if (!s->write_flag) |
71fdc3f7c771
Only reset buffer state if seeking is successful; update seek reg ref.
bcoudurier
parents:
3286
diff
changeset
|
173 s->buf_end = s->buffer; |
71fdc3f7c771
Only reset buffer state if seeking is successful; update seek reg ref.
bcoudurier
parents:
3286
diff
changeset
|
174 s->buf_ptr = s->buffer; |
1323 | 175 s->pos = offset; |
0 | 176 } |
1323 | 177 s->eof_reached = 0; |
0 | 178 return offset; |
179 } | |
180 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
181 void url_fskip(ByteIOContext *s, int64_t offset) |
0 | 182 { |
183 url_fseek(s, offset, SEEK_CUR); | |
184 } | |
185 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
186 int64_t url_ftell(ByteIOContext *s) |
0 | 187 { |
188 return url_fseek(s, 0, SEEK_CUR); | |
189 } | |
190 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
191 int64_t url_fsize(ByteIOContext *s) |
764
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
719
diff
changeset
|
192 { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
193 int64_t size; |
885 | 194 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
195 if(!s) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
196 return AVERROR(EINVAL); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
197 |
764
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
719
diff
changeset
|
198 if (!s->seek) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1747
diff
changeset
|
199 return AVERROR(EPIPE); |
1612
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1592
diff
changeset
|
200 size = s->seek(s->opaque, 0, AVSEEK_SIZE); |
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1592
diff
changeset
|
201 if(size<0){ |
1741
e9c7714b1c34
proper error handling in file size retrieval, patch by Ronald S. Bultje rbultje at ronald bitfreak net
bcoudurier
parents:
1613
diff
changeset
|
202 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0) |
e9c7714b1c34
proper error handling in file size retrieval, patch by Ronald S. Bultje rbultje at ronald bitfreak net
bcoudurier
parents:
1613
diff
changeset
|
203 return size; |
e9c7714b1c34
proper error handling in file size retrieval, patch by Ronald S. Bultje rbultje at ronald bitfreak net
bcoudurier
parents:
1613
diff
changeset
|
204 size++; |
1613 | 205 s->seek(s->opaque, s->pos, SEEK_SET); |
1612
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1592
diff
changeset
|
206 } |
764
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
719
diff
changeset
|
207 return size; |
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
719
diff
changeset
|
208 } |
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
719
diff
changeset
|
209 |
0 | 210 int url_feof(ByteIOContext *s) |
211 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
212 if(!s) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
213 return 0; |
0 | 214 return s->eof_reached; |
215 } | |
216 | |
554 | 217 int url_ferror(ByteIOContext *s) |
218 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
219 if(!s) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
220 return 0; |
554 | 221 return s->error; |
222 } | |
223 | |
0 | 224 void put_le32(ByteIOContext *s, unsigned int val) |
225 { | |
226 put_byte(s, val); | |
227 put_byte(s, val >> 8); | |
228 put_byte(s, val >> 16); | |
229 put_byte(s, val >> 24); | |
230 } | |
231 | |
232 void put_be32(ByteIOContext *s, unsigned int val) | |
233 { | |
234 put_byte(s, val >> 24); | |
235 put_byte(s, val >> 16); | |
236 put_byte(s, val >> 8); | |
237 put_byte(s, val); | |
238 } | |
239 | |
240 void put_strz(ByteIOContext *s, const char *str) | |
241 { | |
242 if (str) | |
243 put_buffer(s, (const unsigned char *) str, strlen(str) + 1); | |
244 else | |
245 put_byte(s, 0); | |
246 } | |
247 | |
65 | 248 void put_le64(ByteIOContext *s, uint64_t val) |
0 | 249 { |
65 | 250 put_le32(s, (uint32_t)(val & 0xffffffff)); |
251 put_le32(s, (uint32_t)(val >> 32)); | |
0 | 252 } |
253 | |
65 | 254 void put_be64(ByteIOContext *s, uint64_t val) |
0 | 255 { |
65 | 256 put_be32(s, (uint32_t)(val >> 32)); |
257 put_be32(s, (uint32_t)(val & 0xffffffff)); | |
0 | 258 } |
259 | |
260 void put_le16(ByteIOContext *s, unsigned int val) | |
261 { | |
262 put_byte(s, val); | |
263 put_byte(s, val >> 8); | |
264 } | |
265 | |
266 void put_be16(ByteIOContext *s, unsigned int val) | |
267 { | |
268 put_byte(s, val >> 8); | |
269 put_byte(s, val); | |
270 } | |
271 | |
937 | 272 void put_le24(ByteIOContext *s, unsigned int val) |
273 { | |
274 put_le16(s, val & 0xffff); | |
275 put_byte(s, val >> 16); | |
276 } | |
277 | |
822 | 278 void put_be24(ByteIOContext *s, unsigned int val) |
279 { | |
280 put_be16(s, val >> 8); | |
281 put_byte(s, val); | |
282 } | |
283 | |
0 | 284 void put_tag(ByteIOContext *s, const char *tag) |
285 { | |
286 while (*tag) { | |
287 put_byte(s, *tag++); | |
288 } | |
289 } | |
290 | |
291 /* Input stream */ | |
292 | |
293 static void fill_buffer(ByteIOContext *s) | |
294 { | |
4020
9d94163ca066
always use the whole buffer for reading w/ packetized sources to avoid packet truncation
henry
parents:
3998
diff
changeset
|
295 uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer; |
3998
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
296 int len= s->buffer_size - (dst - s->buffer); |
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
297 |
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
298 assert(s->buf_ptr == s->buf_end); |
0 | 299 |
300 /* no need to do anything if EOF already reached */ | |
301 if (s->eof_reached) | |
302 return; | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
303 |
3998
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
304 if(s->update_checksum && dst == s->buffer){ |
780 | 305 if(s->buf_end > s->checksum_ptr) |
306 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr); | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
307 s->checksum_ptr= s->buffer; |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
308 } |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
309 |
2576 | 310 if(s->read_packet) |
3998
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
311 len = s->read_packet(s->opaque, dst, len); |
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
312 else |
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
313 len = 0; |
0 | 314 if (len <= 0) { |
315 /* do not modify buffer if EOF reached so that a seek back can | |
316 be done without rereading data */ | |
317 s->eof_reached = 1; | |
2082 | 318 if(len<0) |
319 s->error= len; | |
0 | 320 } else { |
321 s->pos += len; | |
3998
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
322 s->buf_ptr = dst; |
692e5298a27a
Append read data onto the buffer instead of overwriting, this ensures
michael
parents:
3982
diff
changeset
|
323 s->buf_end = dst + len; |
0 | 324 } |
325 } | |
326 | |
4091 | 327 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, |
328 unsigned int len) | |
329 { | |
2893 | 330 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len); |
2683
153d6efc05b8
rename av_crc04C11DB7_update to ff_crc04C11DB7_update and move it to aviobuf.c so it can be reused by other (de)muxers
bcoudurier
parents:
2598
diff
changeset
|
331 } |
153d6efc05b8
rename av_crc04C11DB7_update to ff_crc04C11DB7_update and move it to aviobuf.c so it can be reused by other (de)muxers
bcoudurier
parents:
2598
diff
changeset
|
332 |
4091 | 333 unsigned long get_checksum(ByteIOContext *s) |
334 { | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
335 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); |
421 | 336 s->update_checksum= NULL; |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
337 return s->checksum; |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
338 } |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
339 |
4091 | 340 void init_checksum(ByteIOContext *s, |
341 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), | |
342 unsigned long checksum) | |
343 { | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
344 s->update_checksum= update_checksum; |
421 | 345 if(s->update_checksum){ |
1184 | 346 s->checksum= checksum; |
421 | 347 s->checksum_ptr= s->buf_ptr; |
348 } | |
418
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
349 } |
41da3366d341
checksuming for nut & nice checksum API for libavformat
michael
parents:
389
diff
changeset
|
350 |
0 | 351 /* XXX: put an inline version */ |
352 int get_byte(ByteIOContext *s) | |
353 { | |
354 if (s->buf_ptr < s->buf_end) { | |
355 return *s->buf_ptr++; | |
356 } else { | |
357 fill_buffer(s); | |
358 if (s->buf_ptr < s->buf_end) | |
359 return *s->buf_ptr++; | |
360 else | |
361 return 0; | |
362 } | |
363 } | |
364 | |
365 int url_fgetc(ByteIOContext *s) | |
366 { | |
367 if (s->buf_ptr < s->buf_end) { | |
368 return *s->buf_ptr++; | |
369 } else { | |
370 fill_buffer(s); | |
371 if (s->buf_ptr < s->buf_end) | |
372 return *s->buf_ptr++; | |
373 else | |
374 return URL_EOF; | |
375 } | |
376 } | |
377 | |
378 int get_buffer(ByteIOContext *s, unsigned char *buf, int size) | |
379 { | |
380 int len, size1; | |
381 | |
382 size1 = size; | |
383 while (size > 0) { | |
384 len = s->buf_end - s->buf_ptr; | |
385 if (len > size) | |
386 len = size; | |
387 if (len == 0) { | |
719 | 388 if(size > s->buffer_size && !s->update_checksum){ |
2576 | 389 if(s->read_packet) |
2577 | 390 len = s->read_packet(s->opaque, buf, size); |
719 | 391 if (len <= 0) { |
392 /* do not modify buffer if EOF reached so that a seek back can | |
393 be done without rereading data */ | |
394 s->eof_reached = 1; | |
395 if(len<0) | |
396 s->error= len; | |
397 break; | |
398 } else { | |
399 s->pos += len; | |
400 size -= len; | |
401 buf += len; | |
402 s->buf_ptr = s->buffer; | |
403 s->buf_end = s->buffer/* + len*/; | |
404 } | |
405 }else{ | |
406 fill_buffer(s); | |
407 len = s->buf_end - s->buf_ptr; | |
408 if (len == 0) | |
409 break; | |
410 } | |
0 | 411 } else { |
412 memcpy(buf, s->buf_ptr, len); | |
413 buf += len; | |
414 s->buf_ptr += len; | |
415 size -= len; | |
416 } | |
417 } | |
5253
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
418 if (size1 == size) { |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
419 if (url_ferror(s)) return url_ferror(s); |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
420 if (url_feof(s)) return AVERROR_EOF; |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
421 } |
0 | 422 return size1 - size; |
423 } | |
424 | |
389
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
425 int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size) |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
426 { |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
427 int len; |
885 | 428 |
643 | 429 if(size<0) |
430 return -1; | |
389
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
431 |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
432 len = s->buf_end - s->buf_ptr; |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
433 if (len == 0) { |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
434 fill_buffer(s); |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
435 len = s->buf_end - s->buf_ptr; |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
436 } |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
437 if (len > size) |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
438 len = size; |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
439 memcpy(buf, s->buf_ptr, len); |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
440 s->buf_ptr += len; |
5253
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
441 if (!len) { |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
442 if (url_ferror(s)) return url_ferror(s); |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
443 if (url_feof(s)) return AVERROR_EOF; |
a2289b41a9f2
Make get_buffer and get_partial_buffer return url_ferror or AVERROR_EOF as
reimar
parents:
4871
diff
changeset
|
444 } |
389
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
445 return len; |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
446 } |
e14fcd57ad2f
decode latency patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
364
diff
changeset
|
447 |
0 | 448 unsigned int get_le16(ByteIOContext *s) |
449 { | |
450 unsigned int val; | |
451 val = get_byte(s); | |
452 val |= get_byte(s) << 8; | |
453 return val; | |
454 } | |
455 | |
937 | 456 unsigned int get_le24(ByteIOContext *s) |
457 { | |
458 unsigned int val; | |
459 val = get_le16(s); | |
460 val |= get_byte(s) << 16; | |
461 return val; | |
462 } | |
463 | |
0 | 464 unsigned int get_le32(ByteIOContext *s) |
465 { | |
466 unsigned int val; | |
822 | 467 val = get_le16(s); |
468 val |= get_le16(s) << 16; | |
0 | 469 return val; |
470 } | |
471 | |
65 | 472 uint64_t get_le64(ByteIOContext *s) |
0 | 473 { |
65 | 474 uint64_t val; |
475 val = (uint64_t)get_le32(s); | |
476 val |= (uint64_t)get_le32(s) << 32; | |
0 | 477 return val; |
478 } | |
479 | |
480 unsigned int get_be16(ByteIOContext *s) | |
481 { | |
482 unsigned int val; | |
483 val = get_byte(s) << 8; | |
484 val |= get_byte(s); | |
485 return val; | |
486 } | |
487 | |
822 | 488 unsigned int get_be24(ByteIOContext *s) |
489 { | |
490 unsigned int val; | |
491 val = get_be16(s) << 8; | |
492 val |= get_byte(s); | |
493 return val; | |
494 } | |
0 | 495 unsigned int get_be32(ByteIOContext *s) |
496 { | |
497 unsigned int val; | |
822 | 498 val = get_be16(s) << 16; |
499 val |= get_be16(s); | |
0 | 500 return val; |
501 } | |
502 | |
503 char *get_strz(ByteIOContext *s, char *buf, int maxlen) | |
504 { | |
505 int i = 0; | |
506 char c; | |
507 | |
508 while ((c = get_byte(s))) { | |
509 if (i < maxlen-1) | |
510 buf[i++] = c; | |
511 } | |
885 | 512 |
0 | 513 buf[i] = 0; /* Ensure null terminated, but may be truncated */ |
514 | |
515 return buf; | |
516 } | |
517 | |
65 | 518 uint64_t get_be64(ByteIOContext *s) |
0 | 519 { |
65 | 520 uint64_t val; |
521 val = (uint64_t)get_be32(s) << 32; | |
522 val |= (uint64_t)get_be32(s); | |
0 | 523 return val; |
524 } | |
525 | |
2700 | 526 uint64_t ff_get_v(ByteIOContext *bc){ |
2699 | 527 uint64_t val = 0; |
528 int tmp; | |
529 | |
530 do{ | |
531 tmp = get_byte(bc); | |
532 val= (val<<7) + (tmp&127); | |
533 }while(tmp&128); | |
534 return val; | |
535 } | |
536 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
537 int url_fdopen(ByteIOContext **s, URLContext *h) |
0 | 538 { |
65 | 539 uint8_t *buffer; |
0 | 540 int buffer_size, max_packet_size; |
541 | |
542 max_packet_size = url_get_max_packet_size(h); | |
543 if (max_packet_size) { | |
544 buffer_size = max_packet_size; /* no need to bufferize more than one packet */ | |
545 } else { | |
546 buffer_size = IO_BUFFER_SIZE; | |
547 } | |
548 buffer = av_malloc(buffer_size); | |
549 if (!buffer) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1747
diff
changeset
|
550 return AVERROR(ENOMEM); |
0 | 551 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
552 *s = av_mallocz(sizeof(ByteIOContext)); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
553 if(!*s) { |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
554 av_free(buffer); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
555 return AVERROR(ENOMEM); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
556 } |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
557 |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
558 if (init_put_byte(*s, buffer, buffer_size, |
364
0d74e8abcb3d
avio patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
277
diff
changeset
|
559 (h->flags & URL_WRONLY || h->flags & URL_RDWR), h, |
2831 | 560 url_read, url_write, url_seek) < 0) { |
0 | 561 av_free(buffer); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
562 av_freep(s); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2082
diff
changeset
|
563 return AVERROR(EIO); |
0 | 564 } |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
565 (*s)->is_streamed = h->is_streamed; |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
566 (*s)->max_packet_size = max_packet_size; |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
567 if(h->prot) { |
2839
b51319dd86e5
Merge recently added and still unused play and pause functions.
michael
parents:
2831
diff
changeset
|
568 (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
569 (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
570 } |
0 | 571 return 0; |
572 } | |
573 | |
574 int url_setbufsize(ByteIOContext *s, int buf_size) | |
575 { | |
65 | 576 uint8_t *buffer; |
0 | 577 buffer = av_malloc(buf_size); |
578 if (!buffer) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1747
diff
changeset
|
579 return AVERROR(ENOMEM); |
0 | 580 |
581 av_free(s->buffer); | |
582 s->buffer = buffer; | |
583 s->buffer_size = buf_size; | |
584 s->buf_ptr = buffer; | |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
585 url_resetbuf(s, s->write_flag ? URL_WRONLY : URL_RDONLY); |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
586 return 0; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
587 } |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
588 |
5320
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
589 #if LIBAVFORMAT_VERSION_MAJOR < 53 |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
590 int url_resetbuf(ByteIOContext *s, int flags) |
5320
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
591 #else |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
592 static int url_resetbuf(ByteIOContext *s, int flags) |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
593 #endif |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
594 { |
5320
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
595 #if LIBAVFORMAT_VERSION_MAJOR < 53 |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
596 URLContext *h = s->opaque; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
597 if ((flags & URL_RDWR) || (h && h->flags != flags && !h->flags & URL_RDWR)) |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
598 return AVERROR(EINVAL); |
5320
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
599 #else |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
600 assert(flags == URL_WRONLY || flags == URL_RDONLY); |
db1e4c61789a
Make url_resetbuf() assert on wrong flags passed and make it static on next
benoit
parents:
5275
diff
changeset
|
601 #endif |
2598
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
602 |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
603 if (flags & URL_WRONLY) { |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
604 s->buf_end = s->buffer + s->buffer_size; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
605 s->write_flag = 1; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
606 } else { |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
607 s->buf_end = s->buffer; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
608 s->write_flag = 0; |
fc7f8ee4700b
Add functionality to set the direction of a ByteIOContext buffer.
benoit
parents:
2577
diff
changeset
|
609 } |
0 | 610 return 0; |
611 } | |
612 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
613 int url_fopen(ByteIOContext **s, const char *filename, int flags) |
0 | 614 { |
615 URLContext *h; | |
616 int err; | |
617 | |
618 err = url_open(&h, filename, flags); | |
619 if (err < 0) | |
620 return err; | |
621 err = url_fdopen(s, h); | |
622 if (err < 0) { | |
623 url_close(h); | |
624 return err; | |
625 } | |
626 return 0; | |
627 } | |
628 | |
629 int url_fclose(ByteIOContext *s) | |
630 { | |
631 URLContext *h = s->opaque; | |
885 | 632 |
0 | 633 av_free(s->buffer); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
634 av_free(s); |
0 | 635 return url_close(h); |
636 } | |
637 | |
638 URLContext *url_fileno(ByteIOContext *s) | |
639 { | |
640 return s->opaque; | |
641 } | |
642 | |
4206 | 643 #if CONFIG_MUXERS |
0 | 644 int url_fprintf(ByteIOContext *s, const char *fmt, ...) |
645 { | |
646 va_list ap; | |
647 char buf[4096]; | |
648 int ret; | |
649 | |
650 va_start(ap, fmt); | |
651 ret = vsnprintf(buf, sizeof(buf), fmt, ap); | |
652 va_end(ap); | |
653 put_buffer(s, buf, strlen(buf)); | |
654 return ret; | |
655 } | |
858
66cc656ea404
Replace CONFIG_ENCODERS/CONFIG_DECODERS with CONFIG_MUXERS/CONFIG_DEMUXERS
diego
parents:
823
diff
changeset
|
656 #endif //CONFIG_MUXERS |
0 | 657 |
658 char *url_fgets(ByteIOContext *s, char *buf, int buf_size) | |
659 { | |
660 int c; | |
661 char *q; | |
662 | |
663 c = url_fgetc(s); | |
664 if (c == EOF) | |
665 return NULL; | |
666 q = buf; | |
667 for(;;) { | |
668 if (c == EOF || c == '\n') | |
669 break; | |
670 if ((q - buf) < buf_size - 1) | |
671 *q++ = c; | |
672 c = url_fgetc(s); | |
673 } | |
674 if (buf_size > 0) | |
675 *q = '\0'; | |
676 return buf; | |
677 } | |
678 | |
679 int url_fget_max_packet_size(ByteIOContext *s) | |
680 { | |
681 return s->max_packet_size; | |
682 } | |
683 | |
2839
b51319dd86e5
Merge recently added and still unused play and pause functions.
michael
parents:
2831
diff
changeset
|
684 int av_url_read_fpause(ByteIOContext *s, int pause) |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
685 { |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
686 if (!s->read_pause) |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
687 return AVERROR(ENOSYS); |
2839
b51319dd86e5
Merge recently added and still unused play and pause functions.
michael
parents:
2831
diff
changeset
|
688 return s->read_pause(s->opaque, pause); |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
689 } |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
690 |
4091 | 691 int64_t av_url_read_fseek(ByteIOContext *s, int stream_index, |
692 int64_t timestamp, int flags) | |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
693 { |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
694 URLContext *h = s->opaque; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
695 int64_t ret; |
2783
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
696 if (!s->read_seek) |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
697 return AVERROR(ENOSYS); |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
698 ret = s->read_seek(h, stream_index, timestamp, flags); |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
699 if(ret >= 0) { |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
700 s->buf_ptr = s->buf_end; // Flush buffer |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
701 s->pos = s->seek(h, 0, SEEK_CUR); |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
702 } |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
703 return ret; |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
704 } |
1a9db30c1d1c
Extend ByteIOContext and add the buffered IO functions:
andoma
parents:
2771
diff
changeset
|
705 |
1546
41356096b2d0
Fix compile with --disable-muxers, patch by Lo«Ác Le Loarer, lll+ffmpeg m4x org.
diego
parents:
1403
diff
changeset
|
706 /* url_open_dyn_buf and url_close_dyn_buf are used in rtp.c to send a response |
4206 | 707 * back to the server even if CONFIG_MUXERS is false. */ |
708 #if CONFIG_MUXERS || CONFIG_NETWORK | |
0 | 709 /* buffer handling */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
710 int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags) |
0 | 711 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
712 int ret; |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
713 *s = av_mallocz(sizeof(ByteIOContext)); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
714 if(!*s) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
715 return AVERROR(ENOMEM); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
716 ret = init_put_byte(*s, buf, buf_size, |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
717 (flags & URL_WRONLY || flags & URL_RDWR), |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
718 NULL, NULL, NULL, NULL); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
719 if(ret != 0) |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
720 av_freep(s); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
721 return ret; |
0 | 722 } |
723 | |
724 int url_close_buf(ByteIOContext *s) | |
725 { | |
726 put_flush_packet(s); | |
727 return s->buf_ptr - s->buffer; | |
728 } | |
729 | |
730 /* output in a dynamic buffer */ | |
731 | |
732 typedef struct DynBuffer { | |
733 int pos, size, allocated_size; | |
65 | 734 uint8_t *buffer; |
0 | 735 int io_buffer_size; |
65 | 736 uint8_t io_buffer[1]; |
0 | 737 } DynBuffer; |
738 | |
554 | 739 static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) |
0 | 740 { |
741 DynBuffer *d = opaque; | |
3982
1505b1ddab11
Make size variables in dyn_buf_write unsigned so gcc will not optimize the
reimar
parents:
3973
diff
changeset
|
742 unsigned new_size, new_allocated_size; |
885 | 743 |
0 | 744 /* reallocate buffer if needed */ |
745 new_size = d->pos + buf_size; | |
746 new_allocated_size = d->allocated_size; | |
639 | 747 if(new_size < d->pos || new_size > INT_MAX/2) |
748 return -1; | |
0 | 749 while (new_size > new_allocated_size) { |
750 if (!new_allocated_size) | |
751 new_allocated_size = new_size; | |
752 else | |
885 | 753 new_allocated_size += new_allocated_size / 2 + 1; |
0 | 754 } |
885 | 755 |
0 | 756 if (new_allocated_size > d->allocated_size) { |
93
69ed49c151bf
ffserver deallocate ctx->streams on closing patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
65
diff
changeset
|
757 d->buffer = av_realloc(d->buffer, new_allocated_size); |
69ed49c151bf
ffserver deallocate ctx->streams on closing patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
65
diff
changeset
|
758 if(d->buffer == NULL) |
4231
07ea426be9a3
Replace nonsense -1234 return value in dyn_buf_write by proper AVERROR(ENOMEM)
reimar
parents:
4206
diff
changeset
|
759 return AVERROR(ENOMEM); |
0 | 760 d->allocated_size = new_allocated_size; |
761 } | |
762 memcpy(d->buffer + d->pos, buf, buf_size); | |
763 d->pos = new_size; | |
764 if (d->pos > d->size) | |
765 d->size = d->pos; | |
554 | 766 return buf_size; |
0 | 767 } |
768 | |
554 | 769 static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) |
0 | 770 { |
771 unsigned char buf1[4]; | |
554 | 772 int ret; |
0 | 773 |
774 /* packetized write: output the header */ | |
4233 | 775 AV_WB32(buf1, buf_size); |
554 | 776 ret= dyn_buf_write(opaque, buf1, 4); |
777 if(ret < 0) | |
778 return ret; | |
0 | 779 |
780 /* then the data */ | |
554 | 781 return dyn_buf_write(opaque, buf, buf_size); |
0 | 782 } |
783 | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3614
diff
changeset
|
784 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) |
0 | 785 { |
786 DynBuffer *d = opaque; | |
787 | |
788 if (whence == SEEK_CUR) | |
789 offset += d->pos; | |
790 else if (whence == SEEK_END) | |
791 offset += d->size; | |
792 if (offset < 0 || offset > 0x7fffffffLL) | |
793 return -1; | |
794 d->pos = offset; | |
795 return 0; | |
796 } | |
797 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
798 static int url_open_dyn_buf_internal(ByteIOContext **s, int max_packet_size) |
0 | 799 { |
800 DynBuffer *d; | |
4235
ce71070e447d
Make io_buffer_size unsigned to avoid a warning about comparing
reimar
parents:
4234
diff
changeset
|
801 int ret; |
4236
63c721da20e5
Merge declaration and initialization of io_buffer_size
reimar
parents:
4235
diff
changeset
|
802 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; |
885 | 803 |
639 | 804 if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size) |
805 return -1; | |
4232
5defcf4194fb
Use av_mallocz instead of explicitly zeroing in url_open_dyn_buf_internal.
reimar
parents:
4231
diff
changeset
|
806 d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); |
0 | 807 if (!d) |
4234
3d57729868a9
Return AVERROR(ENOMEM) instead of -1 when malloc fails in url_open_dyn_buf_internal
reimar
parents:
4233
diff
changeset
|
808 return AVERROR(ENOMEM); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
809 *s = av_mallocz(sizeof(ByteIOContext)); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
810 if(!*s) { |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
811 av_free(d); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
812 return AVERROR(ENOMEM); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
813 } |
0 | 814 d->io_buffer_size = io_buffer_size; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
815 ret = init_put_byte(*s, d->io_buffer, io_buffer_size, |
885 | 816 1, d, NULL, |
817 max_packet_size ? dyn_packet_buf_write : dyn_buf_write, | |
0 | 818 max_packet_size ? NULL : dyn_buf_seek); |
819 if (ret == 0) { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
820 (*s)->max_packet_size = max_packet_size; |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
821 } else { |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
822 av_free(d); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
823 av_freep(s); |
0 | 824 } |
825 return ret; | |
826 } | |
827 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
828 int url_open_dyn_buf(ByteIOContext **s) |
0 | 829 { |
830 return url_open_dyn_buf_internal(s, 0); | |
831 } | |
832 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
833 int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size) |
0 | 834 { |
835 if (max_packet_size <= 0) | |
836 return -1; | |
837 return url_open_dyn_buf_internal(s, max_packet_size); | |
838 } | |
839 | |
65 | 840 int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer) |
0 | 841 { |
842 DynBuffer *d = s->opaque; | |
843 int size; | |
844 | |
845 put_flush_packet(s); | |
846 | |
847 *pbuffer = d->buffer; | |
848 size = d->size; | |
849 av_free(d); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2700
diff
changeset
|
850 av_free(s); |
0 | 851 return size; |
852 } | |
1546
41356096b2d0
Fix compile with --disable-muxers, patch by Lo«Ác Le Loarer, lll+ffmpeg m4x org.
diego
parents:
1403
diff
changeset
|
853 #endif /* CONFIG_MUXERS || CONFIG_NETWORK */ |