On Fri, Oct 07, 2016 at 01:03:03AM +0200, sebechlebsky...@gmail.com wrote: > From: Jan Sebechlebsky <sebechlebsky...@gmail.com> > > Signed-off-by: Jan Sebechlebsky <sebechlebsky...@gmail.com> > --- > This commit makes use of fifo muxer together with tee muxer > easier, fifo muxer does not have to be explicitly specified > for each slave. For the most simple use case it is sufficient > to turn fifo muxer on for all slaves by switching on use_fifo > option. Same options can be passed to all fifo muxer instances of > slaves by assigning them to fifo_options of tee. > Both use_fifo option and individual fifo_options can be > overriden per slave if needed. > > doc/muxers.texi | 20 +++++++++++++ > libavformat/tee.c | 89 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 108 insertions(+), 1 deletion(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index 9ec2e31..b88b83c 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -1473,6 +1473,7 @@ Specify whether to remove all fragments when finished. > Default 0 (do not remove) > > @end table > > +@anchor{fifo} > @section fifo > > The fifo pseudo-muxer allows the separation of encoding and muxing by using > @@ -1580,6 +1581,18 @@ with the tee muxer; encoding can be a very expensive > process. It is not > useful when using the libavformat API directly because it is then possible > to feed the same packets to several muxers directly. > > +@table @option > + > +@item use_fifo @var{bool} > +If set to 1, slave outputs will be processed in separate thread using > @ref{fifo} > +muxer. This allows to compensate for different speed/latency/reliability of > +outputs and setup transparent recovery. By default this feature is turned > off. > + > +@item fifo_options > +Options to pass to fifo pseudo-muxer instances. See @ref{fifo}. > + > +@end table > + > The slave outputs are specified in the file name given to the muxer, > separated by '|'. If any of the slave name contains the '|' separator, > leading or trailing spaces or any special character, it must be > @@ -1601,6 +1614,13 @@ output name suffix. > Specify a list of bitstream filters to apply to the specified > output. > > +@item use_fifo @var{bool} > +This allows to override tee muxer use_fifo option for individual slave muxer. > + > +@item fifo_options > +This allows to override tee muxer fifo_options for individual slave muxer. > +See @ref{fifo}. > + > It is possible to specify to which streams a given bitstream filter > applies, by appending a stream specifier to the option separated by > @code{/}. @var{spec} must be a stream specifier (see @ref{Format > diff --git a/libavformat/tee.c b/libavformat/tee.c > index d59ad4d..764135d 100644 > --- a/libavformat/tee.c > +++ b/libavformat/tee.c > @@ -40,6 +40,8 @@ typedef struct { > AVBSFContext **bsfs; ///< bitstream filters per stream > > SlaveFailurePolicy on_fail; > + int use_fifo; > + AVDictionary *fifo_options; > > /** map from input to output streams indexes, > * disabled output streams are set to -1 */ > @@ -52,15 +54,28 @@ typedef struct TeeContext { > unsigned nb_slaves; > unsigned nb_alive; > TeeSlave *slaves; > + int use_fifo; > + AVDictionary *fifo_options; > + char *fifo_options_str; > } TeeContext; > > static const char *const slave_delim = "|"; > static const char *const slave_bsfs_spec_sep = "/"; > static const char *const slave_select_sep = ","; > > +#define OFFSET(x) offsetof(TeeContext, x) > +static const AVOption options[] = { > + {"use_fifo", "Use fifo pseudo-muxer to separate actual muxers from > encoder", > + OFFSET(use_fifo), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, > AV_OPT_FLAG_ENCODING_PARAM}, > + {"fifo_options", "fifo pseudo-muxer options", > OFFSET(fifo_options_str), > + AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, > AV_OPT_FLAG_ENCODING_PARAM}, > + {NULL} > +}; > + > static const AVClass tee_muxer_class = { > .class_name = "Tee muxer", > .item_name = av_default_item_name, > + .option = options, > .version = LIBAVUTIL_VERSION_INT, > }; > > @@ -81,6 +96,27 @@ static inline int parse_slave_failure_policy_option(const > char *opt, TeeSlave *t > return AVERROR(EINVAL); > } > > +static int parse_slave_fifo_options(const char * use_fifo, > + const char * fifo_options, TeeSlave * > tee_slave) > +{ > + int ret = 0; > + > + if (use_fifo) { > + if (av_match_name(use_fifo, "true,y,yes,enable,enabled,on,1")) { > + tee_slave->use_fifo = 1; > + } else if (av_match_name(use_fifo, > "false,n,no,disable,disabled,off,0")) { > + tee_slave->use_fifo = 0; > + } else { > + return AVERROR(EINVAL); > + } > + } > + > + if (fifo_options) > + ret = av_dict_parse_string(&tee_slave->fifo_options, fifo_options, > "=", ":", 0); > + > + return ret; > +} > + > static int close_slave(TeeSlave *tee_slave) > { > AVFormatContext *avf; > @@ -125,6 +161,7 @@ static int open_slave(AVFormatContext *avf, char *slave, > TeeSlave *tee_slave) > AVDictionaryEntry *entry; > char *filename; > char *format = NULL, *select = NULL, *on_fail = NULL; > + char *use_fifo = NULL, *fifo_options_str = NULL; > AVFormatContext *avf2 = NULL; > AVStream *st, *st2; > int stream_count; > @@ -145,6 +182,8 @@ static int open_slave(AVFormatContext *avf, char *slave, > TeeSlave *tee_slave) > STEAL_OPTION("f", format); > STEAL_OPTION("select", select); > STEAL_OPTION("onfail", on_fail); > + STEAL_OPTION("use_fifo", use_fifo); > + STEAL_OPTION("fifo_options", fifo_options_str); > > ret = parse_slave_failure_policy_option(on_fail, tee_slave); > if (ret < 0) { > @@ -153,7 +192,43 @@ static int open_slave(AVFormatContext *avf, char *slave, > TeeSlave *tee_slave) > goto end; > } > > - ret = avformat_alloc_output_context2(&avf2, NULL, format, filename); > + ret = parse_slave_fifo_options( use_fifo, fifo_options_str, tee_slave); > + if (ret < 0) { > + av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", > av_err2str(ret)); > + goto end; > + } > + > + if (tee_slave->use_fifo) { > + > + if (options) { > + char *format_options_str = NULL; > + ret = av_dict_get_string(options, &format_options_str, '=', ':'); > + if (ret < 0) > + goto end; > + > + ret = av_dict_set(&tee_slave->fifo_options, "format_options", > format_options_str, > + AV_DICT_DONT_STRDUP_VAL); > + if (ret < 0) { > + av_free(format_options_str);
double free i think > + goto end; > + } > + } > + > + if (format) { > + ret = av_dict_set(&tee_slave->fifo_options, "fifo_format", > format, > + AV_DICT_DONT_STRDUP_VAL); > + if (ret < 0) > + goto end; here too see: av_dist_set() doxy * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, * these arguments will be freed on error. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The real ebay dictionary, page 2 "100% positive feedback" - "All either got their money back or didnt complain" "Best seller ever, very honest" - "Seller refunded buyer after failed scam"
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel