[FFmpeg-devel] [PATCH] lavf: consider codec timebase for framerate detection

James Almer jamrial at gmail.com
Wed May 31 00:46:36 EEST 2017


On 5/30/2017 9:07 AM, wm4 wrote:
> On Tue, 23 May 2017 13:36:51 +0200
> wm4 <nfxjfg at googlemail.com> wrote:
> 
>> Fixes detection of some TV sample as 24.5 FPS. With the patch applied,
>> it's detected as 25 FPS.
>> ---
>>  libavformat/utils.c | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>
>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>> index fbd8b58ac2..778a82aeee 100644
>> --- a/libavformat/utils.c
>> +++ b/libavformat/utils.c
>> @@ -3903,6 +3903,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
>>                  st->info->codec_info_duration) {
>>                  int best_fps      = 0;
>>                  double best_error = 0.01;
>> +                AVRational codec_frame_rate = av_inv_q(avctx->time_base);
>>  
>>                  if (st->info->codec_info_duration        >= INT64_MAX / st->time_base.num / 2||
>>                      st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den ||
>> @@ -3924,6 +3925,27 @@ FF_ENABLE_DEPRECATION_WARNINGS
>>                          best_fps   = std_fps.num;
>>                      }
>>                  }
>> +                if (avctx->ticks_per_frame > 0)
>> +                    codec_frame_rate.num /= avctx->ticks_per_frame;
>> +                for (j = 0; j < MAX_STD_TIMEBASES; j++) {
>> +                    AVRational std_fps = { get_std_framerate(j), 12 * 1001 };
>> +                    double error       = fabs(av_q2d(st->avg_frame_rate) /
>> +                                              av_q2d(std_fps) - 1);
>> +
>> +                    if (error < best_error) {
>> +                        best_error = error;
>> +                        best_fps   = std_fps.num;
>> +                    }
>> +
>> +                    if (codec_frame_rate.num > 0 && codec_frame_rate.den > 0) {
>> +                        error       = fabs(av_q2d(codec_frame_rate) /
>> +                                           av_q2d(std_fps) - 1);
>> +                        if (error < best_error) {
>> +                            best_error = error;
>> +                            best_fps   = std_fps.num;
>> +                        }
>> +                    }
>> +                }
>>                  if (best_fps)
>>                      av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
>>                                best_fps, 12 * 1001, INT_MAX);
> 
> Nobody wants to review this? It's pretty intrusive. I guess I'll push
> tomorrow or so.

According to the AVCodecContext->time_base doxy

     * - encoding: MUST be set by user.
     * - decoding: the use of this field for decoding is deprecated.
     *             Use framerate instead.

And it's scheduled to be dropped in the next bump (libav already did it).
It's still used for decoding elsewhere in avformat_find_stream_info(),
though, and even in other places, so this is probably going in the wrong
direction and the other cases should be fixed instead.
ffmpeg.c is apparently not using it for decoding, so that's good.

You may be able to use avctx->framerate for this. Check how the
deprecated code in in lavc/utils.c and lavc/decode.c uses it to set
avctx->time_base.


More information about the ffmpeg-devel mailing list