diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2010-12-27 09:08:20 +0000 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2010-12-27 09:08:20 +0000 |
commit | 9128ae08b38f67147eb75248f7aa2b3247e4fe0c (patch) | |
tree | b315afa11a9bd70bde846ec6086cba6e2bc223b5 /libavformat/utils.c | |
parent | 107a7e3e7b6161cd9ccefeefab1d54be939de43e (diff) | |
download | ffmpeg-9128ae08b38f67147eb75248f7aa2b3247e4fe0c.tar.gz |
Implement av_find_best_stream.
Originally committed as revision 26104 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index e9a8099c95..6f994a1b70 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2458,6 +2458,67 @@ int av_find_stream_info(AVFormatContext *ic) return ret; } +static AVProgram *find_program_from_stream(AVFormatContext *ic, int s) +{ + int i, j; + + for (i = 0; i < ic->nb_programs; i++) + for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++) + if (ic->programs[i]->stream_index[j] == s) + return ic->programs[i]; + return NULL; +} + +int av_find_best_stream(AVFormatContext *ic, + enum AVMediaType type, + int wanted_stream_nb, + int related_stream, + AVCodec **decoder_ret, + int flags) +{ + int i, nb_streams = ic->nb_streams, stream_number = 0; + int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1; + unsigned *program = NULL; + AVCodec *decoder = NULL, *best_decoder = NULL; + + if (related_stream >= 0 && wanted_stream_nb < 0) { + AVProgram *p = find_program_from_stream(ic, related_stream); + if (p) { + program = p->stream_index; + nb_streams = p->nb_stream_indexes; + } + } + for (i = 0; i < nb_streams; i++) { + AVStream *st = ic->streams[program ? program[i] : i]; + AVCodecContext *avctx = st->codec; + if (avctx->codec_type != type) + continue; + if (wanted_stream_nb >= 0 && stream_number++ != wanted_stream_nb) + continue; + if (decoder_ret) { + decoder = avcodec_find_decoder(ic->streams[i]->codec->codec_id); + if (!decoder) { + if (ret < 0) + ret = AVERROR_DECODER_NOT_FOUND; + continue; + } + } + if (best_count >= st->codec_info_nb_frames) + continue; + best_count = st->codec_info_nb_frames; + ret = i; + best_decoder = decoder; + if (program && i == nb_streams - 1 && ret < 0) { + program = NULL; + nb_streams = ic->nb_streams; + i = 0; /* no related stream found, try again with everything */ + } + } + if (decoder_ret) + *decoder_ret = best_decoder; + return ret; +} + /*******************************************************/ int av_read_play(AVFormatContext *s) |