tweaked starve behavior of InboundAudioStream

This commit is contained in:
wangyix 2014-08-05 11:57:34 -07:00
parent 77dad6fe65
commit 84c517c073
3 changed files with 29 additions and 47 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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;