From 54109b1d1472bc49cec5e236508dffc96aa4f0a1 Mon Sep 17 00:00:00 2001 From: Gyan Doshi Date: Sat, 29 Dec 2018 16:17:05 +0530 Subject: ffmpeg: skip disabled streams Fully discarded streams can't be selected for output or mapped or filtered. Previously, a few packets from such streams, probably buffered for stream probing, would get smuggled into output files. Signed-off-by: Michael Niedermayer --- fftools/ffmpeg_filter.c | 7 +++++++ fftools/ffmpeg_opt.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'fftools') diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 6518d50870..8c0ff99dd9 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -293,10 +293,17 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) exit_program(1); } ist = input_streams[input_files[file_idx]->ist_index + st->index]; + if (ist->user_set_discard == AVDISCARD_ALL) { + av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " + "matches a disabled input stream.\n", p, fg->graph_desc); + exit_program(1); + } } else { /* find the first unused stream of corresponding type */ for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; + if (ist->user_set_discard == AVDISCARD_ALL) + continue; if (ist->dec_ctx->codec_type == type && ist->discard) break; } diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index d4851a2cd8..050a65c2c1 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -268,7 +268,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg) { OptionsContext *o = optctx; StreamMap *m = NULL; - int i, negative = 0, file_idx; + int i, negative = 0, file_idx, disabled = 0; int sync_file_idx = -1, sync_stream_idx = 0; char *p, *sync; char *map; @@ -303,6 +303,11 @@ static int opt_map(void *optctx, const char *opt, const char *arg) "match any streams.\n", arg); exit_program(1); } + if (input_streams[input_files[sync_file_idx]->ist_index + sync_stream_idx]->user_set_discard == AVDISCARD_ALL) { + av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s matches a disabled input " + "stream.\n", arg); + exit_program(1); + } } @@ -339,6 +344,10 @@ static int opt_map(void *optctx, const char *opt, const char *arg) if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i], *p == ':' ? p + 1 : p) <= 0) continue; + if (input_streams[input_files[file_idx]->ist_index + i]->user_set_discard == AVDISCARD_ALL) { + disabled = 1; + continue; + } GROW_ARRAY(o->stream_maps, o->nb_stream_maps); m = &o->stream_maps[o->nb_stream_maps - 1]; @@ -358,6 +367,10 @@ static int opt_map(void *optctx, const char *opt, const char *arg) if (!m) { if (allow_unused) { av_log(NULL, AV_LOG_VERBOSE, "Stream map '%s' matches no streams; ignoring.\n", arg); + } else if (disabled) { + av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches disabled streams.\n" + "To ignore this, add a trailing '?' to the map.\n", arg); + exit_program(1); } else { av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n" "To ignore this, add a trailing '?' to the map.\n", arg); @@ -437,7 +450,8 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg) /* allow trailing ? to map_channel */ if (allow_unused = strchr(mapchan, '?')) *allow_unused = 0; - if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels) { + if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels || + input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) { if (allow_unused) { av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n", m->file_idx, m->stream_idx, m->channel_idx); @@ -2174,6 +2188,8 @@ static int open_output_file(OptionsContext *o, const char *filename) int new_area; ist = input_streams[i]; new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames; + if (ist->user_set_discard == AVDISCARD_ALL) + continue; if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) new_area = 1; if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && @@ -2195,6 +2211,8 @@ static int open_output_file(OptionsContext *o, const char *filename) int score; ist = input_streams[i]; score = ist->st->codecpar->channels + 100000000*!!ist->st->codec_info_nb_frames; + if (ist->user_set_discard == AVDISCARD_ALL) + continue; if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && score > best_score) { best_score = score; @@ -2216,6 +2234,8 @@ static int open_output_file(OptionsContext *o, const char *filename) AVCodec const *output_codec = avcodec_find_encoder(oc->oformat->subtitle_codec); int input_props = 0, output_props = 0; + if (input_streams[i]->user_set_discard == AVDISCARD_ALL) + continue; if (output_codec) output_descriptor = avcodec_descriptor_get(output_codec->id); if (input_descriptor) @@ -2237,6 +2257,8 @@ static int open_output_file(OptionsContext *o, const char *filename) if (!o->data_disable ) { enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA); for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) { + if (input_streams[i]->user_set_discard == AVDISCARD_ALL) + continue; if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_DATA && input_streams[i]->st->codecpar->codec_id == codec_id ) new_data_stream(o, oc, i); @@ -2275,6 +2297,11 @@ loop_end: int src_idx = input_files[map->file_index]->ist_index + map->stream_index; ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index]; + if (ist->user_set_discard == AVDISCARD_ALL) { + av_log(NULL, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n", + map->file_index, map->stream_index); + exit_program(1); + } if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) continue; if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) -- cgit v1.2.3