[FFmpeg-devel] [PATCH] libavformat/tee: Add fifo support for tee
Michael Niedermayer
michael at niedermayer.cc
Fri Oct 7 23:25:35 EEST 2016
On Fri, Oct 07, 2016 at 01:03:03AM +0200, sebechlebskyjan at gmail.com wrote:
> From: Jan Sebechlebsky <sebechlebskyjan at gmail.com>
>
> Signed-off-by: Jan Sebechlebsky <sebechlebskyjan at 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
>
> + at 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.
>
> + at table @option
> +
> + at 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.
> +
> + at item fifo_options
> +Options to pass to fifo pseudo-muxer instances. See @ref{fifo}.
> +
> + at 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.
>
> + at item use_fifo @var{bool}
> +This allows to override tee muxer use_fifo option for individual slave muxer.
> +
> + at 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"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20161007/1910d6ff/attachment.sig>
More information about the ffmpeg-devel
mailing list