00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/crc.h"
00023 #include "libavutil/intreadwrite.h"
00024 #include "avformat.h"
00025 #include "avio.h"
00026 #include <stdarg.h>
00027
00028 #define IO_BUFFER_SIZE 32768
00029
00030 static void fill_buffer(ByteIOContext *s);
00031 #if LIBAVFORMAT_VERSION_MAJOR >= 53
00032 static int url_resetbuf(ByteIOContext *s, int flags);
00033 #endif
00034
00035 int init_put_byte(ByteIOContext *s,
00036 unsigned char *buffer,
00037 int buffer_size,
00038 int write_flag,
00039 void *opaque,
00040 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
00041 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
00042 int64_t (*seek)(void *opaque, int64_t offset, int whence))
00043 {
00044 s->buffer = buffer;
00045 s->buffer_size = buffer_size;
00046 s->buf_ptr = buffer;
00047 s->opaque = opaque;
00048 url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY);
00049 s->write_packet = write_packet;
00050 s->read_packet = read_packet;
00051 s->seek = seek;
00052 s->pos = 0;
00053 s->must_flush = 0;
00054 s->eof_reached = 0;
00055 s->error = 0;
00056 s->is_streamed = 0;
00057 s->max_packet_size = 0;
00058 s->update_checksum= NULL;
00059 if(!read_packet && !write_flag){
00060 s->pos = buffer_size;
00061 s->buf_end = s->buffer + buffer_size;
00062 }
00063 s->read_pause = NULL;
00064 s->read_seek = NULL;
00065 return 0;
00066 }
00067
00068 ByteIOContext *av_alloc_put_byte(
00069 unsigned char *buffer,
00070 int buffer_size,
00071 int write_flag,
00072 void *opaque,
00073 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
00074 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
00075 int64_t (*seek)(void *opaque, int64_t offset, int whence))
00076 {
00077 ByteIOContext *s = av_mallocz(sizeof(ByteIOContext));
00078 init_put_byte(s, buffer, buffer_size, write_flag, opaque,
00079 read_packet, write_packet, seek);
00080 return s;
00081 }
00082
00083 static void flush_buffer(ByteIOContext *s)
00084 {
00085 if (s->buf_ptr > s->buffer) {
00086 if (s->write_packet && !s->error){
00087 int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
00088 if(ret < 0){
00089 s->error = ret;
00090 }
00091 }
00092 if(s->update_checksum){
00093 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
00094 s->checksum_ptr= s->buffer;
00095 }
00096 s->pos += s->buf_ptr - s->buffer;
00097 }
00098 s->buf_ptr = s->buffer;
00099 }
00100
00101 void put_byte(ByteIOContext *s, int b)
00102 {
00103 *(s->buf_ptr)++ = b;
00104 if (s->buf_ptr >= s->buf_end)
00105 flush_buffer(s);
00106 }
00107
00108 void put_buffer(ByteIOContext *s, const unsigned char *buf, int size)
00109 {
00110 while (size > 0) {
00111 int len = FFMIN(s->buf_end - s->buf_ptr, size);
00112 memcpy(s->buf_ptr, buf, len);
00113 s->buf_ptr += len;
00114
00115 if (s->buf_ptr >= s->buf_end)
00116 flush_buffer(s);
00117
00118 buf += len;
00119 size -= len;
00120 }
00121 }
00122
00123 void put_flush_packet(ByteIOContext *s)
00124 {
00125 flush_buffer(s);
00126 s->must_flush = 0;
00127 }
00128
00129 int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence)
00130 {
00131 int64_t offset1;
00132 int64_t pos;
00133
00134 if(!s)
00135 return AVERROR(EINVAL);
00136
00137 pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));
00138
00139 if (whence != SEEK_CUR && whence != SEEK_SET)
00140 return AVERROR(EINVAL);
00141
00142 if (whence == SEEK_CUR) {
00143 offset1 = pos + (s->buf_ptr - s->buffer);
00144 if (offset == 0)
00145 return offset1;
00146 offset += offset1;
00147 }
00148 offset1 = offset - pos;
00149 if (!s->must_flush &&
00150 offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
00151
00152 s->buf_ptr = s->buffer + offset1;
00153 } else if(s->is_streamed && !s->write_flag &&
00154 offset1 >= 0 && offset1 < (s->buf_end - s->buffer) + (1<<16)){
00155 while(s->pos < offset && !s->eof_reached)
00156 fill_buffer(s);
00157 if (s->eof_reached)
00158 return AVERROR(EPIPE);
00159 s->buf_ptr = s->buf_end + offset - s->pos;
00160 } else {
00161 int64_t res = AVERROR(EPIPE);
00162
00163 #if CONFIG_MUXERS || CONFIG_NETWORK
00164 if (s->write_flag) {
00165 flush_buffer(s);
00166 s->must_flush = 1;
00167 }
00168 #endif
00169 if (!s->seek || (res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
00170 return res;
00171 if (!s->write_flag)
00172 s->buf_end = s->buffer;
00173 s->buf_ptr = s->buffer;
00174 s->pos = offset;
00175 }
00176 s->eof_reached = 0;
00177 return offset;
00178 }
00179
00180 void url_fskip(ByteIOContext *s, int64_t offset)
00181 {
00182 url_fseek(s, offset, SEEK_CUR);
00183 }
00184
00185 int64_t url_ftell(ByteIOContext *s)
00186 {
00187 return url_fseek(s, 0, SEEK_CUR);
00188 }
00189
00190 int64_t url_fsize(ByteIOContext *s)
00191 {
00192 int64_t size;
00193
00194 if(!s)
00195 return AVERROR(EINVAL);
00196
00197 if (!s->seek)
00198 return AVERROR(EPIPE);
00199 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
00200 if(size<0){
00201 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
00202 return size;
00203 size++;
00204 s->seek(s->opaque, s->pos, SEEK_SET);
00205 }
00206 return size;
00207 }
00208
00209 int url_feof(ByteIOContext *s)
00210 {
00211 if(!s)
00212 return 0;
00213 return s->eof_reached;
00214 }
00215
00216 int url_ferror(ByteIOContext *s)
00217 {
00218 if(!s)
00219 return 0;
00220 return s->error;
00221 }
00222
00223 void put_le32(ByteIOContext *s, unsigned int val)
00224 {
00225 put_byte(s, val);
00226 put_byte(s, val >> 8);
00227 put_byte(s, val >> 16);
00228 put_byte(s, val >> 24);
00229 }
00230
00231 void put_be32(ByteIOContext *s, unsigned int val)
00232 {
00233 put_byte(s, val >> 24);
00234 put_byte(s, val >> 16);
00235 put_byte(s, val >> 8);
00236 put_byte(s, val);
00237 }
00238
00239 void put_strz(ByteIOContext *s, const char *str)
00240 {
00241 if (str)
00242 put_buffer(s, (const unsigned char *) str, strlen(str) + 1);
00243 else
00244 put_byte(s, 0);
00245 }
00246
00247 void put_le64(ByteIOContext *s, uint64_t val)
00248 {
00249 put_le32(s, (uint32_t)(val & 0xffffffff));
00250 put_le32(s, (uint32_t)(val >> 32));
00251 }
00252
00253 void put_be64(ByteIOContext *s, uint64_t val)
00254 {
00255 put_be32(s, (uint32_t)(val >> 32));
00256 put_be32(s, (uint32_t)(val & 0xffffffff));
00257 }
00258
00259 void put_le16(ByteIOContext *s, unsigned int val)
00260 {
00261 put_byte(s, val);
00262 put_byte(s, val >> 8);
00263 }
00264
00265 void put_be16(ByteIOContext *s, unsigned int val)
00266 {
00267 put_byte(s, val >> 8);
00268 put_byte(s, val);
00269 }
00270
00271 void put_le24(ByteIOContext *s, unsigned int val)
00272 {
00273 put_le16(s, val & 0xffff);
00274 put_byte(s, val >> 16);
00275 }
00276
00277 void put_be24(ByteIOContext *s, unsigned int val)
00278 {
00279 put_be16(s, val >> 8);
00280 put_byte(s, val);
00281 }
00282
00283 void put_tag(ByteIOContext *s, const char *tag)
00284 {
00285 while (*tag) {
00286 put_byte(s, *tag++);
00287 }
00288 }
00289
00290
00291
00292 static void fill_buffer(ByteIOContext *s)
00293 {
00294 uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer;
00295 int len= s->buffer_size - (dst - s->buffer);
00296
00297 assert(s->buf_ptr == s->buf_end);
00298
00299
00300 if (s->eof_reached)
00301 return;
00302
00303 if(s->update_checksum && dst == s->buffer){
00304 if(s->buf_end > s->checksum_ptr)
00305 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr);
00306 s->checksum_ptr= s->buffer;
00307 }
00308
00309 if(s->read_packet)
00310 len = s->read_packet(s->opaque, dst, len);
00311 else
00312 len = 0;
00313 if (len <= 0) {
00314
00315
00316 s->eof_reached = 1;
00317 if(len<0)
00318 s->error= len;
00319 } else {
00320 s->pos += len;
00321 s->buf_ptr = dst;
00322 s->buf_end = dst + len;
00323 }
00324 }
00325
00326 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
00327 unsigned int len)
00328 {
00329 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
00330 }
00331
00332 unsigned long get_checksum(ByteIOContext *s)
00333 {
00334 s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
00335 s->update_checksum= NULL;
00336 return s->checksum;
00337 }
00338
00339 void init_checksum(ByteIOContext *s,
00340 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
00341 unsigned long checksum)
00342 {
00343 s->update_checksum= update_checksum;
00344 if(s->update_checksum){
00345 s->checksum= checksum;
00346 s->checksum_ptr= s->buf_ptr;
00347 }
00348 }
00349
00350
00351 int get_byte(ByteIOContext *s)
00352 {
00353 if (s->buf_ptr < s->buf_end) {
00354 return *s->buf_ptr++;
00355 } else {
00356 fill_buffer(s);
00357 if (s->buf_ptr < s->buf_end)
00358 return *s->buf_ptr++;
00359 else
00360 return 0;
00361 }
00362 }
00363
00364 int url_fgetc(ByteIOContext *s)
00365 {
00366 if (s->buf_ptr < s->buf_end) {
00367 return *s->buf_ptr++;
00368 } else {
00369 fill_buffer(s);
00370 if (s->buf_ptr < s->buf_end)
00371 return *s->buf_ptr++;
00372 else
00373 return URL_EOF;
00374 }
00375 }
00376
00377 int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
00378 {
00379 int len, size1;
00380
00381 size1 = size;
00382 while (size > 0) {
00383 len = s->buf_end - s->buf_ptr;
00384 if (len > size)
00385 len = size;
00386 if (len == 0) {
00387 if(size > s->buffer_size && !s->update_checksum){
00388 if(s->read_packet)
00389 len = s->read_packet(s->opaque, buf, size);
00390 if (len <= 0) {
00391
00392
00393 s->eof_reached = 1;
00394 if(len<0)
00395 s->error= len;
00396 break;
00397 } else {
00398 s->pos += len;
00399 size -= len;
00400 buf += len;
00401 s->buf_ptr = s->buffer;
00402 s->buf_end = s->buffer;
00403 }
00404 }else{
00405 fill_buffer(s);
00406 len = s->buf_end - s->buf_ptr;
00407 if (len == 0)
00408 break;
00409 }
00410 } else {
00411 memcpy(buf, s->buf_ptr, len);
00412 buf += len;
00413 s->buf_ptr += len;
00414 size -= len;
00415 }
00416 }
00417 if (size1 == size) {
00418 if (url_ferror(s)) return url_ferror(s);
00419 if (url_feof(s)) return AVERROR_EOF;
00420 }
00421 return size1 - size;
00422 }
00423
00424 int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size)
00425 {
00426 int len;
00427
00428 if(size<0)
00429 return -1;
00430
00431 len = s->buf_end - s->buf_ptr;
00432 if (len == 0) {
00433 fill_buffer(s);
00434 len = s->buf_end - s->buf_ptr;
00435 }
00436 if (len > size)
00437 len = size;
00438 memcpy(buf, s->buf_ptr, len);
00439 s->buf_ptr += len;
00440 if (!len) {
00441 if (url_ferror(s)) return url_ferror(s);
00442 if (url_feof(s)) return AVERROR_EOF;
00443 }
00444 return len;
00445 }
00446
00447 unsigned int get_le16(ByteIOContext *s)
00448 {
00449 unsigned int val;
00450 val = get_byte(s);
00451 val |= get_byte(s) << 8;
00452 return val;
00453 }
00454
00455 unsigned int get_le24(ByteIOContext *s)
00456 {
00457 unsigned int val;
00458 val = get_le16(s);
00459 val |= get_byte(s) << 16;
00460 return val;
00461 }
00462
00463 unsigned int get_le32(ByteIOContext *s)
00464 {
00465 unsigned int val;
00466 val = get_le16(s);
00467 val |= get_le16(s) << 16;
00468 return val;
00469 }
00470
00471 uint64_t get_le64(ByteIOContext *s)
00472 {
00473 uint64_t val;
00474 val = (uint64_t)get_le32(s);
00475 val |= (uint64_t)get_le32(s) << 32;
00476 return val;
00477 }
00478
00479 unsigned int get_be16(ByteIOContext *s)
00480 {
00481 unsigned int val;
00482 val = get_byte(s) << 8;
00483 val |= get_byte(s);
00484 return val;
00485 }
00486
00487 unsigned int get_be24(ByteIOContext *s)
00488 {
00489 unsigned int val;
00490 val = get_be16(s) << 8;
00491 val |= get_byte(s);
00492 return val;
00493 }
00494 unsigned int get_be32(ByteIOContext *s)
00495 {
00496 unsigned int val;
00497 val = get_be16(s) << 16;
00498 val |= get_be16(s);
00499 return val;
00500 }
00501
00502 char *get_strz(ByteIOContext *s, char *buf, int maxlen)
00503 {
00504 int i = 0;
00505 char c;
00506
00507 while ((c = get_byte(s))) {
00508 if (i < maxlen-1)
00509 buf[i++] = c;
00510 }
00511
00512 buf[i] = 0;
00513
00514 return buf;
00515 }
00516
00517 uint64_t get_be64(ByteIOContext *s)
00518 {
00519 uint64_t val;
00520 val = (uint64_t)get_be32(s) << 32;
00521 val |= (uint64_t)get_be32(s);
00522 return val;
00523 }
00524
00525 uint64_t ff_get_v(ByteIOContext *bc){
00526 uint64_t val = 0;
00527 int tmp;
00528
00529 do{
00530 tmp = get_byte(bc);
00531 val= (val<<7) + (tmp&127);
00532 }while(tmp&128);
00533 return val;
00534 }
00535
00536 int url_fdopen(ByteIOContext **s, URLContext *h)
00537 {
00538 uint8_t *buffer;
00539 int buffer_size, max_packet_size;
00540
00541 max_packet_size = url_get_max_packet_size(h);
00542 if (max_packet_size) {
00543 buffer_size = max_packet_size;
00544 } else {
00545 buffer_size = IO_BUFFER_SIZE;
00546 }
00547 buffer = av_malloc(buffer_size);
00548 if (!buffer)
00549 return AVERROR(ENOMEM);
00550
00551 *s = av_mallocz(sizeof(ByteIOContext));
00552 if(!*s) {
00553 av_free(buffer);
00554 return AVERROR(ENOMEM);
00555 }
00556
00557 if (init_put_byte(*s, buffer, buffer_size,
00558 (h->flags & URL_WRONLY || h->flags & URL_RDWR), h,
00559 url_read, url_write, url_seek) < 0) {
00560 av_free(buffer);
00561 av_freep(s);
00562 return AVERROR(EIO);
00563 }
00564 (*s)->is_streamed = h->is_streamed;
00565 (*s)->max_packet_size = max_packet_size;
00566 if(h->prot) {
00567 (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause;
00568 (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek;
00569 }
00570 return 0;
00571 }
00572
00573 int url_setbufsize(ByteIOContext *s, int buf_size)
00574 {
00575 uint8_t *buffer;
00576 buffer = av_malloc(buf_size);
00577 if (!buffer)
00578 return AVERROR(ENOMEM);
00579
00580 av_free(s->buffer);
00581 s->buffer = buffer;
00582 s->buffer_size = buf_size;
00583 s->buf_ptr = buffer;
00584 url_resetbuf(s, s->write_flag ? URL_WRONLY : URL_RDONLY);
00585 return 0;
00586 }
00587
00588 #if LIBAVFORMAT_VERSION_MAJOR < 53
00589 int url_resetbuf(ByteIOContext *s, int flags)
00590 #else
00591 static int url_resetbuf(ByteIOContext *s, int flags)
00592 #endif
00593 {
00594 #if LIBAVFORMAT_VERSION_MAJOR < 53
00595 URLContext *h = s->opaque;
00596 if ((flags & URL_RDWR) || (h && h->flags != flags && !h->flags & URL_RDWR))
00597 return AVERROR(EINVAL);
00598 #else
00599 assert(flags == URL_WRONLY || flags == URL_RDONLY);
00600 #endif
00601
00602 if (flags & URL_WRONLY) {
00603 s->buf_end = s->buffer + s->buffer_size;
00604 s->write_flag = 1;
00605 } else {
00606 s->buf_end = s->buffer;
00607 s->write_flag = 0;
00608 }
00609 return 0;
00610 }
00611
00612 int url_fopen(ByteIOContext **s, const char *filename, int flags)
00613 {
00614 URLContext *h;
00615 int err;
00616
00617 err = url_open(&h, filename, flags);
00618 if (err < 0)
00619 return err;
00620 err = url_fdopen(s, h);
00621 if (err < 0) {
00622 url_close(h);
00623 return err;
00624 }
00625 return 0;
00626 }
00627
00628 int url_fclose(ByteIOContext *s)
00629 {
00630 URLContext *h = s->opaque;
00631
00632 av_free(s->buffer);
00633 av_free(s);
00634 return url_close(h);
00635 }
00636
00637 URLContext *url_fileno(ByteIOContext *s)
00638 {
00639 return s->opaque;
00640 }
00641
00642 #if CONFIG_MUXERS
00643 int url_fprintf(ByteIOContext *s, const char *fmt, ...)
00644 {
00645 va_list ap;
00646 char buf[4096];
00647 int ret;
00648
00649 va_start(ap, fmt);
00650 ret = vsnprintf(buf, sizeof(buf), fmt, ap);
00651 va_end(ap);
00652 put_buffer(s, buf, strlen(buf));
00653 return ret;
00654 }
00655 #endif //CONFIG_MUXERS
00656
00657 char *url_fgets(ByteIOContext *s, char *buf, int buf_size)
00658 {
00659 int c;
00660 char *q;
00661
00662 c = url_fgetc(s);
00663 if (c == EOF)
00664 return NULL;
00665 q = buf;
00666 for(;;) {
00667 if (c == EOF || c == '\n')
00668 break;
00669 if ((q - buf) < buf_size - 1)
00670 *q++ = c;
00671 c = url_fgetc(s);
00672 }
00673 if (buf_size > 0)
00674 *q = '\0';
00675 return buf;
00676 }
00677
00678 int url_fget_max_packet_size(ByteIOContext *s)
00679 {
00680 return s->max_packet_size;
00681 }
00682
00683 int av_url_read_fpause(ByteIOContext *s, int pause)
00684 {
00685 if (!s->read_pause)
00686 return AVERROR(ENOSYS);
00687 return s->read_pause(s->opaque, pause);
00688 }
00689
00690 int64_t av_url_read_fseek(ByteIOContext *s, int stream_index,
00691 int64_t timestamp, int flags)
00692 {
00693 URLContext *h = s->opaque;
00694 int64_t ret;
00695 if (!s->read_seek)
00696 return AVERROR(ENOSYS);
00697 ret = s->read_seek(h, stream_index, timestamp, flags);
00698 if(ret >= 0) {
00699 s->buf_ptr = s->buf_end;
00700 s->pos = s->seek(h, 0, SEEK_CUR);
00701 }
00702 return ret;
00703 }
00704
00705
00706
00707 #if CONFIG_MUXERS || CONFIG_NETWORK
00708
00709 int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags)
00710 {
00711 int ret;
00712 *s = av_mallocz(sizeof(ByteIOContext));
00713 if(!*s)
00714 return AVERROR(ENOMEM);
00715 ret = init_put_byte(*s, buf, buf_size,
00716 (flags & URL_WRONLY || flags & URL_RDWR),
00717 NULL, NULL, NULL, NULL);
00718 if(ret != 0)
00719 av_freep(s);
00720 return ret;
00721 }
00722
00723 int url_close_buf(ByteIOContext *s)
00724 {
00725 put_flush_packet(s);
00726 return s->buf_ptr - s->buffer;
00727 }
00728
00729
00730
00731 typedef struct DynBuffer {
00732 int pos, size, allocated_size;
00733 uint8_t *buffer;
00734 int io_buffer_size;
00735 uint8_t io_buffer[1];
00736 } DynBuffer;
00737
00738 static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
00739 {
00740 DynBuffer *d = opaque;
00741 unsigned new_size, new_allocated_size;
00742
00743
00744 new_size = d->pos + buf_size;
00745 new_allocated_size = d->allocated_size;
00746 if(new_size < d->pos || new_size > INT_MAX/2)
00747 return -1;
00748 while (new_size > new_allocated_size) {
00749 if (!new_allocated_size)
00750 new_allocated_size = new_size;
00751 else
00752 new_allocated_size += new_allocated_size / 2 + 1;
00753 }
00754
00755 if (new_allocated_size > d->allocated_size) {
00756 d->buffer = av_realloc(d->buffer, new_allocated_size);
00757 if(d->buffer == NULL)
00758 return AVERROR(ENOMEM);
00759 d->allocated_size = new_allocated_size;
00760 }
00761 memcpy(d->buffer + d->pos, buf, buf_size);
00762 d->pos = new_size;
00763 if (d->pos > d->size)
00764 d->size = d->pos;
00765 return buf_size;
00766 }
00767
00768 static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
00769 {
00770 unsigned char buf1[4];
00771 int ret;
00772
00773
00774 AV_WB32(buf1, buf_size);
00775 ret= dyn_buf_write(opaque, buf1, 4);
00776 if(ret < 0)
00777 return ret;
00778
00779
00780 return dyn_buf_write(opaque, buf, buf_size);
00781 }
00782
00783 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
00784 {
00785 DynBuffer *d = opaque;
00786
00787 if (whence == SEEK_CUR)
00788 offset += d->pos;
00789 else if (whence == SEEK_END)
00790 offset += d->size;
00791 if (offset < 0 || offset > 0x7fffffffLL)
00792 return -1;
00793 d->pos = offset;
00794 return 0;
00795 }
00796
00797 static int url_open_dyn_buf_internal(ByteIOContext **s, int max_packet_size)
00798 {
00799 DynBuffer *d;
00800 int ret;
00801 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
00802
00803 if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
00804 return -1;
00805 d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
00806 if (!d)
00807 return AVERROR(ENOMEM);
00808 *s = av_mallocz(sizeof(ByteIOContext));
00809 if(!*s) {
00810 av_free(d);
00811 return AVERROR(ENOMEM);
00812 }
00813 d->io_buffer_size = io_buffer_size;
00814 ret = init_put_byte(*s, d->io_buffer, io_buffer_size,
00815 1, d, NULL,
00816 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
00817 max_packet_size ? NULL : dyn_buf_seek);
00818 if (ret == 0) {
00819 (*s)->max_packet_size = max_packet_size;
00820 } else {
00821 av_free(d);
00822 av_freep(s);
00823 }
00824 return ret;
00825 }
00826
00827 int url_open_dyn_buf(ByteIOContext **s)
00828 {
00829 return url_open_dyn_buf_internal(s, 0);
00830 }
00831
00832 int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size)
00833 {
00834 if (max_packet_size <= 0)
00835 return -1;
00836 return url_open_dyn_buf_internal(s, max_packet_size);
00837 }
00838
00839 int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer)
00840 {
00841 DynBuffer *d = s->opaque;
00842 int size;
00843
00844 put_flush_packet(s);
00845
00846 *pbuffer = d->buffer;
00847 size = d->size;
00848 av_free(d);
00849 av_free(s);
00850 return size;
00851 }
00852 #endif