ensure that injectors are cleaned up once inactive

This commit is contained in:
Stephen Birarda 2016-02-09 14:30:59 -08:00
parent 1773233af4
commit 7b2726f89b
3 changed files with 23 additions and 38 deletions

View file

@ -155,50 +155,33 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
}
void AudioMixerClientData::checkBuffersBeforeFrameSend() {
QReadLocker readLocker { &_streamsLock };
auto it = _audioStreams.cbegin();
while (it != _audioStreams.cend()) {
SharedStreamPointer stream = it->second;
if (stream->popFrames(1, true) > 0) {
stream->updateLastPopOutputLoudnessAndTrailingLoudness();
}
++it;
}
}
void AudioMixerClientData::removeDeadInjectedStreams() {
const int INJECTOR_CONSECUTIVE_NOT_MIXED_AFTER_STARTED_THRESHOLD = 100;
// we have this second threshold in case the injected audio is so short that the injected stream
// never even reaches its desired size, which means it will never start.
const int INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD = 1000;
QWriteLocker writeLocker { &_streamsLock };
qDebug() << _audioStreams.size();
auto it = _audioStreams.begin();
while (it != _audioStreams.end()) {
PositionalAudioStream* audioStream = it->second.get();
SharedStreamPointer stream = it->second;
if (audioStream->getType() == PositionalAudioStream::Injector && audioStream->isStarved()) {
InjectedAudioStream* injectedStream = dynamic_cast<InjectedAudioStream*>(audioStream);
int notMixedThreshold = audioStream->hasStarted()
? INJECTOR_CONSECUTIVE_NOT_MIXED_AFTER_STARTED_THRESHOLD
: INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD;
static const int INJECTOR_INACTIVITY_USECS = 5 * USECS_PER_SECOND;
if (injectedStream->getConsecutiveNotMixedCount() >= notMixedThreshold) {
emit injectorStreamFinished(injectedStream->getStreamIdentifier());
it = _audioStreams.erase(it);
continue;
// if we don't have new data for an injected stream in the last INJECTOR_INACTIVITY_MSECS then
// we remove the injector from our streams
if (stream->getType() == PositionalAudioStream::Injector
&& stream->usecsSinceLastPacket() > INJECTOR_INACTIVITY_USECS) {
// this is an inactive injector, pull it from our streams
// first emit that it is finished so that the HRTF objects for this source can be cleaned up
emit injectorStreamFinished(it->second->getStreamIdentifier());
// erase the stream to drop our ref to the shared pointer and remove it
it = _audioStreams.erase(it);
} else {
if (stream->popFrames(1, true) > 0) {
stream->updateLastPopOutputLoudnessAndTrailingLoudness();
}
}
++it;
++it;
}
}
}

View file

@ -45,7 +45,7 @@ public:
// removes an AudioHRTF object for a given stream
void removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID = QUuid());
int parseData(ReceivedMessage& me ssage);
int parseData(ReceivedMessage& message);
void checkBuffersBeforeFrameSend();

View file

@ -116,6 +116,8 @@ public:
bool lastPopSucceeded() const { return _lastPopSucceeded; };
const AudioRingBuffer::ConstIterator& getLastPopOutput() const { return _lastPopOutput; }
quint64 usecsSinceLastPacket() { return usecTimestampNow() - _lastPacketReceivedTime; }
void setToStarved();
void setSettings(const Settings& settings);
@ -171,7 +173,7 @@ public:
float getWetLevel() const { return _wetLevel; }
void setReverb(float reverbTime, float wetLevel);
void clearReverb() { _hasReverb = false; }
public slots:
/// This function should be called every second for all the stats to function properly. If dynamic jitter buffers
/// is enabled, those stats are used to calculate _desiredJitterBufferFrames.