[FFmpeg-devel] Reducing time spent in av_find_stream_info()

Michael Niedermayer michaelni
Wed Nov 14 22:41:18 CET 2007


On Wed, Nov 14, 2007 at 04:35:05PM +0100, Diego Santa Cruz wrote:
> > >
> > > I see, any hints about which framerates should be kept? I will try
> also
> > 
> > well, i dont know, but all which occur in real files at least :)
> > 
> > 
> > > to reduce the complexity of the calculations.
> > >
> 
> OK I have done both :)

[...]
 
> Second patch attached (ffmpeg-info-fps.patch) modifies the table of
> standard framerates. The new set is much reduced (from 725 to 42). I
> replaced all framerates 1 to 60 in 1/12 steps by all regular framerates
> derived from 18, 24, 30 and 60 which are not below 1 fps and which are
> also a multiple of 1/12 (as was the case before). Note that this second
> patch is independent of the one above, although it may not apply cleanly
> without it due to nearby changes. I also added 17.98 = 18*1000/1001,
> since I guess this might appear in some cases...

i doubt these will be enough framerates also it looks a little more
complex than what i would have hoped ...

[...]


Content-Description: ffmpeg-fp-dur-error.patch
> --- libavformat/utils.c.orig2	2007-11-14 16:11:13.000000000 +0100
> +++ libavformat/utils.c	2007-11-14 16:11:29.000000000 +0100
> @@ -1756,7 +1756,7 @@
>      AVPacket pkt1, *pkt;
>      int64_t last_dts[MAX_STREAMS];
>      int duration_count[MAX_STREAMS]={0};
> -    double (*duration_error)[MAX_STD_TIMEBASES];
> +    int64_t (*duration_error)[MAX_STD_TIMEBASES];
>      offset_t old_offset = url_ftell(&ic->pb);
>      int64_t codec_info_duration[MAX_STREAMS]={0};
>      int codec_info_nb_frames[MAX_STREAMS]={0};
> @@ -1860,17 +1860,28 @@
>              int64_t duration= pkt->dts - last;
>  
>              if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
> -                double dur= duration * av_q2d(st->time_base);
>  
>  //                if(st->codec->codec_type == CODEC_TYPE_VIDEO)
>  //                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
>                  if(duration_count[index] < 2)
>                      memset(duration_error, 0, MAX_STREAMS * sizeof(*duration_error));
> +		/* NOTE: we store the quadratic error in duration for
> +		 * each standard frame rate in .32 fixed-point
> +		 * format */

tabs are forbidden in svn


>                  for(i=1; i<MAX_STD_TIMEBASES; i++){
>                      int framerate= get_std_framerate(i);
> -                    int ticks= lrintf(dur*framerate/(1001*12));
> -                    double error= dur - ticks*1001*12/(double)framerate;
> -                    duration_error[index][i] += error*error;
> +		    int ticks_den = st->time_base.den * 1001 * 12;

this can overflow, also it can be moved out of this loop


> +		    int64_t ticks =
> +			(2 * duration * st->time_base.num *
> +			 framerate + ticks_den - 1) / (2*ticks_den);



> +		    /* 'error' is the difference between the duration
> +		     * as integer multiple of the frame rate and the
> +		     * actual duration in .16 fixed-point */
> +		    int64_t error=
> +			( (duration * st->time_base.num * framerate -

duration * st->time_base.num * framerate can be factorized out


> +			   ticks * ticks_den) << 16) /
> +			(st->time_base.den * framerate);
> +                    duration_error[index][i] += (error*error);

this is not accurate also the denominator is not needed all
values added have the same


>                  }
>                  duration_count[index]++;
>              }

> @@ -1939,11 +1950,11 @@
>                 && (st->codec->time_base.num*101LL <= st->codec->time_base.den || st->codec->codec_id == CODEC_ID_MPEG2VIDEO) /*&&
>                 //FIXME we should not special case mpeg2, but this needs testing with non mpeg2 ...
>                 st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){
> -                double best_error= 2*av_q2d(st->time_base);
> +                int64_t best_error= (st->time_base.num<<17)/st->time_base.den;
>                  best_error= best_error*best_error*duration_count[i]*1000*12*30;
>  
>                  for(j=1; j<MAX_STD_TIMEBASES; j++){
> -                    double error= duration_error[i][j] * get_std_framerate(j);
> +                    int64_t error= duration_error[i][j] * get_std_framerate(j);
>  //                    if(st->codec->codec_type == CODEC_TYPE_VIDEO)
>  //                        av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
>                      if(error < best_error){

i dont think this matters speed wise, also both these changes can cause
overflows


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Freedom in capitalist society always remains about the same as it was in
ancient Greek republics: Freedom for slave owners. -- Vladimir Lenin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20071114/8c9145a3/attachment.pgp>



More information about the ffmpeg-devel mailing list