diff --git a/doc/APIchanges b/doc/APIchanges
index 4fd30def410aa3c42ac9b02e082b302b70a79e57..69995949661cb55a8d75d6fb62d3e81a8f56bed9 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil:     2012-10-22
 
 API changes, most recent first:
 
+2014-05-xx - xxxxxxx - lavu 52.86.100 - fifo.h
+  Add av_fifo_alloc_array() function.
+
 2014-05-xx - xxxxxxx - lavu 53.15.0 - frame.h, display.h
   Add AV_FRAME_DATA_DISPLAYMATRIX for exporting frame-level
   spatial rendering on video frames for proper display.
diff --git a/ffmpeg.c b/ffmpeg.c
index 9df3b829d2119a08281d909f4bd01a45a9eed299..7ec5889fae0b478ed05eec777f962dbdabcc8708 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3180,7 +3180,7 @@ static int init_input_threads(void)
     for (i = 0; i < nb_input_files; i++) {
         InputFile *f = input_files[i];
 
-        if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
+        if (!(f->fifo = av_fifo_alloc_array(8, sizeof(AVPacket))))
             return AVERROR(ENOMEM);
 
         if (f->ctx->pb ? !f->ctx->pb->seekable :
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 3178ee5e5536e1f35ad0dd8a82b2814af98186ed..68c915e9ce40c1ce0daf713166553cfb8c49e13e 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -707,7 +707,7 @@ static av_cold int flac_parse_init(AVCodecParserContext *c)
     fpc->pc = c;
     /* There will generally be FLAC_MIN_HEADERS buffered in the fifo before
        it drains.  This is allocated early to avoid slow reallocation. */
-    fpc->fifo_buf = av_fifo_alloc(FLAC_AVG_FRAME_SIZE * (FLAC_MIN_HEADERS + 3));
+    fpc->fifo_buf = av_fifo_alloc_array(FLAC_MIN_HEADERS + 3, FLAC_AVG_FRAME_SIZE);
     if (!fpc->fifo_buf)
         return AVERROR(ENOMEM);
     return 0;
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index 9ab7c3475e9f494d07b51d881e6cc63ee2860d7b..9e176985ee675028654e2bedd5fb7a1498dbde25 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -168,7 +168,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
 
     c->parent_avctx = avctx;
 
-    c->task_fifo = av_fifo_alloc(sizeof(Task) * BUFFER_SIZE);
+    c->task_fifo = av_fifo_alloc_array(BUFFER_SIZE, sizeof(Task));
     if(!c->task_fifo)
         goto fail;
 
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index 759ef9bcdfbaa67282477b6f1b74a808c1ebd58d..70aa6ffcc13d0e51ad1dd27f6b7a006b0e0ee4b6 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -194,9 +194,9 @@ static int start_jack(AVFormatContext *context)
     }
 
     /* Create FIFO buffers */
-    self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket));
+    self->filled_pkts = av_fifo_alloc_array(FIFO_PACKETS_NUM, sizeof(AVPacket));
     /* New packets FIFO with one extra packet for safety against underruns */
-    self->new_pkts    = av_fifo_alloc((FIFO_PACKETS_NUM + 1) * sizeof(AVPacket));
+    self->new_pkts    = av_fifo_alloc_array((FIFO_PACKETS_NUM + 1), sizeof(AVPacket));
     if ((test = supply_new_packets(self, context))) {
         jack_client_close(self->client);
         return test;
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 345af773ff3995d3a722868380db68235a10fef8..525f97bfb0c492d6f34292646d98883f3dc930ae 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -246,7 +246,7 @@ static av_cold int common_init(AVFilterContext *ctx)
 {
     BufferSinkContext *buf = ctx->priv;
 
-    buf->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef *));
+    buf->fifo = av_fifo_alloc_array(FIFO_INIT_SIZE, sizeof(AVFilterBufferRef *));
     if (!buf->fifo) {
         av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
         return AVERROR(ENOMEM);
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index ad7297aab45659289c37ecc433f03baf4987f6d1..a38633d50a832a61b9eb0c72112c34af27ed6cf5 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -79,7 +79,7 @@ static av_cold int init(AVFilterContext *ctx)
 {
     FPSContext *s = ctx->priv;
 
-    if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*))))
+    if (!(s->fifo = av_fifo_alloc_array(2, sizeof(AVFrame*))))
         return AVERROR(ENOMEM);
 
     s->first_pts    = AV_NOPTS_VALUE;
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index 6d24ff5c7fe3e21664016c183a39006df28cc4c9..7f580b970dc32422121a98e0f3aec508775e33f7 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -45,11 +45,11 @@ int ff_audio_interleave_init(AVFormatContext *s,
     int i;
 
     if (!samples_per_frame)
-        return -1;
+        return AVERROR(EINVAL);
 
     if (!time_base.num) {
         av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
@@ -60,14 +60,15 @@ int ff_audio_interleave_init(AVFormatContext *s,
                                 av_get_bits_per_sample(st->codec->codec_id)) / 8;
             if (!aic->sample_size) {
                 av_log(s, AV_LOG_ERROR, "could not compute sample size\n");
-                return -1;
+                return AVERROR(EINVAL);
             }
             aic->samples_per_frame = samples_per_frame;
             aic->samples = aic->samples_per_frame;
             aic->time_base = time_base;
 
             aic->fifo_size = 100* *aic->samples;
-            aic->fifo= av_fifo_alloc(100 * *aic->samples);
+            if (!(aic->fifo= av_fifo_alloc_array(100, *aic->samples)))
+                return AVERROR(ENOMEM);
         }
     }
 
@@ -113,7 +114,7 @@ int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt
             unsigned new_size = av_fifo_size(aic->fifo) + pkt->size;
             if (new_size > aic->fifo_size) {
                 if (av_fifo_realloc2(aic->fifo, new_size) < 0)
-                    return -1;
+                    return AVERROR(ENOMEM);
                 aic->fifo_size = new_size;
             }
             av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL);
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index defcf2a16e3c1ce8385d77c9131eb31f411b6a16..bd484d96e895b2b5364bed11dc66c7f5a7bfa79d 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -331,7 +331,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
         c->start_time = ff_iso8601_to_unix_time(t->value);
 
     for (i=0; i < c->n_ast; i++) {
-        if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*MAX_AUDIO_FRAME_SIZE))) {
+        if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc_array(100, MAX_AUDIO_FRAME_SIZE))) {
             while (i > 0) {
                 i--;
                 av_fifo_freep(&c->audio_data[i]);
diff --git a/libavformat/ftp.c b/libavformat/ftp.c
index dae8aa086d2f45ede2cea0b81694c04351cda14b..60011650b5f5a2f8cba827619670ec3ec2c501fc 100644
--- a/libavformat/ftp.c
+++ b/libavformat/ftp.c
@@ -227,6 +227,48 @@ static int ftp_auth(FTPContext *s)
     return 0;
 }
 
+static int ftp_passive_mode_epsv(FTPContext *s)
+{
+    char *res = NULL, *start = NULL, *end = NULL;
+    int i;
+    static const char d = '|';
+    static const char *command = "EPSV\r\n";
+    static const int epsv_codes[] = {229, 500, 501, 0}; /* 500, 501 are incorrect codes */
+
+    if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res)
+        goto fail;
+
+    for (i = 0; res[i]; ++i) {
+        if (res[i] == '(') {
+            start = res + i + 1;
+        } else if (res[i] == ')') {
+            end = res + i;
+            break;
+        }
+    }
+    if (!start || !end)
+        goto fail;
+
+    *end = '\0';
+    if (strlen(start) < 5)
+        goto fail;
+    if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d)
+        goto fail;
+    start += 3;
+    end[-1] = '\0';
+
+    s->server_data_port = atoi(start);
+    av_dlog(s, "Server data port: %d\n", s->server_data_port);
+
+    av_free(res);
+    return 0;
+
+  fail:
+    av_free(res);
+    s->server_data_port = -1;
+    return AVERROR(ENOSYS);
+}
+
 static int ftp_passive_mode(FTPContext *s)
 {
     char *res = NULL, *start = NULL, *end = NULL;
@@ -270,8 +312,6 @@ static int ftp_passive_mode(FTPContext *s)
   fail:
     av_free(res);
     s->server_data_port = -1;
-    av_log(s, AV_LOG_ERROR, "Set passive mode failed\n"
-                            "Your FTP server may use IPv6 which is not supported yet.\n");
     return AVERROR(EIO);
 }
 
@@ -439,8 +479,11 @@ static int ftp_connect_data_connection(URLContext *h)
 
     if (!s->conn_data) {
         /* Enter passive mode */
-        if ((err = ftp_passive_mode(s)) < 0)
-            return err;
+        if (ftp_passive_mode_epsv(s) < 0) {
+            /* Use PASV as fallback */
+            if ((err = ftp_passive_mode(s)) < 0)
+                return err;
+        }
         /* Open data connection */
         ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
         if (s->rw_timeout != -1) {
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index 09ffa4fd26eb107cc37f9c83574f7913530bc708..77391ee7f27360b1fbd05d839e96587c8c379121 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -24,19 +24,34 @@
 #include "common.h"
 #include "fifo.h"
 
-AVFifoBuffer *av_fifo_alloc(unsigned int size)
+static AVFifoBuffer *fifo_alloc_common(void *buffer, size_t size)
 {
-    AVFifoBuffer *f = av_mallocz(sizeof(AVFifoBuffer));
-    if (!f)
+    AVFifoBuffer *f;
+    if (!buffer)
+        return NULL;
+    f = av_mallocz(sizeof(AVFifoBuffer));
+    if (!f) {
+        av_free(buffer);
         return NULL;
-    f->buffer = av_malloc(size);
+    }
+    f->buffer = buffer;
     f->end    = f->buffer + size;
     av_fifo_reset(f);
-    if (!f->buffer)
-        av_freep(&f);
     return f;
 }
 
+AVFifoBuffer *av_fifo_alloc(unsigned int size)
+{
+    void *buffer = av_malloc(size);
+    return fifo_alloc_common(buffer, size);
+}
+
+AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
+{
+    void *buffer = av_malloc_array(nmemb, size);
+    return fifo_alloc_common(buffer, nmemb * size);
+}
+
 void av_fifo_free(AVFifoBuffer *f)
 {
     if (f) {
diff --git a/libavutil/fifo.h b/libavutil/fifo.h
index f0b11094d0c40b27de20a8182609fa8e193e85bd..dda7dd2e964500d683a3801478fb9fed30fdd617 100644
--- a/libavutil/fifo.h
+++ b/libavutil/fifo.h
@@ -41,6 +41,14 @@ typedef struct AVFifoBuffer {
  */
 AVFifoBuffer *av_fifo_alloc(unsigned int size);
 
+/**
+ * Initialize an AVFifoBuffer.
+ * @param nmemb number of elements
+ * @param size  size of the single element
+ * @return AVFifoBuffer or NULL in case of memory allocation failure
+ */
+AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size);
+
 /**
  * Free an AVFifoBuffer.
  * @param f AVFifoBuffer to free
diff --git a/libavutil/version.h b/libavutil/version.h
index 9eeba9abd953bc2aed6372bc6afc71bc0cfd4a39..b134615a5bf91e048f2f642f7f1553b8e265f332 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -56,7 +56,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  85
+#define LIBAVUTIL_VERSION_MINOR  86
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \