diff options
author | Tobias Rapp <t.rapp@noa-archive.com> | 2016-02-11 13:35:21 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2016-02-11 13:50:46 +0100 |
commit | 202f97872891071a24bc383ac07dd7e233ee4343 (patch) | |
tree | d82b0fa3b9fe95b9a027ffc76f0e62273a3010a1 | |
parent | 8b99c5e8daf27c8198df4061eef0ac8b193e1b73 (diff) | |
download | ffmpeg-202f97872891071a24bc383ac07dd7e233ee4343.tar.gz |
avfilter/f_metadata: add support for file output
Signed-off-by: Tobias Rapp <t.rapp@noa-archive.com>
-rw-r--r-- | doc/filters.texi | 6 | ||||
-rw-r--r-- | libavfilter/f_metadata.c | 66 |
2 files changed, 67 insertions, 5 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index 6c5003f207..8f4dcea111 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8526,6 +8526,12 @@ Float representation of @code{value} from metadata key. @item VALUE2 Float representation of @code{value} as supplied by user in @code{value} option. @end table + +@item file +If specified in @code{print} mode, output is written to the named file. When +filename equals "-" data is written to standard output. +If @code{file} option is not set, output is written to the log with AV_LOG_INFO +loglevel. @end table @subsection Examples diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c index e0ea30b951..9246a2afc9 100644 --- a/libavfilter/f_metadata.c +++ b/libavfilter/f_metadata.c @@ -81,8 +81,12 @@ typedef struct MetadataContext { AVExpr *expr; double var_values[VAR_VARS_NB]; + FILE *file; + char *file_str; + int (*compare)(struct MetadataContext *s, const char *value1, const char *value2, size_t length); + void (*print)(AVFilterContext *ctx, const char *msg, ...) av_printf_format(2, 3); } MetadataContext; #define OFFSET(x) offsetof(MetadataContext, x) @@ -104,6 +108,7 @@ static const AVOption filt_name##_options[] = { \ { "expr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = METADATAF_EXPR }, 0, 3, FLAGS, "function" }, \ { "expr", "set expression for expr function", OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, FLAGS }, \ { "length", "compare up to N chars for string function", OFFSET(length), AV_OPT_TYPE_INT, {.i64 = INT_MAX }, 1, INT_MAX, FLAGS }, \ + { "file", "set file where to print metadata information", OFFSET(file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, \ { NULL } \ } @@ -155,6 +160,27 @@ static int parse_expr(MetadataContext *s, const char *value1, const char *value2 return av_expr_eval(s->expr, s->var_values, NULL); } +static void print_log(AVFilterContext *ctx, const char *msg, ...) +{ + va_list argument_list; + + va_start(argument_list, msg); + if (msg) + av_vlog(ctx, AV_LOG_INFO, msg, argument_list); + va_end(argument_list); +} + +static void print_file(AVFilterContext *ctx, const char *msg, ...) +{ + MetadataContext *s = ctx->priv; + va_list argument_list; + + va_start(argument_list, msg); + if (msg) + vfprintf(s->file, msg, argument_list); + va_end(argument_list); +} + static av_cold int init(AVFilterContext *ctx) { MetadataContext *s = ctx->priv; @@ -203,9 +229,37 @@ static av_cold int init(AVFilterContext *ctx) } } + if (s->file_str) { + if (!strcmp(s->file_str, "-")) { + s->file = stdout; + } 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; + } + } + s->print = print_file; + } else { + s->print = print_log; + } + return 0; } +static av_cold void uninit(AVFilterContext *ctx) +{ + MetadataContext *s = ctx->priv; + + if (s->file && s->file != stdout) + fclose(s->file); + s->file = NULL; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; @@ -245,14 +299,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) break; case METADATA_PRINT: if (!s->key && e) { - av_log(ctx, AV_LOG_INFO, "frame %"PRId64" pts %"PRId64"\n", inlink->frame_count, frame->pts); - av_log(ctx, AV_LOG_INFO, "%s=%s\n", e->key, e->value); + s->print(ctx, "frame %"PRId64" pts %"PRId64"\n", inlink->frame_count, frame->pts); + s->print(ctx, "%s=%s\n", e->key, e->value); while ((e = av_dict_get(metadata, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL) { - av_log(ctx, AV_LOG_INFO, "%s=%s\n", e->key, e->value); + s->print(ctx, "%s=%s\n", e->key, e->value); } } else if (e && e->value && (!s->value || (e->value && s->compare(s, e->value, s->value, s->length)))) { - av_log(ctx, AV_LOG_INFO, "frame %"PRId64" pts %"PRId64"\n", inlink->frame_count, frame->pts); - av_log(ctx, AV_LOG_INFO, "%s=%s\n", s->key, e->value); + s->print(ctx, "frame %"PRId64" pts %"PRId64"\n", inlink->frame_count, frame->pts); + s->print(ctx, "%s=%s\n", s->key, e->value); } return ff_filter_frame(outlink, frame); break; @@ -301,6 +355,7 @@ AVFilter ff_af_ametadata = { .priv_size = sizeof(MetadataContext), .priv_class = &ametadata_class, .init = init, + .uninit = uninit, .query_formats = ff_query_formats_all, .inputs = ainputs, .outputs = aoutputs, @@ -336,6 +391,7 @@ AVFilter ff_vf_metadata = { .priv_size = sizeof(MetadataContext), .priv_class = &metadata_class, .init = init, + .uninit = uninit, .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, |