summaryrefslogtreecommitdiff
path: root/libavformat/utils.c
diff options
context:
space:
mode:
authorNicolas George <nicolas.george@normalesup.org>2010-12-27 09:08:20 +0000
committerNicolas George <nicolas.george@normalesup.org>2010-12-27 09:08:20 +0000
commit9128ae08b38f67147eb75248f7aa2b3247e4fe0c (patch)
treeb315afa11a9bd70bde846ec6086cba6e2bc223b5 /libavformat/utils.c
parent107a7e3e7b6161cd9ccefeefab1d54be939de43e (diff)
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.c61
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)