mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-15 11:30:08 +01:00
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
(cherry picked from commit b3461c29c1)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
committed by
Reinhard Tartler
parent
183e0eb5b9
commit
d16653c3d4
@@ -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;
|
||||||
@@ -2179,6 +2180,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;
|
||||||
@@ -2403,16 +2405,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 {
|
||||||
(options && i < orig_nb_streams) ?
|
err = try_decode_frame(st, &empty_pkt,
|
||||||
&options[i] : NULL)) >= 0)
|
(options && i < orig_nb_streams) ?
|
||||||
if (has_codec_parameters(st->codec))
|
&options[i] : NULL);
|
||||||
break;
|
} while (err > 0 && !has_codec_parameters(st->codec));
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user