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