r3d: do not create the audio stream until we know the sample rate
[ffmpeg.git] / libavformat / aviobuf.c
index 7d76e0b..bb575ed 100644 (file)
  */
 #define SHORT_SEEK_THRESHOLD 4096
 
-static void *ffio_url_child_next(void *obj, void *prev)
+static void *ff_avio_child_next(void *obj, void *prev)
 {
     AVIOContext *s = obj;
     return prev ? NULL : s->opaque;
 }
 
-static const AVClass *ffio_url_child_class_next(const AVClass *prev)
+static const AVClass *ff_avio_child_class_next(const AVClass *prev)
 {
     return prev ? NULL : &ffurl_context_class;
 }
 
-static const AVOption ffio_url_options[] = {
+static const AVOption ff_avio_options[] = {
     { NULL },
 };
 
-const AVClass ffio_url_class = {
+const AVClass ff_avio_class = {
     .class_name = "AVIOContext",
     .item_name  = av_default_item_name,
     .version    = LIBAVUTIL_VERSION_INT,
-    .option     = ffio_url_options,
-    .child_next = ffio_url_child_next,
-    .child_class_next = ffio_url_child_class_next,
+    .option     = ff_avio_options,
+    .child_next = ff_avio_child_next,
+    .child_class_next = ff_avio_child_class_next,
 };
 
 static void fill_buffer(AVIOContext *s);
@@ -206,7 +206,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
     }
     offset1 = offset - pos;
     if (!s->must_flush &&
-        offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
+        offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
         /* can do the seek inside the buffer */
         s->buf_ptr = s->buffer + offset1;
     } else if ((!s->seekable ||
@@ -284,22 +284,28 @@ int avio_put_str(AVIOContext *s, const char *str)
     return len;
 }
 
-int avio_put_str16le(AVIOContext *s, const char *str)
-{
-    const uint8_t *q = str;
-    int ret = 0;
+#define PUT_STR16(type, write)                                   \
+    int avio_put_str16 ## type(AVIOContext * s, const char *str) \
+    {                                                            \
+        const uint8_t *q = str;                                  \
+        int ret          = 0;                                    \
+                                                                 \
+        while (*q) {                                             \
+            uint32_t ch;                                         \
+            uint16_t tmp;                                        \
+                                                                 \
+            GET_UTF8(ch, *q++, break; )                          \
+            PUT_UTF16(ch, tmp, write(s, tmp); ret += 2; )        \
+        }                                                        \
+        write(s, 0);                                             \
+        ret += 2;                                                \
+        return ret;                                              \
+    }
 
-    while (*q) {
-        uint32_t ch;
-        uint16_t tmp;
+PUT_STR16(le, avio_wl16)
+PUT_STR16(be, avio_wb16)
 
-        GET_UTF8(ch, *q++, break;)
-        PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;)
-    }
-    avio_wl16(s, 0);
-    ret += 2;
-    return ret;
-}
+#undef PUT_STR16
 
 int ff_get_v_length(uint64_t val)
 {
@@ -414,6 +420,12 @@ unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
     return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
 }
 
+unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
+                                unsigned int len)
+{
+    return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
+}
+
 unsigned long ffio_get_checksum(AVIOContext *s)
 {
     s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
@@ -490,6 +502,14 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
     return size1 - size;
 }
 
+int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
+{
+    int ret = avio_read(s, buf, size);
+    if (ret != size)
+        return AVERROR_INVALIDDATA;
+    return ret;
+}
+
 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
 {
     if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
@@ -686,7 +706,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
         return AVERROR(ENOMEM);
 
     *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
-                            ffurl_read, ffurl_write, ffurl_seek);
+                            (int (*)(void *, uint8_t *, int)) ffurl_read,
+                            (int (*)(void *, uint8_t *, int)) ffurl_write,
+                            (int64_t (*)(void *, int64_t, int)) ffurl_seek);
     if (!*s) {
         av_free(buffer);
         return AVERROR(ENOMEM);
@@ -697,7 +719,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
         (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause;
         (*s)->read_seek  = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek;
     }
-    (*s)->av_class = &ffio_url_class;
+    (*s)->av_class = &ff_avio_class;
     return 0;
 }
 
@@ -880,8 +902,11 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
 
     if (new_allocated_size > d->allocated_size) {
         int err;
-        if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0)
+        if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
+            d->allocated_size = 0;
+            d->size = 0;
             return err;
+        }
         d->allocated_size = new_allocated_size;
     }
     memcpy(d->buffer + d->pos, buf, buf_size);
@@ -956,22 +981,71 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
 
 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
 {
-    DynBuffer *d = s->opaque;
+    DynBuffer *d;
     int size;
-    static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
+    static const char padbuf[AV_INPUT_BUFFER_PADDING_SIZE] = {0};
     int padding = 0;
 
+    if (!s) {
+        *pbuffer = NULL;
+        return 0;
+    }
+
     /* don't attempt to pad fixed-size packet buffers */
     if (!s->max_packet_size) {
         avio_write(s, padbuf, sizeof(padbuf));
-        padding = FF_INPUT_BUFFER_PADDING_SIZE;
+        padding = AV_INPUT_BUFFER_PADDING_SIZE;
     }
 
     avio_flush(s);
 
+    d = s->opaque;
     *pbuffer = d->buffer;
     size = d->size;
     av_free(d);
     av_free(s);
     return size - padding;
 }
+
+void ffio_free_dyn_buf(AVIOContext **s)
+{
+    uint8_t *tmp;
+    if (!*s)
+        return;
+    avio_close_dyn_buf(*s, &tmp);
+    av_free(tmp);
+    *s = NULL;
+}
+
+static int null_buf_write(void *opaque, uint8_t *buf, int buf_size)
+{
+    DynBuffer *d = opaque;
+
+    d->pos += buf_size;
+    if (d->pos > d->size)
+        d->size = d->pos;
+    return buf_size;
+}
+
+int ffio_open_null_buf(AVIOContext **s)
+{
+    int ret = url_open_dyn_buf_internal(s, 0);
+    if (ret >= 0) {
+        AVIOContext *pb = *s;
+        pb->write_packet = null_buf_write;
+    }
+    return ret;
+}
+
+int ffio_close_null_buf(AVIOContext *s)
+{
+    DynBuffer *d = s->opaque;
+    int size;
+
+    avio_flush(s);
+
+    size = d->size;
+    av_free(d);
+    av_free(s);
+    return size;
+}