Commit b3461c29 authored by Janne Grunau's avatar Janne Grunau

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
parent d2ee8c17
...@@ -2130,6 +2130,7 @@ static int has_decode_delay_been_guessed(AVStream *st) ...@@ -2130,6 +2130,7 @@ static int has_decode_delay_been_guessed(AVStream *st)
st->info->nb_decoded_frames >= 6; 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) static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{ {
AVCodec *codec; AVCodec *codec;
...@@ -2177,6 +2178,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option ...@@ -2177,6 +2178,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option
st->info->nb_decoded_frames++; st->info->nb_decoded_frames++;
pkt.data += ret; pkt.data += ret;
pkt.size -= ret; pkt.size -= ret;
ret = got_picture;
} }
} }
return ret; return ret;
...@@ -2401,16 +2403,20 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ...@@ -2401,16 +2403,20 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
st = ic->streams[i]; st = ic->streams[i];
/* flush the decoders */ /* flush the decoders */
while ((err = try_decode_frame(st, &empty_pkt, do {
err = try_decode_frame(st, &empty_pkt,
(options && i < orig_nb_streams) ? (options && i < orig_nb_streams) ?
&options[i] : NULL)) >= 0) &options[i] : NULL);
if (has_codec_parameters(st->codec)) } while (err > 0 && !has_codec_parameters(st->codec));
break;
if (!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]; char buf[256];
avcodec_string(buf, sizeof(buf), st->codec, 0); 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 { } else {
ret = 0; ret = 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment