Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create MythAVRational to wrap AVRational #946

Merged
merged 5 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ add_library(
livetvchain.h
metadataimagehelper.cpp
metadataimagehelper.h
mythavrational.h
mythavutil.cpp
mythavutil.h
mythframe.cpp
Expand Down
16 changes: 8 additions & 8 deletions mythtv/libs/libmythtv/decoders/avformatdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3028,9 +3028,9 @@ void AvFormatDecoder::HandleGopStart(
m_positionMap.push_back(entry);
if (m_trackTotalDuration)
{
m_frameToDurMap[m_framesRead] =
llround(m_totalDuration.num * 1000.0 / m_totalDuration.den);
m_durToFrameMap[m_frameToDurMap[m_framesRead]] = m_framesRead;
long long duration = m_totalDuration.toFixed(1000LL);
m_frameToDurMap[m_framesRead] = duration;
m_durToFrameMap[duration] = m_framesRead;
}
}

Expand Down Expand Up @@ -3307,11 +3307,11 @@ bool AvFormatDecoder::PreProcessVideoPacket(AVStream *curstream, AVPacket *pkt)
// The ffmpeg libraries represent a frame interval of a
// 59.94fps video as 1501/90000 seconds, when it should
// actually be 1501.5/90000 seconds.
AVRational pkt_dur = AVRationalInit(pkt->duration);
pkt_dur = av_mul_q(pkt_dur, curstream->time_base);
if (pkt_dur.num == 1501 && pkt_dur.den == 90000)
pkt_dur = AVRationalInit(1001, 60000); // 1501.5/90000
m_totalDuration = av_add_q(m_totalDuration, pkt_dur);
MythAVRational pkt_dur {static_cast<int>(pkt->duration)};
pkt_dur *= MythAVRational(curstream->time_base);
if (pkt_dur == MythAVRational(1501, 90000))
pkt_dur = MythAVRational(1001, 60000); // 1501.5/90000
m_totalDuration += pkt_dur;
}

m_justAfterChange = false;
Expand Down
9 changes: 4 additions & 5 deletions mythtv/libs/libmythtv/decoders/decoderbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo)
: m_parent(parent), m_playbackInfo(new ProgramInfo(pginfo)),
m_audio(m_parent->GetAudio()),
m_totalDuration(AVRationalInit(0)),

// language preference
m_languagePreference(iso639_get_language_key_list())
Expand Down Expand Up @@ -61,7 +60,7 @@ void DecoderBase::Reset(bool reset_video_data, bool seek_reset, bool reset_file)
m_frameCounter += 100;
m_fpsSkip = 0;
m_framesRead = 0;
m_totalDuration = AVRationalInit(0);
m_totalDuration = MythAVRational(0);
m_dontSyncPositionMap = false;
}

Expand Down Expand Up @@ -883,7 +882,7 @@ void DecoderBase::FileChanged(void)
ResetPosMap();
m_framesPlayed = 0;
m_framesRead = 0;
m_totalDuration = AVRationalInit(0);
m_totalDuration = MythAVRational(0);

m_waitingForChange = false;
m_justAfterChange = true;
Expand Down Expand Up @@ -1293,10 +1292,10 @@ QString toString(AudioTrackType type)

void DecoderBase::SaveTotalDuration(void)
{
if (!m_playbackInfo || av_q2d(m_totalDuration) == 0)
if (!m_playbackInfo || !m_totalDuration.isNonzero() || !m_totalDuration.isValid())
return;

m_playbackInfo->SaveTotalDuration(millisecondsFromFloat(1000 * av_q2d(m_totalDuration)));
m_playbackInfo->SaveTotalDuration(std::chrono::milliseconds{m_totalDuration.toFixed(1000)});
}

void DecoderBase::SaveTotalFrames(void)
Expand Down
12 changes: 3 additions & 9 deletions mythtv/libs/libmythtv/decoders/decoderbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "libmythbase/mythdbcon.h"
#include "libmythbase/programinfo.h"
#include "libmythtv/io/mythmediabuffer.h"
#include "libmythtv/mythavrational.h"
#include "libmythtv/mythavutil.h"
#include "libmythtv/mythcodecid.h"
#include "libmythtv/mythvideoprofile.h"
Expand Down Expand Up @@ -110,13 +111,6 @@ class StreamInfo
};
using sinfo_vec_t = std::vector<StreamInfo>;

inline AVRational AVRationalInit(int num, int den = 1) {
AVRational result;
result.num = num;
result.den = den;
return result;
}

class DecoderBase
{
public:
Expand Down Expand Up @@ -256,7 +250,7 @@ class DecoderBase
virtual bool SetVideoByComponentTag(int /*tag*/) { return false; }

void SaveTotalDuration(void);
void ResetTotalDuration(void) { m_totalDuration = AVRationalInit(0); }
void ResetTotalDuration(void) { m_totalDuration = MythAVRational(0); }
void SaveTotalFrames(void);
void TrackTotalDuration(bool track) { m_trackTotalDuration = track; }
int GetfpsMultiplier(void) const { return m_fpsMultiplier; }
Expand Down Expand Up @@ -300,7 +294,7 @@ class DecoderBase
long long m_framesPlayed {0};
long long m_framesRead {0};
uint64_t m_frameCounter {0};
AVRational m_totalDuration;
MythAVRational m_totalDuration {0};
int m_keyframeDist {-1};
long long m_lastKey {0};
long long m_indexOffset {0};
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/libmythtv.pro
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ HEADERS += io/mythstreamingbuffer.h
HEADERS += io/mythinteractivebuffer.h
HEADERS += io/mythopticalbuffer.h
HEADERS += metadataimagehelper.h
HEADERS += mythavrational.h
HEADERS += mythavutil.h
HEADERS += recordingfile.h
HEADERS += driveroption.h
Expand Down
8 changes: 4 additions & 4 deletions mythtv/libs/libmythtv/mpeg/AVCParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,12 +1074,12 @@ double AVCParser::frameRate(void) const
return fps;
}

void AVCParser::getFrameRate(FrameRate &result) const
MythAVRational AVCParser::getFrameRate() const
{
if (m_unitsInTick == 0)
result = FrameRate(0);
return MythAVRational(0);
else if (m_timeScale & 0x1)
result = FrameRate(m_timeScale, m_unitsInTick * 2);
return MythAVRational(m_timeScale, m_unitsInTick * 2);
else
result = FrameRate(m_timeScale / 2, m_unitsInTick);
return MythAVRational(m_timeScale / 2, m_unitsInTick);
}
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/mpeg/AVCParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class AVCParser : public H2645Parser
uint pictureHeightCropped(void) const override;

double frameRate(void) const;
void getFrameRate(FrameRate &result) const override;
MythAVRational getFrameRate() const override;

void set_AU_pending(void)
{
Expand Down
51 changes: 24 additions & 27 deletions mythtv/libs/libmythtv/mpeg/H2645Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "recorders/dtvrecorder.h" // for FrameRate and ScanType
#include "bitreader.h"

#include <cmath>
#include <strings.h>

/*
Expand Down Expand Up @@ -388,10 +387,10 @@ void H2645Parser::vui_parameters(BitReader& br, bool hevc)
uint H2645Parser::aspectRatio(void) const
{

double aspect = 0.0;
MythAVRational aspect {0};

if (m_picHeight)
aspect = pictureWidthCropped() / (double)pictureHeightCropped();
aspect = MythAVRational(pictureWidthCropped(), pictureHeightCropped());

switch (m_aspectRatioIdc)
{
Expand All @@ -400,82 +399,80 @@ uint H2645Parser::aspectRatio(void) const
break;
case 2:
// 12:11
aspect *= 1.0909090909090908;
aspect *= MythAVRational(12, 11);
break;
case 3:
// 10:11
aspect *= 0.90909090909090906;
aspect *= MythAVRational(10, 11);
break;
case 4:
// 16:11
aspect *= 1.4545454545454546;
aspect *= MythAVRational(16, 11);
break;
case 5:
// 40:33
aspect *= 1.2121212121212122;
aspect *= MythAVRational(40, 33);
break;
case 6:
// 24:11
aspect *= 2.1818181818181817;
aspect *= MythAVRational(24, 11);
break;
case 7:
// 20:11
aspect *= 1.8181818181818181;
aspect *= MythAVRational(20, 11);
break;
case 8:
// 32:11
aspect *= 2.9090909090909092;
aspect *= MythAVRational(32, 11);
break;
case 9:
// 80:33
aspect *= 2.4242424242424243;
aspect *= MythAVRational(80, 33);
break;
case 10:
// 18:11
aspect *= 1.6363636363636365;
aspect *= MythAVRational(18, 11);
break;
case 11:
// 15:11
aspect *= 1.3636363636363635;
aspect *= MythAVRational(15, 11);
break;
case 12:
// 64:33
aspect *= 1.9393939393939394;
aspect *= MythAVRational(64, 33);
break;
case 13:
// 160:99
aspect *= 1.6161616161616161;
aspect *= MythAVRational(160, 99);
break;
case 14:
// 4:3
aspect *= 1.3333333333333333;
aspect *= MythAVRational(4, 3);
break;
case 15:
// 3:2
aspect *= 1.5;
aspect *= MythAVRational(3, 2);
break;
case 16:
// 2:1
aspect *= 2.0;
aspect *= MythAVRational(2, 1);
break;
case kExtendedSar:
if (m_sarHeight)
aspect *= m_sarWidth / (double)m_sarHeight;
aspect *= MythAVRational(m_sarWidth, m_sarHeight);
else
aspect = 0.0;
aspect = MythAVRational(0);
break;
}

// TODO use an integer-based Rational number instead of floating point
static constexpr double eps = 1E-5;
if (aspect == 0.0)
if (aspect == MythAVRational(0))
return 0;
if (fabs(aspect - 1.3333333333333333) < eps)
if (aspect == MythAVRational(4, 3)) // 1.3333333333333333
return 2;
if (fabs(aspect - 1.7777777777777777) < eps)
if (aspect == MythAVRational(16, 9)) // 1.7777777777777777
return 3;
if (fabs(aspect - 2.21) < eps)
if (aspect == MythAVRational(221, 100)) // 2.21
return 4;

return aspect * 1000000;
return aspect.toFixed(1000000);
}
4 changes: 2 additions & 2 deletions mythtv/libs/libmythtv/mpeg/H2645Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#include "libmythbase/mythconfig.h"
#include "libmythbase/mythlogging.h"

#include "libmythtv/mythavrational.h"
#include "libmythtv/scantype.h"

class BitReader;
class FrameRate;

class H2645Parser {
public:
Expand Down Expand Up @@ -70,7 +70,7 @@ class H2645Parser {
/** \brief Computes aspect ratio from picture size and sample aspect ratio
*/
uint aspectRatio(void) const;
virtual void getFrameRate(FrameRate &result) const = 0;
virtual MythAVRational getFrameRate() const = 0;
virtual field_type getFieldType(void) const = 0;

uint64_t frameAUstreamOffset(void) const {return m_frameStartOffset;}
Expand Down
6 changes: 3 additions & 3 deletions mythtv/libs/libmythtv/mpeg/HEVCParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2067,8 +2067,8 @@ uint HEVCParser::pictureHeightCropped(void) const
m_frameCropBottomOffset) * crop_unit_y);
}

void HEVCParser::getFrameRate(FrameRate &result) const
MythAVRational HEVCParser::getFrameRate() const
{
result = (m_unitsInTick == 0) ? FrameRate(0) :
FrameRate(m_timeScale, m_unitsInTick);
return (m_unitsInTick == 0) ? MythAVRational(0) :
MythAVRational(m_timeScale, m_unitsInTick);
}
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/mpeg/HEVCParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class HEVCParser : public H2645Parser
uint pictureHeightCropped(void) const override;

field_type getFieldType(void) const override { return FRAME; }
void getFrameRate(FrameRate &result) const override;
MythAVRational getFrameRate() const override;

protected:
bool newAU(void);
Expand Down
Loading
Loading