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:
committed by
Yoann Lopes
parent
58019c256e
commit
1816f89b6f
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user