mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Support additional audio ssrc.
This commit is contained in:
parent
5e2cdde2c8
commit
f17fc0b670
7 changed files with 135 additions and 50 deletions
|
@ -233,10 +233,11 @@ GroupCall::VideoTrack::VideoTrack(
|
|||
struct VideoParams {
|
||||
std::string endpointId;
|
||||
std::vector<tgcalls::MediaSsrcGroup> ssrcGroups;
|
||||
uint32 additionalSsrc = 0;
|
||||
bool paused = false;
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return endpointId.empty() || ssrcGroups.empty();
|
||||
return !additionalSsrc && (endpointId.empty() || ssrcGroups.empty());
|
||||
}
|
||||
[[nodiscard]] explicit operator bool() const {
|
||||
return !empty();
|
||||
|
@ -255,7 +256,8 @@ struct ParticipantVideoParams {
|
|||
return !was;
|
||||
}
|
||||
return now->match([&](const MTPDgroupCallParticipantVideo &data) {
|
||||
if (data.is_paused() != was.paused) {
|
||||
if (data.is_paused() != was.paused
|
||||
|| data.vaudio_source().value_or_empty() != was.additionalSsrc) {
|
||||
return false;
|
||||
}
|
||||
if (gsl::make_span(data.vendpoint().v)
|
||||
|
@ -304,6 +306,7 @@ struct ParticipantVideoParams {
|
|||
params->match([&](const MTPDgroupCallParticipantVideo &data) {
|
||||
result.paused = data.is_paused();
|
||||
result.endpointId = data.vendpoint().v.toStdString();
|
||||
result.additionalSsrc = data.vaudio_source().value_or_empty();
|
||||
const auto &list = data.vsource_groups().v;
|
||||
result.ssrcGroups.reserve(list.size());
|
||||
for (const auto &group : list) {
|
||||
|
@ -343,6 +346,11 @@ bool IsScreenPaused(const std::shared_ptr<ParticipantVideoParams> ¶ms) {
|
|||
return params && params->screen.paused;
|
||||
}
|
||||
|
||||
uint32 GetAdditionalAudioSsrc(
|
||||
const std::shared_ptr<ParticipantVideoParams> ¶ms) {
|
||||
return params ? params->screen.additionalSsrc : 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<ParticipantVideoParams> ParseVideoParams(
|
||||
const tl::conditional<MTPGroupCallParticipantVideo> &camera,
|
||||
const tl::conditional<MTPGroupCallParticipantVideo> &screen,
|
||||
|
@ -2763,7 +2771,7 @@ void GroupCall::checkJoined() {
|
|||
MTP_vector<MTPint>(std::move(sources))
|
||||
)).done([=](const MTPVector<MTPint> &result) {
|
||||
if (!ranges::contains(result.v, MTP_int(_joinState.ssrc))) {
|
||||
LOG(("Call Info: Rejoin after no _mySsrc in checkGroupCall."));
|
||||
LOG(("Call Info: Rejoin after no my ssrc in checkGroupCall."));
|
||||
_joinState.nextActionPending = true;
|
||||
checkNextJoinAction();
|
||||
} else {
|
||||
|
|
|
@ -169,6 +169,8 @@ struct ParticipantVideoParams;
|
|||
const std::shared_ptr<ParticipantVideoParams> ¶ms);
|
||||
[[nodiscard]] bool IsScreenPaused(
|
||||
const std::shared_ptr<ParticipantVideoParams> ¶ms);
|
||||
[[nodiscard]] uint32 GetAdditionalAudioSsrc(
|
||||
const std::shared_ptr<ParticipantVideoParams> ¶ms);
|
||||
|
||||
class GroupCall final : public base::has_weak_ptr {
|
||||
public:
|
||||
|
|
|
@ -224,6 +224,7 @@ private:
|
|||
const Data::GroupCallParticipant &now);
|
||||
void updateRow(
|
||||
not_null<Row*> row,
|
||||
const std::optional<Data::GroupCallParticipant> &was,
|
||||
const Data::GroupCallParticipant *participant);
|
||||
void removeRow(not_null<Row*> row);
|
||||
void updateRowLevel(not_null<Row*> row, float level);
|
||||
|
@ -496,7 +497,7 @@ void Members::Controller::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
if (!update.now) {
|
||||
if (const auto row = findRow(participantPeer)) {
|
||||
if (isMe(participantPeer)) {
|
||||
updateRow(row, nullptr);
|
||||
updateRow(row, update.was, nullptr);
|
||||
} else {
|
||||
removeRow(row);
|
||||
delegate()->peerListRefreshRows();
|
||||
|
@ -596,7 +597,7 @@ void Members::Controller::updateRow(
|
|||
if (row->state() == Row::State::Invited) {
|
||||
reorderIfInvitedBefore = row->absoluteIndex();
|
||||
}
|
||||
updateRow(row, &now);
|
||||
updateRow(row, was, &now);
|
||||
if ((now.speaking && (!was || !was->speaking))
|
||||
|| (now.raisedHandRating != (was ? was->raisedHandRating : 0))
|
||||
|| (!now.canSelfUnmute && was && was->canSelfUnmute)) {
|
||||
|
@ -774,17 +775,25 @@ void Members::Controller::checkRowPosition(not_null<Row*> row) {
|
|||
|
||||
void Members::Controller::updateRow(
|
||||
not_null<Row*> row,
|
||||
const std::optional<Data::GroupCallParticipant> &was,
|
||||
const Data::GroupCallParticipant *participant) {
|
||||
const auto wasSounding = row->sounding();
|
||||
const auto wasSsrc = row->ssrc();
|
||||
const auto wasSsrc = was ? was->ssrc : 0;
|
||||
const auto wasAdditionalSsrc = was
|
||||
? GetAdditionalAudioSsrc(was->videoParams)
|
||||
: 0;
|
||||
row->setSkipLevelUpdate(_skipRowLevelUpdate);
|
||||
row->updateState(participant);
|
||||
const auto nowSounding = row->sounding();
|
||||
const auto nowSsrc = row->ssrc();
|
||||
const auto nowSsrc = participant ? participant->ssrc : 0;
|
||||
const auto nowAdditionalSsrc = participant
|
||||
? GetAdditionalAudioSsrc(participant->videoParams)
|
||||
: 0;
|
||||
|
||||
const auto wasNoSounding = _soundingRowBySsrc.empty();
|
||||
|
||||
if (wasSsrc == nowSsrc) {
|
||||
if (nowSounding != wasSounding) {
|
||||
if (nowSsrc && nowSounding != wasSounding) {
|
||||
if (nowSounding) {
|
||||
_soundingRowBySsrc.emplace(nowSsrc, row);
|
||||
} else {
|
||||
|
@ -793,11 +802,25 @@ void Members::Controller::updateRow(
|
|||
}
|
||||
} else {
|
||||
_soundingRowBySsrc.remove(wasSsrc);
|
||||
if (nowSounding) {
|
||||
Assert(nowSsrc != 0);
|
||||
if (nowSounding && nowSsrc) {
|
||||
_soundingRowBySsrc.emplace(nowSsrc, row);
|
||||
}
|
||||
}
|
||||
if (wasAdditionalSsrc == nowAdditionalSsrc) {
|
||||
if (nowAdditionalSsrc && nowSounding != wasSounding) {
|
||||
if (nowSounding) {
|
||||
_soundingRowBySsrc.emplace(nowAdditionalSsrc, row);
|
||||
} else {
|
||||
_soundingRowBySsrc.remove(nowAdditionalSsrc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_soundingRowBySsrc.remove(wasAdditionalSsrc);
|
||||
if (nowSounding && nowAdditionalSsrc) {
|
||||
_soundingRowBySsrc.emplace(nowAdditionalSsrc, row);
|
||||
}
|
||||
}
|
||||
|
||||
const auto nowNoSounding = _soundingRowBySsrc.empty();
|
||||
if (wasNoSounding && !nowNoSounding) {
|
||||
_soundingAnimation.start();
|
||||
|
@ -809,7 +832,14 @@ void Members::Controller::updateRow(
|
|||
}
|
||||
|
||||
void Members::Controller::removeRow(not_null<Row*> row) {
|
||||
_soundingRowBySsrc.remove(row->ssrc());
|
||||
// There may be 0, 1 or 2 entries for a row.
|
||||
for (auto i = begin(_soundingRowBySsrc); i != end(_soundingRowBySsrc);) {
|
||||
if (i->second == row) {
|
||||
i = _soundingRowBySsrc.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
delegate()->peerListRemoveRow(row);
|
||||
}
|
||||
|
||||
|
@ -1343,11 +1373,17 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (real->ssrc() != 0
|
||||
&& (!isMe(participantPeer) || _peer->canManageGroupCall())) {
|
||||
addMuteActionsToContextMenu(result, participantPeer, admin, real);
|
||||
if (participant
|
||||
&& (!isMe(participantPeer) || _peer->canManageGroupCall())
|
||||
&& (participant->ssrc != 0
|
||||
|| GetAdditionalAudioSsrc(participant->videoParams) != 0)) {
|
||||
addMuteActionsToContextMenu(
|
||||
result,
|
||||
participantPeer,
|
||||
admin,
|
||||
static_cast<Row*>(row.get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (isMe(participantPeer)) {
|
||||
|
@ -1545,14 +1581,14 @@ void Members::Controller::addMuteActionsToContextMenu(
|
|||
|
||||
std::unique_ptr<Row> Members::Controller::createRowForMe() {
|
||||
auto result = std::make_unique<Row>(this, _call->joinAs());
|
||||
updateRow(result.get(), nullptr);
|
||||
updateRow(result.get(), std::nullopt, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Row> Members::Controller::createRow(
|
||||
const Data::GroupCallParticipant &participant) {
|
||||
auto result = std::make_unique<Row>(this, participant.peer);
|
||||
updateRow(result.get(), &participant);
|
||||
updateRow(result.get(), std::nullopt, &participant);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1562,7 +1598,7 @@ std::unique_ptr<Row> Members::Controller::createInvitedRow(
|
|||
return nullptr;
|
||||
}
|
||||
auto result = std::make_unique<Row>(this, participantPeer);
|
||||
updateRow(result.get(), nullptr);
|
||||
updateRow(result.get(), std::nullopt, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,6 @@ void MembersRow::setSkipLevelUpdate(bool value) {
|
|||
|
||||
void MembersRow::updateState(
|
||||
const Data::GroupCallParticipant *participant) {
|
||||
setSsrc(participant ? participant->ssrc : 0);
|
||||
setVolume(participant
|
||||
? participant->volume
|
||||
: Group::kDefaultVolume);
|
||||
|
@ -155,10 +154,16 @@ void MembersRow::updateState(
|
|||
_mutedByMe = false;
|
||||
_raisedHandRating = 0;
|
||||
} else if (!participant->muted
|
||||
|| (participant->sounding && participant->ssrc != 0)) {
|
||||
|| (participant->sounding && participant->ssrc != 0)
|
||||
|| (participant->additionalSounding
|
||||
&& GetAdditionalAudioSsrc(participant->videoParams) != 0)) {
|
||||
setState(State::Active);
|
||||
setSounding(participant->sounding && participant->ssrc != 0);
|
||||
setSpeaking(participant->speaking && participant->ssrc != 0);
|
||||
setSounding((participant->sounding && participant->ssrc != 0)
|
||||
|| (participant->additionalSounding
|
||||
&& GetAdditionalAudioSsrc(participant->videoParams) != 0));
|
||||
setSpeaking((participant->speaking && participant->ssrc != 0)
|
||||
|| (participant->additionalSpeaking
|
||||
&& GetAdditionalAudioSsrc(participant->videoParams) != 0));
|
||||
_mutedByMe = participant->mutedByMe;
|
||||
_raisedHandRating = 0;
|
||||
} else if (participant->canSelfUnmute) {
|
||||
|
@ -283,10 +288,6 @@ void MembersRow::setState(State state) {
|
|||
}
|
||||
}
|
||||
|
||||
void MembersRow::setSsrc(uint32 ssrc) {
|
||||
_ssrc = ssrc;
|
||||
}
|
||||
|
||||
void MembersRow::setVolume(int volume) {
|
||||
_volume = volume;
|
||||
if (_statusIcon) {
|
||||
|
|
|
@ -85,9 +85,6 @@ public:
|
|||
[[nodiscard]] State state() const {
|
||||
return _state;
|
||||
}
|
||||
[[nodiscard]] uint32 ssrc() const {
|
||||
return _ssrc;
|
||||
}
|
||||
[[nodiscard]] bool sounding() const {
|
||||
return _sounding;
|
||||
}
|
||||
|
@ -179,7 +176,6 @@ private:
|
|||
void setSounding(bool sounding);
|
||||
void setSpeaking(bool speaking);
|
||||
void setState(State state);
|
||||
void setSsrc(uint32 ssrc);
|
||||
void setVolume(int volume);
|
||||
|
||||
void ensureUserpicCache(
|
||||
|
@ -212,7 +208,6 @@ private:
|
|||
QString _aboutText;
|
||||
crl::time _speakingLastTime = 0;
|
||||
uint64 _raisedHandRating = 0;
|
||||
uint32 _ssrc = 0;
|
||||
int _volume = Group::kDefaultVolume;
|
||||
bool _sounding : 1;
|
||||
bool _speaking : 1;
|
||||
|
|
|
@ -543,6 +543,8 @@ void GroupCall::applyParticipantsSlice(
|
|||
.was = *i,
|
||||
};
|
||||
_participantPeerByAudioSsrc.erase(i->ssrc);
|
||||
_participantPeerByAudioSsrc.erase(
|
||||
GetAdditionalAudioSsrc(i->videoParams));
|
||||
_speakingByActiveFinishes.remove(participantPeer);
|
||||
_participants.erase(i);
|
||||
if (sliceSource != ApplySliceSource::FullReloaded) {
|
||||
|
@ -599,18 +601,33 @@ void GroupCall::applyParticipantsSlice(
|
|||
.raisedHandRating = raisedHandRating,
|
||||
.ssrc = uint32(data.vsource().v),
|
||||
.volume = volume,
|
||||
.applyVolumeFromMin = applyVolumeFromMin,
|
||||
.speaking = canSelfUnmute && (was ? was->speaking : false),
|
||||
.sounding = canSelfUnmute && was && was->sounding,
|
||||
.speaking = canSelfUnmute && was && was->speaking,
|
||||
.additionalSounding = (canSelfUnmute
|
||||
&& was
|
||||
&& was->additionalSounding),
|
||||
.additionalSpeaking = (canSelfUnmute
|
||||
&& was
|
||||
&& was->additionalSpeaking),
|
||||
.muted = data.is_muted(),
|
||||
.mutedByMe = mutedByMe,
|
||||
.canSelfUnmute = canSelfUnmute,
|
||||
.onlyMinLoaded = onlyMinLoaded,
|
||||
.videoJoined = videoJoined,
|
||||
.applyVolumeFromMin = applyVolumeFromMin,
|
||||
};
|
||||
if (i == end(_participants)) {
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
value.ssrc,
|
||||
participantPeer);
|
||||
if (value.ssrc) {
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
value.ssrc,
|
||||
participantPeer);
|
||||
}
|
||||
if (const auto additional = GetAdditionalAudioSsrc(
|
||||
value.videoParams)) {
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
additional,
|
||||
participantPeer);
|
||||
}
|
||||
_participants.push_back(value);
|
||||
if (const auto user = participantPeer->asUser()) {
|
||||
_peer->owner().unregisterInvitedToCallUser(_id, user);
|
||||
|
@ -618,9 +635,22 @@ void GroupCall::applyParticipantsSlice(
|
|||
} else {
|
||||
if (i->ssrc != value.ssrc) {
|
||||
_participantPeerByAudioSsrc.erase(i->ssrc);
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
value.ssrc,
|
||||
participantPeer);
|
||||
if (value.ssrc) {
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
value.ssrc,
|
||||
participantPeer);
|
||||
}
|
||||
}
|
||||
if (GetAdditionalAudioSsrc(i->videoParams)
|
||||
!= GetAdditionalAudioSsrc(value.videoParams)) {
|
||||
_participantPeerByAudioSsrc.erase(
|
||||
GetAdditionalAudioSsrc(i->videoParams));
|
||||
if (const auto additional = GetAdditionalAudioSsrc(
|
||||
value.videoParams)) {
|
||||
_participantPeerByAudioSsrc.emplace(
|
||||
additional,
|
||||
participantPeer);
|
||||
}
|
||||
}
|
||||
*i = value;
|
||||
}
|
||||
|
@ -662,11 +692,22 @@ void GroupCall::applyLastSpoke(
|
|||
if (speaking) {
|
||||
_participantSpeaking.fire({ participant });
|
||||
}
|
||||
if (participant->sounding != sounding
|
||||
|| participant->speaking != speaking) {
|
||||
const auto useAdditional = (ssrc != participant->ssrc);
|
||||
const auto nowSounding = useAdditional
|
||||
? participant->additionalSounding
|
||||
: participant->sounding;
|
||||
const auto nowSpeaking = useAdditional
|
||||
? participant->additionalSpeaking
|
||||
: participant->speaking;
|
||||
if (nowSounding != sounding || nowSpeaking != speaking) {
|
||||
const auto was = *participant;
|
||||
participant->sounding = sounding;
|
||||
participant->speaking = speaking;
|
||||
if (useAdditional) {
|
||||
participant->additionalSounding = sounding;
|
||||
participant->additionalSpeaking = speaking;
|
||||
} else {
|
||||
participant->sounding = sounding;
|
||||
participant->speaking = speaking;
|
||||
}
|
||||
_participantUpdates.fire({
|
||||
.was = was,
|
||||
.now = *participant,
|
||||
|
|
|
@ -32,14 +32,16 @@ struct GroupCallParticipant {
|
|||
uint64 raisedHandRating = 0;
|
||||
uint32 ssrc = 0;
|
||||
int volume = 0;
|
||||
bool applyVolumeFromMin = true;
|
||||
bool sounding = false;
|
||||
bool speaking = false;
|
||||
bool muted = false;
|
||||
bool mutedByMe = false;
|
||||
bool canSelfUnmute = false;
|
||||
bool onlyMinLoaded = false;
|
||||
bool sounding : 1;
|
||||
bool speaking : 1;
|
||||
bool additionalSounding : 1;
|
||||
bool additionalSpeaking : 1;
|
||||
bool muted : 1;
|
||||
bool mutedByMe : 1;
|
||||
bool canSelfUnmute : 1;
|
||||
bool onlyMinLoaded : 1;
|
||||
bool videoJoined = false;
|
||||
bool applyVolumeFromMin = true;
|
||||
|
||||
[[nodiscard]] const std::string &cameraEndpoint() const;
|
||||
[[nodiscard]] const std::string &screenEndpoint() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue