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