Try to do a non-failed double->crl::time cast.
A crash on some old CPUs show, that in video frame processing sometimes a cast from double to crl::time fails, writing to the resulting crl::time value INT64_MIN (0x8000000000000000). This is shown in crash logs, with lines like: ...,rounded:104,casted:-9223372036854775808,... where logs are written like: ... ).arg(std::round(adjust * _options.speed) ).arg(crl::time(std::round(adjust * _options.speed)) ... I don't know what to do and how to workaround this. Trying other casts.
This commit is contained in:
		
							parent
							
								
									3a92a181a1
								
							
						
					
					
						commit
						27d58ba07b
					
				
					 1 changed files with 94 additions and 7 deletions
				
			
		|  | @ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | |||
| 
 | ||||
| #include "zlib.h" | ||||
| 
 | ||||
| extern "C" { | ||||
| extern int __isa_available; | ||||
| } | ||||
| 
 | ||||
| #define TO_LOG(x) debugLog(QString x) | ||||
| 
 | ||||
| namespace Media { | ||||
|  | @ -199,7 +203,7 @@ VideoTrackObject::VideoTrackObject( | |||
| 	Expects(_error != nullptr); | ||||
| 
 | ||||
| 	TO_LOG(("created,speed:%1,mode:%2,position:%3,sync:%4," | ||||
| 		"loop:%5,wait:%6,duration:%7,initialized:%8" | ||||
| 		"loop:%5,wait:%6,duration:%7,initialized:%8,isa:%9" | ||||
| 		).arg(options.speed | ||||
| 		).arg(int(options.mode) | ||||
| 		).arg(options.position | ||||
|  | @ -207,7 +211,8 @@ VideoTrackObject::VideoTrackObject( | |||
| 		).arg(options.loop ? "true" : "false" | ||||
| 		).arg(options.waitForMarkAsShown ? "true" : "false" | ||||
| 		).arg(_stream.duration | ||||
| 		).arg(_shared->initialized() ? "true" : "false")); | ||||
| 		).arg(_shared->initialized() ? "true" : "false" | ||||
| 		).arg(__isa_available)); | ||||
| } | ||||
| 
 | ||||
| rpl::producer<> VideoTrackObject::checkNextFrame() const { | ||||
|  | @ -846,16 +851,98 @@ TimePoint VideoTrackObject::trackTime() const { | |||
| 		} | ||||
| 	} | ||||
| 	const auto adjust = (result.worldTime - _syncTimePoint.worldTime); | ||||
| 	result.trackTime = _syncTimePoint.trackTime | ||||
| 		+ crl::time(std::round(adjust * _options.speed)); | ||||
| 	const auto adjustSpeed = adjust * _options.speed; | ||||
| 	const auto roundAdjustSpeed = std::round(adjustSpeed); | ||||
| 	auto timeRoundAdjustSpeed = crl::time(roundAdjustSpeed); | ||||
| 	const auto fpuErrorHappened = [](crl::time value) { | ||||
| 		return uint64(value) == 0x8000'0000'0000'0000ULL | ||||
| 			|| uint64(value) == 0x8000'0000ULL | ||||
| 			|| uint64(value) == 0xFFFF'FFFF'FFFF'FFFFULL | ||||
| 			|| uint64(value) == 0xFFFF'FFFFULL; | ||||
| 	}; | ||||
| 	if (roundAdjustSpeed > -1000'000'000. | ||||
| 		&& roundAdjustSpeed < 1000'000'000. | ||||
| 		&& fpuErrorHappened(timeRoundAdjustSpeed)) { | ||||
| 		TO_LOG(("BAD1,round:%1").arg(roundAdjustSpeed)); | ||||
| 		timeRoundAdjustSpeed = crl::time(roundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(timeRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD2,round:%1,result:%2").arg(roundAdjustSpeed).arg(timeRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-1, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD2,round:%1").arg(roundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto floatRoundAdjustSpeed = float(roundAdjustSpeed); | ||||
| 		timeRoundAdjustSpeed = crl::time(floatRoundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(timeRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD3,round:%1,result:%2").arg(floatRoundAdjustSpeed).arg(timeRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-2, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD3,round:%1").arg(floatRoundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto intRoundAdjustSpeet = int(roundAdjustSpeed); | ||||
| 		timeRoundAdjustSpeed = crl::time(intRoundAdjustSpeet); | ||||
| 		if (!fpuErrorHappened(timeRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD4,int:%1,result:%2").arg(intRoundAdjustSpeet).arg(timeRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-3, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD4,int:%1").arg(intRoundAdjustSpeet)); | ||||
| 		} | ||||
| 		const auto intFloatRoundAdjustSpeed = int(floatRoundAdjustSpeed); | ||||
| 		timeRoundAdjustSpeed = crl::time(intFloatRoundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(timeRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD5,int:%1,result:%2").arg(intFloatRoundAdjustSpeed).arg(timeRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-4, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD5,int:%1").arg(intFloatRoundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto uint64RoundAdjustSpeed = uint64((roundAdjustSpeed >= 0.) | ||||
| 			? roundAdjustSpeed | ||||
| 			: -roundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(uint64RoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD6,round:%1,uint:%2").arg(roundAdjustSpeed).arg(uint64RoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-5, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD6,uint:%1").arg(uint64RoundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto uint64FloatRoundAdjustSpeed = uint64((floatRoundAdjustSpeed >= 0.) | ||||
| 			? floatRoundAdjustSpeed | ||||
| 			: -floatRoundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(uint64FloatRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD7,round:%1,uint:%2").arg(floatRoundAdjustSpeed).arg(uint64FloatRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-6, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD7,uint:%1").arg(uint64FloatRoundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto uint32RoundAdjustSpeed = uint32((roundAdjustSpeed >= 0.) | ||||
| 			? roundAdjustSpeed | ||||
| 			: -roundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(uint32RoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD8,round:%1,uint:%2").arg(roundAdjustSpeed).arg(uint32RoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-7, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD8,uint:%1").arg(uint32RoundAdjustSpeed)); | ||||
| 		} | ||||
| 		const auto uint32FloatRoundAdjustSpeed = uint32((floatRoundAdjustSpeed >= 0.) | ||||
| 			? floatRoundAdjustSpeed | ||||
| 			: -floatRoundAdjustSpeed); | ||||
| 		if (!fpuErrorHappened(uint32FloatRoundAdjustSpeed)) { | ||||
| 			TO_LOG(("GOOD9,round:%1,uint:%2").arg(floatRoundAdjustSpeed).arg(uint32FloatRoundAdjustSpeed)); | ||||
| 			debugAssertKnownTime(-8, kTimeUnknown); | ||||
| 		} else { | ||||
| 			TO_LOG(("BAD9,uint:%1").arg(uint32FloatRoundAdjustSpeed)); | ||||
| 		} | ||||
| 		debugAssertKnownTime(-9, kTimeUnknown); | ||||
| 	} | ||||
| 	const auto trackTime = _syncTimePoint.trackTime + timeRoundAdjustSpeed; | ||||
| 	TO_LOG(("track_time_adjusted,world:%1,adjust:%2,speed:%3,delta:%4,rounded:%5,casted:%6,final:%7" | ||||
| 		).arg(result.worldTime | ||||
| 		).arg(adjust | ||||
| 		).arg(_options.speed | ||||
| 		).arg(adjust * _options.speed | ||||
| 		).arg(std::round(adjust * _options.speed) | ||||
| 		).arg(crl::time(std::round(adjust * _options.speed)) | ||||
| 		).arg(adjustSpeed | ||||
| 		).arg(roundAdjustSpeed | ||||
| 		).arg(timeRoundAdjustSpeed | ||||
| 		).arg(result.trackTime)); | ||||
| 	result.trackTime = trackTime; | ||||
| 	debugAssertKnownTime(11, result.trackTime); | ||||
| 	return result; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 John Preston
						John Preston