Fix minor error in vfr.cpp: lines which end exactly on a frame's start time are not visible on that frame.

Originally committed to SVN as r4649.
This commit is contained in:
Thomas Goyne 2010-06-30 06:29:27 +00:00
parent be1ed9e672
commit 65d40e2408
1 changed files with 23 additions and 41 deletions

View File

@ -268,60 +268,42 @@ void FrameRate::SetVFR(std::vector<int> newTimes) {
/// @brief Gets frame number at time
/// @param ms
/// @param useceil
/// @param start
/// @return
int FrameRate::PFrameAtTime(int ms,bool useceil) const {
// Check if it's loaded
int FrameRate::PFrameAtTime(int ms,bool start) const {
if (!loaded) return -1;
// Get for constant frame rate
// Lines begin on the first frame whose start time is greater than or equal
// to the line's start time, and are last visible on the last frame whose
// start time is less than (note: not equal) the line's end time
if (FrameRateType == CFR || Frame.size() == 0 || ms < 0) {
double value = double(ms) * AverageFrameRate / 1000.0;
if (useceil) return (int)ceil(value);
else return (int)floor(value);
double value = double(ms) * AverageFrameRate / 1000.;
if (start) return (int)ceil(value);
else return (int)floor(value - .0001);
}
// Get for variable frame rate
else if (FrameRateType == VFR) {
// Get last
double trueLast;
//if (useceil) trueLast = ceil(last_time);
//else trueLast = floor(last_time);
trueLast = Frame[Frame.size()-1];
// Inside VFR range
if (ms <= trueLast) {
// Prepare binary search
size_t start = 0;
size_t end = last_frame;
size_t cur;
bool largerEqual;
if (ms <= Frame.back()) {
int frame = std::distance(Frame.begin(), std::lower_bound(Frame.begin(), Frame.end(), ms));
if (!start && frame > 0) {
// In the end case, frame is the first frame in which the line
// is no longer visible, so subtract 1
// Do binary search
while (start <= end) {
// Current frame being checked
cur = (start+end)>>1;
// Don't need to worry about the equal case here as lower_bound
// finds the entry >= ms
// Is it larger or equal to searched time?
largerEqual = Frame[cur] >= ms;
// If it is, is the previous smaller?
// If so, this is the frame we're looking for
if (largerEqual && (cur == 0 || Frame[cur-1] < ms)) {
if (useceil) return (int)cur;
return (int)(cur)-1;
// The frame > 0 check isn't actually correct -- the frame
// ending at time 0 should be -1, but parts of the program
// (like PTimeAtFrame below) assume that frames are positive
--frame;
}
// Not found, continue search
if (largerEqual) end = cur-1;
else start = cur+1;
return frame;
}
}
// After VFR range
else {
if (useceil) return (int)(last_frame + ceil((ms-last_time) * AverageFrameRate / 1000));
else return (int)(last_frame + floor((ms-last_time) * AverageFrameRate / 1000));
if (start) return (int)(last_frame + ceil((ms-last_time) * AverageFrameRate / 1000.));
else return (int)(last_frame + floor((ms-last_time - .0001) * AverageFrameRate / 1000.));
}
}
return -1;