summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp
index 5eb23d0..ead9995 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.cpp
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp
@@ -121,6 +121,11 @@ int QAudioInputPrivate::xrun_recovery(int err)
err = snd_pcm_prepare(handle);
if(err < 0)
reset = true;
+ else {
+ bytesAvailable = bytesReady();
+ if (bytesAvailable <= 0)
+ reset = true;
+ }
} else if((err == -ESTRPIPE)||(err == -EIO)) {
errorState = QAudio::IOError;
@@ -443,6 +448,7 @@ int QAudioInputPrivate::bytesReady() const
if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
return 0;
int frames = snd_pcm_avail_update(handle);
+ if (frames < 0) return frames;
if((int)frames > (int)buffer_frames)
frames = buffer_frames;
@@ -459,6 +465,20 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
bytesAvailable = bytesReady();
+ if (bytesAvailable < 0) {
+ // bytesAvailable as negative is error code, try to recover from it.
+ xrun_recovery(bytesAvailable);
+ bytesAvailable = bytesReady();
+ if (bytesAvailable < 0) {
+ // recovery failed must stop and set error.
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return 0;
+ }
+ }
+
int count=0, err = 0;
while(count < 5) {
int chunks = bytesAvailable/period_size;