diff --git a/libavformat/tee.c b/libavformat/tee.c index 806beaa14f..9d0a4cb39e 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -27,8 +27,6 @@ #include "avformat.h" #include "avio_internal.h" -#define MAX_SLAVES 16 - typedef enum { ON_SLAVE_FAILURE_ABORT = 1, ON_SLAVE_FAILURE_IGNORE = 2 @@ -52,7 +50,7 @@ typedef struct TeeContext { const AVClass *class; unsigned nb_slaves; unsigned nb_alive; - TeeSlave slaves[MAX_SLAVES]; + TeeSlave *slaves; } TeeContext; static const char *const slave_delim = "|"; @@ -203,6 +201,7 @@ static void close_slaves(AVFormatContext *avf) for (i = 0; i < tee->nb_slaves; i++) { close_slave(&tee->slaves[i]); } + av_freep(&tee->slaves); } static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) @@ -443,24 +442,28 @@ static int tee_write_header(AVFormatContext *avf) TeeContext *tee = avf->priv_data; unsigned nb_slaves = 0, i; const char *filename = avf->filename; - char *slaves[MAX_SLAVES]; + char **slaves = NULL; int ret; while (*filename) { - if (nb_slaves == MAX_SLAVES) { - av_log(avf, AV_LOG_ERROR, "Maximum %d slave muxers reached.\n", - MAX_SLAVES); - ret = AVERROR_PATCHWELCOME; + char *slave = av_get_token(&filename, slave_delim); + if (!slave) { + ret = AVERROR(ENOMEM); goto fail; } - if (!(slaves[nb_slaves++] = av_get_token(&filename, slave_delim))) { - ret = AVERROR(ENOMEM); + ret = av_dynarray_add_nofree(&slaves, &nb_slaves, slave); + if (ret < 0) { + av_free(slave); goto fail; } if (strspn(filename, slave_delim)) filename++; } + if (!(tee->slaves = av_mallocz_array(nb_slaves, sizeof(*tee->slaves)))) { + ret = AVERROR(ENOMEM); + goto fail; + } tee->nb_slaves = tee->nb_alive = nb_slaves; for (i = 0; i < nb_slaves; i++) { @@ -483,12 +486,14 @@ static int tee_write_header(AVFormatContext *avf) av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped " "to any slave.\n", i); } + av_free(slaves); return 0; fail: for (i = 0; i < nb_slaves; i++) av_freep(&slaves[i]); close_slaves(avf); + av_free(slaves); return ret; } @@ -505,6 +510,7 @@ static int tee_write_trailer(AVFormatContext *avf) ret_all = ret; } } + av_freep(&tee->slaves); return ret_all; }