diff options
author | Janne Grunau <janne-libav@jannau.net> | 2012-01-18 10:59:32 +0100 |
---|---|---|
committer | Janne Grunau <janne-libav@jannau.net> | 2012-01-26 00:45:05 +0100 |
commit | b3461c29c1aee7d62eeb02a59d46593c60362679 (patch) | |
tree | 542468d213efdefceb8ce45afbb30949447326d4 /libavformat/utils.c | |
parent | d2ee8c17793201ce969afd1f433ba1580c143cd2 (diff) | |
download | ffmpeg-b3461c29c1aee7d62eeb02a59d46593c60362679.tar.gz |
lavf: prevent infinite loops while flushing in avformat_find_stream_info
If no data was seen for a stream decoder are returning 0 when fed with
empty packets for flushing. We can stop flushing when the decoder does
not return delayed delayed frames anymore. Changes try_decode_frame()
return value to got_picture or negative error.
CC: libav-stable@libav.org
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index 093389b386..17eec072d0 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2130,6 +2130,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->info->nb_decoded_frames >= 6; } +/* returns 1 or 0 if or if not decoded data was returned, or a negative error */ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { AVCodec *codec; @@ -2177,6 +2178,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option st->info->nb_decoded_frames++; pkt.data += ret; pkt.size -= ret; + ret = got_picture; } } return ret; @@ -2401,16 +2403,20 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st = ic->streams[i]; /* flush the decoders */ - while ((err = try_decode_frame(st, &empty_pkt, - (options && i < orig_nb_streams) ? - &options[i] : NULL)) >= 0) - if (has_codec_parameters(st->codec)) - break; - - if (!has_codec_parameters(st->codec)){ + do { + err = try_decode_frame(st, &empty_pkt, + (options && i < orig_nb_streams) ? + &options[i] : NULL); + } while (err > 0 && !has_codec_parameters(st->codec)); + + if (err < 0) { + av_log(ic, AV_LOG_WARNING, + "decoding for stream %d failed\n", st->index); + } else if (!has_codec_parameters(st->codec)){ char buf[256]; avcodec_string(buf, sizeof(buf), st->codec, 0); - av_log(ic, AV_LOG_WARNING, "Could not find codec parameters (%s)\n", buf); + av_log(ic, AV_LOG_WARNING, + "Could not find codec parameters (%s)\n", buf); } else { ret = 0; } |