summaryrefslogtreecommitdiff
path: root/avconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'avconv.c')
-rw-r--r--avconv.c106
1 files changed, 75 insertions, 31 deletions
diff --git a/avconv.c b/avconv.c
index 1407565b1e..877079c887 100644
--- a/avconv.c
+++ b/avconv.c
@@ -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) {