X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Ff_metadata.c;h=f4a929c1d5da59efe037014339898d1b881fe740;hb=f51ddbf83cb7193f7aee4cb971dc1f2ca8539e94;hp=ab07ccf4826b66407edce8631230a3a100d77df4;hpb=2021326f995ff2eda5cd2aae600853f6eddb507d;p=ffmpeg diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c index ab07ccf4826..f4a929c1d5d 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" @@ -80,7 +81,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, @@ -180,8 +181,11 @@ 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_write(s->avio_context, buf, av_strnlen(buf, sizeof(buf))); + } va_end(argument_list); } @@ -190,7 +194,7 @@ static av_cold int init(AVFilterContext *ctx) MetadataContext *s = ctx->priv; int ret; - if (!s->key && s->mode != METADATA_PRINT) { + if (!s->key && s->mode != METADATA_PRINT && s->mode != METADATA_DELETE) { av_log(ctx, AV_LOG_WARNING, "Metadata key must be set\n"); return AVERROR(EINVAL); } @@ -236,25 +240,29 @@ 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; - } - } + if (s->mode == METADATA_PRINT && s->file_str) { s->print = print_file; } else { s->print = print_log; } + s->avio_context = NULL; + if (s->file_str) { + if (!strcmp("-", s->file_str)) { + ret = avio_open(&s->avio_context, "pipe:1", AVIO_FLAG_WRITE); + } else { + ret = avio_open(&s->avio_context, s->file_str, 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", + s->file_str, buf); + return ret; + } + } + return 0; } @@ -262,9 +270,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) @@ -272,13 +280,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; MetadataContext *s = ctx->priv; - AVDictionary *metadata = av_frame_get_metadata(frame); + AVDictionary **metadata = avpriv_frame_get_metadatap(frame); AVDictionaryEntry *e; - if (!metadata) + if (!*metadata) return ff_filter_frame(outlink, frame); - e = av_dict_get(metadata, !s->key ? "" : s->key, NULL, + e = av_dict_get(*metadata, !s->key ? "" : s->key, NULL, !s->key ? AV_DICT_IGNORE_SUFFIX: 0); switch (s->mode) { @@ -294,13 +302,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (e && e->value) { ; } else { - av_dict_set(&metadata, s->key, s->value, 0); + av_dict_set(metadata, s->key, s->value, 0); } return ff_filter_frame(outlink, frame); break; case METADATA_MODIFY: if (e && e->value) { - av_dict_set(&metadata, s->key, s->value, 0); + av_dict_set(metadata, s->key, s->value, 0); } return ff_filter_frame(outlink, frame); break; @@ -309,7 +317,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) 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)); s->print(ctx, "%s=%s\n", e->key, e->value); - while ((e = av_dict_get(metadata, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL) { + while ((e = av_dict_get(*metadata, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL) { 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)))) { @@ -320,10 +328,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) return ff_filter_frame(outlink, frame); break; case METADATA_DELETE: - if (e && e->value && s->value && s->compare(s, e->value, s->value)) { - av_dict_set(&metadata, s->key, NULL, 0); + if (!s->key) { + av_dict_free(metadata); + } else if (e && e->value && s->value && s->compare(s, e->value, s->value)) { + av_dict_set(metadata, s->key, NULL, 0); } else if (e && e->value) { - av_dict_set(&metadata, s->key, NULL, 0); + av_dict_set(metadata, s->key, NULL, 0); } return ff_filter_frame(outlink, frame); break;