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, \