Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2021-03-24 02:09:47 +05:00
commit e2e63a4ddf
15 changed files with 184 additions and 125 deletions

View File

@ -283,6 +283,9 @@ public final class FFMpegMediaFrameSource: NSObject, MediaFrameSource {
let _ = currentSemaphore.swap(nil)
subscriber.putError(.generic)
}
} else {
let _ = currentSemaphore.swap(nil)
subscriber.putError(.generic)
}
}
})

View File

@ -1,10 +1,30 @@
#if !os(macOS)
import UIKit
#else
import AppKit
#endif
import CoreMedia
import Accelerate
import FFMpegBinding
private let bufferCount = 32
#if os(macOS)
private let deviceColorSpace: CGColorSpace = {
if #available(OSX 10.11.2, *) {
if let colorSpace = CGColorSpace(name: CGColorSpace.displayP3) {
return colorSpace
} else {
return CGColorSpaceCreateDeviceRGB()
}
} else {
return CGColorSpaceCreateDeviceRGB()
}
}()
#else
private let deviceColorSpace: CGColorSpace = {
if #available(iOSApplicationExtension 9.3, iOS 9.3, *) {
if let colorSpace = CGColorSpace(name: CGColorSpace.displayP3) {
@ -16,7 +36,7 @@ private let deviceColorSpace: CGColorSpace = {
return CGColorSpaceCreateDeviceRGB()
}
}()
#endif
public final class FFMpegMediaVideoFrameDecoder: MediaTrackFrameDecoder {
public enum ReceiveResult {
case error

View File

@ -73,8 +73,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
case optimizeDatabase(PresentationTheme)
case photoPreview(PresentationTheme, Bool)
case knockoutWallpaper(PresentationTheme, Bool)
case demoAudioStream(Bool)
case snapPinListToTop(Bool)
case demoVideoChats(Bool)
case playerEmbedding(Bool)
case playlistPlayback(Bool)
case voiceConference
@ -94,7 +93,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return DebugControllerSection.logging.rawValue
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
return DebugControllerSection.experiments.rawValue
case .clearTips, .reimport, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .demoAudioStream, .snapPinListToTop, .playerEmbedding, .playlistPlayback, .voiceConference:
case .clearTips, .reimport, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .demoVideoChats, .playerEmbedding, .playlistPlayback, .voiceConference:
return DebugControllerSection.experiments.rawValue
case .preferredVideoCodec:
return DebugControllerSection.videoExperiments.rawValue
@ -155,10 +154,8 @@ private enum DebugControllerEntry: ItemListNodeEntry {
return 22
case .knockoutWallpaper:
return 23
case .demoAudioStream:
case .demoVideoChats:
return 24
case .snapPinListToTop:
return 25
case .playerEmbedding:
return 26
case .playlistPlayback:
@ -706,22 +703,12 @@ private enum DebugControllerEntry: ItemListNodeEntry {
})
}).start()
})
case let .demoAudioStream(value):
return ItemListSwitchItem(presentationData: presentationData, title: "Demo Audio Stream", value: value, sectionId: self.section, style: .blocks, updated: { value in
case let .demoVideoChats(value):
return ItemListSwitchItem(presentationData: presentationData, title: "Demo Video", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.demoAudioStream = value
return settings
})
}).start()
})
case let .snapPinListToTop(value):
return ItemListSwitchItem(presentationData: presentationData, title: "Pin List Top Edge", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.snapPinListToTop = value
settings.demoVideoChats = value
return settings
})
}).start()
@ -824,10 +811,8 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS
entries.append(.resetHoles(presentationData.theme))
entries.append(.reindexUnread(presentationData.theme))
entries.append(.optimizeDatabase(presentationData.theme))
//entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos))
entries.append(.knockoutWallpaper(presentationData.theme, experimentalSettings.knockoutWallpaper))
entries.append(.demoAudioStream(experimentalSettings.demoAudioStream))
entries.append(.snapPinListToTop(experimentalSettings.snapPinListToTop))
entries.append(.demoVideoChats(experimentalSettings.demoVideoChats))
entries.append(.playerEmbedding(experimentalSettings.playerEmbedding))
entries.append(.playlistPlayback(experimentalSettings.playlistPlayback))

View File

@ -142,7 +142,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[767652808] = { return Api.InputEncryptedFile.parse_inputEncryptedFileBigUploaded($0) }
dict[1304052993] = { return Api.account.Takeout.parse_takeout($0) }
dict[-1456996667] = { return Api.messages.InactiveChats.parse_inactiveChats($0) }
dict[430815881] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) }
dict[-1184160274] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) }
dict[1443858741] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedMessage($0) }
dict[-1802240206] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedFile($0) }
dict[289586518] = { return Api.SavedContact.parse_savedPhoneContact($0) }

View File

@ -3604,13 +3604,13 @@ public extension Api {
}
public enum GroupCallParticipant: TypeConstructorDescription {
case groupCallParticipant(flags: Int32, peer: Api.Peer, date: Int32, activeDate: Int32?, source: Int32, volume: Int32?, about: String?, raiseHandRating: Int64?)
case groupCallParticipant(flags: Int32, peer: Api.Peer, date: Int32, activeDate: Int32?, source: Int32, volume: Int32?, about: String?, raiseHandRating: Int64?, params: Api.DataJSON?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .groupCallParticipant(let flags, let peer, let date, let activeDate, let source, let volume, let about, let raiseHandRating):
case .groupCallParticipant(let flags, let peer, let date, let activeDate, let source, let volume, let about, let raiseHandRating, let params):
if boxed {
buffer.appendInt32(430815881)
buffer.appendInt32(-1184160274)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
@ -3620,14 +3620,15 @@ public extension Api {
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(volume!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 11) != 0 {serializeString(about!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {serializeInt64(raiseHandRating!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 6) != 0 {params!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .groupCallParticipant(let flags, let peer, let date, let activeDate, let source, let volume, let about, let raiseHandRating):
return ("groupCallParticipant", [("flags", flags), ("peer", peer), ("date", date), ("activeDate", activeDate), ("source", source), ("volume", volume), ("about", about), ("raiseHandRating", raiseHandRating)])
case .groupCallParticipant(let flags, let peer, let date, let activeDate, let source, let volume, let about, let raiseHandRating, let params):
return ("groupCallParticipant", [("flags", flags), ("peer", peer), ("date", date), ("activeDate", activeDate), ("source", source), ("volume", volume), ("about", about), ("raiseHandRating", raiseHandRating), ("params", params)])
}
}
@ -3650,6 +3651,10 @@ public extension Api {
if Int(_1!) & Int(1 << 11) != 0 {_7 = parseString(reader) }
var _8: Int64?
if Int(_1!) & Int(1 << 13) != 0 {_8 = reader.readInt64() }
var _9: Api.DataJSON?
if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.DataJSON
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -3658,8 +3663,9 @@ public extension Api {
let _c6 = (Int(_1!) & Int(1 << 7) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 11) == 0) || _7 != nil
let _c8 = (Int(_1!) & Int(1 << 13) == 0) || _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.GroupCallParticipant.groupCallParticipant(flags: _1!, peer: _2!, date: _3!, activeDate: _4, source: _5!, volume: _6, about: _7, raiseHandRating: _8)
let _c9 = (Int(_1!) & Int(1 << 6) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.GroupCallParticipant.groupCallParticipant(flags: _1!, peer: _2!, date: _3!, activeDate: _4, source: _5!, volume: _6, about: _7, raiseHandRating: _8, params: _9)
}
else {
return nil

View File

@ -571,8 +571,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.statePromise = ValuePromise(self.stateValue)
self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
//self.videoCapturer = OngoingCallVideoCapturer(keepLandscape: true)
if accountContext.sharedContext.immediateExperimentalUISettings.demoVideoChats {
self.videoCapturer = OngoingCallVideoCapturer(keepLandscape: false)
}
self.isVideo = self.videoCapturer != nil
var didReceiveAudioOutputs = false
@ -1039,6 +1041,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if let current = self.callContext {
callContext = current
} else {
var outgoingAudioBitrateKbit: Int32?
let appConfiguration = self.accountContext.currentAppConfiguration.with({ $0 })
if let data = appConfiguration.data, let value = data["voice_chat_send_bitrate"] as? Int32 {
outgoingAudioBitrateKbit = value
}
callContext = OngoingGroupCallContext(video: self.videoCapturer, participantDescriptionsRequired: { [weak self] ssrcs in
Queue.mainQueue().async {
guard let strongSelf = self else {
@ -1055,7 +1063,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.requestCall(movingFromBroadcastToRtc: false)
}
}
})
}, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit, enableVideo: self.isVideo)
self.incomingVideoSourcePromise.set(callContext.videoSources
|> deliverOnMainQueue
|> map { [weak self] sources -> [PeerId: UInt32] in

View File

@ -178,6 +178,8 @@ final class GroupVideoNode: ASDisplayNode {
self.videoViewContainer.addSubview(self.videoView.view)
self.view.addSubview(self.videoViewContainer)
self.clipsToBounds = true
videoView.setOnFirstFrameReceived({ [weak self] _ in
Queue.mainQueue().async {
guard let strongSelf = self else {
@ -270,6 +272,7 @@ private final class MainVideoContainerNode: ASDisplayNode {
private let call: PresentationGroupCall
private var currentVideoNode: GroupVideoNode?
private var candidateVideoNode: GroupVideoNode?
private var currentPeer: (PeerId, UInt32)?
private var validLayout: CGSize?
@ -283,7 +286,7 @@ private final class MainVideoContainerNode: ASDisplayNode {
self.backgroundColor = .black
}
func updatePeer(peer: (peerId: PeerId, source: UInt32)?) {
func updatePeer(peer: (peerId: PeerId, source: UInt32)?, waitForFullSize: Bool) {
if self.currentPeer?.0 == peer?.0 && self.currentPeer?.1 == peer?.1 {
return
}
@ -294,15 +297,40 @@ private final class MainVideoContainerNode: ASDisplayNode {
guard let strongSelf = self, let videoView = videoView else {
return
}
let videoNode = GroupVideoNode(videoView: videoView)
if let currentVideoNode = strongSelf.currentVideoNode {
currentVideoNode.removeFromSupernode()
strongSelf.currentVideoNode = nil
}
strongSelf.currentVideoNode = videoNode
strongSelf.addSubnode(videoNode)
if let size = strongSelf.validLayout {
strongSelf.update(size: size, transition: .immediate)
if waitForFullSize {
let candidateVideoNode = GroupVideoNode(videoView: videoView)
strongSelf.candidateVideoNode = candidateVideoNode
Queue.mainQueue().after(0.3, { [weak candidateVideoNode] in
guard let strongSelf = self, let videoNode = candidateVideoNode, videoNode === strongSelf.candidateVideoNode else {
return
}
if let currentVideoNode = strongSelf.currentVideoNode {
currentVideoNode.removeFromSupernode()
strongSelf.currentVideoNode = nil
}
strongSelf.currentVideoNode = videoNode
strongSelf.addSubnode(videoNode)
if let size = strongSelf.validLayout {
strongSelf.update(size: size, transition: .immediate)
}
})
} else {
strongSelf.candidateVideoNode = nil
let videoNode = GroupVideoNode(videoView: videoView)
if let currentVideoNode = strongSelf.currentVideoNode {
currentVideoNode.removeFromSupernode()
strongSelf.currentVideoNode = nil
}
strongSelf.currentVideoNode = videoNode
strongSelf.addSubnode(videoNode)
if let size = strongSelf.validLayout {
strongSelf.update(size: size, transition: .immediate)
}
}
}
})
@ -778,9 +806,9 @@ public final class VoiceChatController: ViewController {
self.backgroundNode.backgroundColor = secondaryPanelBackgroundColor
self.backgroundNode.clipsToBounds = false
/*if false {
if sharedContext.immediateExperimentalUISettings.demoVideoChats {
self.mainVideoContainer = MainVideoContainerNode(context: call.accountContext, call: call)
}*/
}
self.listNode = ListView()
self.listNode.verticalScrollIndicatorColor = UIColor(white: 1.0, alpha: 0.3)
@ -874,12 +902,6 @@ public final class VoiceChatController: ViewController {
let _ = self?.call.updateMuteState(peerId: peerId, isMuted: isMuted)
}, openPeer: { [weak self] peerId in
if let strongSelf = self {
/*let context = strongSelf.context
strongSelf.controller?.dismiss(completion: {
Queue.mainQueue().justDispatch {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), keepStack: .always, purposefulAction: {}, peekData: nil))
}
})*/
for entry in strongSelf.currentEntries {
switch entry {
case let .peer(peer):
@ -888,11 +910,11 @@ public final class VoiceChatController: ViewController {
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
strongSelf.call.setFullSizeVideo(peerId: peerId)
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source))
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source), waitForFullSize: false)
} else {
strongSelf.currentDominantSpeakerWithVideo = nil
strongSelf.call.setFullSizeVideo(peerId: nil)
strongSelf.mainVideoContainer?.updatePeer(peer: nil)
strongSelf.mainVideoContainer?.updatePeer(peer: nil, waitForFullSize: false)
}
}
}
@ -1182,17 +1204,19 @@ public final class VoiceChatController: ViewController {
}
}), true))
}
/*items.append(.action(ContextMenuActionItem(text: "Toggle Full Screen", icon: { theme in
return nil
}, action: { _, f in
guard let strongSelf = self else {
return
}
strongSelf.itemInteraction?.openPeer(peer.id)
f(.default)
})))*/
if strongSelf.context.sharedContext.immediateExperimentalUISettings.demoVideoChats {
items.append(.action(ContextMenuActionItem(text: "Toggle Full Screen", icon: { theme in
return nil
}, action: { _, f in
guard let strongSelf = self else {
return
}
strongSelf.itemInteraction?.openPeer(peer.id)
f(.default)
})))
}
if peer.id == strongSelf.callState?.myPeerId {
if entry.raisedHand {
@ -1598,7 +1622,7 @@ public final class VoiceChatController: ViewController {
if strongSelf.currentDominantSpeakerWithVideo?.0 != peerId || strongSelf.currentDominantSpeakerWithVideo?.1 != source {
strongSelf.currentDominantSpeakerWithVideo = (peerId, source)
strongSelf.call.setFullSizeVideo(peerId: peerId)
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source))
strongSelf.mainVideoContainer?.updatePeer(peer: (peerId: peerId, source: source), waitForFullSize: true)
}
}
@ -1750,7 +1774,7 @@ public final class VoiceChatController: ViewController {
if !validSources.contains(source) {
strongSelf.currentDominantSpeakerWithVideo = nil
strongSelf.call.setFullSizeVideo(peerId: nil)
strongSelf.mainVideoContainer?.updatePeer(peer: nil)
strongSelf.mainVideoContainer?.updatePeer(peer: nil, waitForFullSize: false)
}
}
@ -2534,7 +2558,7 @@ public final class VoiceChatController: ViewController {
let topPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: panelOffset), size: CGSize(width: size.width, height: topPanelHeight))
if let mainVideoContainer = self.mainVideoContainer {
let videoContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: layout.size.width, height: 200.0))
let videoContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: layout.size.width, height: min(300.0, layout.size.width)))
transition.updateFrameAdditive(node: mainVideoContainer, frame: videoContainerFrame)
mainVideoContainer.update(size: videoContainerFrame.size, transition: transition)
}
@ -2805,7 +2829,7 @@ public final class VoiceChatController: ViewController {
let bottomPanelHeight = bottomAreaHeight + layout.intrinsicInsets.bottom
var listTopInset = layoutTopInset + topPanelHeight
if self.mainVideoContainer != nil {
listTopInset += 200.0
listTopInset += min(300.0, layout.size.width)
}
let listSize = CGSize(width: size.width, height: layout.size.height - listTopInset - bottomPanelHeight)

View File

@ -110,7 +110,7 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
loop: for participant in participants {
switch participant {
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating):
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating, params):
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
@ -134,13 +134,13 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
} else if mutedByYou {
muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: false, mutedByYou: mutedByYou)
}
let jsonParams: String? = nil
/*if let params = params {
var jsonParams: String? = nil
if let params = params {
switch params {
case let .dataJSON(data):
jsonParams = data
}
}*/
}
parsedParticipants.append(GroupCallParticipantsContext.Participant(
peer: peer,
ssrc: ssrc,
@ -297,7 +297,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
loop: for participant in participants {
switch participant {
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating):
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating, params):
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
@ -320,13 +320,13 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
} else if mutedByYou {
muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: false, mutedByYou: mutedByYou)
}
let jsonParams: String? = nil
/*if let params = params {
var jsonParams: String? = nil
if let params = params {
switch params {
case let .dataJSON(data):
jsonParams = data
}
}*/
}
parsedParticipants.append(GroupCallParticipantsContext.Participant(
peer: peer,
ssrc: ssrc,
@ -525,7 +525,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
case let .updateGroupCallParticipants(_, participants, _):
loop: for participant in participants {
switch participant {
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating):
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating, params):
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
@ -548,13 +548,13 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
} else if mutedByYou {
muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: false, mutedByYou: mutedByYou)
}
let jsonParams: String? = nil
/*if let params = params {
var jsonParams: String? = nil
if let params = params {
switch params {
case let .dataJSON(data):
jsonParams = data
}
}*/
}
if !state.participants.contains(where: { $0.peer.id == peer.id }) {
state.participants.append(GroupCallParticipantsContext.Participant(
peer: peer,
@ -797,6 +797,12 @@ public final class GroupCallParticipantsContext {
}
public static func compare(lhs: Participant, rhs: Participant, sortAscending: Bool) -> Bool {
let lhsCanUnmute = lhs.muteState?.canUnmute ?? true
let rhsCanUnmute = rhs.muteState?.canUnmute ?? true
if lhsCanUnmute != rhsCanUnmute {
return lhsCanUnmute
}
if let lhsActivityRank = lhs.activityRank, let rhsActivityRank = rhs.activityRank {
if lhsActivityRank != rhsActivityRank {
return lhsActivityRank < rhsActivityRank
@ -1440,6 +1446,11 @@ public final class GroupCallParticipantsContext {
activityTimestamp = participantUpdate.activityTimestamp ?? previousActivityTimestamp
}
if let muteState = participantUpdate.muteState, !muteState.canUnmute {
previousActivityRank = nil
activityTimestamp = nil
}
var volume = participantUpdate.volume
var muteState = participantUpdate.muteState
if participantUpdate.isMin {
@ -1720,7 +1731,7 @@ public final class GroupCallParticipantsContext {
extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
init(_ apiParticipant: Api.GroupCallParticipant) {
switch apiParticipant {
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating):
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating, params):
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
@ -1753,13 +1764,13 @@ extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
participationStatusChange = .none
}
let jsonParams: String? = nil
/*if let params = params {
var jsonParams: String? = nil
if let params = params {
switch params {
case let .dataJSON(data):
jsonParams = data
}
}*/
}
self.init(
peerId: peerId,
@ -1783,7 +1794,7 @@ extension GroupCallParticipantsContext.Update.StateUpdate {
var participantUpdates: [GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate] = []
for participant in participants {
switch participant {
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating):
case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about, raiseHandRating, params):
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
@ -1816,13 +1827,13 @@ extension GroupCallParticipantsContext.Update.StateUpdate {
participationStatusChange = .none
}
let jsonParams: String? = nil
/*if let params = params {
var jsonParams: String? = nil
if let params = params {
switch params {
case let .dataJSON(data):
jsonParams = data
}
}*/
}
participantUpdates.append(GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate(
peerId: peerId,

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 126
return 127
}
public func parseMessage(_ data: Data!) -> Any! {

View File

@ -3722,13 +3722,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var isScrolled: Bool
}
let messageRangeEdge: Signal<Bool, NoError> = self.context.sharedContext.accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.experimentalUISettings]))
|> map { sharedData -> Bool in
let experimentalSettings: ExperimentalUISettings = (sharedData.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings] as? ExperimentalUISettings) ?? ExperimentalUISettings.defaultSettings
return experimentalSettings.snapPinListToTop
}
|> distinctUntilChanged
let referenceMessage: Signal<ReferenceMessage?, NoError>
if latest {
referenceMessage = .single(nil)
@ -3736,16 +3729,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
referenceMessage = combineLatest(
queue: Queue.mainQueue(),
self.scrolledToMessageId.get(),
self.chatDisplayNode.historyNode.topVisibleMessageRange.get(),
messageRangeEdge
self.chatDisplayNode.historyNode.topVisibleMessageRange.get()
)
|> map { scrolledToMessageId, topVisibleMessageRange, messageRangeEdge -> ReferenceMessage? in
|> map { scrolledToMessageId, topVisibleMessageRange -> ReferenceMessage? in
let topVisibleMessage: MessageId?
if messageRangeEdge {
topVisibleMessage = topVisibleMessageRange?.lowerBound
} else {
topVisibleMessage = topVisibleMessageRange?.upperBound
}
topVisibleMessage = topVisibleMessageRange?.upperBound
if let scrolledToMessageId = scrolledToMessageId {
if let topVisibleMessage = topVisibleMessage {

View File

@ -14,8 +14,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
public var preferredVideoCodec: String?
public var disableVideoAspectScaling: Bool
public var enableVoipTcp: Bool
public var snapPinListToTop: Bool
public var demoAudioStream: Bool
public var demoVideoChats: Bool
public static var defaultSettings: ExperimentalUISettings {
return ExperimentalUISettings(
@ -30,8 +29,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
preferredVideoCodec: nil,
disableVideoAspectScaling: false,
enableVoipTcp: false,
snapPinListToTop: false,
demoAudioStream: false
demoVideoChats: false
)
}
@ -47,8 +45,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
preferredVideoCodec: String?,
disableVideoAspectScaling: Bool,
enableVoipTcp: Bool,
snapPinListToTop: Bool,
demoAudioStream: Bool
demoVideoChats: Bool
) {
self.keepChatNavigationStack = keepChatNavigationStack
self.skipReadHistory = skipReadHistory
@ -61,8 +58,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
self.preferredVideoCodec = preferredVideoCodec
self.disableVideoAspectScaling = disableVideoAspectScaling
self.enableVoipTcp = enableVoipTcp
self.snapPinListToTop = snapPinListToTop
self.demoAudioStream = demoAudioStream
self.demoVideoChats = demoVideoChats
}
public init(decoder: PostboxDecoder) {
@ -77,8 +73,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
self.preferredVideoCodec = decoder.decodeOptionalStringForKey("preferredVideoCodec")
self.disableVideoAspectScaling = decoder.decodeInt32ForKey("disableVideoAspectScaling", orElse: 0) != 0
self.enableVoipTcp = decoder.decodeInt32ForKey("enableVoipTcp", orElse: 0) != 0
self.snapPinListToTop = decoder.decodeInt32ForKey("snapPinListToTop", orElse: 0) != 0
self.demoAudioStream = decoder.decodeInt32ForKey("demoAudioStream", orElse: 0) != 0
self.demoVideoChats = decoder.decodeInt32ForKey("demoVideoChats", orElse: 0) != 0
}
public func encode(_ encoder: PostboxEncoder) {
@ -95,8 +90,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
}
encoder.encodeInt32(self.disableVideoAspectScaling ? 1 : 0, forKey: "disableVideoAspectScaling")
encoder.encodeInt32(self.enableVoipTcp ? 1 : 0, forKey: "enableVoipTcp")
encoder.encodeInt32(self.snapPinListToTop ? 1 : 0, forKey: "snapPinListToTop")
encoder.encodeInt32(self.demoAudioStream ? 1 : 0, forKey: "demoAudioStream")
encoder.encodeInt32(self.demoVideoChats ? 1 : 0, forKey: "demoVideoChats")
}
public func isEqual(to: PreferencesEntry) -> Bool {

View File

@ -179,7 +179,7 @@ public final class OngoingGroupCallContext {
private var broadcastPartsSource: BroadcastPartSource?
init(queue: Queue, inputDeviceId: String, outputDeviceId: String, video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void) {
init(queue: Queue, inputDeviceId: String, outputDeviceId: String, video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?, enableVideo: Bool) {
self.queue = queue
var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)?
@ -220,7 +220,9 @@ public final class OngoingGroupCallContext {
}
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
}
},
outgoingAudioBitrateKbit: outgoingAudioBitrateKbit ?? 32,
enableVideo: enableVideo
)
let queue = self.queue
@ -508,10 +510,10 @@ public final class OngoingGroupCallContext {
}
}
public init(inputDeviceId: String = "", outputDeviceId: String = "", video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void) {
public init(inputDeviceId: String = "", outputDeviceId: String = "", video: OngoingCallVideoCapturer?, participantDescriptionsRequired: @escaping (Set<UInt32>) -> Void, audioStreamData: AudioStreamData?, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?, enableVideo: Bool) {
let queue = self.queue
self.impl = QueueLocalObject(queue: queue, generate: {
return Impl(queue: queue, inputDeviceId: inputDeviceId, outputDeviceId: outputDeviceId, video: video, participantDescriptionsRequired: participantDescriptionsRequired, audioStreamData: audioStreamData, rejoinNeeded: rejoinNeeded)
return Impl(queue: queue, inputDeviceId: inputDeviceId, outputDeviceId: outputDeviceId, video: video, participantDescriptionsRequired: participantDescriptionsRequired, audioStreamData: audioStreamData, rejoinNeeded: rejoinNeeded, outgoingAudioBitrateKbit: outgoingAudioBitrateKbit, enableVideo: enableVideo)
})
}

View File

@ -196,7 +196,7 @@ typedef NS_ENUM(int32_t, OngoingGroupCallBroadcastPartStatus) {
@interface GroupCallThreadLocalContext : NSObject
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart;
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit enableVideo:(bool)enableVideo;
- (void)stop;

View File

@ -854,7 +854,7 @@ private:
@implementation GroupCallThreadLocalContext
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart {
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated inputDeviceId:(NSString * _Nonnull)inputDeviceId outputDeviceId:(NSString * _Nonnull)outputDeviceId videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer incomingVideoSourcesUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))incomingVideoSourcesUpdated participantDescriptionsRequired:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))participantDescriptionsRequired requestBroadcastPart:(id<OngoingGroupCallBroadcastPartTask> _Nonnull (^ _Nonnull)(int64_t, int64_t, void (^ _Nonnull)(OngoingGroupCallBroadcastPart * _Nullable)))requestBroadcastPart outgoingAudioBitrateKbit:(int32_t)outgoingAudioBitrateKbit enableVideo:(bool)enableVideo {
self = [super init];
if (self != nil) {
_queue = queue;
@ -937,7 +937,9 @@ private:
completion(std::move(parsedPart));
});
return std::make_shared<BroadcastPartTaskImpl>(task);
}
},
.outgoingAudioBitrateKbit = outgoingAudioBitrateKbit,
.enableVideo = enableVideo
}));
}
return self;
@ -1232,6 +1234,22 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
}
parsedParticipants.push_back(parsedParticipant);
}
NSDictionary *video = dict[@"video"];
if ([video isKindOfClass:[NSDictionary class]]) {
NSArray *serverSources = video[@"server_sources"];
if ([serverSources isKindOfClass:[NSArray class]]) {
for (NSNumber *sourceNumber in serverSources) {
if ([sourceNumber isKindOfClass:[NSNumber class]]) {
int32_t signedSource = [sourceNumber intValue];
result.serverVideoBandwidthProbingSsrc = *(int32_t *)&signedSource;
} else if ([sourceNumber isKindOfClass:[NSString class]]) {
uint32_t source = (uint32_t)[sourceNumber longLongValue];
result.serverVideoBandwidthProbingSsrc = source;
}
}
}
}
if (_instance) {
_instance->setJoinResponsePayload(result, std::move(parsedParticipants));

@ -1 +1 @@
Subproject commit 194449a2dd5a2bcb56a487e691842111bf5adf5f
Subproject commit 68ade13752f14fecf0b32bc08e8e47164ef52ddc