]> git.sesse.net Git - ffmpeg/blobdiff - libavdevice/lavfi.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavdevice / lavfi.c
index 944794fb87451261998337e068edc54d777915a5..4f1ba582e7120a8995ce7f48fb3917e8ad025c0e 100644 (file)
 
 #include "float.h"              /* DBL_MIN, DBL_MAX */
 
+#include "libavutil/bprint.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/file.h"
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
-#include "libavutil/audioconvert.h"
 #include "libavfilter/avfilter.h"
 #include "libavfilter/avfiltergraph.h"
 #include "libavfilter/buffersink.h"
@@ -42,6 +44,7 @@
 typedef struct {
     AVClass *class;          ///< class for private options
     char          *graph_str;
+    char          *graph_filename;
     char          *dump_graph;
     AVFilterGraph *graph;
     AVFilterContext **sinks;
@@ -103,6 +106,32 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
     buffersink = avfilter_get_by_name("ffbuffersink");
     abuffersink = avfilter_get_by_name("ffabuffersink");
 
+    if (lavfi->graph_filename && lavfi->graph_str) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Only one of the graph or graph_file options must be specified\n");
+        FAIL(AVERROR(EINVAL));
+    }
+
+    if (lavfi->graph_filename) {
+        uint8_t *file_buf, *graph_buf;
+        size_t file_bufsize;
+        ret = av_file_map(lavfi->graph_filename,
+                          &file_buf, &file_bufsize, 0, avctx);
+        if (ret < 0)
+            goto end;
+
+        /* create a 0-terminated string based on the read file */
+        graph_buf = av_malloc(file_bufsize + 1);
+        if (!graph_buf) {
+            av_file_unmap(file_buf, file_bufsize);
+            FAIL(AVERROR(ENOMEM));
+        }
+        memcpy(graph_buf, file_buf, file_bufsize);
+        graph_buf[file_bufsize] = 0;
+        av_file_unmap(file_buf, file_bufsize);
+        lavfi->graph_str = graph_buf;
+    }
+
     if (!lavfi->graph_str)
         lavfi->graph_str = av_strdup(avctx->filename);
 
@@ -339,6 +368,28 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
         memcpy(pkt->data, ref->data[0], size);
     }
 
+    if (ref->metadata) {
+        uint8_t *metadata;
+        AVDictionaryEntry *e = NULL;
+        AVBPrint meta_buf;
+
+        av_bprint_init(&meta_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+        while ((e = av_dict_get(ref->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
+            av_bprintf(&meta_buf, "%s", e->key);
+            av_bprint_chars(&meta_buf, '\0', 1);
+            av_bprintf(&meta_buf, "%s", e->value);
+            av_bprint_chars(&meta_buf, '\0', 1);
+        }
+        if (!av_bprint_is_complete(&meta_buf) ||
+            !(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
+                                                 meta_buf.len))) {
+            av_bprint_finalize(&meta_buf, NULL);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(metadata, meta_buf.str, meta_buf.len);
+        av_bprint_finalize(&meta_buf, NULL);
+    }
+
     pkt->stream_index = stream_idx;
     pkt->pts = ref->pts;
     pkt->pos = ref->pos;
@@ -353,6 +404,7 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
 
 static const AVOption options[] = {
     { "graph",     "set libavfilter graph", OFFSET(graph_str),  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+    { "graph_file","set libavfilter graph filename", OFFSET(graph_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
     { "dumpgraph", "dump graph to stderr",  OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
     { NULL },
 };