From d37f4061c94f49cdfaeda474f8209b2b3db9b6b3 Mon Sep 17 00:00:00 2001 From: Piyush Aggarwal Date: Sun, 20 Jun 2021 22:22:08 +0530 Subject: [PATCH] systemvolumeplugin_win: fix a desktop memory leak that occurs when sink list is open on Android app --- .../systemvolume/systemvolumeplugin-win.cpp | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/plugins/systemvolume/systemvolumeplugin-win.cpp b/plugins/systemvolume/systemvolumeplugin-win.cpp index e2708e387..e65d44d34 100644 --- a/plugins/systemvolume/systemvolumeplugin-win.cpp +++ b/plugins/systemvolume/systemvolumeplugin-win.cpp @@ -413,17 +413,54 @@ bool SystemvolumePlugin::receivePacket(const NetworkPacket &np) if (sinkList.contains(name)) { + // unregister ControlChangeNotify before doing any changes to a sink + HRESULT unregisterSuccess = E_POINTER; + auto sinkListIterator = this->sinkList.find(name); + auto &sink = sinkListIterator.value(); + if (!(sinkListIterator == this->sinkList.end())) { + unregisterSuccess = sink.first->UnregisterControlChangeNotify(sink.second); + } + if (np.has(QStringLiteral("volume"))) { - sinkList[name].first->SetMasterVolumeLevelScalar((float)np.get(QStringLiteral("volume")) / 100, NULL); + float currentVolume; + sink.first->GetMasterVolumeLevelScalar(¤tVolume); + float requestedVolume = (float)np.get(QStringLiteral("volume"), 100) / 100; + if (currentVolume != requestedVolume) { + sinkList[name].first->SetMasterVolumeLevelScalar(requestedVolume, NULL); + } } + if (np.has(QStringLiteral("muted"))) { - sinkList[name].first->SetMute(np.get(QStringLiteral("muted")), NULL); + BOOL currentMuteStatus; + sink.first->GetMute(¤tMuteStatus); + BOOL requestedMuteStatus = np.get(QStringLiteral("muted"), false); + if(currentMuteStatus != requestedMuteStatus) { + sinkList[name].first->SetMute(requestedMuteStatus, NULL); + } } + if (np.has(QStringLiteral("enabled"))) { - setDefaultAudioPlaybackDevice(name, np.get(QStringLiteral("enabled"))); + // get the current default device ID + IMMDevice *defaultDevice = nullptr; + deviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &defaultDevice); + LPWSTR defaultId = NULL; + defaultDevice->GetId(&defaultId); + defaultDevice->Release(); + // get current sink's device ID + QString qDefaultId = QString::fromWCharArray(defaultId); + QString currentDeviceId = idToNameMap.key(name); + + if ((bool)qDefaultId.compare(currentDeviceId)) { + setDefaultAudioPlaybackDevice(name, np.get(QStringLiteral("enabled"))); + } + } + + // re-register ControlChangeNotify in case we unregistered it + if (unregisterSuccess == S_OK) { + sink.first->RegisterControlChangeNotify(sink.second); } } }