Workaround both std::round-s in video streaming.
This commit is contained in:
parent
f21d7821e7
commit
8f5830d520
|
@ -78,6 +78,31 @@ static_assert(kDisplaySkipped != kTimeUnknown);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] float64 SafeRound(float64 value) {
|
||||||
|
Expects(!std::isnan(value));
|
||||||
|
|
||||||
|
if (const auto result = std::round(value); !std::isnan(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const auto errors = std::fetestexcept(FE_ALL_EXCEPT);
|
||||||
|
LOG(("Streaming Error: Got NAN in std::round(%1), fe: %2."
|
||||||
|
).arg(value
|
||||||
|
).arg(errors));
|
||||||
|
if (const auto result = std::round(value); !std::isnan(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
if (const auto result = std::round(value); !std::isnan(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
CrashReports::SetAnnotation("FE-Error-Value", QString::number(value));
|
||||||
|
CrashReports::SetAnnotation("FE-Errors-Were", QString::number(errors));
|
||||||
|
CrashReports::SetAnnotation(
|
||||||
|
"FE-Errors-Now",
|
||||||
|
QString::number(std::fetestexcept(FE_ALL_EXCEPT)));
|
||||||
|
Unexpected("NAN after third std::round.");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class VideoTrackObject final {
|
class VideoTrackObject final {
|
||||||
|
@ -379,6 +404,7 @@ void VideoTrackObject::debugLog(const QString &entry) const {
|
||||||
_debugLog.push_back("stp.worldTime:"
|
_debugLog.push_back("stp.worldTime:"
|
||||||
+ QString::number(_syncTimePoint.worldTime)
|
+ QString::number(_syncTimePoint.worldTime)
|
||||||
+ ";stp.trackTime:" + QString::number(_syncTimePoint.trackTime)
|
+ ";stp.trackTime:" + QString::number(_syncTimePoint.trackTime)
|
||||||
|
+ ";fe:" + QString::number(std::fetestexcept(FE_ALL_EXCEPT))
|
||||||
+ ";" + entry);
|
+ ";" + entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,8 +852,6 @@ void VideoTrackObject::callReady() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TimePoint VideoTrackObject::trackTime() const {
|
TimePoint VideoTrackObject::trackTime() const {
|
||||||
const auto errors1 = std::fetestexcept(FE_ALL_EXCEPT);
|
|
||||||
|
|
||||||
debugAssertKnownTime(7, _syncTimePoint.trackTime);
|
debugAssertKnownTime(7, _syncTimePoint.trackTime);
|
||||||
|
|
||||||
auto result = TimePoint();
|
auto result = TimePoint();
|
||||||
|
@ -855,28 +879,7 @@ TimePoint VideoTrackObject::trackTime() const {
|
||||||
}
|
}
|
||||||
const auto adjust = (result.worldTime - _syncTimePoint.worldTime);
|
const auto adjust = (result.worldTime - _syncTimePoint.worldTime);
|
||||||
const auto adjustSpeed = adjust * _options.speed;
|
const auto adjustSpeed = adjust * _options.speed;
|
||||||
const auto errors2 = std::fetestexcept(FE_ALL_EXCEPT);
|
const auto roundAdjustSpeed = SafeRound(adjustSpeed);
|
||||||
auto roundAdjustSpeed = std::round(adjustSpeed);
|
|
||||||
if (std::isnan(roundAdjustSpeed)) {
|
|
||||||
TO_LOG(("NAN1,errors1:%1,errors2:%2,errors:%3").arg(errors1).arg(errors2).arg(std::fetestexcept(FE_ALL_EXCEPT)));
|
|
||||||
roundAdjustSpeed = std::round(adjustSpeed);
|
|
||||||
if (!std::isnan(roundAdjustSpeed)) {
|
|
||||||
TO_LOG(("WELL2,adjust:%1,rounded:%2").arg(adjustSpeed).arg(roundAdjustSpeed));
|
|
||||||
debugAssertKnownTime(-1, kTimeUnknown);
|
|
||||||
} else {
|
|
||||||
TO_LOG(("NAN2,adjust:%1").arg(adjustSpeed));
|
|
||||||
}
|
|
||||||
std::feclearexcept(FE_ALL_EXCEPT);
|
|
||||||
const auto errors3 = std::fetestexcept(FE_ALL_EXCEPT);
|
|
||||||
roundAdjustSpeed = std::round(adjustSpeed);
|
|
||||||
if (!std::isnan(roundAdjustSpeed)) {
|
|
||||||
TO_LOG(("WELL3,adjust:%1,rounded:%2").arg(adjustSpeed).arg(roundAdjustSpeed));
|
|
||||||
debugAssertKnownTime(-2, kTimeUnknown);
|
|
||||||
} else {
|
|
||||||
TO_LOG(("NAN3,adjust:%1,errors3:%2,errors:%3").arg(adjustSpeed).arg(errors3).arg(std::fetestexcept(FE_ALL_EXCEPT)));
|
|
||||||
}
|
|
||||||
TO_LOG(("qRound:%1,qRound64:%2").arg(qRound(adjustSpeed)).arg(qRound64(adjustSpeed)));
|
|
||||||
}
|
|
||||||
auto timeRoundAdjustSpeed = crl::time(roundAdjustSpeed);
|
auto timeRoundAdjustSpeed = crl::time(roundAdjustSpeed);
|
||||||
const auto fpuErrorHappened = [](crl::time value) {
|
const auto fpuErrorHappened = [](crl::time value) {
|
||||||
return uint64(value) == 0x8000'0000'0000'0000ULL
|
return uint64(value) == 0x8000'0000'0000'0000ULL
|
||||||
|
@ -1099,9 +1102,11 @@ auto VideoTrack::Shared::presentFrame(
|
||||||
return { kTimeUnknown, kTimeUnknown, addedWorldTimeDelay };
|
return { kTimeUnknown, kTimeUnknown, addedWorldTimeDelay };
|
||||||
}
|
}
|
||||||
const auto trackLeft = position - time.trackTime;
|
const auto trackLeft = position - time.trackTime;
|
||||||
|
const auto adjustedBySpeed = trackLeft / playbackSpeed;
|
||||||
|
const auto roundedAdjustedBySpeed = SafeRound(adjustedBySpeed);
|
||||||
frame->display = time.worldTime
|
frame->display = time.worldTime
|
||||||
+ addedWorldTimeDelay
|
+ addedWorldTimeDelay
|
||||||
+ crl::time(std::round(trackLeft / playbackSpeed));
|
+ crl::time(roundedAdjustedBySpeed);
|
||||||
|
|
||||||
// Release this frame to the main thread for rendering.
|
// Release this frame to the main thread for rendering.
|
||||||
_counter.store(
|
_counter.store(
|
||||||
|
|
Loading…
Reference in New Issue