Commit 8d2e4a7e authored by Anton Khirnov's avatar Anton Khirnov

avconv: 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.
parent 3d4f0dab
......@@ -79,6 +79,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;
......@@ -2780,27 +2781,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;
}
......@@ -3514,21 +3570,9 @@ static void opt_output_file(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) {
......
......@@ -634,35 +634,60 @@ 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
Designate one or more input streams as a source for the output file. Each input
stream is identified by the input file index @var{input_file_id} and
the input stream index @var{input_stream_id} within the input
file. Both indexes start at 0. If specified,
@var{sync_file_id}.@var{sync_stream_id} sets which input stream
file. Both indices 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 data -- then @var{input_stream_id} counts only the streams
of this type. Same for @var{sync_stream_type}.
@var{input_stream_id} may be omitted, in which case all streams of the given
type are mapped (or all streams in the file, if no type is specified).
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.
A @code{-} character before the stream identifier creates a "negative" mapping.
It disables matching streams from already created mappings.
For example, to map ALL streams from the first input file to output
@example
av -i INPUT -map 0 output
@end example
For example, if you have two audio streams in the first input file,
these streams are identified by "0.0" and "0.1". You can use
these streams are identified by "0:0" and "0:1". You can use
@code{-map} to select which streams to place in an output file. For
example:
@example
avconv -i INPUT -map 0.1 out.wav
avconv -i INPUT -map 0:1 out.wav
@end example
will map the input stream in @file{INPUT} identified by "0.1" to
will map the input stream in @file{INPUT} identified by "0:1" to
the (single) output stream in @file{out.wav}.
For example, to select the stream with index 2 from input file
@file{a.mov} (specified by the identifier "0.2"), and stream with
index 6 from input @file{b.mov} (specified by the identifier "1.6"),
@file{a.mov} (specified by the identifier "0:2"), and stream with
index 6 from input @file{b.mov} (specified by the identifier "1:6"),
and copy them to the output file @file{out.mov}:
@example
avconv -i a.mov -i b.mov -vcodec copy -acodec copy -map 0.2 -map 1.6 out.mov
avconv -i a.mov -i b.mov -vcodec copy -acodec copy -map 0:2 -map 1:6 out.mov
@end example
To select all video and the third audio stream from an input file:
@example
avconv -i INPUT -map 0:v -map 0:a:2 OUTPUT
@end example
To map all the streams except the second audio, use negative mappings
@example
avconv -i INPUT -map 0 -map -0:a:1 OUTPUT
@end example
Note that using this option disables the default mappings for this output file.
......@@ -943,7 +968,7 @@ You can encode to several formats at the same time and define a
mapping from input stream to output streams:
@example
avconv -i /tmp/a.wav -ab 64k /tmp/a.mp2 -ab 128k /tmp/b.mp2 -map 0:0 -map 0:0
avconv -i /tmp/a.wav -map 0:a -ab 64k /tmp/a.mp2 -map 0:a -ab 128k /tmp/b.mp2
@end example
Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment