aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2010-10-08 22:01:19 +0000
committerAurelien Jacobs <aurel@gnuage.org>2010-10-08 22:01:19 +0000
commitfd0368e7ca35e2feaf7960564e61a76655c4d1f6 (patch)
tree0dc1e28a21af61d68754709a8c421269919a5a58
parentf47d172f13f97edd8300403f370d11f29274f11c (diff)
downloadffmpeg-fd0368e7ca35e2feaf7960564e61a76655c4d1f6.tar.gz
move av_find_stream_info() info struct to AVStream to avoid messy (re)allocation
Originally committed as revision 25418 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--ffmpeg.c1
-rw-r--r--libavformat/avformat.h12
-rw-r--r--libavformat/utils.c89
3 files changed, 48 insertions, 54 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index b29d8350a8..8519159bd5 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -600,6 +600,7 @@ static int ffmpeg_exit(int ret)
for(j=0;j<s->nb_streams;j++) {
av_metadata_free(&s->streams[j]->metadata);
av_free(s->streams[j]->codec);
+ av_free(s->streams[j]->info);
av_free(s->streams[j]);
}
for(j=0;j<s->nb_programs;j++) {
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index b08f758d0f..a5c745bb78 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -617,6 +617,18 @@ typedef struct AVStream {
* Number of frames that have been demuxed during av_find_stream_info()
*/
int codec_info_nb_frames;
+
+ /**
+ * Stream informations used internally by av_find_stream_info()
+ */
+#define MAX_STD_TIMEBASES (60*12+5)
+ struct {
+ int64_t last_dts;
+ int64_t duration_gcd;
+ int duration_count;
+ double duration_error[MAX_STD_TIMEBASES];
+ int64_t codec_info_duration;
+ } *info;
} AVStream;
#define AV_PROGRAM_RUNNING 1
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 9f6b1509e0..8a08557890 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -489,6 +489,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
av_free(st->priv_data);
av_free(st->codec->extradata);
av_free(st->codec);
+ av_free(st->info);
}
av_free(st);
}
@@ -2138,7 +2139,6 @@ static void compute_chapters_end(AVFormatContext *s)
}
}
-#define MAX_STD_TIMEBASES (60*12+5)
static int get_std_framerate(int i){
if(i<60*12) return i*1001;
else return ((const int[]){24,30,60,12,15})[i-60*12]*1000*12;
@@ -2170,18 +2170,6 @@ 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, *tmp_info;
-
- if (ic->nb_streams >= INT_MAX/sizeof(*info) ||
- !(info = av_mallocz(ic->nb_streams * sizeof(*info))))
- return AVERROR(ENOMEM);
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
@@ -2222,7 +2210,7 @@ int av_find_stream_info(AVFormatContext *ic)
}
for (i=0; i<ic->nb_streams; i++) {
- info[i].last_dts= AV_NOPTS_VALUE;
+ ic->streams[i]->info->last_dts = AV_NOPTS_VALUE;
}
count = 0;
@@ -2241,7 +2229,7 @@ int av_find_stream_info(AVFormatContext *ic)
break;
/* variable fps and no guess at the real fps */
if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
- && info[i].duration_count<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ && st->info->duration_count<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
break;
if(st->parser && st->parser->parser->split && !st->codec->extradata)
break;
@@ -2285,39 +2273,25 @@ 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);
- }
+ if ((ret = av_dup_packet(pkt)) < 0)
+ goto find_stream_info_err;
read_size += pkt->size;
st = ic->streams[pkt->stream_index];
- if(st->codec_info_nb_frames>1) {
- if (st->time_base.den > 0 && av_rescale_q(info[st->index].codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
+ if (st->codec_info_nb_frames>1) {
+ if (st->time_base.den > 0 && av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
break;
}
- info[st->index].codec_info_duration += pkt->duration;
+ st->info->codec_info_duration += pkt->duration;
}
{
- int index= pkt->stream_index;
- int64_t last= info[index].last_dts;
+ int64_t last = st->info->last_dts;
int64_t duration= pkt->dts - last;
if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
@@ -2325,21 +2299,21 @@ int av_find_stream_info(AVFormatContext *ic)
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
- if(info[index].duration_count < 2)
- memset(info[index].duration_error, 0, sizeof(info[index].duration_error));
- for(i=1; i<MAX_STD_TIMEBASES; i++){
+ if (st->info->duration_count < 2)
+ memset(st->info->duration_error, 0, sizeof(st->info->duration_error));
+ for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
int framerate= get_std_framerate(i);
int ticks= lrintf(dur*framerate/(1001*12));
double error= dur - ticks*1001*12/(double)framerate;
- info[index].duration_error[i] += error*error;
+ st->info->duration_error[i] += error*error;
}
- info[index].duration_count++;
+ st->info->duration_count++;
// ignore the first 4 values, they might have some random jitter
- if (info[index].duration_count > 3)
- info[index].duration_gcd = av_gcd(info[index].duration_gcd, duration);
+ if (st->info->duration_count > 3)
+ st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration);
}
- if(last == AV_NOPTS_VALUE || info[index].duration_count <= 1)
- info[pkt->stream_index].last_dts = pkt->dts;
+ if (last == AV_NOPTS_VALUE || st->info->duration_count <= 1)
+ st->info->last_dts = pkt->dts;
}
if(st->parser && st->parser->parser->split && !st->codec->extradata){
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
@@ -2370,10 +2344,10 @@ int av_find_stream_info(AVFormatContext *ic)
}
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
- if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && info[i].codec_info_duration)
+ if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration)
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
(st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
- info[i].codec_info_duration*(int64_t)st->time_base.num, 60000);
+ st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
@@ -2381,18 +2355,18 @@ int av_find_stream_info(AVFormatContext *ic)
// the check for tb_unreliable() is not completely correct, since this is not about handling
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
// ipmovie.c produces.
- if (tb_unreliable(st->codec) && info[i].duration_count > 15 && info[i].duration_gcd > 1 && !st->r_frame_rate.num)
- av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * info[i].duration_gcd, INT_MAX);
- if(info[i].duration_count && !st->r_frame_rate.num
+ if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)
+ av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
+ if (st->info->duration_count && !st->r_frame_rate.num
&& tb_unreliable(st->codec) /*&&
//FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
- st->time_base.num*duration_sum[i]/info[i].duration_count*101LL > st->time_base.den*/){
+ st->time_base.num*duration_sum[i]/st->info->duration_count*101LL > st->time_base.den*/){
int num = 0;
double best_error= 2*av_q2d(st->time_base);
- best_error= best_error*best_error*info[i].duration_count*1000*12*30;
+ best_error = best_error*best_error*st->info->duration_count*1000*12*30;
- for(j=1; j<MAX_STD_TIMEBASES; j++){
- double error= info[i].duration_error[j] * get_std_framerate(j);
+ for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {
+ double error = st->info->duration_error[j] * get_std_framerate(j);
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
if(error < best_error){
@@ -2450,7 +2424,9 @@ int av_find_stream_info(AVFormatContext *ic)
}
#endif
- av_free(info);
+ find_stream_info_err:
+ for (i=0; i < ic->nb_streams; i++)
+ av_freep(&ic->streams[i]->info);
return ret;
}
@@ -2496,6 +2472,7 @@ void av_close_input_stream(AVFormatContext *s)
av_free(st->filename);
#endif
av_free(st->priv_data);
+ av_free(st->info);
av_free(st);
}
for(i=s->nb_programs-1; i>=0; i--) {
@@ -2555,6 +2532,10 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
st = av_mallocz(sizeof(AVStream));
if (!st)
return NULL;
+ if (!(st->info = av_mallocz(sizeof(*st->info)))) {
+ av_free(st);
+ return NULL;
+ }
st->codec= avcodec_alloc_context();
if (s->iformat) {