From 4a7342e7ee9efc76892018c517ab367d39b930ec Mon Sep 17 00:00:00 2001
From: Karl Dietz <dekarl@mythtv.org>
Date: Sun, 27 Apr 2014 02:19:55 +0200
Subject: [PATCH 1/3] divide framerate by number of ticks (fields) per frame
Inspired by av_guess_frame_rate, see
https://www.ffmpeg.org/doxygen/trunk/group__lavf__misc.html#ga12c049178414cc221dfafd4e7f836dea
Why don't we just use that?
Fixes #12047
---
mythtv/libs/libmythtv/avformatdecoder.cpp | 54 ++++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 552d3fe..e176d09 100644
a
|
b
|
int AvFormatDecoder::OpenFile(RingBuffer *rbuffer, bool novideo, |
1337 | 1337 | return recordingHasPositionMap; |
1338 | 1338 | } |
1339 | 1339 | |
| 1340 | /* FIXME remove after updating FFmpeg past 2.0 */ |
| 1341 | /** |
| 1342 | * Guess the frame rate, based on both the container and codec information. |
| 1343 | * |
| 1344 | * @param ctx the format context which the stream is part of |
| 1345 | * @param stream the stream which the frame is part of |
| 1346 | * @param frame the frame for which the frame rate should be determined, may be NULL |
| 1347 | * @return the guessed (valid) frame rate, 0/1 if no idea |
| 1348 | */ |
| 1349 | |
| 1350 | AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame); |
| 1351 | |
| 1352 | AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame) |
| 1353 | { |
| 1354 | AVRational fr = st->r_frame_rate; |
| 1355 | AVRational codec_fr = av_inv_q(st->codec->time_base); |
| 1356 | AVRational avg_fr = st->avg_frame_rate; |
| 1357 | |
| 1358 | if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 && |
| 1359 | av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) { |
| 1360 | fr = avg_fr; |
| 1361 | } |
| 1362 | |
| 1363 | |
| 1364 | if (st->codec->ticks_per_frame > 1) { |
| 1365 | codec_fr.den *= st->codec->ticks_per_frame; |
| 1366 | if ( codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7 |
| 1367 | && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1) |
| 1368 | fr = codec_fr; |
| 1369 | } |
| 1370 | |
| 1371 | return fr; |
| 1372 | } |
| 1373 | |
1340 | 1374 | float AvFormatDecoder::normalized_fps(AVStream *stream, AVCodecContext *enc) |
1341 | 1375 | { |
1342 | | float fps, avg_fps, codec_fps, container_fps, estimated_fps; |
1343 | | avg_fps = codec_fps = container_fps = estimated_fps = 0.0f; |
| 1376 | float fps, avg_fps, codec_fps, container_fps, estimated_fps, guess_fps; |
| 1377 | avg_fps = codec_fps = container_fps = estimated_fps = guess_fps = 0.0f; |
| 1378 | |
| 1379 | guess_fps = av_q2d(av_guess_frame_rate(ic, stream, NULL)); |
1344 | 1380 | |
| 1381 | /* this is not a good source for FPS according to |
| 1382 | * https://trac.bunkus.org/wiki/FAQ:WrongFrameRateDisplayed |
| 1383 | */ |
1345 | 1384 | if (stream->avg_frame_rate.den && stream->avg_frame_rate.num) |
1346 | 1385 | avg_fps = av_q2d(stream->avg_frame_rate); // MKV default_duration |
1347 | 1386 | |
… |
… |
float AvFormatDecoder::normalized_fps(AVStream *stream, AVCodecContext *enc) |
1360 | 1399 | if (stream->r_frame_rate.den && stream->r_frame_rate.num) // tbr |
1361 | 1400 | estimated_fps = av_q2d(stream->r_frame_rate); |
1362 | 1401 | |
| 1402 | if (guess_fps > 3.0f) |
| 1403 | { |
| 1404 | fps = guess_fps; |
| 1405 | } |
1363 | 1406 | // matroska demuxer sets the default_duration to avg_frame_rate |
1364 | 1407 | // mov,mp4,m4a,3gp,3g2,mj2 demuxer sets avg_frame_rate |
1365 | | if ((QString(ic->iformat->name).contains("matroska") || |
| 1408 | else if ((QString(ic->iformat->name).contains("matroska") || |
1366 | 1409 | QString(ic->iformat->name).contains("mov")) && |
1367 | 1410 | avg_fps < 121.0f && avg_fps > 3.0f) |
1368 | 1411 | fps = avg_fps; |
… |
… |
float AvFormatDecoder::normalized_fps(AVStream *stream, AVCodecContext *enc) |
1383 | 1426 | if (fps != m_fps) |
1384 | 1427 | { |
1385 | 1428 | LOG(VB_PLAYBACK, LOG_INFO, LOC + |
1386 | | QString("Selected FPS is %1 (avg %2 codec %3 " |
| 1429 | QString("Selected FPS is %1 (guess %6 avg %2 codec %3 " |
1387 | 1430 | "container %4 estimated %5)").arg(fps).arg(avg_fps) |
1388 | | .arg(codec_fps).arg(container_fps).arg(estimated_fps)); |
| 1431 | .arg(codec_fps).arg(container_fps).arg(estimated_fps) |
| 1432 | .arg(guess_fps)); |
1389 | 1433 | m_fps = fps; |
1390 | 1434 | } |
1391 | 1435 | |