From 84c517c073f19bdcde327c4914d3d7009fc732b4 Mon Sep 17 00:00:00 2001 From: wangyix Date: Tue, 5 Aug 2014 11:57:34 -0700 Subject: [PATCH] tweaked starve behavior of InboundAudioStream --- interface/src/Audio.cpp | 8 +-- libraries/audio/src/InboundAudioStream.cpp | 62 +++++++++------------- libraries/audio/src/InboundAudioStream.h | 6 +-- 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 1af76c3342..fe2ac4b2a0 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1747,18 +1747,12 @@ float Audio::getInputRingBufferMsecsAvailable() const { } qint64 Audio::AudioOutputIODevice::readData(char * data, qint64 maxSize) { - MixedProcessedAudioStream& receivedAUdioStream = _parent._receivedAudioStream; - const QAudioOutput* audioOutput = _parent._audioOutput; - if (audioOutput->bytesFree() == audioOutput->bufferSize()) { - receivedAUdioStream.setToStarved(); - } - int samplesRequested = maxSize / sizeof(int16_t); int samplesPopped; int bytesWritten; - if ((samplesPopped = receivedAUdioStream.popSamples(samplesRequested, false, false)) > 0) { + if ((samplesPopped = receivedAUdioStream.popSamples(samplesRequested, false)) > 0) { AudioRingBuffer::ConstIterator lastPopOutput = receivedAUdioStream.getLastPopOutput(); lastPopOutput.readSamples((int16_t*)data, samplesPopped); bytesWritten = samplesPopped * sizeof(int16_t); diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 4b76aaeeb5..0cd9be4a18 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -137,7 +137,7 @@ int InboundAudioStream::parseData(const QByteArray& packet) { return readBytes; } -int InboundAudioStream::popSamples(int maxSamples, bool allOrNothing, bool starveOnFail) { +int InboundAudioStream::popSamples(int maxSamples, bool allOrNothing, bool starveIfNoSamplesPopped) { int samplesPopped = 0; int samplesAvailable = _ringBuffer.samplesAvailable(); if (_isStarved) { @@ -146,30 +146,27 @@ int InboundAudioStream::popSamples(int maxSamples, bool allOrNothing, bool starv _lastPopSucceeded = false; } else { if (samplesAvailable >= maxSamples) { - // we have enough samples to pop, so we're good to mix + // we have enough samples to pop, so we're good to pop popSamplesNoCheck(maxSamples); samplesPopped = maxSamples; - + } else if (!allOrNothing && samplesAvailable > 0) { + // we don't have the requested number of samples, but we do have some + // samples available, so pop all those (except in all-or-nothing mode) + popSamplesNoCheck(samplesAvailable); + samplesPopped = samplesAvailable; } else { - // we don't have enough frames, so set this stream to starve - // if starveOnFail is true - if (starveOnFail) { - starved(); + // we can't pop any samples. set this stream to starved if needed + if (starveIfNoSamplesPopped) { + setToStarved(); _consecutiveNotMixedCount++; } - - if (!allOrNothing && samplesAvailable > 0) { - popSamplesNoCheck(samplesAvailable); - samplesPopped = samplesAvailable; - } else { - _lastPopSucceeded = false; - } + _lastPopSucceeded = false; } } return samplesPopped; } -int InboundAudioStream::popFrames(int maxFrames, bool allOrNothing, bool starveOnFail) { +int InboundAudioStream::popFrames(int maxFrames, bool allOrNothing, bool starveIfNoFramesPopped) { int framesPopped = 0; int framesAvailable = _ringBuffer.framesAvailable(); if (_isStarved) { @@ -178,24 +175,21 @@ int InboundAudioStream::popFrames(int maxFrames, bool allOrNothing, bool starveO _lastPopSucceeded = false; } else { if (framesAvailable >= maxFrames) { - // we have enough samples to pop, so we're good to mix + // we have enough frames to pop, so we're good to pop popSamplesNoCheck(maxFrames * _ringBuffer.getNumFrameSamples()); framesPopped = maxFrames; - + } else if (!allOrNothing && framesAvailable > 0) { + // we don't have the requested number of frames, but we do have some + // frames available, so pop all those (except in all-or-nothing mode) + popSamplesNoCheck(framesAvailable * _ringBuffer.getNumFrameSamples()); + framesPopped = framesAvailable; } else { - // we don't have enough frames, so set this stream to starve - // if starveOnFail is true - if (starveOnFail) { - starved(); - _consecutiveNotMixedCount++; - } - - if (!allOrNothing && framesAvailable > 0) { - popSamplesNoCheck(framesAvailable * _ringBuffer.getNumFrameSamples()); - framesPopped = framesAvailable; - } else { - _lastPopSucceeded = false; + // we can't pop any frames. set this stream to starved if needed + if (starveIfNoFramesPopped) { + setToStarved(); + _consecutiveNotMixedCount = 1; } + _lastPopSucceeded = false; } } return framesPopped; @@ -220,16 +214,12 @@ void InboundAudioStream::framesAvailableChanged() { } void InboundAudioStream::setToStarved() { - starved(); - if (_ringBuffer.framesAvailable() >= _desiredJitterBufferFrames) { - _isStarved = false; - } -} - -void InboundAudioStream::starved() { _isStarved = true; _consecutiveNotMixedCount = 0; _starveCount++; + // if we have more than the desired frames when setToStarved() is called, then we'll immediately + // be considered refilled. in that case, there's no need to set _isStarved to true. + _isStarved = (_ringBuffer.framesAvailable() < _desiredJitterBufferFrames); } void InboundAudioStream::setDynamicJitterBuffers(bool dynamicJitterBuffers) { diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 590421e50f..b65d5c5de0 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -63,8 +63,8 @@ public: virtual int parseData(const QByteArray& packet); - int popFrames(int maxFrames, bool allOrNothing, bool starveOnFail = true); - int popSamples(int maxSamples, bool allOrNothing, bool starveOnFail = true); + int popFrames(int maxFrames, bool allOrNothing, bool starveIfNoFramesPopped = true); + int popSamples(int maxSamples, bool allOrNothing, bool starveIfNoSamplesPopped = true); bool lastPopSucceeded() const { return _lastPopSucceeded; }; const AudioRingBuffer::ConstIterator& getLastPopOutput() const { return _lastPopOutput; } @@ -111,8 +111,6 @@ public: int getPacketsReceived() const { return _incomingSequenceNumberStats.getReceived(); } private: - void starved(); - void frameReceivedUpdateTimingStats(); int clampDesiredJitterBufferFramesValue(int desired) const;