opensl: fix incorrect injected buffer

Sometimes, buffer with incorrect capacity were injected into
the audio, causing the daemon to crash.
Before the stream's split, stopStream was flushing the buffers.
In this patch, stopStream will correctly re-init the buffers and
avoid to inject incorrect buffer into the audio.
Also, remove unused value in buf_manager.h and clean some warnings
for log.
Finally, modify engineServiceRing to avoid many push operations
and make it similar to engineServicePlay

Change-Id: I589cea814452d3dbf5172af6369e448dcd9d5c72
GitLab: #676
This commit is contained in:
Sébastien Blin
2021-12-15 11:34:21 -05:00
parent 41eab75d73
commit ea97002a08
3 changed files with 28 additions and 17 deletions

View File

@ -76,7 +76,7 @@ AudioPlayer::processSLCallback(SLAndroidSimpleBufferQueueItf bq)
while (playQueue_->front(&buf) && devShadowQueue_.push(buf)) {
if ((*bq)->Enqueue(bq, buf->buf_, buf->size_) != SL_RESULT_SUCCESS) {
devShadowQueue_.pop();
JAMI_ERR("enqueue failed %zu %zu %zu %zu",
JAMI_ERR("enqueue failed %zu %d %d %d",
buf->size_,
freeQueue_->size(),
playQueue_->size(),
@ -279,7 +279,7 @@ AudioPlayer::playAudioBuffers(unsigned count)
SLresult result = (*playBufferQueueItf_)->Enqueue(playBufferQueueItf_, buf->buf_, buf->size_);
if (result != SL_RESULT_SUCCESS) {
JAMI_ERR("%s Error @( %p, %d ), result = %d",
JAMI_ERR("%s Error @( %p, %zu ), result = %d",
__FUNCTION__,
(void*) buf->buf_,
buf->size_,

View File

@ -30,10 +30,6 @@
#include <limits>
#include <vector>
#ifndef CACHE_ALIGN
#define CACHE_ALIGN 64
#endif
/*
* ProducerConsumerQueue, borrowed from Ian NiLewis
*/
@ -160,7 +156,7 @@ public:
int writeptr = write_.load(std::memory_order_acquire);
int readptr = read_.load(std::memory_order_relaxed);
return (uint32_t)(writeptr - readptr);
return (uint32_t) (writeptr - readptr);
}
private:

View File

@ -116,6 +116,8 @@ void
OpenSLLayer::stopStream(AudioDeviceType stream)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!engineObject_)
return; // bufs_ should be initialized
JAMI_WARN("Stopping OpenSL audio layer for type %u", (unsigned) stream);
if (stream == AudioDeviceType::PLAYBACK) {
@ -124,13 +126,27 @@ OpenSLLayer::stopStream(AudioDeviceType stream)
player_->stop();
player_.reset();
}
freePlayBufQueue_.clear();
for (int i = 0; i < BUF_COUNT; i++)
freePlayBufQueue_.push(&bufs_[i]);
playBufQueue_.clear();
} else if (stream == AudioDeviceType::RINGTONE) {
if (ringtone_) {
ringtone_->stop();
ringtone_.reset();
}
// Flush buffer
freeRingBufQueue_.clear();
for (int i = BUF_COUNT; i < 2 * BUF_COUNT; i++)
freeRingBufQueue_.push(&bufs_[i]);
ringBufQueue_.clear();
} else if (stream == AudioDeviceType::CAPTURE) {
stopAudioCapture();
// Flush buffer
freeRecBufQueue_.clear();
for (int i = 2 * BUF_COUNT; i < 3 * BUF_COUNT; i++)
freeRecBufQueue_.push(&bufs_[i]);
recBufQueue_.clear();
}
if (not player_ and not ringtone_ and not recorder_)
@ -168,7 +184,10 @@ OpenSLLayer::initAudioEngine()
SLASSERT((*engineObject_)->GetInterface(engineObject_, SL_IID_ENGINE, &engineInterface_));
size_t bufSize = hardwareBuffSize_ * hardwareFormat_.getBytesPerFrame();
JAMI_DBG("OpenSL init: using buffer of %u bytes to support %s with %zu samples per channel", bufSize, hardwareFormat_.toString().c_str(), hardwareBuffSize_);
JAMI_DBG("OpenSL init: using buffer of %zu bytes to support %s with %zu samples per channel",
bufSize,
hardwareFormat_.toString().c_str(),
hardwareBuffSize_);
bufs_ = allocateSampleBufs(BUF_COUNT * 3, bufSize);
for (int i = 0; i < BUF_COUNT; i++)
freePlayBufQueue_.push(&bufs_[i]);
@ -224,17 +243,17 @@ OpenSLLayer::dbgEngineGetBufCount()
count_ringtone += freeRingBufQueue_.size();
count_ringtone += ringBufQueue_.size();
JAMI_ERR("Buf Disrtibutions: PlayerDev=%d, PlayQ=%d, FreePlayQ=%d",
JAMI_ERR("Buf Disrtibutions: PlayerDev=%zu, PlayQ=%u, FreePlayQ=%u",
player_->dbgGetDevBufCount(),
playBufQueue_.size(),
freePlayBufQueue_.size());
JAMI_ERR("Buf Disrtibutions: RingDev=%d, RingQ=%d, FreeRingQ=%d",
JAMI_ERR("Buf Disrtibutions: RingDev=%zu, RingQ=%u, FreeRingQ=%u",
ringtone_->dbgGetDevBufCount(),
ringBufQueue_.size(),
freeRingBufQueue_.size());
if (count_player != BUF_COUNT) {
JAMI_ERR("====Lost Bufs among the queue(supposed = %d, found = %d)",
JAMI_ERR("====Lost Bufs among the queue(supposed = %d, found = %u)",
BUF_COUNT,
count_player);
}
@ -260,8 +279,6 @@ OpenSLLayer::engineServicePlay()
dat->pointer()->nb_samples);
break;
}
// JAMI_ERR("std::copy_n %p -> %p %zu", dat->pointer()->data[0], buf->buf_,
// dat->pointer()->nb_samples);
std::copy_n((const AudioSample*) dat->pointer()->data[0],
dat->pointer()->nb_samples,
(AudioSample*) buf->buf_);
@ -281,7 +298,6 @@ OpenSLLayer::engineServiceRing()
{
sample_buf* buf;
while (ringtone_ and freeRingBufQueue_.front(&buf)) {
freeRingBufQueue_.pop();
if (auto dat = getToRing(hardwareFormat_, hardwareBuffSize_)) {
buf->size_ = dat->pointer()->nb_samples * dat->pointer()->channels
* sizeof(AudioSample);
@ -301,11 +317,10 @@ OpenSLLayer::engineServiceRing()
(AudioSample*) buf->buf_);
if (!ringBufQueue_.push(buf)) {
JAMI_WARN("playThread ringtone_ PLAY_KICKSTART_BUFFER_COUNT 1");
freeRingBufQueue_.push(buf);
break;
}
} else
freeRingBufQueue_.pop();
} else {
freeRingBufQueue_.push(buf);
break;
}
}