From feb2440c38c7bde97b04e3ad32575e50cb85c826 Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Wed, 6 Oct 2010 20:52:26 +0000 Subject: [PATCH] dynamically use nb_streams instead of static use of MAX_STREAMS Originally committed as revision 25380 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/utils.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index a51a5faf59..2776a0ff05 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1879,19 +1879,24 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) /* only usable for MPEG-PS streams */ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) { + unsigned int nb_streams = ic->nb_streams; AVPacket pkt1, *pkt = &pkt1; AVStream *st; int read_size, i, ret; - int64_t end_time, start_time[MAX_STREAMS]; + int64_t end_time, *start_time; int64_t filesize, offset, duration; int retry=0; + if (nb_streams >= INT_MAX/sizeof(*start_time) || + !(start_time = av_malloc(nb_streams * sizeof(*start_time)))) + return; + ic->cur_st = NULL; /* flush packet queue */ flush_packet_queue(ic); - for(i=0;inb_streams;i++) { + for (i=0; istreams[i]; if(st->start_time != AV_NOPTS_VALUE){ start_time[i]= st->start_time; @@ -1946,11 +1951,12 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset }while( end_time==AV_NOPTS_VALUE && filesize > (DURATION_MAX_READ_SIZE<pb, old_offset, SEEK_SET); - for(i=0; inb_streams; i++){ + for (i=0; istreams[i]; st->cur_dts= st->first_dts; st->last_IP_pts = AV_NOPTS_VALUE; @@ -2172,13 +2178,18 @@ int av_find_stream_info(AVFormatContext *ic) AVStream *st; AVPacket pkt1, *pkt; int64_t old_offset = url_ftell(ic->pb); + unsigned int nb_streams = ic->nb_streams; struct { int64_t last_dts; int64_t duration_gcd; int duration_count; double duration_error[MAX_STD_TIMEBASES]; int64_t codec_info_duration; - } info[MAX_STREAMS] = {{0}}; + } *info, *tmp_info; + + if (ic->nb_streams >= INT_MAX/sizeof(*info) || + !(info = av_mallocz(ic->nb_streams * sizeof(*info)))) + return AVERROR(ENOMEM); for(i=0;inb_streams;i++) { AVCodec *codec; @@ -2218,7 +2229,7 @@ int av_find_stream_info(AVFormatContext *ic) } } - for(i=0;inb_streams; i++) { info[i].last_dts= AV_NOPTS_VALUE; } @@ -2266,9 +2277,7 @@ int av_find_stream_info(AVFormatContext *ic) /* NOTE: a new stream can be added there if no header in file (AVFMTCTX_NOHEADER) */ ret = av_read_frame_internal(ic, &pkt1); - if(ret == AVERROR(EAGAIN)) - continue; - if (ret < 0) { + if (ret < 0 && ret != AVERROR(EAGAIN)) { /* EOF or error */ ret = -1; /* we could not have all the codec parameters before EOF */ for(i=0;inb_streams;i++) { @@ -2284,8 +2293,23 @@ int av_find_stream_info(AVFormatContext *ic) break; } + if (ic->nb_streams > nb_streams) { + if (ic->nb_streams >= INT_MAX/sizeof(*info) || + !(tmp_info = av_realloc(info, ic->nb_streams*sizeof(*info)))) { + av_free(info); + return AVERROR(ENOMEM); + } + info = tmp_info; + memset(info + nb_streams, 0, (ic->nb_streams - nb_streams) * sizeof(*info)); + nb_streams = ic->nb_streams; + } + + if (ret == AVERROR(EAGAIN)) + continue; + pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end); if(av_dup_packet(pkt) < 0) { + av_free(info); return AVERROR(ENOMEM); } @@ -2434,6 +2458,7 @@ int av_find_stream_info(AVFormatContext *ic) } #endif + av_free(info); return ret; }