fftools/ffmpeg: switch -map parsing to new stream specifier API

Makes optional map handling less hacky, fixes combining optional maps
with metadata matching on tags/values containing the '?' character/

Forward errors from stream specifier parsing, previously the code would
ignore them.
release/7.1
Anton Khirnov 6 months ago
parent d1bdd89c2f
commit 9e3b5b8a26
  1. 54
      fftools/ffmpeg_opt.c

@ -427,22 +427,20 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
{ {
OptionsContext *o = optctx; OptionsContext *o = optctx;
StreamMap *m = NULL; StreamMap *m = NULL;
StreamSpecifier ss;
int i, negative = 0, file_idx, disabled = 0; int i, negative = 0, file_idx, disabled = 0;
int ret; int ret, allow_unused = 0;
char *map, *p;
char *allow_unused; memset(&ss, 0, sizeof(ss));
if (*arg == '-') { if (*arg == '-') {
negative = 1; negative = 1;
arg++; arg++;
} }
map = av_strdup(arg);
if (!map)
return AVERROR(ENOMEM);
if (map[0] == '[') { if (arg[0] == '[') {
/* this mapping refers to lavfi output */ /* this mapping refers to lavfi output */
const char *c = map + 1; const char *c = arg + 1;
ret = GROW_ARRAY(o->stream_maps, o->nb_stream_maps); ret = GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
if (ret < 0) if (ret < 0)
@ -451,33 +449,55 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
m = &o->stream_maps[o->nb_stream_maps - 1]; m = &o->stream_maps[o->nb_stream_maps - 1];
m->linklabel = av_get_token(&c, "]"); m->linklabel = av_get_token(&c, "]");
if (!m->linklabel) { if (!m->linklabel) {
av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map); av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", arg);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail; goto fail;
} }
} else { } else {
if (allow_unused = strchr(map, '?')) char *endptr;
*allow_unused = 0;
file_idx = strtol(map, &p, 0); file_idx = strtol(arg, &endptr, 0);
if (file_idx >= nb_input_files || file_idx < 0) { if (file_idx >= nb_input_files || file_idx < 0) {
av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx); av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail; goto fail;
} }
arg = endptr;
ret = stream_specifier_parse(&ss, *arg == ':' ? arg + 1 : arg, 1, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Invalid stream specifier: %s\n", arg);
goto fail;
}
if (ss.remainder) {
if (!strcmp(ss.remainder, "?"))
allow_unused = 1;
else {
av_log(NULL, AV_LOG_ERROR, "Trailing garbage after stream specifier: %s\n",
ss.remainder);
ret = AVERROR(EINVAL);
goto fail;
}
}
if (negative) if (negative)
/* disable some already defined maps */ /* disable some already defined maps */
for (i = 0; i < o->nb_stream_maps; i++) { for (i = 0; i < o->nb_stream_maps; i++) {
m = &o->stream_maps[i]; m = &o->stream_maps[i];
if (file_idx == m->file_index && if (file_idx == m->file_index &&
check_stream_specifier(input_files[m->file_index]->ctx, stream_specifier_match(&ss,
input_files[m->file_index]->ctx,
input_files[m->file_index]->ctx->streams[m->stream_index], input_files[m->file_index]->ctx->streams[m->stream_index],
*p == ':' ? p + 1 : p) > 0) NULL))
m->disabled = 1; m->disabled = 1;
} }
else else
for (i = 0; i < input_files[file_idx]->nb_streams; i++) { for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i], if (!stream_specifier_match(&ss,
*p == ':' ? p + 1 : p) <= 0) input_files[file_idx]->ctx,
input_files[file_idx]->ctx->streams[i],
NULL))
continue; continue;
if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) { if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) {
disabled = 1; disabled = 1;
@ -511,7 +531,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
} }
ret = 0; ret = 0;
fail: fail:
av_freep(&map); stream_specifier_uninit(&ss);
return ret; return ret;
} }

Loading…
Cancel
Save