Allows mapping n-th stream of the given type.
---
 avengine.c        |   41 ++++++++++++++++++++++++++++++++++++++++-
 doc/avengine.texi |   11 ++++++++++-
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/avengine.c b/avengine.c
index dddf5ec..a0a00b4 100644
--- a/avengine.c
+++ b/avengine.c
@@ -81,8 +81,10 @@ const int program_birth_year = 2000;
 typedef struct StreamMap {
     int file_index;
     int stream_index;
+    char stream_type;
     int sync_file_index;
     int sync_stream_index;
+    char sync_stream_type;
 } StreamMap;
 
 /**
@@ -2784,16 +2786,27 @@ static int opt_map(const char *opt, const char *arg)
     if (*p)
         p++;
 
+    if (*p == 'v' || *p == 's' || *p == 'a' || *p == 'd') {
+        m->stream_type = *p++;
+        if (*p)
+            p++;
+    }
     m->stream_index = strtol(p, &p, 0);
     if (*p) {
         p++;
         m->sync_file_index = strtol(p, &p, 0);
         if (*p)
             p++;
+        if (*p == 'v' || *p == 's' || *p == 'a' || *p == 'd') {
+            m->sync_stream_type = *p++;
+            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->sync_stream_type = m->stream_type;
     }
     return 0;
 }
@@ -3406,7 +3419,7 @@ static int opt_streamid(const char *opt, const char *arg)
 static void opt_output_file(const char *filename)
 {
     AVFormatContext *oc;
-    int i, err;
+    int i, j, err;
     AVOutputFormat *file_oformat;
     OutputStream *ost;
     InputStream  *ist;
@@ -3494,6 +3507,7 @@ static void opt_output_file(const char *filename)
 
         for (i = 0; i < nb_stream_maps; i++) {
             StreamMap *map = &stream_maps[i];
+            AVFormatContext *ic;
             int         fi = map->file_index;
             int         si = map->stream_index;
 
@@ -3510,6 +3524,31 @@ static void opt_output_file(const char *filename)
                 avengine_exit(1);
             }
 
+            ic = input_files[map->file_index].ctx;
+#define SELECT_STREAM(stream_type, index)\
+            if (stream_type) {\
+                enum AVMediaType type;\
+                switch (stream_type) {\
+                case 'v': type = AVMEDIA_TYPE_VIDEO;    break;\
+                case 'a': type = AVMEDIA_TYPE_AUDIO;    break;\
+                case 's': type = AVMEDIA_TYPE_SUBTITLE; break;\
+                case 'd': type = AVMEDIA_TYPE_DATA;     break;\
+                default: av_assert0(0);\
+                }\
+                for (j = 0; j < ic->nb_streams; j++)\
+                    if (ic->streams[j]->codec->codec_type == type && index-- 
== 0) {\
+                        index = j;\
+                        break;\
+                    }\
+                if (j == ic->nb_streams) {\
+                    av_log(NULL, AV_LOG_ERROR, "Input file #%d does not have 
enough streams of type %c.\n",\
+                           map->file_index, stream_type);\
+                    avengine_exit(1);\
+                }\
+            }
+            SELECT_STREAM(map->stream_type, map->stream_index);
+            SELECT_STREAM(map->sync_stream_type, map->sync_stream_index);
+
             ist = &input_streams[input_files[map->file_index].ist_index + 
map->stream_index];
             switch (ist->st->codec->codec_type) {
             case AVMEDIA_TYPE_VIDEO:    ost = new_video_stream(oc, 
nb_output_files);    break;
diff --git a/doc/avengine.texi b/doc/avengine.texi
index 5a889a1..29b8634 100644
--- a/doc/avengine.texi
+++ b/doc/avengine.texi
@@ -623,7 +623,7 @@ Synchronize read on input.
 @section Advanced options
 
 @table @option
-@item -map 
@var{input_file_id}.@var{input_stream_id}[:@var{sync_file_id}.@var{sync_stream_id}]
+@item -map 
@var{input_file_id}[:@var{input_stream_type}].@var{input_stream_id}[:@var{sync_file_id}[:@var{sync_stream_type}].@var{sync_stream_id}]
 
 Designate an input stream as a source for the output file. Each input
 stream is identified by the input file index @var{input_file_id} and
@@ -632,6 +632,10 @@ file. Both indexes start at 0. If specified,
 @var{sync_file_id}.@var{sync_stream_id} sets which input stream
 is used as a presentation sync reference.
 
+If @var{input_stream_type} is specified -- 'v' for video, 'a' for audio, 's' 
for
+subtitle and 'd' for fata -- then @var{input_stream_id} counts only the streams
+of this type. Same for @var{sync_stream_type}.
+
 The first @code{-map} option on the command line specifies the
 source for output stream 0, the second @code{-map} option specifies
 the source for output stream 1, etc.
@@ -657,6 +661,11 @@ and copy them to the output file @file{out.mov}:
 avengine -i a.mov -i b.mov -vcodec copy -acodec copy -map 0.2 -map 1.6 out.mov
 @end example
 
+To select the second video and third audio stream from an input file:
+@example
+avengine -i INPUT -map 0:v:1 -map 0:a:2 OUTPUT
+@end example
+
 @item -map_metadata[:@var{metadata_type}][:@var{index}] 
@var{infile}[:@var{metadata_type}][:@var{index}]
 Set metadata information of the next output file from @var{infile}. Note that
 those are file indices (zero-based), not filenames.
-- 
1.7.5.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to