@@ -2701,6 +2701,94 @@ int ff_alloc_extradata(AVCodecContext *avctx, int size)
2701
2701
return ret ;
2702
2702
}
2703
2703
2704
+ int ff_rfps_add_frame (AVFormatContext * ic , AVStream * st , int64_t ts )
2705
+ {
2706
+ int i , j ;
2707
+ int64_t last = st -> info -> last_dts ;
2708
+
2709
+ if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last
2710
+ && ts - (uint64_t )last < INT64_MAX ){
2711
+ double dts = (is_relative (ts ) ? ts - RELATIVE_TS_BASE : ts ) * av_q2d (st -> time_base );
2712
+ int64_t duration = ts - last ;
2713
+
2714
+ if (!st -> info -> duration_error )
2715
+ st -> info -> duration_error = av_mallocz (sizeof (st -> info -> duration_error [0 ])* 2 );
2716
+ if (!st -> info -> duration_error )
2717
+ return AVERROR (ENOMEM );
2718
+
2719
+ // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2720
+ // av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
2721
+ for (i = 0 ; i < MAX_STD_TIMEBASES ; i ++ ) {
2722
+ int framerate = get_std_framerate (i );
2723
+ double sdts = dts * framerate /(1001 * 12 );
2724
+ for (j = 0 ; j < 2 ; j ++ ){
2725
+ int64_t ticks = llrint (sdts + j * 0.5 );
2726
+ double error = sdts - ticks + j * 0.5 ;
2727
+ st -> info -> duration_error [j ][0 ][i ] += error ;
2728
+ st -> info -> duration_error [j ][1 ][i ] += error * error ;
2729
+ }
2730
+ }
2731
+ st -> info -> duration_count ++ ;
2732
+ // ignore the first 4 values, they might have some random jitter
2733
+ if (st -> info -> duration_count > 3 && is_relative (ts ) == is_relative (last ))
2734
+ st -> info -> duration_gcd = av_gcd (st -> info -> duration_gcd , duration );
2735
+ }
2736
+ if (ts != AV_NOPTS_VALUE )
2737
+ st -> info -> last_dts = ts ;
2738
+
2739
+ return 0 ;
2740
+ }
2741
+
2742
+ void ff_rfps_calculate (AVFormatContext * ic )
2743
+ {
2744
+ int i , j ;
2745
+
2746
+ for (i = 0 ; i < ic -> nb_streams ; i ++ ) {
2747
+ AVStream * st = ic -> streams [i ];
2748
+
2749
+ if (st -> codec -> codec_type != AVMEDIA_TYPE_VIDEO )
2750
+ continue ;
2751
+ // the check for tb_unreliable() is not completely correct, since this is not about handling
2752
+ // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
2753
+ // ipmovie.c produces.
2754
+ if (tb_unreliable (st -> codec ) && st -> info -> duration_count > 15 && st -> info -> duration_gcd > FFMAX (1 , st -> time_base .den /(500LL * st -> time_base .num )) && !st -> r_frame_rate .num )
2755
+ 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 );
2756
+ if (st -> info -> duration_count > 1 && !st -> r_frame_rate .num
2757
+ && tb_unreliable (st -> codec )) {
2758
+ int num = 0 ;
2759
+ double best_error = 0.01 ;
2760
+
2761
+ for (j = 0 ; j < MAX_STD_TIMEBASES ; j ++ ) {
2762
+ int k ;
2763
+
2764
+ if (st -> info -> codec_info_duration && st -> info -> codec_info_duration * av_q2d (st -> time_base ) < (1001 * 12.0 )/get_std_framerate (j ))
2765
+ continue ;
2766
+ if (!st -> info -> codec_info_duration && 1.0 < (1001 * 12.0 )/get_std_framerate (j ))
2767
+ continue ;
2768
+ for (k = 0 ; k < 2 ; k ++ ){
2769
+ int n = st -> info -> duration_count ;
2770
+ double a = st -> info -> duration_error [k ][0 ][j ] / n ;
2771
+ double error = st -> info -> duration_error [k ][1 ][j ]/n - a * a ;
2772
+
2773
+ if (error < best_error && best_error > 0.000000001 ){
2774
+ best_error = error ;
2775
+ num = get_std_framerate (j );
2776
+ }
2777
+ if (error < 0.02 )
2778
+ av_log (NULL , AV_LOG_DEBUG , "rfps: %f %f\n" , get_std_framerate (j ) / 12.0 /1001 , error );
2779
+ }
2780
+ }
2781
+ // do not increase frame rate by more than 1 % in order to match a standard rate.
2782
+ if (num && (!st -> r_frame_rate .num || (double )num /(12 * 1001 ) < 1.01 * av_q2d (st -> r_frame_rate )))
2783
+ av_reduce (& st -> r_frame_rate .num , & st -> r_frame_rate .den , num , 12 * 1001 , INT_MAX );
2784
+ }
2785
+
2786
+ av_freep (& st -> info -> duration_error );
2787
+ st -> info -> last_dts = AV_NOPTS_VALUE ;
2788
+ st -> info -> duration_count = 0 ;
2789
+ }
2790
+ }
2791
+
2704
2792
int avformat_find_stream_info (AVFormatContext * ic , AVDictionary * * options )
2705
2793
{
2706
2794
int i , count , ret = 0 , j ;
@@ -2918,39 +3006,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
2918
3006
}
2919
3007
}
2920
3008
#if FF_API_R_FRAME_RATE
2921
- {
2922
- int64_t last = st -> info -> last_dts ;
2923
-
2924
- if ( pkt -> dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt -> dts > last
2925
- && pkt -> dts - (uint64_t )last < INT64_MAX ){
2926
- double dts = (is_relative (pkt -> dts ) ? pkt -> dts - RELATIVE_TS_BASE : pkt -> dts ) * av_q2d (st -> time_base );
2927
- int64_t duration = pkt -> dts - last ;
2928
-
2929
- if (!st -> info -> duration_error )
2930
- st -> info -> duration_error = av_mallocz (sizeof (st -> info -> duration_error [0 ])* 2 );
2931
- if (!st -> info -> duration_error )
2932
- return AVERROR (ENOMEM );
2933
-
2934
- // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2935
- // av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
2936
- for (i = 0 ; i < MAX_STD_TIMEBASES ; i ++ ) {
2937
- int framerate = get_std_framerate (i );
2938
- double sdts = dts * framerate /(1001 * 12 );
2939
- for (j = 0 ; j < 2 ; j ++ ){
2940
- int64_t ticks = llrint (sdts + j * 0.5 );
2941
- double error = sdts - ticks + j * 0.5 ;
2942
- st -> info -> duration_error [j ][0 ][i ] += error ;
2943
- st -> info -> duration_error [j ][1 ][i ] += error * error ;
2944
- }
2945
- }
2946
- st -> info -> duration_count ++ ;
2947
- // ignore the first 4 values, they might have some random jitter
2948
- if (st -> info -> duration_count > 3 && is_relative (pkt -> dts ) == is_relative (last ))
2949
- st -> info -> duration_gcd = av_gcd (st -> info -> duration_gcd , duration );
2950
- }
2951
- if (pkt -> dts != AV_NOPTS_VALUE )
2952
- st -> info -> last_dts = pkt -> dts ;
2953
- }
3009
+ ff_rfps_add_frame (ic , st , pkt -> dts );
2954
3010
#endif
2955
3011
if (st -> parser && st -> parser -> parser -> split && !st -> codec -> extradata ){
2956
3012
int i = st -> parser -> parser -> split (st -> codec , pkt -> data , pkt -> size );
@@ -3006,6 +3062,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
3006
3062
st = ic -> streams [i ];
3007
3063
avcodec_close (st -> codec );
3008
3064
}
3065
+
3066
+ ff_rfps_calculate (ic );
3067
+
3009
3068
for (i = 0 ;i < ic -> nb_streams ;i ++ ) {
3010
3069
st = ic -> streams [i ];
3011
3070
if (st -> codec -> codec_type == AVMEDIA_TYPE_VIDEO ) {
@@ -3044,40 +3103,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
3044
3103
best_fps , 12 * 1001 , INT_MAX );
3045
3104
}
3046
3105
}
3047
- // the check for tb_unreliable() is not completely correct, since this is not about handling
3048
- // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
3049
- // ipmovie.c produces.
3050
- if (tb_unreliable (st -> codec ) && st -> info -> duration_count > 15 && st -> info -> duration_gcd > FFMAX (1 , st -> time_base .den /(500LL * st -> time_base .num )) && !st -> r_frame_rate .num )
3051
- 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 );
3052
- if (st -> info -> duration_count > 1 && !st -> r_frame_rate .num
3053
- && tb_unreliable (st -> codec )) {
3054
- int num = 0 ;
3055
- double best_error = 0.01 ;
3056
-
3057
- for (j = 0 ; j < MAX_STD_TIMEBASES ; j ++ ) {
3058
- int k ;
3059
-
3060
- if (st -> info -> codec_info_duration && st -> info -> codec_info_duration * av_q2d (st -> time_base ) < (1001 * 12.0 )/get_std_framerate (j ))
3061
- continue ;
3062
- if (!st -> info -> codec_info_duration && 1.0 < (1001 * 12.0 )/get_std_framerate (j ))
3063
- continue ;
3064
- for (k = 0 ; k < 2 ; k ++ ){
3065
- int n = st -> info -> duration_count ;
3066
- double a = st -> info -> duration_error [k ][0 ][j ] / n ;
3067
- double error = st -> info -> duration_error [k ][1 ][j ]/n - a * a ;
3068
-
3069
- if (error < best_error && best_error > 0.000000001 ){
3070
- best_error = error ;
3071
- num = get_std_framerate (j );
3072
- }
3073
- if (error < 0.02 )
3074
- av_log (NULL , AV_LOG_DEBUG , "rfps: %f %f\n" , get_std_framerate (j ) / 12.0 /1001 , error );
3075
- }
3076
- }
3077
- // do not increase frame rate by more than 1 % in order to match a standard rate.
3078
- if (num && (!st -> r_frame_rate .num || (double )num /(12 * 1001 ) < 1.01 * av_q2d (st -> r_frame_rate )))
3079
- av_reduce (& st -> r_frame_rate .num , & st -> r_frame_rate .den , num , 12 * 1001 , INT_MAX );
3080
- }
3081
3106
3082
3107
if (!st -> r_frame_rate .num ){
3083
3108
if ( st -> codec -> time_base .den * (int64_t )st -> time_base .num
0 commit comments