[FFmpeg-cvslog] ffmpeg: change semantics of -map

Anton Khirnov git at videolan.org
Tue Aug 30 18:14:59 CEST 2011


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue Aug 30 04:06:24 2011 +0200| [88bfe4518bc31a111023d5c7f0b54b17955a735e] | committer: Michael Niedermayer

ffmpeg: change semantics of -map

New syntax contains an optional stream type, allowing to refer to n-th
stream of specific type.

Omitting stream number now maps all streams of the given type.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=88bfe4518bc31a111023d5c7f0b54b17955a735e
---

 ffmpeg.c |  106 +++++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 75 insertions(+), 31 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index ce25df7..6082dd9 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -91,6 +91,7 @@ const int program_birth_year = 2000;
 
 /* select an input stream for an output stream */
 typedef struct StreamMap {
+    int disabled;           /** 1 is this mapping is disabled by a negative map */
     int file_index;
     int stream_index;
     int sync_file_index;
@@ -2953,27 +2954,82 @@ static int opt_codec_tag(const char *opt, const char *arg)
 
 static int opt_map(const char *opt, const char *arg)
 {
-    StreamMap *m;
-    char *p;
+    StreamMap *m = NULL;
+    int i, negative = 0, file_idx;
+    int sync_file_idx = -1, sync_stream_idx;
+    char *p, *sync;
+    char *map;
+
+    if (*arg == '-') {
+        negative = 1;
+        arg++;
+    }
+    map = av_strdup(arg);
+
+    /* parse sync stream first, just pick first matching stream */
+    if (sync = strchr(map, ',')) {
+        *sync = 0;
+        sync_file_idx = strtol(sync + 1, &sync, 0);
+        if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid sync file index: %d.\n", sync_file_idx);
+            exit_program(1);
+        }
+        if (*sync)
+            sync++;
+        for (i = 0; i < input_files[sync_file_idx].ctx->nb_streams; i++)
+            if (check_stream_specifier(input_files[sync_file_idx].ctx,
+                                       input_files[sync_file_idx].ctx->streams[i], sync) == 1) {
+                sync_stream_idx = i;
+                break;
+            }
+        if (i == input_files[sync_file_idx].ctx->nb_streams) {
+            av_log(NULL, AV_LOG_ERROR, "Sync stream specification in map %s does not "
+                                       "match any streams.\n", arg);
+            exit_program(1);
+        }
+    }
 
-    stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1);
-    m = &stream_maps[nb_stream_maps-1];
 
-    m->file_index = strtol(arg, &p, 0);
-    if (*p)
-        p++;
+    file_idx = strtol(map, &p, 0);
+    if (file_idx >= nb_input_files || file_idx < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Invalid input file index: %d.\n", file_idx);
+        exit_program(1);
+    }
+    if (negative)
+        /* disable some already defined maps */
+        for (i = 0; i < nb_stream_maps; i++) {
+            m = &stream_maps[i];
+            if (check_stream_specifier(input_files[m->file_index].ctx,
+                                       input_files[m->file_index].ctx->streams[m->stream_index],
+                                       *p == ':' ? p + 1 : p) > 0)
+                m->disabled = 1;
+        }
+    else
+        for (i = 0; i < input_files[file_idx].ctx->nb_streams; i++) {
+            if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i],
+                        *p == ':' ? p + 1 : p) <= 0)
+                continue;
+            stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1);
+            m = &stream_maps[nb_stream_maps - 1];
 
-    m->stream_index = strtol(p, &p, 0);
-    if (*p) {
-        p++;
-        m->sync_file_index = strtol(p, &p, 0);
-        if (*p)
-            p++;
-        m->sync_stream_index = strtol(p, &p, 0);
-    } else {
-        m->sync_file_index = m->file_index;
-        m->sync_stream_index = m->stream_index;
+            m->file_index   = file_idx;
+            m->stream_index = i;
+
+            if (sync_file_idx >= 0) {
+                m->sync_file_index   = sync_file_idx;
+                m->sync_stream_index = sync_stream_idx;
+            } else {
+                m->sync_file_index   = file_idx;
+                m->sync_stream_index = i;
+            }
+        }
+
+    if (!m) {
+        av_log(NULL, AV_LOG_ERROR, "Stream map '%s' matches no streams.\n", arg);
+        exit_program(1);
     }
+
+    av_freep(&map);
     return 0;
 }
 
@@ -3710,21 +3766,9 @@ static int opt_output_file(const char *opt, const char *filename)
     } else {
         for (i = 0; i < nb_stream_maps; i++) {
             StreamMap *map = &stream_maps[i];
-            int         fi = map->file_index;
-            int         si = map->stream_index;
 
-            if (fi < 0 || fi >= nb_input_files ||
-                si < 0 || si >= input_files[fi].ctx->nb_streams) {
-                av_log(NULL, AV_LOG_ERROR, "Input stream #%d.%d does not exist.\n", fi, si);
-                exit_program(1);
-            }
-            fi = map->sync_file_index;
-            si = map->sync_stream_index;
-            if (fi < 0 || fi >= nb_input_files ||
-                si < 0 || si >= input_files[fi].ctx->nb_streams) {
-                av_log(NULL, AV_LOG_ERROR, "Sync stream #%d.%d does not exist.\n", fi, si);
-                exit_program(1);
-            }
+            if (map->disabled)
+                continue;
 
             ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index];
             switch (ist->st->codec->codec_type) {



More information about the ffmpeg-cvslog mailing list