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