Commit d46a8e30 authored by Jan Sebechlebsky's avatar Jan Sebechlebsky Committed by Marton Balint

avformat/tee: Support arbitrary number of slaves

Signed-off-by: 's avatarJan Sebechlebsky <sebechlebskyjan@gmail.com>
parent 888a5c79
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include "avformat.h" #include "avformat.h"
#include "avio_internal.h" #include "avio_internal.h"
#define MAX_SLAVES 16
typedef enum { typedef enum {
ON_SLAVE_FAILURE_ABORT = 1, ON_SLAVE_FAILURE_ABORT = 1,
ON_SLAVE_FAILURE_IGNORE = 2 ON_SLAVE_FAILURE_IGNORE = 2
...@@ -52,7 +50,7 @@ typedef struct TeeContext { ...@@ -52,7 +50,7 @@ typedef struct TeeContext {
const AVClass *class; const AVClass *class;
unsigned nb_slaves; unsigned nb_slaves;
unsigned nb_alive; unsigned nb_alive;
TeeSlave slaves[MAX_SLAVES]; TeeSlave *slaves;
} TeeContext; } TeeContext;
static const char *const slave_delim = "|"; static const char *const slave_delim = "|";
...@@ -203,6 +201,7 @@ static void close_slaves(AVFormatContext *avf) ...@@ -203,6 +201,7 @@ static void close_slaves(AVFormatContext *avf)
for (i = 0; i < tee->nb_slaves; i++) { for (i = 0; i < tee->nb_slaves; i++) {
close_slave(&tee->slaves[i]); close_slave(&tee->slaves[i]);
} }
av_freep(&tee->slaves);
} }
static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
...@@ -443,24 +442,28 @@ static int tee_write_header(AVFormatContext *avf) ...@@ -443,24 +442,28 @@ static int tee_write_header(AVFormatContext *avf)
TeeContext *tee = avf->priv_data; TeeContext *tee = avf->priv_data;
unsigned nb_slaves = 0, i; unsigned nb_slaves = 0, i;
const char *filename = avf->filename; const char *filename = avf->filename;
char *slaves[MAX_SLAVES]; char **slaves = NULL;
int ret; int ret;
while (*filename) { while (*filename) {
if (nb_slaves == MAX_SLAVES) { char *slave = av_get_token(&filename, slave_delim);
av_log(avf, AV_LOG_ERROR, "Maximum %d slave muxers reached.\n", if (!slave) {
MAX_SLAVES); ret = AVERROR(ENOMEM);
ret = AVERROR_PATCHWELCOME;
goto fail; goto fail;
} }
if (!(slaves[nb_slaves++] = av_get_token(&filename, slave_delim))) { ret = av_dynarray_add_nofree(&slaves, &nb_slaves, slave);
ret = AVERROR(ENOMEM); if (ret < 0) {
av_free(slave);
goto fail; goto fail;
} }
if (strspn(filename, slave_delim)) if (strspn(filename, slave_delim))
filename++; 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; tee->nb_slaves = tee->nb_alive = nb_slaves;
for (i = 0; i < nb_slaves; i++) { for (i = 0; i < nb_slaves; i++) {
...@@ -483,12 +486,14 @@ static int tee_write_header(AVFormatContext *avf) ...@@ -483,12 +486,14 @@ static int tee_write_header(AVFormatContext *avf)
av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped " av_log(avf, AV_LOG_WARNING, "Input stream #%d is not mapped "
"to any slave.\n", i); "to any slave.\n", i);
} }
av_free(slaves);
return 0; return 0;
fail: fail:
for (i = 0; i < nb_slaves; i++) for (i = 0; i < nb_slaves; i++)
av_freep(&slaves[i]); av_freep(&slaves[i]);
close_slaves(avf); close_slaves(avf);
av_free(slaves);
return ret; return ret;
} }
...@@ -505,6 +510,7 @@ static int tee_write_trailer(AVFormatContext *avf) ...@@ -505,6 +510,7 @@ static int tee_write_trailer(AVFormatContext *avf)
ret_all = ret; ret_all = ret;
} }
} }
av_freep(&tee->slaves);
return ret_all; return ret_all;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment