PulseAudio: fix playback for short streams in pull mode

If the provided stream's length is shorter than the stream prebuf
attribute, the stream will never play. We adjust the prebuf attribute
in this case.

Change-Id: Ia397ac967ad2fa357a7aba137fbb78de272440ed
Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
This commit is contained in:
Dyami Caliri
2016-02-22 08:37:00 -08:00
committed by Yoann Lopes
parent 58019c256e
commit 1816f89b6f

View File

@@ -133,6 +133,18 @@ static void outputStreamDrainComplete(pa_stream *stream, int success, void *user
#endif #endif
} }
static void streamAdjustPrebufferCallback(pa_stream *stream, int success, void *userdata)
{
Q_UNUSED(stream);
Q_UNUSED(success);
Q_UNUSED(userdata);
#ifdef DEBUG_PULSE
qDebug() << "Adjust prebuffer completed successfully: " << (bool)success;
#endif
}
QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device) QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device)
: m_device(device) : m_device(device)
, m_errorState(QAudio::NoError) , m_errorState(QAudio::NoError)
@@ -207,17 +219,19 @@ void QPulseAudioOutput::start(QIODevice *device)
// Handle change of mode // Handle change of mode
if (m_audioSource && !m_pullMode) { if (m_audioSource && !m_pullMode) {
delete m_audioSource; delete m_audioSource;
m_audioSource = 0;
} }
m_audioSource = 0;
close(); close();
if (!open())
return;
m_pullMode = true; m_pullMode = true;
m_audioSource = device; m_audioSource = device;
if (!open()) {
m_audioSource = 0;
return;
}
setState(QAudio::ActiveState); setState(QAudio::ActiveState);
} }
@@ -229,17 +243,18 @@ QIODevice *QPulseAudioOutput::start()
// Handle change of mode // Handle change of mode
if (m_audioSource && !m_pullMode) { if (m_audioSource && !m_pullMode) {
delete m_audioSource; delete m_audioSource;
m_audioSource = 0;
} }
m_audioSource = 0;
close(); close();
m_pullMode = false;
if (!open()) if (!open())
return Q_NULLPTR; return Q_NULLPTR;
m_audioSource = new PulseOutputPrivate(this); m_audioSource = new PulseOutputPrivate(this);
m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered); m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
m_pullMode = false;
setState(QAudio::IdleState); setState(QAudio::IdleState);
@@ -349,6 +364,17 @@ bool QPulseAudioOutput::open()
m_bufferSize = buffer->tlength; m_bufferSize = buffer->tlength;
m_maxBufferSize = buffer->maxlength; m_maxBufferSize = buffer->maxlength;
m_audioBuffer = new char[m_maxBufferSize]; m_audioBuffer = new char[m_maxBufferSize];
const qint64 streamSize = m_audioSource ? m_audioSource->size() : 0;
if (m_pullMode && streamSize > 0 && static_cast<qint64>(buffer->prebuf) > streamSize) {
pa_buffer_attr newBufferAttr;
newBufferAttr = *buffer;
newBufferAttr.prebuf = streamSize;
pa_operation *o = pa_stream_set_buffer_attr(m_stream, &newBufferAttr, streamAdjustPrebufferCallback, NULL);
if (o)
pa_operation_unref(o);
}
#ifdef DEBUG_PULSE #ifdef DEBUG_PULSE
qDebug() << "Buffering info:"; qDebug() << "Buffering info:";
qDebug() << "\tMax length: " << buffer->maxlength; qDebug() << "\tMax length: " << buffer->maxlength;