summaryrefslogtreecommitdiffstats
path: root/pica-client/audiodevice.cpp
diff options
context:
space:
mode:
authorAnton <anton@picapica.im>2026-11-14 00:27:08 +0400
committerAnton <anton@picapica.im>2026-11-14 00:27:08 +0400
commit6d8ece9aa9a90937434ef2a4b6917a319a325d4e (patch)
tree632f92290d841861c6b1234fc56954c0358ebbaa /pica-client/audiodevice.cpp
parentc4ca50c617f2b158a4448b68dd7c7a289c1ff0d9 (diff)
downloadpica-pica-audio_video_calls.tar.gz
pica-pica-audio_video_calls.zip
pica-client: fix releasing call resourcesaudio_video_calls
Diffstat (limited to 'pica-client/audiodevice.cpp')
-rw-r--r--pica-client/audiodevice.cpp84
1 files changed, 68 insertions, 16 deletions
diff --git a/pica-client/audiodevice.cpp b/pica-client/audiodevice.cpp
index fdfd449..19ce04e 100644
--- a/pica-client/audiodevice.cpp
+++ b/pica-client/audiodevice.cpp
@@ -243,7 +243,8 @@ static AVSampleFormat chooseEncoderSampleFmt(const AVCodec *enc)
}
AudioDevice::AudioDevice(QObject *parent)
- : QObject(parent), m_sampleRate(48000), m_bitrate(kOpusBitrate), m_abort(0),
+ : QObject(parent), m_sampleRate(48000), m_bitrate(kOpusBitrate), m_reconfigure(0),
+ m_pendingSampleRate(48000),
m_clipCount(0), m_levelCount(0), m_levelPeak(0),
m_lastPlayedSeq(0), m_havePlayedSeq(false)
{
@@ -290,21 +291,46 @@ AudioDevice::~AudioDevice()
Close();
}
-void AudioDevice::configureCapture(QString deviceName, QString codec, int sampleRate, int bitrate)
+void AudioDevice::configureCapture(QString deviceName, QString codec, int sampleRate, int bitrate,
+ QByteArray caller_id, QByteArray callee_id)
{
+ m_caller_id = caller_id;
+ m_callee_id = callee_id;
m_deviceName = deviceName;
m_codec = codec;
m_sampleRate = sampleRate;
m_bitrate = bitrate > 0 ? bitrate : kOpusBitrate;
}
-void AudioDevice::configurePlayback(QString deviceName, QString codec, int sampleRate)
+void AudioDevice::configurePlayback(QString deviceName, QString codec, int sampleRate,
+ QByteArray caller_id, QByteArray callee_id)
{
+ m_caller_id = caller_id;
+ m_callee_id = callee_id;
m_deviceName = deviceName;
m_codec = codec;
m_sampleRate = sampleRate;
}
+void AudioDevice::openSession(QByteArray caller_id, QByteArray callee_id)
+{
+ m_openSession.open(caller_id, callee_id);
+}
+
+void AudioDevice::changePlayback(QString deviceName, QString codec, int sampleRate)
+{
+ {
+ QMutexLocker locker(&m_queueMutex);
+ m_pendingDeviceName = deviceName;
+ m_pendingCodec = codec;
+ m_pendingSampleRate = sampleRate;
+ m_reconfigure.storeRelaxed(1);
+ /* encoded with the parameters being replaced */
+ m_playQueue.clear();
+ }
+ m_queueCond.wakeAll();
+}
+
void AudioDevice::setEchoCanceller(EchoCancellerPtr ec)
{
m_echoCanceller = ec;
@@ -357,10 +383,11 @@ void AudioDevice::enqueuePacket(quint16 seq_num, QByteArray data)
void AudioDevice::Close()
{
- m_abort.storeRelaxed(1);
+ m_openSession.close();
{
QMutexLocker locker(&m_queueMutex);
+ m_reconfigure.storeRelaxed(0);
m_playQueue.clear();
/* the next call starts its own numbering */
m_havePlayedSeq = false;
@@ -375,7 +402,7 @@ void AudioDevice::waitForPreroll()
// the queue and starve the device buffer (heard as crackling/xruns).
QMutexLocker locker(&m_queueMutex);
- while (m_playQueue.size() < kPrerollDepth && !m_abort.loadRelaxed())
+ while (m_playQueue.size() < kPrerollDepth && !stopRequested())
m_queueCond.wait(&m_queueMutex, 100);
}
@@ -383,11 +410,14 @@ bool AudioDevice::nextPacket(QByteArray *out)
{
QMutexLocker locker(&m_queueMutex);
- while (m_playQueue.isEmpty() && !m_abort.loadRelaxed())
+ while (m_playQueue.isEmpty() && !stopRequested())
m_queueCond.wait(&m_queueMutex, 100);
+ if (stopRequested())
+ return false;
+
if (m_playQueue.isEmpty())
- return !m_abort.loadRelaxed();
+ return true;
PlaybackPacket p = m_playQueue.takeFirst();
@@ -400,7 +430,10 @@ bool AudioDevice::nextPacket(QByteArray *out)
void AudioDevice::Capture()
{
- m_abort.storeRelaxed(0);
+ /* closed before it got to start */
+ if (sessionClosed())
+ return;
+
resetCaptureLevel();
const QString driver = AudioDevice::PlatformDriverName(CAPTURE);
@@ -413,14 +446,33 @@ void AudioDevice::Capture()
void AudioDevice::Play()
{
- m_abort.storeRelaxed(0);
-
const QString driver = AudioDevice::PlatformDriverName(PLAYBACK);
- if (AudioDevice::IsPlatformDriver(driver))
- playNative(AudioDevice::PlatformApiName(driver));
- else
- playFFmpeg(driver);
+ // More than one pass only when changePlayback() interrupts the one that is
+ // running. Also covers being closed before getting to start.
+ while (!sessionClosed())
+ {
+ {
+ QMutexLocker locker(&m_queueMutex);
+
+ if (m_reconfigure.loadRelaxed())
+ {
+ m_deviceName = m_pendingDeviceName;
+ m_codec = m_pendingCodec;
+ m_sampleRate = m_pendingSampleRate;
+ m_reconfigure.storeRelaxed(0);
+ }
+ }
+
+ if (AudioDevice::IsPlatformDriver(driver))
+ playNative(AudioDevice::PlatformApiName(driver));
+ else
+ playFFmpeg(driver);
+
+ /* closed, or gave up on an error */
+ if (!m_reconfigure.loadRelaxed())
+ break;
+ }
}
void AudioDevice::captureFFmpeg(const QString &driver)
@@ -571,7 +623,7 @@ void AudioDevice::captureFFmpeg(const QString &driver)
bool loggedDecodeError = false;
bool loggedEncodeError = false;
- while (!m_abort.loadRelaxed())
+ while (!stopRequested())
{
ret = av_read_frame(ifmt_ctx, in_pkt);
if (ret < 0)
@@ -785,7 +837,7 @@ void AudioDevice::captureNative(const QString &api)
int64_t pts = 0;
bool loggedEncodeError = false;
- while (!m_abort.loadRelaxed())
+ while (!stopRequested())
{
int got = backend->read(scratch.data(), scratch.size(), 100);
if (got < 0)