From: Sami Hult <sami.h...@gmail.com> I added option mode=pipe which accepts file=(file descriptor) option. This way multiple streams can for example be silencedetected and the result directed to different outputs.
Example: ffmpeg -i test.wav -filter_complex "silencedetect=n=-40dB:d=0.1,ametadata=mode=pipe:file=4" -f null - 4> test.txt Also at the same time I converted mode=file output to avio. Signed-off-by: Sami Hult <sami.h...@gmail.com> --- Changelog | 1 + libavfilter/f_metadata.c | 52 +++++++++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Changelog b/Changelog index f6016f4..4909abf 100644 --- a/Changelog +++ b/Changelog @@ -42,6 +42,7 @@ version <next>: - OpenExr improvements (tile data and B44/B44A support) - BitJazz SheerVideo decoder - CUDA CUVID H264/HEVC decoder +- Pipe output to metadata filter version 3.0: diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c index ab07ccf..aa9fb92 100644 --- a/libavfilter/f_metadata.c +++ b/libavfilter/f_metadata.c @@ -31,6 +31,7 @@ #include "libavutil/internal.h" #include "libavutil/opt.h" #include "libavutil/timestamp.h" +#include "libavformat/avio.h" #include "avfilter.h" #include "audio.h" #include "formats.h" @@ -43,6 +44,7 @@ enum MetadataMode { METADATA_MODIFY, METADATA_DELETE, METADATA_PRINT, + METADATA_PIPE, METADATA_NB }; @@ -80,7 +82,7 @@ typedef struct MetadataContext { AVExpr *expr; double var_values[VAR_VARS_NB]; - FILE *file; + AVIOContext* avio_context; char *file_str; int (*compare)(struct MetadataContext *s, @@ -97,6 +99,7 @@ static const AVOption filt_name##_options[] = { \ { "modify", "modify metadata", 0, AV_OPT_TYPE_CONST, {.i64 = METADATA_MODIFY }, 0, 0, FLAGS, "mode" }, \ { "delete", "delete metadata", 0, AV_OPT_TYPE_CONST, {.i64 = METADATA_DELETE }, 0, 0, FLAGS, "mode" }, \ { "print", "print metadata", 0, AV_OPT_TYPE_CONST, {.i64 = METADATA_PRINT }, 0, 0, FLAGS, "mode" }, \ + { "pipe", "pipe metadata", 0, AV_OPT_TYPE_CONST, {.i64 = METADATA_PIPE }, 0, 0, FLAGS, "mode" }, \ { "key", "set metadata key", OFFSET(key), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, FLAGS }, \ { "value", "set metadata value", OFFSET(value), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, FLAGS }, \ { "function", "function for comparing values", OFFSET(function), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, METADATAF_NB-1, FLAGS, "function" }, \ @@ -180,17 +183,21 @@ static void print_file(AVFilterContext *ctx, const char *msg, ...) va_list argument_list; va_start(argument_list, msg); - if (msg) - vfprintf(s->file, msg, argument_list); + if (msg) { + char buf[128]; + vsnprintf(buf, sizeof(buf), msg, argument_list); + avio_printf(s->avio_context, buf); + } va_end(argument_list); } static av_cold int init(AVFilterContext *ctx) { MetadataContext *s = ctx->priv; + char *url = NULL; int ret; - if (!s->key && s->mode != METADATA_PRINT) { + if (!s->key && s->mode != METADATA_PRINT && s->mode != METADATA_PIPE) { av_log(ctx, AV_LOG_WARNING, "Metadata key must be set\n"); return AVERROR(EINVAL); } @@ -236,25 +243,33 @@ static av_cold int init(AVFilterContext *ctx) } } - if (s->file_str) { + if (s->mode == METADATA_PIPE) { + url = av_asprintf("pipe:%s", s->file_str); + s->print = print_file; + } else if (s->mode == METADATA_PRINT) { if (!strcmp(s->file_str, "-")) { - s->file = stdout; + url = av_asprintf("pipe:1"); } else { - s->file = fopen(s->file_str, "w"); - if (!s->file) { - int err = AVERROR(errno); - char buf[128]; - av_strerror(err, buf, sizeof(buf)); - av_log(ctx, AV_LOG_ERROR, "Could not open file %s: %s\n", - s->file_str, buf); - return err; - } + url = av_asprintf("file:%s", s->file_str); } s->print = print_file; } else { s->print = print_log; } + s->avio_context = NULL; + if (url) { + ret = avio_open(&s->avio_context, url, AVIO_FLAG_WRITE); + if (ret < 0) { + char buf[128]; + av_strerror(ret, buf, sizeof(buf)); + av_log(ctx, AV_LOG_ERROR, "Could not open %s: %s\n", + url, buf); + return ret; + } + av_free(url); + } + return 0; } @@ -262,9 +277,9 @@ static av_cold void uninit(AVFilterContext *ctx) { MetadataContext *s = ctx->priv; - if (s->file && s->file != stdout) - fclose(s->file); - s->file = NULL; + if (s->avio_context) { + avio_closep(&s->avio_context); + } } static int filter_frame(AVFilterLink *inlink, AVFrame *frame) @@ -305,6 +320,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) return ff_filter_frame(outlink, frame); break; case METADATA_PRINT: + case METADATA_PIPE: if (!s->key && e) { s->print(ctx, "frame:%-4"PRId64" pts:%-7s pts_time:%-7s\n", inlink->frame_count, av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base)); -- 2.1.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel