mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 20:16:16 +02:00
Merge pull request #6976 from birarda/injector-dos
fix for overflow on injector playNextFrameAt
This commit is contained in:
commit
c67f39a6c0
4 changed files with 9 additions and 11 deletions
|
@ -29,7 +29,10 @@ namespace AudioConstants {
|
||||||
const int NETWORK_FRAME_SAMPLES_PER_CHANNEL = NETWORK_FRAME_BYTES_PER_CHANNEL / sizeof(AudioSample);
|
const int NETWORK_FRAME_SAMPLES_PER_CHANNEL = NETWORK_FRAME_BYTES_PER_CHANNEL / sizeof(AudioSample);
|
||||||
const float NETWORK_FRAME_MSECS = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL
|
const float NETWORK_FRAME_MSECS = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL
|
||||||
/ (float)AudioConstants::SAMPLE_RATE) * 1000.0f;
|
/ (float)AudioConstants::SAMPLE_RATE) * 1000.0f;
|
||||||
|
|
||||||
|
// be careful with overflows when using this constant
|
||||||
const int NETWORK_FRAME_USECS = static_cast<int>(NETWORK_FRAME_MSECS * 1000.0f);
|
const int NETWORK_FRAME_USECS = static_cast<int>(NETWORK_FRAME_MSECS * 1000.0f);
|
||||||
|
|
||||||
const int MIN_SAMPLE_VALUE = std::numeric_limits<AudioSample>::min();
|
const int MIN_SAMPLE_VALUE = std::numeric_limits<AudioSample>::min();
|
||||||
const int MAX_SAMPLE_VALUE = std::numeric_limits<AudioSample>::max();
|
const int MAX_SAMPLE_VALUE = std::numeric_limits<AudioSample>::max();
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,14 +295,7 @@ int64_t AudioInjector::injectNextFrame() {
|
||||||
|
|
||||||
if (audioMixer) {
|
if (audioMixer) {
|
||||||
// send off this audio packet
|
// send off this audio packet
|
||||||
auto bytesWritten = nodeList->sendUnreliablePacket(*_currentPacket, *audioMixer);
|
nodeList->sendUnreliablePacket(*_currentPacket, *audioMixer);
|
||||||
if (bytesWritten < 0) {
|
|
||||||
auto currentTime = _frameTimer->nsecsElapsed() / 1000;
|
|
||||||
qDebug() << this << "error sending audio injector packet. NF:"
|
|
||||||
<< _nextFrame << "CT:" << currentTime
|
|
||||||
<< "CF:" << currentTime / AudioConstants::NETWORK_FRAME_USECS;
|
|
||||||
}
|
|
||||||
|
|
||||||
_outgoingSequenceNumber++;
|
_outgoingSequenceNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,14 +314,16 @@ int64_t AudioInjector::injectNextFrame() {
|
||||||
const int MAX_ALLOWED_FRAMES_TO_FALL_BEHIND = 7;
|
const int MAX_ALLOWED_FRAMES_TO_FALL_BEHIND = 7;
|
||||||
int64_t currentTime = _frameTimer->nsecsElapsed() / 1000;
|
int64_t currentTime = _frameTimer->nsecsElapsed() / 1000;
|
||||||
auto currentFrameBasedOnElapsedTime = currentTime / AudioConstants::NETWORK_FRAME_USECS;
|
auto currentFrameBasedOnElapsedTime = currentTime / AudioConstants::NETWORK_FRAME_USECS;
|
||||||
|
|
||||||
if (currentFrameBasedOnElapsedTime - _nextFrame > MAX_ALLOWED_FRAMES_TO_FALL_BEHIND) {
|
if (currentFrameBasedOnElapsedTime - _nextFrame > MAX_ALLOWED_FRAMES_TO_FALL_BEHIND) {
|
||||||
// If we are falling behind by more frames than our threshold, let's skip the frames ahead
|
// If we are falling behind by more frames than our threshold, let's skip the frames ahead
|
||||||
qDebug() << "AudioInjector::injectNextFrame() skipping ahead, fell behind by " << (currentFrameBasedOnElapsedTime - _nextFrame) << " frames";
|
qDebug() << this << "injectNextFrame() skipping ahead, fell behind by " << (currentFrameBasedOnElapsedTime - _nextFrame) << " frames";
|
||||||
_nextFrame = currentFrameBasedOnElapsedTime;
|
_nextFrame = currentFrameBasedOnElapsedTime;
|
||||||
_currentSendOffset = _nextFrame * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL * (_options.stereo ? 2 : 1) % _audioData.size();
|
_currentSendOffset = _nextFrame * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL * (_options.stereo ? 2 : 1) % _audioData.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t playNextFrameAt = ++_nextFrame * AudioConstants::NETWORK_FRAME_USECS;
|
int64_t playNextFrameAt = ++_nextFrame * AudioConstants::NETWORK_FRAME_USECS;
|
||||||
|
|
||||||
return std::max(INT64_C(0), playNextFrameAt - currentTime);
|
return std::max(INT64_C(0), playNextFrameAt - currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ private:
|
||||||
AbstractAudioInterface* _localAudioInterface { nullptr };
|
AbstractAudioInterface* _localAudioInterface { nullptr };
|
||||||
AudioInjectorLocalBuffer* _localBuffer { nullptr };
|
AudioInjectorLocalBuffer* _localBuffer { nullptr };
|
||||||
|
|
||||||
int _nextFrame { 0 };
|
int64_t _nextFrame { 0 };
|
||||||
std::unique_ptr<QElapsedTimer> _frameTimer { nullptr };
|
std::unique_ptr<QElapsedTimer> _frameTimer { nullptr };
|
||||||
quint16 _outgoingSequenceNumber { 0 };
|
quint16 _outgoingSequenceNumber { 0 };
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ void AudioInjectorManager::run() {
|
||||||
if (!injector.isNull()) {
|
if (!injector.isNull()) {
|
||||||
// this is an injector that's ready to go, have it send a frame now
|
// this is an injector that's ready to go, have it send a frame now
|
||||||
auto nextCallDelta = injector->injectNextFrame();
|
auto nextCallDelta = injector->injectNextFrame();
|
||||||
|
|
||||||
if (nextCallDelta >= 0 && !injector->isFinished()) {
|
if (nextCallDelta >= 0 && !injector->isFinished()) {
|
||||||
// re-enqueue the injector with the correct timing
|
// re-enqueue the injector with the correct timing
|
||||||
_injectors.emplace(usecTimestampNow() + nextCallDelta, injector);
|
_injectors.emplace(usecTimestampNow() + nextCallDelta, injector);
|
||||||
|
|
Loading…
Reference in a new issue