AUDIO: Wrap around in the Timestamp constructor

The "making of" video in the Xbox version of Myst III is
unusually long. VideoDecoder::FixedRateVideoTrack::getFrameTime
would trigger an overflow.
This commit is contained in:
Bastien Bouclet 2014-09-14 15:07:50 +02:00
parent 0f590561bd
commit 200b05246c
2 changed files with 15 additions and 4 deletions

View file

@ -39,12 +39,10 @@ Timestamp::Timestamp(uint ms, uint fr) {
Timestamp::Timestamp(uint s, uint frames, uint fr) { Timestamp::Timestamp(uint s, uint frames, uint fr) {
assert(fr > 0); assert(fr > 0);
_secs = s; _secs = s + (frames / fr);
_framerateFactor = 1000 / Common::gcd<uint>(1000, fr); _framerateFactor = 1000 / Common::gcd<uint>(1000, fr);
_framerate = fr * _framerateFactor; _framerate = fr * _framerateFactor;
_numFrames = frames * _framerateFactor; _numFrames = (frames % fr) * _framerateFactor;
normalize();
} }
Timestamp Timestamp::convertToFramerate(uint newFramerate) const { Timestamp Timestamp::convertToFramerate(uint newFramerate) const {

View file

@ -2,6 +2,8 @@
#include "audio/timestamp.h" #include "audio/timestamp.h"
#include <limits.h>
class TimestampTestSuite : public CxxTest::TestSuite class TimestampTestSuite : public CxxTest::TestSuite
{ {
public: public:
@ -238,4 +240,15 @@ class TimestampTestSuite : public CxxTest::TestSuite
TS_ASSERT_EQUALS(c.numberOfFrames(), 11025); TS_ASSERT_EQUALS(c.numberOfFrames(), 11025);
TS_ASSERT_EQUALS(c.totalNumberOfFrames(), 33075); TS_ASSERT_EQUALS(c.totalNumberOfFrames(), 33075);
} }
void test_no_overflow() {
// The constructor should not overflow and give incoherent values
const Audio::Timestamp a = Audio::Timestamp(0, UINT_MAX, 1000);
int secs = UINT_MAX / 1000;
int frames = UINT_MAX % 1000;
TS_ASSERT_EQUALS(a.secs(), secs);
TS_ASSERT_EQUALS(a.numberOfFrames(), frames);
}
}; };