From 7336e39f3cd2833786b0ebcca5604e13d2f86500 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sat, 10 May 2014 08:06:53 +0200 Subject: [PATCH 01/12] lavu/fifo: add av_fifo_alloc_array function Allows to alloc fifo buffer by passing number of elements and size of element. Signed-off-by: Lukasz Marek --- doc/APIchanges | 3 +++ libavutil/fifo.c | 27 +++++++++++++++++++++------ libavutil/fifo.h | 8 ++++++++ libavutil/version.h | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 4fd30def41..6999594966 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/libavutil/fifo.c b/libavutil/fifo.c index 09ffa4fd26..77391ee7f2 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->buffer = av_malloc(size); + f = av_mallocz(sizeof(AVFifoBuffer)); + if (!f) { + av_free(buffer); + return NULL; + } + 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 f0b11094d0..dda7dd2e96 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 9eeba9abd9..b134615a5b 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, \ From 51bad41a13c702fc474ad76e53c3d43fa302fe83 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:13:31 +0200 Subject: [PATCH 02/12] lavd/jack_audio: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavdevice/jack_audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c index 759ef9bcdf..70aa6ffcc1 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; From 4d686674b26596ccf951528a85526977016db8dd Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:15:49 +0200 Subject: [PATCH 03/12] ffmpeg: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- ffmpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg.c b/ffmpeg.c index 9df3b829d2..7ec5889fae 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 : From d15db8e413e9fd8455989cfa1af94bc63a3c9e35 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:18:38 +0200 Subject: [PATCH 04/12] lavfi/buffersink: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavfilter/buffersink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 345af773ff..525f97bfb0 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); From ce051ceefc7040fe0af311e4ee5d702d4b402dbf Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:20:44 +0200 Subject: [PATCH 05/12] lavfi/vf_fps: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavfilter/vf_fps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index ad7297aab4..a38633d50a 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; From bc4f362c9281c6d3355133acdadc13a0993248e1 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:22:43 +0200 Subject: [PATCH 06/12] lavc/frame_thread_encoder: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavcodec/frame_thread_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 9ab7c3475e..9e176985ee 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; From 8aa29880365c4d801e46289efb31dc7378972ff4 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:24:45 +0200 Subject: [PATCH 07/12] lavc/flac_parser: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavcodec/flac_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 3178ee5e55..68c915e9ce 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; From 74f9c5947d69ce0261335eb76b1e51ea5c7fd40d Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:26:31 +0200 Subject: [PATCH 08/12] lavf/dvenc: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavformat/dvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c index defcf2a16e..bd484d96e8 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]); From c61cdefa4d795b4484bc8e2280aa570c00833336 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:29:19 +0200 Subject: [PATCH 09/12] lavf/audiointerleave: use av_fifo_alloc_array Signed-off-by: Lukasz Marek --- libavformat/audiointerleave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c index 6d24ff5c7f..1243f43c18 100644 --- a/libavformat/audiointerleave.c +++ b/libavformat/audiointerleave.c @@ -67,7 +67,7 @@ int ff_audio_interleave_init(AVFormatContext *s, aic->time_base = time_base; aic->fifo_size = 100* *aic->samples; - aic->fifo= av_fifo_alloc(100 * *aic->samples); + aic->fifo= av_fifo_alloc_array(100, *aic->samples); } } From 2ed9e17ed1793b3b66ed27c0a113676a46eb9871 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:33:56 +0200 Subject: [PATCH 10/12] lavf/audiointerleave: check for allocation failure Signed-off-by: Lukasz Marek --- libavformat/audiointerleave.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c index 1243f43c18..97bd801aa7 100644 --- a/libavformat/audiointerleave.c +++ b/libavformat/audiointerleave.c @@ -67,7 +67,8 @@ int ff_audio_interleave_init(AVFormatContext *s, aic->time_base = time_base; aic->fifo_size = 100* *aic->samples; - aic->fifo= av_fifo_alloc_array(100, *aic->samples); + if (!(aic->fifo= av_fifo_alloc_array(100, *aic->samples))) + return AVERROR(ENOMEM); } } From 37fa4b9bb9672520fa901b69234ac611bbbd133f Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 11 May 2014 05:40:25 +0200 Subject: [PATCH 11/12] lavf/audiointerleave: return more meaningful error codes Signed-off-by: Lukasz Marek --- libavformat/audiointerleave.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c index 97bd801aa7..7f580b970d 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,7 +60,7 @@ 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; @@ -114,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); From b9419b58826effc3d9afabd1a2e50d66391fbdbf Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Mon, 19 May 2014 23:53:08 +0200 Subject: [PATCH 12/12] lavf/ftp: favour EPSV over PASV command EPSV is newer version of PASV and allows to use IPv6. Signed-off-by: Lukasz Marek --- libavformat/ftp.c | 51 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/libavformat/ftp.c b/libavformat/ftp.c index dae8aa086d..60011650b5 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) {