]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/f_metadata.c
af_hdcd: add experimental 20 and 24-bit decoding support
[ffmpeg] / libavfilter / f_metadata.c
index ab07ccf4826b66407edce8631230a3a100d77df4..f4a929c1d5da59efe037014339898d1b881fe740 100644 (file)
@@ -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;