Merge commit '8dc06f48ce'
# Conflicts: # submodules/TgVoipWebrtc/tgcalls
This commit is contained in:
commit
ebe43c72c6
44 changed files with 1049 additions and 212 deletions
40
.bazelrc
40
.bazelrc
|
|
@ -1,32 +1,34 @@
|
|||
build --action_env=ZERO_AR_DATE=1
|
||||
|
||||
build --apple_platform_type=ios
|
||||
build --enable_platform_specific_config
|
||||
build --apple_crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build --crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build --host_crosstool_top=@local_config_apple_cc//:toolchain
|
||||
|
||||
build --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs"
|
||||
build --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs"
|
||||
|
||||
build --features=debug_prefix_map_pwd_is_dot
|
||||
build --features=swift.cacheable_swiftmodules
|
||||
build --features=swift.debug_prefix_map
|
||||
build --features=swift.enable_vfsoverlays
|
||||
# macOS-specific settings (auto-applied on macOS via --enable_platform_specific_config)
|
||||
build:macos --apple_platform_type=ios
|
||||
build:macos --apple_crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build:macos --crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build:macos --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs"
|
||||
build:macos --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs"
|
||||
build:macos --features=debug_prefix_map_pwd_is_dot
|
||||
build:macos --features=swift.cacheable_swiftmodules
|
||||
build:macos --features=swift.debug_prefix_map
|
||||
build:macos --features=swift.enable_vfsoverlays
|
||||
build:dbg --features=swift.emit_swiftsourceinfo
|
||||
|
||||
# Linux-specific settings (auto-applied on Linux via --enable_platform_specific_config)
|
||||
build:linux --action_env=CC
|
||||
build:linux --action_env=CXX
|
||||
|
||||
build --strategy=Genrule=standalone
|
||||
build --spawn_strategy=standalone
|
||||
|
||||
build --strategy=SwiftCompile=worker
|
||||
build:macos --strategy=SwiftCompile=worker
|
||||
|
||||
#common --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/
|
||||
|
||||
# SourceKit BSP: Swift indexing features
|
||||
common --features=swift.index_while_building
|
||||
common --features=swift.use_global_index_store
|
||||
common --features=swift.use_global_module_cache
|
||||
common --features=oso_prefix_is_pwd
|
||||
# SourceKit BSP: Swift indexing features (macOS only)
|
||||
common:macos --features=swift.index_while_building
|
||||
common:macos --features=swift.use_global_index_store
|
||||
common:macos --features=swift.use_global_module_cache
|
||||
common:macos --features=oso_prefix_is_pwd
|
||||
|
||||
# SourceKit BSP: Index build config (used for background indexing)
|
||||
common:index_build --experimental_convenience_symlinks=ignore
|
||||
|
|
|
|||
27
MODULE.bazel
27
MODULE.bazel
|
|
@ -3,6 +3,25 @@ http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_
|
|||
bazel_dep(name = "bazel_features", version = "1.33.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.8.1")
|
||||
bazel_dep(name = "platforms", version = "0.0.11")
|
||||
bazel_dep(name = "rules_go", version = "0.60.0", repo_name = "io_bazel_rules_go")
|
||||
|
||||
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.24.2")
|
||||
|
||||
bazel_dep(name = "gazelle", version = "0.43.0", repo_name = "bazel_gazelle")
|
||||
|
||||
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//submodules/TgVoipWebrtc/tgcalls/tools/go_sfu:go.mod")
|
||||
use_repo(
|
||||
go_deps,
|
||||
"com_github_pion_datachannel",
|
||||
"com_github_pion_dtls_v3",
|
||||
"com_github_pion_ice_v4",
|
||||
"com_github_pion_logging",
|
||||
"com_github_pion_rtcp",
|
||||
"com_github_pion_sctp",
|
||||
"com_github_pion_srtp_v3",
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_xcodeproj")
|
||||
local_path_override(
|
||||
|
|
@ -30,26 +49,26 @@ local_path_override(
|
|||
|
||||
http_file(
|
||||
name = "cmake_tar_gz",
|
||||
urls = ["https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-macos-universal.tar.gz"],
|
||||
sha256 = "3be85f5b999e327b1ac7d804cbc9acd767059e9f603c42ec2765f6ab68fbd367",
|
||||
urls = ["https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-macos-universal.tar.gz"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "meson_tar_gz",
|
||||
urls = ["https://github.com/mesonbuild/meson/releases/download/1.6.0/meson-1.6.0.tar.gz"],
|
||||
sha256 = "999b65f21c03541cf11365489c1fad22e2418bb0c3d50ca61139f2eec09d5496",
|
||||
urls = ["https://github.com/mesonbuild/meson/releases/download/1.6.0/meson-1.6.0.tar.gz"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "ninja-mac_zip",
|
||||
urls = ["https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-mac.zip"],
|
||||
sha256 = "89a287444b5b3e98f88a945afa50ce937b8ffd1dcc59c555ad9b1baf855298c9",
|
||||
urls = ["https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-mac.zip"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "flatbuffers_zip",
|
||||
urls = ["https://github.com/google/flatbuffers/archive/refs/tags/v24.12.23.zip"],
|
||||
sha256 = "c5cd6a605ff20350c7faa19d8eeb599df6117ea4aabd16ac58a7eb5ba82df4e7",
|
||||
urls = ["https://github.com/google/flatbuffers/archive/refs/tags/v24.12.23.zip"],
|
||||
)
|
||||
|
||||
provisioning_profile_repository = use_extension("@build_bazel_rules_apple//apple:apple.bzl", "provisioning_profile_repository_extension")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,22 @@ config_setting(
|
|||
values = {"cpu": "ios_sim_arm64"},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "linux_arm64",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:aarch64",
|
||||
],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "linux_x86_64",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
)
|
||||
|
||||
exports_files([
|
||||
"GenerateStrings/GenerateStrings.py",
|
||||
])
|
||||
|
|
|
|||
|
|
@ -189,7 +189,10 @@ public final class BrowserBookmarksScreen: ViewController {
|
|||
}, requestToggleTodoMessageItem: { _, _, _ in
|
||||
}, displayTodoToggleUnavailable: { _ in
|
||||
}, openStarsPurchase: { _ in
|
||||
}, openRankInfo: { _, _, _ in }, openSetPeerAvatar: {}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
|
||||
}, openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
}, displayPollRestrictedToast: { _ in
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
|
||||
|
||||
|
||||
let tagMask: MessageTags = .webPage
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ func pollCloudMediaToInputMedia(_ media: Media) -> Api.InputMedia? {
|
|||
|
||||
public enum RequestMessageSelectPollOptionError {
|
||||
case generic
|
||||
case restrictedToSubscribers
|
||||
}
|
||||
|
||||
func _internal_requestMessageSelectPollOption(account: Account, messageId: MessageId, opaqueIdentifiers: [Data]) -> Signal<TelegramMediaPoll?, RequestMessageSelectPollOptionError> {
|
||||
|
|
@ -40,7 +41,10 @@ func _internal_requestMessageSelectPollOption(account: Account, messageId: Messa
|
|||
|> mapToSignal { peer in
|
||||
if let inputPeer = apiInputPeer(peer) {
|
||||
return account.network.request(Api.functions.messages.sendVote(peer: inputPeer, msgId: messageId.id, options: opaqueIdentifiers.map { Buffer(data: $0) }))
|
||||
|> mapError { _ -> RequestMessageSelectPollOptionError in
|
||||
|> mapError { error -> RequestMessageSelectPollOptionError in
|
||||
if error.errorDescription == "POLL_MEMBER_RESTRICTED" {
|
||||
return .restrictedToSubscribers
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<TelegramMediaPoll?, RequestMessageSelectPollOptionError> in
|
||||
|
|
@ -266,7 +270,7 @@ func _internal_requestClosePoll(postbox: Postbox, network: Network, stateManager
|
|||
pollMediaFlags |= 1 << 1
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(.init(flags: pollMediaFlags, poll: .poll(.init(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(.init(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary()))), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil, countriesIso2: poll.countries, hash: 0)), correctAnswers: correctAnswersIndices, attachedMedia: nil, solution: mappedSolution, solutionEntities: mappedSolutionEntities, solutionMedia: nil)), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(.init(flags: pollMediaFlags, poll: .poll(.init(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(.init(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary()))), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: poll.deadlineDate, countriesIso2: poll.countries, hash: 0)), correctAnswers: correctAnswersIndices, attachedMedia: nil, solution: mappedSolution, solutionEntities: mappedSolutionEntities, solutionMedia: nil)), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
|
|
|
|||
|
|
@ -2918,49 +2918,7 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
if case .public = poll.publicity {
|
||||
item.controllerInteraction.openMessagePollResults(item.message.id, option.opaqueIdentifier)
|
||||
} else if isRestricted {
|
||||
let text: String
|
||||
|
||||
let peerName = item.message.peers[item.message.id.peerId].flatMap(EnginePeer.init)?.compactDisplayTitle ?? ""
|
||||
if !poll.countries.isEmpty {
|
||||
let locale = localeWithStrings(item.presentationData.strings)
|
||||
let countryNames = poll.countries.map { id in
|
||||
if id == "FT" {
|
||||
return "Fragment"
|
||||
} else if let countryName = locale.localizedString(forRegionCode: id) {
|
||||
return countryName
|
||||
} else {
|
||||
return id
|
||||
}
|
||||
}
|
||||
var countries: String = ""
|
||||
if countryNames.count == 1, let country = countryNames.first {
|
||||
countries = "**\(country)**"
|
||||
} else {
|
||||
for i in 0 ..< countryNames.count {
|
||||
countries.append("**\(countryNames[i])**")
|
||||
if i == countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesLastDelimiter)
|
||||
} else if i < countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesDelimiter)
|
||||
}
|
||||
}
|
||||
}
|
||||
if poll.restrictToSubscribers {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_SubscribersCountry(peerName, countries).string
|
||||
} else {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_Country(countries).string
|
||||
}
|
||||
} else {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_Subscribers(peerName).string
|
||||
}
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: item.context.sharedContext.currentPresentationData.with { $0 },
|
||||
content: .banned(text: text),
|
||||
elevatedLayout: true,
|
||||
position: .bottom,
|
||||
action: { _ in return true }
|
||||
)
|
||||
item.controllerInteraction.presentController(controller, nil)
|
||||
item.controllerInteraction.displayPollRestrictedToast(item.message.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -666,7 +666,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
}, requestToggleTodoMessageItem: { _, _, _ in
|
||||
}, displayTodoToggleUnavailable: { _ in
|
||||
}, openStarsPurchase: { _ in
|
||||
}, openRankInfo: { _, _, _ in }, openSetPeerAvatar: {}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
||||
}, openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
}, displayPollRestrictedToast: { _ in
|
||||
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
||||
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: self.backgroundNode))
|
||||
self.controllerInteraction = controllerInteraction
|
||||
|
||||
|
|
|
|||
|
|
@ -513,7 +513,10 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess
|
|||
}, requestToggleTodoMessageItem: { _, _, _ in
|
||||
}, displayTodoToggleUnavailable: { _ in
|
||||
}, openStarsPurchase: { _ in
|
||||
}, openRankInfo: { _, _, _ in }, openSetPeerAvatar: {}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
}, openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
}, displayPollRestrictedToast: { _ in
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: self.context, backgroundNode: self.wallpaperBackgroundNode))
|
||||
|
||||
let associatedData = ChatMessageItemAssociatedData(
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
public let openStarsPurchase: (Int64?) -> Void
|
||||
public let openRankInfo: (EnginePeer, ChatRankInfoScreenRole, String) -> Void
|
||||
public let openSetPeerAvatar: () -> Void
|
||||
public let displayPollRestrictedToast: (EngineMessage.Id) -> Void
|
||||
|
||||
public var canPlayMedia: Bool = false
|
||||
public var hiddenMedia: [MessageId: [Media]] = [:]
|
||||
|
|
@ -480,6 +481,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
openStarsPurchase: @escaping (Int64?) -> Void,
|
||||
openRankInfo: @escaping (EnginePeer, ChatRankInfoScreenRole, String) -> Void,
|
||||
openSetPeerAvatar: @escaping () -> Void,
|
||||
displayPollRestrictedToast: @escaping (EngineMessage.Id) -> Void,
|
||||
automaticMediaDownloadSettings: MediaAutoDownloadSettings,
|
||||
pollActionState: ChatInterfacePollActionState,
|
||||
stickerSettings: ChatInterfaceStickerSettings,
|
||||
|
|
@ -610,6 +612,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||
self.openStarsPurchase = openStarsPurchase
|
||||
self.openRankInfo = openRankInfo
|
||||
self.openSetPeerAvatar = openSetPeerAvatar
|
||||
self.displayPollRestrictedToast = displayPollRestrictedToast
|
||||
|
||||
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings
|
||||
|
||||
|
|
|
|||
|
|
@ -1284,7 +1284,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}, requestToggleTodoMessageItem: { _, _, _ in
|
||||
}, displayTodoToggleUnavailable: { _ in
|
||||
}, openStarsPurchase: { _ in
|
||||
}, openRankInfo: { _, _, _ in }, openSetPeerAvatar: {}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
}, openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
}, displayPollRestrictedToast: { _ in
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
|
||||
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in
|
||||
guard let strongSelf = self else {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import Display
|
|||
import UndoUI
|
||||
import AccountContext
|
||||
import ChatControllerInteraction
|
||||
import TelegramStringFormatting
|
||||
|
||||
extension ChatControllerImpl {
|
||||
func displaySendReactionRestrictedToast() {
|
||||
|
|
@ -20,6 +21,71 @@ extension ChatControllerImpl {
|
|||
action: { _ in return true }
|
||||
), nil)
|
||||
}
|
||||
|
||||
func displayPollRestrictedToast(messageId: EngineMessage.Id) {
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Messages.Message(id: messageId),
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] message, peer in
|
||||
guard let self, let message, let peer else {
|
||||
return
|
||||
}
|
||||
let peerName = peer.compactDisplayTitle
|
||||
guard let poll = message.media.first(where: { $0 is TelegramMediaPoll }) as? TelegramMediaPoll else {
|
||||
return
|
||||
}
|
||||
|
||||
var accountCountry = ""
|
||||
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let country = data["phone_country_iso2"] as? String {
|
||||
accountCountry = (country)
|
||||
}
|
||||
var text = ""
|
||||
if !poll.countries.isEmpty && !poll.countries.contains(accountCountry) {
|
||||
let locale = localeWithStrings(self.presentationData.strings)
|
||||
let countryNames = poll.countries.map { id in
|
||||
if id == "FT" {
|
||||
return "Fragment"
|
||||
} else if let countryName = locale.localizedString(forRegionCode: id) {
|
||||
return countryName
|
||||
} else {
|
||||
return id
|
||||
}
|
||||
}
|
||||
var countries: String = ""
|
||||
if countryNames.count == 1, let country = countryNames.first {
|
||||
countries = "**\(country)**"
|
||||
} else {
|
||||
for i in 0 ..< countryNames.count {
|
||||
countries.append("**\(countryNames[i])**")
|
||||
if i == countryNames.count - 2 {
|
||||
countries.append(self.presentationData.strings.Chat_Poll_Restriction_Country_CountriesLastDelimiter)
|
||||
} else if i < countryNames.count - 2 {
|
||||
countries.append(self.presentationData.strings.Chat_Poll_Restriction_Country_CountriesDelimiter)
|
||||
}
|
||||
}
|
||||
}
|
||||
if poll.restrictToSubscribers {
|
||||
text = self.presentationData.strings.Chat_Poll_Restriction_SubscribersCountry(peerName, countries).string
|
||||
} else {
|
||||
text = self.presentationData.strings.Chat_Poll_Restriction_Country(countries).string
|
||||
}
|
||||
} else {
|
||||
if case let .channel(channel) = peer, case .member = channel.participationStatus {
|
||||
text = self.presentationData.strings.Chat_Poll_Restriction_Subscribers_TimeLimit
|
||||
} else {
|
||||
text = self.presentationData.strings.Chat_Poll_Restriction_Subscribers(peerName).string
|
||||
}
|
||||
}
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: self.presentationData,
|
||||
content: .banned(text: text),
|
||||
position: .bottom,
|
||||
action: { _ in return true }
|
||||
)
|
||||
self.controllerInteraction?.presentControllerInCurrent(controller, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func displayPostedScheduledMessagesToast(ids: [EngineMessage.Id]) {
|
||||
let timestamp = CFAbsoluteTimeGetCurrent()
|
||||
|
|
|
|||
|
|
@ -3896,20 +3896,26 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
)
|
||||
strongSelf.present(controller, in: .current)
|
||||
}
|
||||
}, error: { _ in
|
||||
}, error: { error in
|
||||
guard let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction else {
|
||||
return
|
||||
}
|
||||
if controllerInteraction.pollActionState.pollMessageIdsInProgress.removeValue(forKey: id) != nil {
|
||||
strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id)
|
||||
}
|
||||
|
||||
switch error {
|
||||
case .restrictedToSubscribers:
|
||||
strongSelf.displayPollRestrictedToast(messageId: id)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}, completed: {
|
||||
guard let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction else {
|
||||
return
|
||||
}
|
||||
if controllerInteraction.pollActionState.pollMessageIdsInProgress.removeValue(forKey: id) != nil {
|
||||
Queue.mainQueue().after(1.0, {
|
||||
|
||||
strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id)
|
||||
})
|
||||
}
|
||||
|
|
@ -5664,6 +5670,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
return
|
||||
}
|
||||
self.interfaceInteraction?.openSetPeerAvatar()
|
||||
}, displayPollRestrictedToast: { [weak self] messageId in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.displayPollRestrictedToast(messageId: messageId)
|
||||
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode))
|
||||
controllerInteraction.enableFullTranslucency = context.sharedContext.energyUsageSettings.fullTranslucency
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,10 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
|||
}, requestToggleTodoMessageItem: { _, _, _ in
|
||||
}, displayTodoToggleUnavailable: { _ in
|
||||
}, openStarsPurchase: { _ in
|
||||
}, openRankInfo: { _, _, _ in }, openSetPeerAvatar: {}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
|
||||
}, openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
}, displayPollRestrictedToast: { _ in
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
|
||||
|
||||
self.dimNode = ASDisplayNode()
|
||||
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
|
||||
|
|
|
|||
|
|
@ -2581,7 +2581,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
openStarsPurchase: { _ in
|
||||
},
|
||||
openRankInfo: { _, _, _ in
|
||||
}, openSetPeerAvatar: {
|
||||
},
|
||||
openSetPeerAvatar: {
|
||||
},
|
||||
displayPollRestrictedToast: { _ in
|
||||
},
|
||||
automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
pollActionState: ChatInterfacePollActionState(),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ config_setting(
|
|||
},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "is_macos",
|
||||
constraint_values = ["@platforms//os:macos"],
|
||||
)
|
||||
|
||||
optimization_flags = select({
|
||||
":debug_build": [
|
||||
],
|
||||
|
|
@ -107,6 +112,7 @@ sources = glob([
|
|||
"tgcalls/tgcalls/group/AudioStreamingPartPersistentDecoder.cpp",
|
||||
"tgcalls/tgcalls/group/AVIOContextImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupInstanceReferenceImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupJoinPayloadInternal.cpp",
|
||||
"tgcalls/tgcalls/group/GroupNetworkManager.cpp",
|
||||
"tgcalls/tgcalls/group/StreamingMediaContext.cpp",
|
||||
|
|
@ -116,6 +122,7 @@ sources = glob([
|
|||
"tgcalls/tgcalls/v2/DirectNetworkingImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/ExternalSignalingConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2Impl.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2CompatImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2ReferenceImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/NativeNetworkingImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/RawTcpSocket.cpp",
|
||||
|
|
@ -125,6 +132,7 @@ sources = glob([
|
|||
"tgcalls/tgcalls/v2/SignalingConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingEncryption.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingSctpConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/CustomDcSctpSocket.cpp",
|
||||
]
|
||||
|
||||
objc_library(
|
||||
|
|
@ -189,3 +197,105 @@ objc_library(
|
|||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
||||
# Pure C++ core library for non-iOS targets (e.g. CLI tools).
|
||||
# Uses FakeInterface instead of darwin platform files.
|
||||
cc_library(
|
||||
name = "tgcalls_core",
|
||||
srcs = glob([
|
||||
"tgcalls/tgcalls/**/*.h",
|
||||
"tgcalls/tgcalls/**/*.hpp",
|
||||
"tgcalls/tgcalls/platform/fake/**/*.cpp",
|
||||
"tgcalls/tgcalls/third-party/**/*.cpp",
|
||||
"tgcalls/tgcalls/utils/**/*.cpp",
|
||||
], allow_empty=True, exclude = [
|
||||
"tgcalls/tgcalls/legacy/**",
|
||||
"tgcalls/tgcalls/platform/tdesktop/**",
|
||||
"tgcalls/tgcalls/platform/android/**",
|
||||
"tgcalls/tgcalls/platform/windows/**",
|
||||
"tgcalls/tgcalls/platform/uwp/**",
|
||||
"tgcalls/tgcalls/platform/darwin/**",
|
||||
"tgcalls/tgcalls/desktop_capturer/**",
|
||||
]) + [
|
||||
"tgcalls/tgcalls/Manager.cpp",
|
||||
"tgcalls/tgcalls/MediaManager.cpp",
|
||||
"tgcalls/tgcalls/AudioDeviceHelper.cpp",
|
||||
"tgcalls/tgcalls/ChannelManager.cpp",
|
||||
"tgcalls/tgcalls/CodecSelectHelper.cpp",
|
||||
"tgcalls/tgcalls/CryptoHelper.cpp",
|
||||
"tgcalls/tgcalls/EncryptedConnection.cpp",
|
||||
"tgcalls/tgcalls/FakeAudioDeviceModule.cpp",
|
||||
"tgcalls/tgcalls/FakeVideoTrackSource.cpp",
|
||||
"tgcalls/tgcalls/FieldTrialsConfig.cpp",
|
||||
"tgcalls/tgcalls/Instance.cpp",
|
||||
"tgcalls/tgcalls/InstanceImpl.cpp",
|
||||
"tgcalls/tgcalls/LogSinkImpl.cpp",
|
||||
"tgcalls/tgcalls/Message.cpp",
|
||||
"tgcalls/tgcalls/NetworkManager.cpp",
|
||||
"tgcalls/tgcalls/SctpDataChannelProviderInterfaceImpl.cpp",
|
||||
"tgcalls/tgcalls/StaticThreads.cpp",
|
||||
"tgcalls/tgcalls/ThreadLocalObject.cpp",
|
||||
"tgcalls/tgcalls/TurnCustomizerImpl.cpp",
|
||||
"tgcalls/tgcalls/VideoCaptureInterface.cpp",
|
||||
"tgcalls/tgcalls/VideoCaptureInterfaceImpl.cpp",
|
||||
|
||||
"tgcalls/tgcalls/group/AudioStreamingPart.cpp",
|
||||
"tgcalls/tgcalls/group/AudioStreamingPartInternal.cpp",
|
||||
"tgcalls/tgcalls/group/AudioStreamingPartPersistentDecoder.cpp",
|
||||
"tgcalls/tgcalls/group/AVIOContextImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupInstanceReferenceImpl.cpp",
|
||||
"tgcalls/tgcalls/group/GroupJoinPayloadInternal.cpp",
|
||||
"tgcalls/tgcalls/group/GroupNetworkManager.cpp",
|
||||
"tgcalls/tgcalls/group/StreamingMediaContext.cpp",
|
||||
"tgcalls/tgcalls/group/VideoStreamingPart.cpp",
|
||||
|
||||
"tgcalls/tgcalls/v2/ContentNegotiation.cpp",
|
||||
"tgcalls/tgcalls/v2/DirectNetworkingImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/ExternalSignalingConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2Impl.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2CompatImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/InstanceV2ReferenceImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/NativeNetworkingImpl.cpp",
|
||||
"tgcalls/tgcalls/v2/RawTcpSocket.cpp",
|
||||
"tgcalls/tgcalls/v2/ReflectorPort.cpp",
|
||||
"tgcalls/tgcalls/v2/ReflectorRelayPortFactory.cpp",
|
||||
"tgcalls/tgcalls/v2/Signaling.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingEncryption.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingSctpConnection.cpp",
|
||||
"tgcalls/tgcalls/v2/SignalingTranslator.cpp",
|
||||
"tgcalls/tgcalls/v2/CustomDcSctpSocket.cpp",
|
||||
],
|
||||
copts = [
|
||||
"-I{}/tgcalls/tgcalls".format(package_name()),
|
||||
"-Ithird-party/webrtc/webrtc",
|
||||
"-Ithird-party/webrtc/dependencies",
|
||||
"-Ithird-party/webrtc/absl",
|
||||
"-Ithird-party/libyuv",
|
||||
"-DRTC_ENABLE_VP9",
|
||||
"-DTGVOIP_NAMESPACE=tgvoip_webrtc",
|
||||
"-std=c++17",
|
||||
"-w",
|
||||
] + select({
|
||||
"@platforms//os:linux": ["-DWEBRTC_LINUX", "-DWEBRTC_POSIX"],
|
||||
"//conditions:default": ["-DWEBRTC_MAC", "-DWEBRTC_POSIX"],
|
||||
}) + optimization_flags,
|
||||
deps = [
|
||||
"//third-party/webrtc",
|
||||
"//third-party/boringssl:crypto",
|
||||
"//third-party/boringssl:ssl",
|
||||
"//third-party/ogg:ogg",
|
||||
"//third-party/opusfile:opusfile",
|
||||
"//submodules/ffmpeg:ffmpeg",
|
||||
"//third-party/rnnoise:rnnoise",
|
||||
"//third-party/libyuv",
|
||||
] + select({
|
||||
":is_macos": ["//third-party/webrtc:webrtc_platform_helpers"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
linkopts = ["-lz"],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
292
submodules/TgVoipWebrtc/CLAUDE.md
Normal file
292
submodules/TgVoipWebrtc/CLAUDE.md
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
# tgcalls Library
|
||||
|
||||
The tgcalls VoIP library source. See the root `CLAUDE.md` for build instructions and the project overview.
|
||||
|
||||
## macOS Build Support
|
||||
|
||||
This repo has been patched to support native macOS arm64 builds (`darwin_arm64` CPU) in addition to the original iOS targets. Changes made:
|
||||
- `third-party/webrtc/BUILD` — added `@platforms//os:linux` to `arch_specific_cflags` select (fixes macOS getting Linux flags via `//conditions:default`); moved `cocoa_threading.mm` from `cc_library` to `webrtc_platform_helpers` `objc_library` (Bazel 8 rejects `.mm` in `cc_library`); replaced UIKit with AppKit for macOS
|
||||
- `third-party/openh264/BUILD` — added `//conditions:default` to `select()` statements
|
||||
- `third-party/webrtc/absl/absl/base/attributes.h` — disabled `ABSL_ATTRIBUTE_LIFETIME_BOUND` (newer Xcode clang rejects it on void-returning functions)
|
||||
- 8 third-party BUILD files + 8 build shell scripts — added `darwin_arm64 -> macos_arm64` architecture support (opus, libvpx, ffmpeg, dav1d, mozjpeg, webp, libjxl, td)
|
||||
|
||||
## Linux Build Support
|
||||
|
||||
The repo supports native Linux arm64 and x86_64 builds. Key changes from the iOS/macOS-only baseline:
|
||||
- `.bazelrc` — Apple toolchain settings under `build:macos`, Linux uses default CC toolchain via `build:linux` (auto-selected by `--enable_platform_specific_config`)
|
||||
- `build-system/BUILD` — `linux_arm64` and `linux_x86_64` config_settings
|
||||
- `objc_library` → `cc_library` conversions for pure C/C++ targets (ogg, opusfile, rnnoise, opus, libvpx, dav1d, ffmpeg wrappers, WebRTC main target)
|
||||
- WebRTC BUILD — platform flags via `select()` (`-DWEBRTC_LINUX` vs `-DWEBRTC_MAC`), stdlib task queue instead of GCD on Linux, macOS-only sources excluded
|
||||
- Third-party genrule build scripts — Linux architecture cases added (libvpx, dav1d, ffmpeg), system cmake/meson/ninja used instead of downloaded macOS binaries
|
||||
- BoringSSL — `_Generic` C11 guarded for C++ mode (GCC compatibility)
|
||||
- tgcalls headers — `#include <cstdint>` added for GCC 15 strictness
|
||||
|
||||
## SCTP Signaling
|
||||
|
||||
### Writable Gate (role-based handshake ordering)
|
||||
|
||||
tgcalls uses a custom SCTP association (via dc-sctp) over the signaling channel for reliable message delivery. `SignalingSctpConnection` wraps `DcSctpTransport` with a `SignalingPacketTransport` shim.
|
||||
|
||||
The SCTP handshake is ordered using DcSctpTransport's writable gate (`MaybeConnectSocket()`), mirroring how WebRTC PeerConnection uses DTLS writable state to control SCTP connection timing:
|
||||
|
||||
- **Caller** (`isOutgoing=true`): `SignalingPacketTransport` starts writable → `Connect()` fires immediately → sends INIT
|
||||
- **Callee** (`isOutgoing=false`): starts not-writable → `Connect()` deferred → on first `receiveExternal()`, `setWritable(true)` fires `SignalWritableState` → `MaybeConnectSocket()` → `Connect()`
|
||||
|
||||
The callee's `Connect()` and processing of the caller's INIT happen synchronously within the same `BlockingCall` on the network thread (RFC 4960 §5.2.1 simultaneous-open).
|
||||
|
||||
Key files:
|
||||
- `SignalingSctpConnection.cpp` — `SignalingPacketTransport` writable state, `setWritable()`, constructor takes `isInitiator`
|
||||
- `InstanceV2Impl.cpp` / `InstanceV2ReferenceImpl.cpp` — pass `_encryptionKey.isOutgoing` as `isInitiator`
|
||||
- `third-party/webrtc/webrtc/media/sctp/dcsctp_transport.cc:662-667` — `MaybeConnectSocket()` gate (unmodified)
|
||||
|
||||
### Timer Tuning (CustomDcSctpSocket)
|
||||
|
||||
WebRTC's stock `DcSctpSocket` has a bug: `max_timer_backoff_duration` is wired to the T3-rtx (data retransmission) timer but **not** to the t1_init and t1_cookie (handshake) timers. The handshake timers use unlimited exponential backoff (1000, 2000, 4000, 8000ms...), causing the SCTP handshake to stall for 20+ seconds under packet loss with simultaneous-open (both sides call `Connect()`).
|
||||
|
||||
Fix: `CustomDcSctpSocket` (in `tgcalls/v2/`) is a copy of `DcSctpSocket` with the 6-line fix that passes `max_timer_backoff_duration` to the t1_init and t1_cookie timer constructors. A `CustomDcSctpSocketFactory` in `SignalingSctpConnection.cpp` creates it instead of the stock socket, with configurable timer overrides. WebRTC source is **untouched**.
|
||||
|
||||
Default signaling SCTP timer values (set in `SignalingSctpConnection::Options`):
|
||||
|
||||
| Setting | WebRTC Default | Signaling Override |
|
||||
|---|---|---|
|
||||
| `t1_init_timeout` | 1000ms | 400ms |
|
||||
| `t1_cookie_timeout` | 1000ms | 400ms |
|
||||
| `max_timer_backoff_duration` | 3000ms | 750ms |
|
||||
| `max_init_retransmits` | 8 | unlimited (from `DcSctpTransport::Start`) |
|
||||
|
||||
Retry pattern: 400ms, 750ms, 750ms, 750ms... (~18 attempts in 15s). At 30% loss, 100% success rate over 5000 runs.
|
||||
|
||||
These values are configurable via JSON custom parameters (passed to `InstanceV2Impl` via `config.customParameters`):
|
||||
- `network_sctp_t1_init_ms` — T1-init timeout (0 = use default 400ms)
|
||||
- `network_sctp_t1_cookie_ms` — T1-cookie timeout (0 = use default 400ms)
|
||||
- `network_sctp_max_backoff_ms` — max timer backoff cap (0 = use default 750ms)
|
||||
|
||||
Key files:
|
||||
- `tgcalls/v2/CustomDcSctpSocket.h/.cpp` — patched `DcSctpSocket` copy
|
||||
- `tgcalls/v2/SignalingSctpConnection.cpp` — `CustomDcSctpSocketFactory`, timer option plumbing
|
||||
- `tgcalls/v2/InstanceV2Impl.cpp` — reads JSON params, passes `Options` to `SignalingSctpConnection`
|
||||
|
||||
## InstanceV2CompatImpl (version 14.0.0)
|
||||
|
||||
A cross-version interop implementation that uses WebRTC PeerConnection internally (like InstanceV2ReferenceImpl) but speaks V2Impl's signaling protocol (`InitialSetupMessage`, `NegotiateChannelsMessage`, `CandidatesMessage`). This enables bidirectional calls between PeerConnection-based clients and V2Impl-based clients (versions 7.0.0–13.0.0).
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
PeerConnection <-> SignalingTranslator <-> EncryptedConnection <-> SignalingSctpConnection
|
||||
```
|
||||
|
||||
- **SignalingTranslator** (`tgcalls/v2/SignalingTranslator.h/.cpp`): Converts between `cricket::SessionDescription` (PeerConnection's internal format) and V2Impl signaling messages. Uses `JsepSessionDescription` programmatic API — no SDP string round-trips.
|
||||
- **Outbound**: PeerConnection generates offer/answer → SignalingTranslator extracts `InitialSetupMessage` (transport params) + `NegotiateChannelsMessage` (media contents)
|
||||
- **Inbound**: Buffers both messages until complete → builds `cricket::SessionDescription` → wraps in `JsepSessionDescription` → `SetRemoteDescription`
|
||||
|
||||
### Key Design Decisions
|
||||
|
||||
- **No data channel with V2Impl peers**: WebRTC data channel requires PeerConnection on both sides. V2Impl uses NativeNetworkingImpl (no PeerConnection). When paired with V2Impl, the data channel m-line is padded as `rejected` in the remote answer so PeerConnection accepts it. For CompatImpl↔CompatImpl calls, the data channel works normally.
|
||||
- **Caller-only renegotiation**: Only the outgoing side triggers offers from `onRenegotiationNeeded` to prevent unsolicited offer storms.
|
||||
- **MediaState via signaling**: `MediaStateMessage` sent over the SCTP signaling channel (not data channel), ensuring it works with both V2Impl and CompatImpl peers.
|
||||
- **Sequential content IDs**: Uses "0", "1", ... as m-line mids, matching PeerConnection's default scheme.
|
||||
- **Shared conversion functions**: `convertContentInfoToSignalingContent()` and `convertSignalingContentToContentInfo()` extracted to `Signaling.h/.cpp` for use by both `ContentNegotiationContext` (V2Impl) and `SignalingTranslator` (CompatImpl).
|
||||
|
||||
### Cross-Version Testing
|
||||
|
||||
```bash
|
||||
# CompatImpl caller → V2Impl callee
|
||||
./bazel-bin/tools/tgcalls_cli/tgcalls_cli --mode p2p --version 14.0.0 --version2 13.0.0 --duration 10 --quiet
|
||||
|
||||
# V2Impl caller → CompatImpl callee
|
||||
./bazel-bin/tools/tgcalls_cli/tgcalls_cli --mode p2p --version 13.0.0 --version2 14.0.0 --duration 10 --quiet
|
||||
|
||||
# With lossy signaling
|
||||
./bazel-bin/tools/tgcalls_cli/tgcalls_cli --mode p2p --version 14.0.0 --version2 13.0.0 --duration 15 --drop-rate 0.3 --delay 50-200 --quiet
|
||||
```
|
||||
|
||||
100% success rate at 30% loss in both directions (tested with 50 sequential + 20 parallel runs each direction).
|
||||
|
||||
Key files:
|
||||
- `tgcalls/v2/InstanceV2CompatImpl.h/.cpp` — main implementation
|
||||
- `tgcalls/v2/SignalingTranslator.h/.cpp` — cricket↔signaling conversion
|
||||
- `tgcalls/v2/Signaling.h/.cpp` — shared conversion functions (`convertContentInfoToSignalingContent`, `convertSignalingContentToContentInfo`)
|
||||
|
||||
## GroupInstanceCustomImpl (Group Calls)
|
||||
|
||||
The group call implementation in `tgcalls/group/GroupInstanceCustomImpl.cpp` (~4700 lines). Uses a client-server model with an SFU, unlike 1:1 calls which are peer-to-peer.
|
||||
|
||||
### Protocol Stack
|
||||
- **Join signaling**: JSON over application layer (`emitJoinPayload` → app sends to SFU → `setJoinResponsePayload`)
|
||||
- **Transport**: ICE + DTLS-SRTP over UDP (standard WebRTC transport, NOT PeerConnection)
|
||||
- **Media**: RTP/RTCP with Opus audio (48kHz, 2ch, 32kbps), optional VP8/H264/VP9 video
|
||||
- **Control**: SCTP data channel over DTLS for Colibri protocol (video constraints, debug messages)
|
||||
|
||||
### Join Flow
|
||||
1. Client calls `emitJoinPayload()` → generates JSON with audio SSRC, ICE ufrag/pwd, DTLS fingerprint
|
||||
2. Application sends JSON to SFU server
|
||||
3. Server responds with its ICE candidates, DTLS fingerprint, video codec info
|
||||
4. Client calls `setJoinResponsePayload(json)` → ICE/DTLS negotiation begins
|
||||
5. On connection: `networkStateUpdated` callback fires
|
||||
|
||||
### Participant Discovery
|
||||
- Unknown SSRC arrives in RTP → `receiveUnknownSsrcPacket()` → `maybeRequestUnknownSsrc(ssrc)`
|
||||
- App's `requestMediaChannelDescriptions` callback queries server for SSRC→participant mapping
|
||||
- `addIncomingAudioChannel(ssrc, userId)` creates decoder channel
|
||||
|
||||
### Colibri Data Channel Messages
|
||||
```json
|
||||
// SFU → Client
|
||||
{"colibriClass": "SenderVideoConstraints", "videoConstraints": {"idealHeight": 360}}
|
||||
|
||||
// Client → SFU
|
||||
{"colibriClass": "ReceiverVideoConstraints", "defaultConstraints": {"maxHeight": 0},
|
||||
"constraints": {"endpoint1": {"minHeight": 720, "maxHeight": 720}}}
|
||||
```
|
||||
|
||||
### Key Files
|
||||
- `tgcalls/group/GroupInstanceCustomImpl.h/.cpp` — main implementation
|
||||
- `tgcalls/group/GroupNetworkManager.h/.cpp` — ICE/DTLS/SRTP transport
|
||||
- `tgcalls/group/GroupJoinPayloadInternal.h/.cpp` — join JSON serialization
|
||||
|
||||
## GroupInstanceReferenceImpl (PeerConnection-based Group Calls)
|
||||
|
||||
An alternative group call implementation that uses standard WebRTC PeerConnection instead of the manual ICE/DTLS/SRTP management in `GroupInstanceCustomImpl`. Supports both audio and video (H264 simulcast). Implements the same `GroupInstanceInterface`.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
GroupInstanceReferenceImpl
|
||||
└── PeerConnection (single, to SFU)
|
||||
├── sendrecv audio transceiver (outgoing audio)
|
||||
├── sendonly video transceiver (outgoing H264 simulcast, SDP-munged SSRCs)
|
||||
├── recvonly audio transceivers (one per remote SSRC, added dynamically)
|
||||
├── recvonly video transceivers (one per remote endpoint, added dynamically)
|
||||
└── data channel ("data", for ActiveAudioSsrcs / ActiveVideoSsrcs)
|
||||
```
|
||||
|
||||
### How It Differs from CustomImpl
|
||||
|
||||
| Aspect | CustomImpl | ReferenceImpl |
|
||||
|--------|-----------|---------------|
|
||||
| Transport | Manual ICE/DTLS/SRTP via GroupNetworkManager | WebRTC PeerConnection |
|
||||
| SDP | None (custom JSON protocol) | Local SDP construction, translates to/from JSON |
|
||||
| SSRC discovery | `unknownSsrcPacketReceived` on raw RTP | `ActiveAudioSsrcs`/`ActiveVideoSsrcs` data channel messages from SFU |
|
||||
| Audio channels | Manual `IncomingAudioChannel` per SSRC | PeerConnection recvonly transceivers |
|
||||
| Audio levels | RTP header extension parsing | Synthetic levels based on known SSRCs |
|
||||
| Video outgoing | Manual `cricket::VideoChannel` with direct SSRC control | PeerConnection sendonly transceiver + SDP munging for simulcast SSRCs |
|
||||
| Video incoming | Manual `IncomingVideoChannel` per endpoint | PeerConnection recvonly transceivers with SSRCs in answer |
|
||||
| Video decode | Manual decoder lifecycle | PeerConnection handles internally |
|
||||
| Code size | ~4700 lines | ~1500 lines |
|
||||
|
||||
### Join Flow (SDP Translation)
|
||||
|
||||
1. Create PeerConnection with Opus audio transceiver, sendonly video transceiver (no track), and data channel
|
||||
2. `createOffer` → munge video SSRCs (replace PeerConnection's auto-generated SSRCs with pre-allocated simulcast SSRCs) → `SetLocalDescription` → extract ICE/DTLS params from local SDP
|
||||
3. Serialize as JSON (same format as CustomImpl): `{ssrc, ufrag, pwd, fingerprints, ssrc-groups}`
|
||||
4. Parse SFU response JSON → construct `JsepSessionDescription("answer")` programmatically via `cricket::SessionDescription` API (no SDP string parsing)
|
||||
5. `SetRemoteDescription` → ICE/DTLS connects via PeerConnection internals
|
||||
6. Add remote ICE candidates via `AddIceCandidate` after `SetRemoteDescription`
|
||||
7. Activate outgoing video: attach `FakeVideoTrackSource` track to the existing sendonly transceiver via `sender()->SetTrack()` — no renegotiation needed
|
||||
|
||||
### Dynamic Participant Handling
|
||||
|
||||
**Audio:**
|
||||
1. SFU sends `{"colibriClass":"ActiveAudioSsrcs","ssrcs":[54321,98765]}` over data channel
|
||||
2. Client diffs against known SSRCs
|
||||
3. New SSRCs: add recvonly audio transceiver → renegotiate (new offer + constructed answer mirroring offer mids)
|
||||
4. Removed SSRCs: clean up from tracking map
|
||||
|
||||
**Video:**
|
||||
1. SFU sends `ActiveVideoSsrcs` over data channel → forwarded to app via `dataChannelMessageReceived`
|
||||
2. App calls `setRequestedVideoChannels()` → adds recvonly video transceivers, sends `ReceiverVideoConstraints` over data channel
|
||||
3. Renegotiate: new offer → munge outgoing video SSRCs → `SetLocalDescription` → build answer with incoming video SSRCs → `SetRemoteDescription`
|
||||
4. `wirePendingVideoSinks()`: attach `FakeVideoSink` to the recvonly transceiver's receiver track after `SetRemoteDescription` completes
|
||||
5. Renegotiations are serialized (`_isRenegotiating` / `_pendingRenegotiation` flags) to prevent overlapping offer/answer cycles
|
||||
|
||||
### Outgoing Video: SDP Munging for Simulcast
|
||||
|
||||
PeerConnection's API doesn't support SSRC-based simulcast directly (only RID-based, which doesn't put SSRCs in the SDP). The workaround:
|
||||
|
||||
1. Pre-allocate 6 random video SSRCs at construction: 3 layers × (primary + RTX)
|
||||
2. Add a sendonly video transceiver in `start()` with no track
|
||||
3. Before `SetLocalDescription`, `mungeVideoSsrcsInOffer()` replaces the video m-line's auto-generated `StreamParams` with our pre-allocated SSRCs + SIM + FID groups
|
||||
4. `UpdateLocalStreams_w()` in WebRTC's `channel.cc` sees SSRCs already present and skips generation
|
||||
5. Later, `setVideoSource()` just calls `sender()->SetTrack()` — no renegotiation
|
||||
|
||||
### Incoming Video: SSRC-Based Demux
|
||||
|
||||
The answer for incoming video m-lines includes remote SSRCs from `VideoChannelDescription.ssrcGroups`. This is required because CustomImpl sets the `WebRTC-Video-DiscardPacketsWithUnknownSsrc` field trial process-wide, which disables unsignaled stream creation. Without explicit SSRCs, PeerConnection drops incoming video packets in mixed groups.
|
||||
|
||||
### Key Implementation Details
|
||||
|
||||
- **ICE roles**: PeerConnection uses standard ICE (full agent, controlling when remote is ICE-lite). The SFU uses `Accept` for PeerConnection clients vs `Dial` for CustomImpl clients.
|
||||
- **Loopback**: `PeerConnectionFactory::Options::network_ignore_mask = 0` enables loopback interface gathering for localhost SFU
|
||||
- **MID exclusion**: The `buildRemoteAnswer()` excludes the `urn:ietf:params:rtp-hdrext:sdes:mid` RTP header extension from ALL m-lines (audio and video). The SFU forwards raw RTP with the sender's MID value, which would cause the BUNDLE demuxer to route packets to the wrong channel. Without MID, PeerConnection falls back to SSRC/PT-based routing.
|
||||
- **RTP header extensions**: Copied from the local offer per m-line (minus MID), ensuring BUNDLE-safe IDs. Hardcoding IDs risks collisions across the BUNDLE group.
|
||||
- **SDP mid matching**: During renegotiation, the constructed remote answer mirrors the local offer's m-line structure and mids exactly. Mismatched mids cause `SetRemoteDescription` to fail.
|
||||
- **Audio level reporting**: Uses synthetic levels (0.1) for all known remote SSRCs, since the SFU forwards RTP with extension IDs that may not match PeerConnection's negotiated mapping
|
||||
- **Video sink wiring**: `OnTrack` doesn't fire for locally-created recvonly transceivers. Sinks are wired explicitly in `wirePendingVideoSinks()` after `SetRemoteDescription` completes, and also in `addIncomingVideoOutput()` if the track already exists.
|
||||
- **H264 codec in answer**: PT 104 (primary) + PT 105 (RTX, apt=104), matching WebRTC's `assignPayloadTypes` order. RTCP feedback: nack, nack pli, ccm fir, goog-remb, transport-cc.
|
||||
- **Renegotiation serialization**: Only one offer/answer cycle runs at a time. Deferred renegotiations only fire if there are unnegotiated transceivers (no mid assigned yet), avoiding redundant cycles.
|
||||
|
||||
### Key Files
|
||||
- `tgcalls/group/GroupInstanceReferenceImpl.h/.cpp` — implementation
|
||||
- `tgcalls/group/GroupInstanceImpl.h` — shared `GroupInstanceInterface`
|
||||
|
||||
## Video Support Pitfalls
|
||||
|
||||
Critical findings from implementing video in the test SFU — relevant for anyone working on group video:
|
||||
|
||||
### H264 Decoder Requires Two Build Flags
|
||||
The WebRTC BUILD needs BOTH `-DWEBRTC_USE_H264` (encoder, OpenH264) AND `-DWEBRTC_USE_H264_DECODER` (decoder, FFmpeg). Without the decoder flag, `H264Decoder::Create()` returns nullptr and WebRTC silently falls back to `NullVideoDecoder` which accepts frames but never decodes them — no error logged. The encoder works fine without the decoder flag, making this easy to miss.
|
||||
|
||||
### FFmpeg 7+ Removed `reordered_opaque`
|
||||
`h264_decoder_impl.cc` uses `AVCodecContext::reordered_opaque` and `AVFrame::reordered_opaque` for passing timestamps through the decode pipeline. FFmpeg 7+ removed this field. The fix uses `AVPacket::pts` instead. IMPORTANT: `AVCodecContext::opaque` is already used to store the `H264DecoderImpl*` pointer (line 74 of `AVGetBuffer2`) — do NOT use it for timestamps.
|
||||
|
||||
### Outgoing Video Channel Steals Incoming RTP
|
||||
`GroupInstanceCustomImpl` creates separate `cricket::VideoChannel` objects for outgoing and incoming video, all sharing the same `RtpTransport`. The outgoing channel's `WebRtcVideoReceiveChannel` has an "unsignalled SSRC" handler that creates default receive streams for unknown SSRCs. When video RTP from other participants arrives before `IncomingVideoChannel` registers its SSRCs, the outgoing channel intercepts the packets permanently. Fix: enable the `WebRTC-Video-DiscardPacketsWithUnknownSsrc` field trial in the field trial string.
|
||||
|
||||
### Video Channel Setup Is Reactive, Not Pre-Registered
|
||||
Video channels are set up reactively when `ActiveVideoSsrcs` arrives via the data channel — same as the real Telegram app. The `dataChannelMessageReceived` callback in `GroupInstanceDescriptor` forwards Colibri messages to the app, which calls `setRequestedVideoChannels`. The `DiscardPacketsWithUnknownSsrc` field trial prevents the outgoing channel from stealing RTP packets for SSRCs not yet registered. The SFU sends proactive PLI after constraints arrive, ensuring keyframes are produced after the incoming channel is ready.
|
||||
|
||||
### SFU Must Send Proactive PLI
|
||||
WebRTC's `VideoReceiveStream2` doesn't immediately request a keyframe when a new receive stream is created — it waits until it detects missing packets or a timeout. The SFU must proactively send PLI to the sender when a receiver first requests video via `ReceiverVideoConstraints`. Without this, the decoder waits indefinitely for a keyframe.
|
||||
|
||||
### RTP/RTCP Demux: Marker Bit False Positives
|
||||
RFC 5761 demux by second byte: RTCP types are 200-211. But RTP with Marker=1 and dynamic PT ≥ 96 gives byte[1] ≥ 224. Using `byte[1] >= 200` falsely classifies H264 RTP (PT=104, M=1 → byte[1]=232) as RTCP. Correct range: `byte[1] >= 200 && byte[1] < 224`.
|
||||
|
||||
### SRTCP Requires Separate Contexts from SRTP
|
||||
Pion's `SessionSRTP` and `SessionSRTCP` can't share the same `net.Conn` (both start read loops that fight for packets). The solution: demux RTCP at the transport level (in `PacketDemux`), create separate `srtp.Context` instances for SRTCP decrypt/encrypt using the same DTLS-extracted keys, and handle RTCP manually without `SessionSRTCP`.
|
||||
|
||||
### PeerConnection Simulcast SSRCs Require SDP Munging
|
||||
PeerConnection's API doesn't support SSRC-based simulcast (only RID-based). With RID-based simulcast, SSRCs are NOT in the `createOffer` SDP — they're generated internally during `SetLocalDescription` and not accessible via `sender->GetParameters()` (only primary SSRCs, not RTX). The workaround: add a single-encoding transceiver (no RIDs), then replace the auto-generated `StreamParams` in the offer with pre-allocated SSRCs + SIM + FID groups before calling `SetLocalDescription`. `UpdateLocalStreams_w()` skips generation when SSRCs already exist. IMPORTANT: `transceiver->mid()` is `nullopt` before `SetLocalDescription` — match by content direction, not mid.
|
||||
|
||||
### MID RTP Header Extension Causes Wrong Channel Routing in SFU
|
||||
The SFU forwards raw RTP packets including all header extensions. If the sender's video RTP includes a MID extension (e.g., MID="1"), the receiver's PeerConnection BUNDLE demuxer routes the packet to its own mid=1 channel — which is the outgoing video, not the incoming video transceiver. Fix: exclude `urn:ietf:params:rtp-hdrext:sdes:mid` from ALL m-lines in `buildRemoteAnswer()`. Without MID negotiated, PeerConnection falls back to SSRC/PT-based routing. This must be done for ALL m-lines (including audio) because the BUNDLE transport shares the extension map across all channels.
|
||||
|
||||
### `DiscardPacketsWithUnknownSsrc` Is Process-Wide
|
||||
CustomImpl calls `field_trial::InitFieldTrialsFromString(...)` which sets `WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/` globally for the process. In mixed groups, this prevents ReferenceImpl's PeerConnection from creating unsignaled receive streams for incoming video. Fix: include explicit remote video SSRCs in the `buildRemoteAnswer()` for incoming video m-lines, so PeerConnection registers SSRC-based demux entries instead of relying on unsignaled stream handling.
|
||||
|
||||
### `OnTrack` Doesn't Fire for Locally-Created Recvonly Transceivers
|
||||
When you call `AddTransceiver(MEDIA_TYPE_VIDEO, {direction=recvonly})`, PeerConnection creates the transceiver and its receiver track immediately. `OnTrack` only fires when a REMOTE-initiated track is added. For locally-created recvonly transceivers, you must wire sinks explicitly after `SetRemoteDescription` completes — don't wait for `OnTrack`.
|
||||
|
||||
### SSRC Parsing: json11 int_value() Overflows for uint32 > INT_MAX
|
||||
`GoSfu_QueryVideoSsrcs` returns SSRCs as `uint32` in JSON. For values > 2^31, json11's `int_value()` (which returns `int`) overflows to `INT_MAX` (2147483647). Fix: use `number_value()` (returns `double`) and cast via `int64_t` to `uint32_t`.
|
||||
|
||||
### Join Payload JSON Field Name: `"sources"` Not `"ssrcs"`
|
||||
tgcalls serializes video SSRC groups in `GroupJoinInternalPayload::serialize()` using the key `"sources"` (not `"ssrcs"`). The Go SFU's JSON struct tags must match: `Sources []int32 \`json:"sources"\``.
|
||||
|
||||
### Simulcast Max Layers Depends on Source Resolution, Not Bitrate
|
||||
WebRTC's `kSimulcastFormats` table in `video/config/simulcast.cc` hardcodes `max_layers` per resolution: 640x360 → 2 layers, 960x540 → 3 layers, 1280x720 → 3 layers. The `SimulcastEncoderAdapter` uses this to cap the number of encoders regardless of available bitrate. If you need 3 simulcast layers, the source must be at least 960x540. The `FakeVideoTrackSource` uses 1280x720 for this reason. With 1280x720 and scale factors /4, /2, /1, the layers are 320x180, 640x360, 1280x720.
|
||||
|
||||
### SFU Must Rewrite SSRCs When Switching Simulcast Layers
|
||||
CustomImpl's `IncomingVideoChannel` calls `SetSink(_mainVideoSsrc, ...)` where `_mainVideoSsrc` is the first SSRC in the SIM group (layer 0). The video sink only receives decoded frames from that specific SSRC's receive stream. When the SFU forwards a higher layer's packets, it must rewrite bytes 8-11 of the RTP header to the primary (layer 0) SSRC. RTX packets must similarly be rewritten to the layer 0 FID SSRC. Without this, higher-layer packets are delivered to the wrong receive stream and produce zero decoded frames. This is standard SFU behavior for simulcast — Jitsi and mediasoup do the same.
|
||||
|
||||
### Sender BWE Start Bitrate Determines Initial Layer Count
|
||||
`adjustBitratePreferences` sets `start_bitrate_bps = max(min_bitrate_bps, 400k)`. At 400kbps start, the `BitrateAllocator` gives L0 (60k) + L1 (110k) = 170k, leaving only 230k for L2 which needs min 300k. Layer 2 is disabled until the GCC ramps up. The SFU's transport-cc feedback enables this ramp-up. The `UpdateAllocationLimits` log shows `total_requested_max_bitrate` — if this is below the sum of all layers' min bitrates, some layers are excluded.
|
||||
|
||||
### `assignPayloadTypes` Codec Ordering
|
||||
WebRTC's `assignPayloadTypes` assigns dynamic PTs starting at 100 in order: VP8 (100/101), VP9 (102/103), H264 (104/105). Both sender and receiver call this independently with the same codec list, so PTs match. The SFU's join response codec PTs (100 for H264 in our case) are used by `configureVideoParams` to SELECT which codec to use, but the actual PT assignment comes from `assignPayloadTypes`.
|
||||
|
||||
## Known Issues
|
||||
- `ThreadLocalObject::~ThreadLocalObject()` posts fire-and-forget cleanup tasks to the tgcalls media thread. If the process does orderly static destruction, the static thread pool may be torn down while these tasks are still executing, causing "pure virtual function called". The CLI tool uses `_exit()` to avoid this. This is not a problem in the real Telegram app.
|
||||
- `SignalingSctpConnection::OnReadyToSend()` had a missing `break` after the first send failure in its pending-data flush loop. This could cause application-level message reordering (though the application handles it gracefully via `_pendingIceCandidates` buffering). Fixed in our fork.
|
||||
- `InstanceV2ReferenceImpl::writeStateLogRecords()` had a use-after-free: it captured a raw `Call*` pointer on the media thread and posted it to the worker thread. If `stop()` called `_peerConnection->Close()` (which destroys `Call`) between the post and worker thread execution, the worker thread would dereference a dangling pointer. The `call_ptr_` field in WebRTC's `PeerConnection` is `Call* const` and is never nulled, so the existing null check didn't catch this. Fixed with an `_isStopped` atomic flag checked in the worker thread lambda before accessing `call`. Manifested as ~2% segfault rate under 250-process parallel load; 100% pass rate after fix (5000/5000).
|
||||
- WebRTC's `RTC_LOG` writes to stdout, not stderr. There is no way to separate it from application output within a single process. The local mass test harness (`run-local-test.sh`) works around this by using separate processes and checking exit codes rather than parsing output.
|
||||
|
|
@ -291,8 +291,10 @@ final class WebAppWebView: WKWebView {
|
|||
}
|
||||
|
||||
func sendEvent(name: String, data: String?) {
|
||||
guard let trustedOrigin = self.trustedOrigin, self.origin == trustedOrigin else {
|
||||
return
|
||||
if self.useSecuredEventProxy {
|
||||
guard let trustedOrigin = self.trustedOrigin, self.origin == trustedOrigin else {
|
||||
return
|
||||
}
|
||||
}
|
||||
let script = "window.TelegramGameProxy && window.TelegramGameProxy.receiveEvent && window.TelegramGameProxy.receiveEvent(\"\(name)\", \(data ?? "null"))"
|
||||
self.evaluateJavaScript(script, completionHandler: { _, _ in
|
||||
|
|
|
|||
32
submodules/ffmpeg/BUILD
vendored
32
submodules/ffmpeg/BUILD
vendored
|
|
@ -271,6 +271,13 @@ genrule(
|
|||
elif [ "$(TARGET_CPU)" == "ios_sim_arm64" ]; then
|
||||
BUILD_ARCH="sim_arm64"
|
||||
VARIANT="debug"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
VARIANT="debug"
|
||||
elif [ "$(TARGET_CPU)" == "k8" ] || [ "$(TARGET_CPU)" == "x86_64" ]; then
|
||||
BUILD_ARCH="linux_x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "aarch64" ] || [ "$(TARGET_CPU)" == "arm64" ]; then
|
||||
BUILD_ARCH="linux_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
@ -301,24 +308,21 @@ cc_library(
|
|||
]
|
||||
)
|
||||
|
||||
objc_library(
|
||||
cc_library(
|
||||
name = "ffmpeg",
|
||||
module_name = "ffmpeg",
|
||||
enable_modules = True,
|
||||
hdrs = ["Public/third_party/ffmpeg/" + x for x in ffmpeg_header_paths] + ["Public/" + x for x in ffmpeg_header_paths],
|
||||
includes = [
|
||||
"Public",
|
||||
],
|
||||
sdk_dylibs = [
|
||||
"libbz2",
|
||||
"libiconv",
|
||||
"z",
|
||||
],
|
||||
sdk_frameworks = [
|
||||
"AudioToolbox",
|
||||
"CoreAudio",
|
||||
"VideoToolbox"
|
||||
],
|
||||
linkopts = select({
|
||||
"@platforms//os:linux": ["-lbz2", "-lz"],
|
||||
"//conditions:default": [
|
||||
"-lbz2", "-liconv", "-lz",
|
||||
"-framework AudioToolbox",
|
||||
"-framework CoreAudio",
|
||||
"-framework VideoToolbox",
|
||||
],
|
||||
}),
|
||||
deps = [
|
||||
":ffmpeg_lib",
|
||||
"//third-party/libvpx:vpx",
|
||||
|
|
@ -327,5 +331,5 @@ objc_library(
|
|||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
]
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ ARCHS=""
|
|||
|
||||
for RAW_ARCH in $RAW_ARCHS; do
|
||||
ARCH_NAME="$RAW_ARCH"
|
||||
if [ "$ARCH_NAME" = "i386" -o "$ARCH_NAME" = "x86_64" -o "$ARCH_NAME" = "arm64" -o "$ARCH_NAME" = "armv7" -o "$ARCH_NAME" = "sim_arm64" ]
|
||||
if [ "$ARCH_NAME" = "i386" -o "$ARCH_NAME" = "x86_64" -o "$ARCH_NAME" = "arm64" -o "$ARCH_NAME" = "armv7" -o "$ARCH_NAME" = "sim_arm64" -o "$ARCH_NAME" = "macos_arm64" -o "$ARCH_NAME" = "linux_arm64" -o "$ARCH_NAME" = "linux_x86_64" ]
|
||||
then
|
||||
ARCHS="$ARCHS $ARCH_NAME"
|
||||
else
|
||||
|
|
@ -38,24 +38,21 @@ LIB_NAMES="libavcodec libavformat libavutil libswresample"
|
|||
set -e
|
||||
|
||||
CONFIGURE_FLAGS="--enable-cross-compile --disable-programs \
|
||||
--disable-armv5te --disable-armv6 --disable-armv6t2 \
|
||||
--disable-armv5te --disable-armv6 --disable-armv6t2 \
|
||||
--disable-doc --enable-pic --disable-all --disable-everything \
|
||||
--enable-avcodec \
|
||||
--enable-swresample \
|
||||
--enable-avformat \
|
||||
--disable-xlib \
|
||||
--enable-libopus \
|
||||
--enable-libvpx \
|
||||
--enable-libdav1d \
|
||||
--enable-audiotoolbox \
|
||||
--enable-libvpx \
|
||||
--enable-libdav1d \
|
||||
--enable-bsf=aac_adtstoasc,vp9_superframe,h264_mp4toannexb \
|
||||
--enable-decoder=h264,libvpx_vp9,hevc,libopus,flac,alac_at,pcm_s16le,pcm_s24le,pcm_f32le,gsm_ms_at,libdav1d,av1,mp3,aac_at \
|
||||
--enable-encoder=libvpx_vp9,aac_at \
|
||||
--enable-decoder=h264,libvpx_vp9,hevc,libopus,flac,pcm_s16le,pcm_s24le,pcm_f32le,libdav1d,av1,mp3 \
|
||||
--enable-demuxer=aac,mov,m4v,mp3,ogg,libopus,flac,wav,aiff,matroska,mpegts, \
|
||||
--enable-parser=aac,h264,mp3,libopus \
|
||||
--enable-protocol=file \
|
||||
--enable-muxer=mp4,matroska,ogg,mpegts \
|
||||
--enable-hwaccel=h264_videotoolbox,hevc_videotoolbox,av1_videotoolbox \
|
||||
"
|
||||
|
||||
#vorbis
|
||||
|
|
@ -84,7 +81,7 @@ do
|
|||
do
|
||||
LIB="$THIN/$ARCH/lib/$LIB_NAME.a"
|
||||
if [ -f "$LIB" ]; then
|
||||
LIB_DATE=`crc32 "$LIB"`
|
||||
LIB_DATE=$(crc32 "$LIB" 2>/dev/null || cksum "$LIB" 2>/dev/null | cut -d' ' -f1 || echo "unknown")
|
||||
LIBS_HASH="$LIBS_HASH $ARCH/$LIB:$LIB_DATE"
|
||||
fi
|
||||
done
|
||||
|
|
@ -99,7 +96,11 @@ then
|
|||
echo "PATH=$PATH"
|
||||
echo "pkg-config=$(which pkg-config)"
|
||||
fi
|
||||
if [ ! `which "$GAS_PREPROCESSOR_PATH"` ]; then
|
||||
IS_LINUX=false
|
||||
for A in $ARCHS; do
|
||||
case "$A" in linux_*) IS_LINUX=true ;; esac
|
||||
done
|
||||
if [ "$IS_LINUX" = "false" ] && [ ! `which "$GAS_PREPROCESSOR_PATH"` ]; then
|
||||
echo '$GAS_PREPROCESSOR_PATH not found.'
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -114,6 +115,8 @@ then
|
|||
ARCH="$RAW_ARCH"
|
||||
if [ "$RAW_ARCH" == "sim_arm64" ]; then
|
||||
ARCH="arm64"
|
||||
elif [ "$RAW_ARCH" == "macos_arm64" ]; then
|
||||
ARCH="arm64"
|
||||
fi
|
||||
|
||||
echo "building $RAW_ARCH..."
|
||||
|
|
@ -124,10 +127,26 @@ then
|
|||
LIBVPX_PATH="$SOURCE_DIR/libvpx"
|
||||
LIBDAV1D_PATH="$SOURCE_DIR/libdav1d"
|
||||
|
||||
if [ "$RAW_ARCH" = "linux_arm64" ]; then
|
||||
ARCH="aarch64"
|
||||
CFLAGS="$EXTRA_CFLAGS -fPIC"
|
||||
CC="gcc"
|
||||
AS="gcc"
|
||||
PLATFORM="linux"
|
||||
elif [ "$RAW_ARCH" = "linux_x86_64" ]; then
|
||||
ARCH="x86_64"
|
||||
CFLAGS="$EXTRA_CFLAGS -fPIC"
|
||||
CC="gcc"
|
||||
AS="nasm"
|
||||
PLATFORM="linux"
|
||||
else
|
||||
CFLAGS="$EXTRA_CFLAGS -arch $ARCH"
|
||||
if [ "$RAW_ARCH" = "sim_arm64" ]; then
|
||||
PLATFORM="iPhoneSimulator"
|
||||
CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET --target=arm64-apple-ios$DEPLOYMENT_TARGET-simulator"
|
||||
elif [ "$RAW_ARCH" = "macos_arm64" ]; then
|
||||
PLATFORM="MacOSX"
|
||||
CFLAGS="$CFLAGS -mmacosx-version-min=14.0 --target=arm64-apple-macosx14.0"
|
||||
else
|
||||
PLATFORM="iPhoneOS"
|
||||
CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET"
|
||||
|
|
@ -136,15 +155,18 @@ then
|
|||
EXPORT="GASPP_FIX_XCODE5=1"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
|
||||
CC="xcrun -sdk $XCRUN_SDK clang"
|
||||
if [ "$PLATFORM" != "linux" ]; then
|
||||
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
|
||||
CC="xcrun -sdk $XCRUN_SDK clang"
|
||||
|
||||
if [ "$RAW_ARCH" = "arm64" ] || [ "$RAW_ARCH" = "sim_arm64" ]
|
||||
then
|
||||
AS="$GAS_PREPROCESSOR_PATH -arch aarch64 -- $CC"
|
||||
else
|
||||
AS="$GAS_PREPROCESSOR_PATH -- $CC"
|
||||
if [ "$RAW_ARCH" = "arm64" ] || [ "$RAW_ARCH" = "sim_arm64" ] || [ "$RAW_ARCH" = "macos_arm64" ]
|
||||
then
|
||||
AS="$GAS_PREPROCESSOR_PATH -arch aarch64 -- $CC"
|
||||
else
|
||||
AS="$GAS_PREPROCESSOR_PATH -- $CC"
|
||||
fi
|
||||
fi
|
||||
|
||||
CXXFLAGS="$CFLAGS"
|
||||
|
|
@ -161,22 +183,42 @@ then
|
|||
echo "1" >/dev/null
|
||||
else
|
||||
mkdir -p "$THIN/$RAW_ARCH"
|
||||
TMPDIR=${TMPDIR/%\/} "$SOURCE/configure" \
|
||||
--target-os=darwin \
|
||||
--arch=$ARCH \
|
||||
--cc="$CC" \
|
||||
--as="$AS" \
|
||||
$CONFIGURE_FLAGS \
|
||||
--extra-cflags="$CFLAGS" \
|
||||
--extra-ldflags="$LDFLAGS" \
|
||||
--prefix="$THIN/$RAW_ARCH" \
|
||||
--pkg-config="$PKG_CONFIG" \
|
||||
--pkg-config-flags="--libopus_path $LIBOPUS_PATH --libvpx_path $LIBVPX_PATH --libdav1d_path $LIBDAV1D_PATH" \
|
||||
|| exit 1
|
||||
if [ "$PLATFORM" = "linux" ]; then
|
||||
TMPDIR=${TMPDIR/%\/} "$SOURCE/configure" \
|
||||
--target-os=linux \
|
||||
--arch=$ARCH \
|
||||
--cc="$CC" \
|
||||
--as="$AS" \
|
||||
$CONFIGURE_FLAGS \
|
||||
--enable-encoder=libvpx_vp9 \
|
||||
--extra-cflags="$CFLAGS" \
|
||||
--extra-ldflags="$LDFLAGS" \
|
||||
--prefix="$THIN/$RAW_ARCH" \
|
||||
--pkg-config="$PKG_CONFIG" \
|
||||
--pkg-config-flags="--libopus_path $LIBOPUS_PATH --libvpx_path $LIBVPX_PATH --libdav1d_path $LIBDAV1D_PATH" \
|
||||
|| exit 1
|
||||
else
|
||||
TMPDIR=${TMPDIR/%\/} "$SOURCE/configure" \
|
||||
--target-os=darwin \
|
||||
--arch=$ARCH \
|
||||
--cc="$CC" \
|
||||
--as="$AS" \
|
||||
$CONFIGURE_FLAGS \
|
||||
--enable-audiotoolbox \
|
||||
--enable-decoder=alac_at,gsm_ms_at,aac_at \
|
||||
--enable-encoder=libvpx_vp9,aac_at \
|
||||
--enable-hwaccel=h264_videotoolbox,hevc_videotoolbox,av1_videotoolbox \
|
||||
--extra-cflags="$CFLAGS" \
|
||||
--extra-ldflags="$LDFLAGS" \
|
||||
--prefix="$THIN/$RAW_ARCH" \
|
||||
--pkg-config="$PKG_CONFIG" \
|
||||
--pkg-config-flags="--libopus_path $LIBOPUS_PATH --libvpx_path $LIBVPX_PATH --libdav1d_path $LIBDAV1D_PATH" \
|
||||
|| exit 1
|
||||
fi
|
||||
echo "$CONFIGURE_FLAGS" > "$CONFIGURED_MARKER"
|
||||
fi
|
||||
|
||||
CORE_COUNT=`PATH="$PATH:/usr/sbin" sysctl -n hw.logicalcpu`
|
||||
CORE_COUNT=$(nproc 2>/dev/null || PATH="$PATH:/usr/sbin" sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
|
||||
make -j$CORE_COUNT install $EXPORT || exit 1
|
||||
|
||||
popd
|
||||
|
|
@ -190,7 +232,7 @@ do
|
|||
do
|
||||
LIB="$THIN/$ARCH/lib/$LIB_NAME.a"
|
||||
if [ -f "$LIB" ]; then
|
||||
LIB_DATE=`crc32 "$LIB"`
|
||||
LIB_DATE=$(crc32 "$LIB" 2>/dev/null || cksum "$LIB" 2>/dev/null | cut -d' ' -f1 || echo "unknown")
|
||||
UPDATED_LIBS_HASH="$UPDATED_LIBS_HASH $ARCH/$LIB:$LIB_DATE"
|
||||
fi
|
||||
done
|
||||
|
|
@ -215,7 +257,11 @@ then
|
|||
LIB_NAME="$(basename $LIB)"
|
||||
echo "LIPO_INPUT command find \"$THIN\" -name \"$LIB_NAME\""
|
||||
LIPO_INPUT=`find "$THIN" -name "$LIB_NAME"`
|
||||
lipo -create $LIPO_INPUT -output "$FAT/lib/$LIB_NAME" || exit 1
|
||||
if command -v lipo >/dev/null 2>&1; then
|
||||
lipo -create $LIPO_INPUT -output "$FAT/lib/$LIB_NAME" || exit 1
|
||||
else
|
||||
cp $LIPO_INPUT "$FAT/lib/$LIB_NAME" || exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
cp -rf "$THIN/$1/include" "$FAT"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# Strip version qualifiers (e.g. "dav1d >= 0.5.0" -> "dav1d")
|
||||
# FFmpeg's configure passes these to pkg-config
|
||||
strip_version() {
|
||||
echo "$@" | sed 's/ *[><=!].*//'
|
||||
}
|
||||
|
||||
if [ "$1" == "--version" ]; then
|
||||
echo "0.29.2"
|
||||
|
|
@ -7,8 +13,10 @@ elif [ "$1" == "--exists" ]; then
|
|||
NAME="$2"
|
||||
PRINT_ERRORS="0"
|
||||
if [ "$NAME" == "--print-errors" ]; then
|
||||
NAME="$3"
|
||||
NAME=$(strip_version "$3")
|
||||
PRINT_ERRORS="1"
|
||||
else
|
||||
NAME=$(strip_version "$2")
|
||||
fi
|
||||
if [ "$NAME" == "zlib" ]; then
|
||||
exit 0
|
||||
|
|
@ -87,17 +95,53 @@ elif [ "$1" == "--libs" ]; then
|
|||
echo "-lz"
|
||||
exit 0
|
||||
elif [ "$NAME" == "opus" ]; then
|
||||
echo "-L$LIBOPUS_PATH/lib -lopus"
|
||||
echo "-L$LIBOPUS_PATH/lib -lopus -lm"
|
||||
exit 0
|
||||
elif [ "$NAME" == "vpx" ]; then
|
||||
echo "-L$LIBVPX_PATH/lib -lVPX"
|
||||
echo "-L$LIBVPX_PATH/lib -lVPX -lm -lpthread"
|
||||
exit 0
|
||||
elif [ "$NAME" == "dav1d" ]; then
|
||||
echo "-L$LIBDAV1D_PATH/lib -ldav1d"
|
||||
echo "-L$LIBDAV1D_PATH/lib -ldav1d -lm -lpthread -ldl"
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$1" == --variable=* ]]; then
|
||||
# Handle --variable=includedir etc.
|
||||
LIBOPUS_PATH=""
|
||||
LIBVPX_PATH=""
|
||||
LIBDAV1D_PATH=""
|
||||
# Parse the library path flags to find NAME (last arg)
|
||||
ARGS=("$@")
|
||||
NAME="${ARGS[-1]}"
|
||||
for ((i=1; i<${#ARGS[@]}-1; i++)); do
|
||||
if [ "${ARGS[$i]}" == "--libopus_path" ]; then
|
||||
LIBOPUS_PATH="${ARGS[$((i+1))]}"
|
||||
elif [ "${ARGS[$i]}" == "--libvpx_path" ]; then
|
||||
LIBVPX_PATH="${ARGS[$((i+1))]}"
|
||||
elif [ "${ARGS[$i]}" == "--libdav1d_path" ]; then
|
||||
LIBDAV1D_PATH="${ARGS[$((i+1))]}"
|
||||
fi
|
||||
done
|
||||
VAR="${1#--variable=}"
|
||||
if [ "$VAR" == "includedir" ]; then
|
||||
if [ "$NAME" == "opus" ]; then
|
||||
echo "$LIBOPUS_PATH/include"
|
||||
exit 0
|
||||
elif [ "$NAME" == "vpx" ]; then
|
||||
echo "$LIBVPX_PATH/include"
|
||||
exit 0
|
||||
elif [ "$NAME" == "dav1d" ]; then
|
||||
echo "$LIBDAV1D_PATH/include"
|
||||
exit 0
|
||||
elif [ "$NAME" == "zlib" ]; then
|
||||
echo "/usr/include"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
# Return empty string for unhandled variables (non-fatal)
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
5
third-party/boringssl/src/crypto/internal.h
vendored
5
third-party/boringssl/src/crypto/internal.h
vendored
|
|
@ -1170,7 +1170,8 @@ static inline uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) {
|
|||
|
||||
// CRYPTO_addc_* returns |x + y + carry|, and sets |*out_carry| to the carry
|
||||
// bit. |carry| must be zero or one.
|
||||
#if OPENSSL_HAS_BUILTIN(__builtin_addc)
|
||||
// _Generic is C11-only and not available in C++ mode with GCC.
|
||||
#if OPENSSL_HAS_BUILTIN(__builtin_addc) && !defined(__cplusplus)
|
||||
|
||||
#define CRYPTO_GENERIC_ADDC(x, y, carry, out_carry) \
|
||||
(_Generic((x), \
|
||||
|
|
@ -1222,7 +1223,7 @@ static inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry,
|
|||
|
||||
// CRYPTO_subc_* returns |x - y - borrow|, and sets |*out_borrow| to the borrow
|
||||
// bit. |borrow| must be zero or one.
|
||||
#if OPENSSL_HAS_BUILTIN(__builtin_subc)
|
||||
#if OPENSSL_HAS_BUILTIN(__builtin_subc) && !defined(__cplusplus)
|
||||
|
||||
#define CRYPTO_GENERIC_SUBC(x, y, borrow, out_borrow) \
|
||||
(_Generic((x), \
|
||||
|
|
|
|||
37
third-party/dav1d/BUILD
vendored
37
third-party/dav1d/BUILD
vendored
|
|
@ -49,6 +49,12 @@ genrule(
|
|||
BUILD_ARCH="arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_sim_arm64" ]; then
|
||||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "k8" ] || [ "$(TARGET_CPU)" == "x86_64" ]; then
|
||||
BUILD_ARCH="linux_x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "aarch64" ] || [ "$(TARGET_CPU)" == "arm64" ]; then
|
||||
BUILD_ARCH="linux_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
@ -57,15 +63,20 @@ genrule(
|
|||
rm -rf "$$BUILD_DIR"
|
||||
mkdir -p "$$BUILD_DIR"
|
||||
|
||||
MESON_DIR="$$(pwd)/$$BUILD_DIR/meson"
|
||||
rm -rf "$$MESON_DIR"
|
||||
mkdir -p "$$MESON_DIR"
|
||||
tar -xzf "$(location @meson_tar_gz//file)" -C "$$MESON_DIR"
|
||||
if [ "$${BUILD_ARCH}" = "linux_x86_64" ] || [ "$${BUILD_ARCH}" = "linux_arm64" ]; then
|
||||
EXTRA_PATH=""
|
||||
else
|
||||
MESON_DIR="$$(pwd)/$$BUILD_DIR/meson"
|
||||
rm -rf "$$MESON_DIR"
|
||||
mkdir -p "$$MESON_DIR"
|
||||
tar -xzf "$(location @meson_tar_gz//file)" -C "$$MESON_DIR"
|
||||
|
||||
NINJA_DIR="$$(pwd)/$$BUILD_DIR/ninja"
|
||||
rm -rf "$$NINJA_DIR"
|
||||
mkdir -p "$$NINJA_DIR"
|
||||
unzip "$(location @ninja-mac_zip//file)" -d "$$NINJA_DIR"
|
||||
NINJA_DIR="$$(pwd)/$$BUILD_DIR/ninja"
|
||||
rm -rf "$$NINJA_DIR"
|
||||
mkdir -p "$$NINJA_DIR"
|
||||
unzip "$(location @ninja-mac_zip//file)" -d "$$NINJA_DIR"
|
||||
EXTRA_PATH="$$MESON_DIR/meson-1.6.0:$$NINJA_DIR"
|
||||
fi
|
||||
|
||||
cp $(location :build-dav1d-bazel.sh) "$$BUILD_DIR/"
|
||||
cp $(location :arm64-iPhoneSimulator.meson) "$$BUILD_DIR/"
|
||||
|
|
@ -78,7 +89,11 @@ genrule(
|
|||
mkdir -p "$$BUILD_DIR/Public/compat"
|
||||
mkdir -p "$$BUILD_DIR/Public/common"
|
||||
|
||||
PATH="$$PATH:$$MESON_DIR/meson-1.6.0:$$NINJA_DIR" sh $$BUILD_DIR/build-dav1d-bazel.sh $$BUILD_ARCH "$$BUILD_DIR"
|
||||
if [ -n "$$EXTRA_PATH" ]; then
|
||||
PATH="$$PATH:$$EXTRA_PATH" bash $$BUILD_DIR/build-dav1d-bazel.sh $$BUILD_ARCH "$$BUILD_DIR"
|
||||
else
|
||||
bash $$BUILD_DIR/build-dav1d-bazel.sh $$BUILD_ARCH "$$BUILD_DIR"
|
||||
fi
|
||||
""" +
|
||||
"\n".join([
|
||||
"cp -f \"$$BUILD_DIR/dav1d/build/include/{}\" \"$(location Public/{})\"".format(header, header) for header in generated_headers
|
||||
|
|
@ -104,10 +119,8 @@ cc_library(
|
|||
srcs = [":Public/dav1d/lib/lib" + x + ".a" for x in libs]
|
||||
)
|
||||
|
||||
objc_library(
|
||||
cc_library(
|
||||
name = "dav1d",
|
||||
module_name = "dav1d",
|
||||
enable_modules = True,
|
||||
hdrs = [":Public/" + x for x in generated_headers],
|
||||
includes = [
|
||||
"Public",
|
||||
|
|
|
|||
47
third-party/dav1d/build-dav1d-bazel.sh
vendored
47
third-party/dav1d/build-dav1d-bazel.sh
vendored
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
|
|
@ -18,6 +18,43 @@ elif [ "$ARCH" = "sim_arm64" ]; then
|
|||
custom_xcode_path="$(xcode-select -p)/"
|
||||
sed -i '' "s|/Applications/Xcode.app/Contents/Developer/|$custom_xcode_path|g" "$TARGET_CROSSFILE"
|
||||
CROSSFILE="../package/crossfiles/arm64-iPhoneSimulator-custom.meson"
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
TARGET_CROSSFILE="$BUILD_DIR/dav1d/package/crossfiles/arm64-MacOSX-custom.meson"
|
||||
custom_xcode_path="$(xcode-select -p)"
|
||||
MACOS_SYSROOT="$custom_xcode_path/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
cat > "$TARGET_CROSSFILE" << MESONEOF
|
||||
[binaries]
|
||||
c = ['clang', '-arch', 'arm64', '-isysroot', '$MACOS_SYSROOT']
|
||||
cpp = ['clang++', '-arch', 'arm64', '-isysroot', '$MACOS_SYSROOT']
|
||||
objc = ['clang', '-arch', 'arm64', '-isysroot', '$MACOS_SYSROOT']
|
||||
objcpp = ['clang++', '-arch', 'arm64', '-isysroot', '$MACOS_SYSROOT']
|
||||
ar = 'ar'
|
||||
strip = 'strip'
|
||||
|
||||
[built-in options]
|
||||
c_args = ['-mmacosx-version-min=14.0']
|
||||
cpp_args = ['-mmacosx-version-min=14.0']
|
||||
c_link_args = ['-mmacosx-version-min=14.0']
|
||||
cpp_link_args = ['-mmacosx-version-min=14.0']
|
||||
objc_args = ['-mmacosx-version-min=14.0']
|
||||
objcpp_args = ['-mmacosx-version-min=14.0']
|
||||
|
||||
[properties]
|
||||
root = '$custom_xcode_path/Platforms/MacOSX.platform/Developer'
|
||||
needs_exe_wrapper = false
|
||||
|
||||
[host_machine]
|
||||
system = 'darwin'
|
||||
subsystem = 'macos'
|
||||
kernel = 'xnu'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'arm64'
|
||||
endian = 'little'
|
||||
MESONEOF
|
||||
CROSSFILE="../package/crossfiles/arm64-MacOSX-custom.meson"
|
||||
elif [ "$ARCH" = "linux_arm64" ] || [ "$ARCH" = "linux_x86_64" ]; then
|
||||
# Native Linux build - no cross file needed
|
||||
CROSSFILE=""
|
||||
else
|
||||
echo "Unsupported architecture $ARCH"
|
||||
exit 1
|
||||
|
|
@ -28,7 +65,13 @@ rm -rf build
|
|||
mkdir build
|
||||
pushd build
|
||||
|
||||
meson.py setup .. --cross-file="$CROSSFILE" $MESON_OPTIONS
|
||||
MESON_CMD=$(command -v meson.py 2>/dev/null || command -v meson 2>/dev/null || echo meson.py)
|
||||
|
||||
if [ -n "$CROSSFILE" ]; then
|
||||
$MESON_CMD setup .. --cross-file="$CROSSFILE" $MESON_OPTIONS
|
||||
else
|
||||
$MESON_CMD setup .. $MESON_OPTIONS
|
||||
fi
|
||||
ninja
|
||||
|
||||
popd
|
||||
|
|
|
|||
2
third-party/libjxl/BUILD
vendored
2
third-party/libjxl/BUILD
vendored
|
|
@ -57,6 +57,8 @@ genrule(
|
|||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then
|
||||
BUILD_ARCH="x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
|
|||
19
third-party/libjxl/build-libjxl-bazel.sh
vendored
19
third-party/libjxl/build-libjxl-bazel.sh
vendored
|
|
@ -33,7 +33,24 @@ elif [ "$ARCH" = "sim_arm64" ]; then
|
|||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneSimulator*.sdk)
|
||||
export CFLAGS="-Wall -arch arm64 --target=arm64-apple-ios13.0-simulator -miphonesimulator-version-min=13.0 -funwind-tables"
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
touch toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_NAME Darwin)" >> toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> toolchain.cmake
|
||||
echo "set(CMAKE_C_COMPILER $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)" >> toolchain.cmake
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} $CMAKE_OPTIONS ../libjxl
|
||||
make
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
IOS_PLATFORMDIR="$(xcode-select -p)/Platforms/MacOSX.platform"
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/MacOSX*.sdk)
|
||||
export CFLAGS="-Wall -arch arm64 --target=arm64-apple-macosx14.0 -mmacosx-version-min=14.0 -funwind-tables"
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
mkdir build
|
||||
cd build
|
||||
|
|
|
|||
15
third-party/libvpx/BUILD
vendored
15
third-party/libvpx/BUILD
vendored
|
|
@ -49,6 +49,15 @@ genrule(
|
|||
elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then
|
||||
BUILD_ARCH="x86_64"
|
||||
PLATFORM_HEADER_DIR="x86_64-iphonesimulator-gcc"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
PLATFORM_HEADER_DIR="arm64-darwin22-gcc"
|
||||
elif [ "$(TARGET_CPU)" == "k8" ] || [ "$(TARGET_CPU)" == "x86_64" ]; then
|
||||
BUILD_ARCH="linux_x86_64"
|
||||
PLATFORM_HEADER_DIR="x86_64-linux-gcc"
|
||||
elif [ "$(TARGET_CPU)" == "aarch64" ] || [ "$(TARGET_CPU)" == "arm64" ]; then
|
||||
BUILD_ARCH="linux_arm64"
|
||||
PLATFORM_HEADER_DIR="arm64-linux-gcc"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
@ -76,7 +85,7 @@ genrule(
|
|||
|
||||
mkdir -p "$$BUILD_DIR/Public/libvpx"
|
||||
|
||||
PATH="$$PATH:$$ABS_YASM_DIR" sh $$BUILD_DIR/build-libvpx-bazel.sh $$BUILD_ARCH "$$BUILD_DIR/libvpx" "$$BUILD_DIR"
|
||||
PATH="$$PATH:$$ABS_YASM_DIR" bash $$BUILD_DIR/build-libvpx-bazel.sh $$BUILD_ARCH "$$BUILD_DIR/libvpx" "$$BUILD_DIR"
|
||||
""" +
|
||||
"\n".join([
|
||||
"cp -f \"$$BUILD_DIR/VPX.framework/Headers/vpx/{}\" \"$(location Public/vpx/{})\"".format(header, header) for header in headers
|
||||
|
|
@ -102,10 +111,8 @@ cc_library(
|
|||
srcs = [":Public/vpx/lib" + x + ".a" for x in libs],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
cc_library(
|
||||
name = "vpx",
|
||||
module_name = "vpx",
|
||||
enable_modules = True,
|
||||
hdrs = [":Public/vpx/" + x for x in headers],
|
||||
includes = [
|
||||
"Public",
|
||||
|
|
|
|||
28
third-party/libvpx/build-libvpx-bazel.sh
vendored
Executable file → Normal file
28
third-party/libvpx/build-libvpx-bazel.sh
vendored
Executable file → Normal file
|
|
@ -1,4 +1,4 @@
|
|||
#! /bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
|
@ -33,18 +33,34 @@ SCRIPT_DIR="$SOURCE_DIR"
|
|||
LIBVPX_SOURCE_DIR="$SOURCE_DIR"
|
||||
|
||||
|
||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
|
||||
ORIG_PWD="$(pwd)"
|
||||
|
||||
EXTRA_CONFIGURE_ARGS=""
|
||||
|
||||
if [ "$ARCH" = "armv7" ]; then
|
||||
TARGETS="armv7-darwin-gcc"
|
||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
elif [ "$ARCH" = "arm64" ]; then
|
||||
TARGETS="arm64-darwin-gcc"
|
||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
elif [ "$ARCH" = "sim_arm64" ]; then
|
||||
TARGETS="arm64-iphonesimulator-gcc"
|
||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
TARGETS="arm64-darwin22-gcc"
|
||||
LIPO=$(xcrun -sdk macosx -find lipo)
|
||||
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
|
||||
elif [ "$ARCH" = "linux_arm64" ]; then
|
||||
TARGETS="arm64-linux-gcc"
|
||||
LIPO="cp"
|
||||
EXTRA_CONFIGURE_ARGS="--enable-pic"
|
||||
elif [ "$ARCH" = "linux_x86_64" ]; then
|
||||
TARGETS="x86_64-linux-gcc"
|
||||
LIPO="cp"
|
||||
EXTRA_CONFIGURE_ARGS="--enable-pic"
|
||||
elif [ "$ARCH" = "x86_64" ]; then
|
||||
TARGETS="x86_64-iphonesimulator-gcc"
|
||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
else
|
||||
echo "Unsupported architecture $ARCH"
|
||||
exit 1
|
||||
|
|
@ -167,7 +183,11 @@ build_framework() {
|
|||
cp -p "${target_dist_dir}"/include/vpx/* "${HEADER_DIR}"
|
||||
|
||||
# Build the fat library.
|
||||
${LIPO} -create ${lib_list} -output ${FRAMEWORK_DIR}/VPX
|
||||
if [ "$LIPO" = "cp" ]; then
|
||||
cp ${lib_list} ${FRAMEWORK_DIR}/VPX
|
||||
else
|
||||
${LIPO} -create ${lib_list} -output ${FRAMEWORK_DIR}/VPX
|
||||
fi
|
||||
|
||||
# Create the vpx_config.h shim that allows usage of vpx_config.h from
|
||||
# within VPX.framework.
|
||||
|
|
|
|||
4
third-party/libyuv/BUILD
vendored
4
third-party/libyuv/BUILD
vendored
|
|
@ -25,7 +25,9 @@ arch_specific_cflags = select({
|
|||
"@build_bazel_rules_apple//apple:ios_arm64": common_flags + arm64_specific_flags,
|
||||
"//build-system:ios_sim_arm64": common_flags + arm64_specific_flags,
|
||||
"@build_bazel_rules_apple//apple:ios_x86_64": common_flags + x86_64_specific_flags,
|
||||
"//conditions:default": common_flags,
|
||||
"//build-system:linux_arm64": common_flags + arm64_specific_flags,
|
||||
"//build-system:linux_x86_64": common_flags + x86_64_specific_flags,
|
||||
"//conditions:default": common_flags + arm64_specific_flags,
|
||||
})
|
||||
|
||||
cc_library(
|
||||
|
|
|
|||
2
third-party/mozjpeg/BUILD
vendored
2
third-party/mozjpeg/BUILD
vendored
|
|
@ -36,6 +36,8 @@ genrule(
|
|||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then
|
||||
BUILD_ARCH="x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
|
|||
16
third-party/mozjpeg/build-mozjpeg-bazel.sh
vendored
16
third-party/mozjpeg/build-mozjpeg-bazel.sh
vendored
|
|
@ -37,6 +37,22 @@ elif [ "$ARCH" = "sim_arm64" ]; then
|
|||
echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> toolchain.cmake
|
||||
echo "set(CMAKE_C_COMPILER $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)" >> toolchain.cmake
|
||||
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} -DPNG_SUPPORTED=FALSE -DENABLE_SHARED=FALSE -DWITH_JPEG8=1 -DBUILD=10000 -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ../mozjpeg
|
||||
make
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
IOS_PLATFORMDIR="$(xcode-select -p)/Platforms/MacOSX.platform"
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/MacOSX*.sdk)
|
||||
export CFLAGS="-Wall -arch arm64 --target=arm64-apple-macosx14.0 -mmacosx-version-min=14.0 -funwind-tables"
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
touch toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_NAME Darwin)" >> toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> toolchain.cmake
|
||||
echo "set(CMAKE_C_COMPILER $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)" >> toolchain.cmake
|
||||
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} -DPNG_SUPPORTED=FALSE -DENABLE_SHARED=FALSE -DWITH_JPEG8=1 -DBUILD=10000 -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ../mozjpeg
|
||||
make
|
||||
else
|
||||
|
|
|
|||
6
third-party/ogg/BUILD
vendored
6
third-party/ogg/BUILD
vendored
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
objc_library(
|
||||
|
||||
cc_library(
|
||||
name = "ogg",
|
||||
enable_modules = True,
|
||||
module_name = "ogg",
|
||||
srcs = glob([
|
||||
"Sources/*.c",
|
||||
"Sources/*.h",
|
||||
|
|
|
|||
15
third-party/ogg/include/ogg/config_types.h
vendored
Normal file
15
third-party/ogg/include/ogg/config_types.h
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef __CONFIG_TYPES_H__
|
||||
#define __CONFIG_TYPES_H__
|
||||
|
||||
/* Generated for Linux builds */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
typedef uint64_t ogg_uint64_t;
|
||||
|
||||
#endif
|
||||
3
third-party/openh264/BUILD
vendored
3
third-party/openh264/BUILD
vendored
|
|
@ -57,18 +57,21 @@ arch_specific_sources = select({
|
|||
"@build_bazel_rules_apple//apple:ios_arm64": arm64_specific_sources,
|
||||
"//build-system:ios_sim_arm64": arm64_specific_sources,
|
||||
"@build_bazel_rules_apple//apple:ios_x86_64": [],
|
||||
"//conditions:default": arm64_specific_sources,
|
||||
})
|
||||
|
||||
arch_specific_copts = select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": arm64_specific_copts,
|
||||
"//build-system:ios_sim_arm64": arm64_specific_copts,
|
||||
"@build_bazel_rules_apple//apple:ios_x86_64": [],
|
||||
"//conditions:default": arm64_specific_copts,
|
||||
})
|
||||
|
||||
arch_specific_textual_hdrs = select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": arm64_specific_textual_hdrs,
|
||||
"//build-system:ios_sim_arm64": arm64_specific_textual_hdrs,
|
||||
"@build_bazel_rules_apple//apple:ios_x86_64": [],
|
||||
"//conditions:default": arm64_specific_textual_hdrs,
|
||||
})
|
||||
|
||||
all_sources = arch_specific_sources + [
|
||||
|
|
|
|||
6
third-party/opus/BUILD
vendored
6
third-party/opus/BUILD
vendored
|
|
@ -33,6 +33,8 @@ genrule(
|
|||
BUILD_ARCH="linux_x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "aarch64" ] || [ "$(TARGET_CPU)" == "arm64" ]; then
|
||||
BUILD_ARCH="linux_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
@ -81,10 +83,8 @@ cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
cc_library(
|
||||
name = "opus",
|
||||
module_name = "opus",
|
||||
enable_modules = True,
|
||||
hdrs = [":Public/opus/" + x for x in headers],
|
||||
includes = [
|
||||
"Public",
|
||||
|
|
|
|||
4
third-party/opus/build-opus-bazel.sh
vendored
4
third-party/opus/build-opus-bazel.sh
vendored
|
|
@ -54,6 +54,10 @@ elif [ "${ARCH}" == "sim_arm64" ]; then
|
|||
PLATFORM="iphonesimulator"
|
||||
EXTRA_CFLAGS="-arch arm64 --target=arm64-apple-ios$MINIOSVERSION-simulator"
|
||||
EXTRA_CONFIG="--host=arm-apple-darwin20"
|
||||
elif [ "${ARCH}" == "macos_arm64" ]; then
|
||||
PLATFORM="macosx"
|
||||
EXTRA_CFLAGS="-arch arm64 --target=arm64-apple-macosx14.0"
|
||||
EXTRA_CONFIG="--host=arm-apple-darwin20"
|
||||
else
|
||||
PLATFORM="iphoneos"
|
||||
EXTRA_CFLAGS="-arch ${ARCH}"
|
||||
|
|
|
|||
6
third-party/opusfile/BUILD
vendored
6
third-party/opusfile/BUILD
vendored
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
objc_library(
|
||||
|
||||
cc_library(
|
||||
name = "opusfile",
|
||||
enable_modules = True,
|
||||
module_name = "opusfile",
|
||||
srcs = glob([
|
||||
"Sources/*.c",
|
||||
"Sources/*.h",
|
||||
|
|
|
|||
6
third-party/rnnoise/BUILD
vendored
6
third-party/rnnoise/BUILD
vendored
|
|
@ -24,11 +24,9 @@ replace_symbol_list = [
|
|||
"pitch_search",
|
||||
"remove_doubling",
|
||||
]
|
||||
|
||||
objc_library(
|
||||
|
||||
cc_library(
|
||||
name = "rnnoise",
|
||||
enable_modules = True,
|
||||
module_name = "rnnoise",
|
||||
srcs = glob([
|
||||
"Sources/*.c",
|
||||
"Sources/*.h",
|
||||
|
|
|
|||
2
third-party/td/BUILD
vendored
2
third-party/td/BUILD
vendored
|
|
@ -38,6 +38,8 @@ genrule(
|
|||
BUILD_ARCH="arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_sim_arm64" ]; then
|
||||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
|
|||
4
third-party/td/build-td-bazel.sh
vendored
4
third-party/td/build-td-bazel.sh
vendored
|
|
@ -34,6 +34,10 @@ elif [ "$ARCH" = "sim_arm64" ]; then
|
|||
IOS_PLATFORMDIR="$(xcode-select -p)/Platforms/iPhoneSimulator.platform"
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneSimulator*.sdk)
|
||||
export CFLAGS="-arch arm64 --target=arm64-apple-ios13.0-simulator -miphonesimulator-version-min=13.0 -w"
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
IOS_PLATFORMDIR="$(xcode-select -p)/Platforms/MacOSX.platform"
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/MacOSX*.sdk)
|
||||
export CFLAGS="-arch arm64 --target=arm64-apple-macosx14.0 -mmacosx-version-min=14.0 -w"
|
||||
else
|
||||
echo "Unsupported architecture $ARCH"
|
||||
exit 1
|
||||
|
|
|
|||
2
third-party/webp/BUILD
vendored
2
third-party/webp/BUILD
vendored
|
|
@ -35,6 +35,8 @@ genrule(
|
|||
BUILD_ARCH="sim_arm64"
|
||||
elif [ "$(TARGET_CPU)" == "ios_x86_64" ]; then
|
||||
BUILD_ARCH="x86_64"
|
||||
elif [ "$(TARGET_CPU)" == "darwin_arm64" ]; then
|
||||
BUILD_ARCH="macos_arm64"
|
||||
else
|
||||
echo "Unsupported architecture $(TARGET_CPU)"
|
||||
fi
|
||||
|
|
|
|||
16
third-party/webp/build-webp-bazel.sh
vendored
16
third-party/webp/build-webp-bazel.sh
vendored
|
|
@ -41,6 +41,22 @@ elif [ "$ARCH" = "sim_arm64" ]; then
|
|||
echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> toolchain.cmake
|
||||
echo "set(CMAKE_C_COMPILER $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)" >> toolchain.cmake
|
||||
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} $COMMON_ARGS ../libwebp
|
||||
make
|
||||
elif [ "$ARCH" = "macos_arm64" ]; then
|
||||
IOS_PLATFORMDIR="$(xcode-select -p)/Platforms/MacOSX.platform"
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/MacOSX*.sdk)
|
||||
export CFLAGS="-Wall -arch arm64 --target=arm64-apple-macosx14.0 -mmacosx-version-min=14.0 -funwind-tables"
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
touch toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_NAME Darwin)" >> toolchain.cmake
|
||||
echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> toolchain.cmake
|
||||
echo "set(CMAKE_C_COMPILER $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)" >> toolchain.cmake
|
||||
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} $COMMON_ARGS ../libwebp
|
||||
make
|
||||
elif [ "$ARCH" = "x86_64" ]; then
|
||||
|
|
|
|||
138
third-party/webrtc/BUILD
vendored
138
third-party/webrtc/BUILD
vendored
|
|
@ -15,7 +15,6 @@ optimization_flags = select({
|
|||
})
|
||||
|
||||
webrtc_objcpp_sources = [
|
||||
"rtc_base/system/cocoa_threading.mm",
|
||||
]
|
||||
|
||||
webrtc_headers = [
|
||||
|
|
@ -2767,46 +2766,58 @@ arm64_specific_sources = ["webrtc/" + path for path in [
|
|||
arch_specific_sources = select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": common_arm_specific_sources + arm64_specific_sources,
|
||||
"//build-system:ios_sim_arm64": common_arm_specific_sources + arm64_specific_sources,
|
||||
"//conditions:default": common_arm_specific_sources + arm64_specific_sources,
|
||||
})
|
||||
|
||||
common_flags = [
|
||||
"-DWEBRTC_IOS",
|
||||
"-DWEBRTC_MAC",
|
||||
platform_shared_flags = [
|
||||
"-DWEBRTC_POSIX",
|
||||
"-DHAVE_WEBRTC_VIDEO",
|
||||
"-DRTC_ENABLE_VP9",
|
||||
"-DRTC_ENABLE_H265",
|
||||
"-DWEBRTC_USE_H264",
|
||||
"-DWEBRTC_USE_H264_DECODER",
|
||||
"-DHAVE_SCTP",
|
||||
"-DWEBRTC_HAVE_DCSCTP",
|
||||
"-DWEBRTC_HAVE_SCTP",
|
||||
"-DWEBRTC_NS_FLOAT",
|
||||
"-DRTC_DISABLE_TRACE_EVENTS",
|
||||
#"-DWEBRTC_OPUS_SUPPORT_120MS_PTIME=1",
|
||||
"-DWEBRTC_APM_DEBUG_DUMP=0",
|
||||
"-DBWE_TEST_LOGGING_COMPILE_TIME_ENABLE=0",
|
||||
"-DABSL_ALLOCATOR_NOTHROW=1",
|
||||
"-DDYNAMIC_ANNOTATIONS_ENABLED=0",
|
||||
#"-DNS_BLOCK_ASSERTIONS=1",
|
||||
"-DWEBRTC_ENABLE_PROTOBUF=0",
|
||||
"-DWEBRTC_ENABLE_AVX2",
|
||||
"-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0",
|
||||
"-Wno-shorten-64-to-32",
|
||||
"-Wno-macro-redefined",
|
||||
"-D__APPLE__",
|
||||
"-DWEBRTC_OPUS_USE_CODEC_PLC",
|
||||
"-DWEBRTC_OPUS_SUPPORT_DRED",
|
||||
]
|
||||
|
||||
apple_specific_flags = [
|
||||
"-DWEBRTC_IOS",
|
||||
"-DWEBRTC_MAC",
|
||||
"-D__APPLE__",
|
||||
"-D__Userspace_os_Darwin",
|
||||
"-DWEBRTC_ENABLE_AVX2",
|
||||
"-Wno-shorten-64-to-32",
|
||||
"-Wno-macro-redefined",
|
||||
]
|
||||
|
||||
linux_specific_flags = [
|
||||
"-DWEBRTC_LINUX",
|
||||
"-D__Userspace_os_Linux",
|
||||
]
|
||||
|
||||
arm64_specific_flags = [
|
||||
"-DWEBRTC_ARCH_ARM64",
|
||||
"-DWEBRTC_HAS_NEON",
|
||||
"-DLIBYUV_NEON",
|
||||
]
|
||||
|
||||
# Flatten platform + arch flags into a single select to avoid nested selects
|
||||
arch_specific_cflags = select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": common_flags + arm64_specific_flags,
|
||||
"//build-system:ios_sim_arm64": common_flags + arm64_specific_flags,
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": platform_shared_flags + apple_specific_flags + arm64_specific_flags,
|
||||
"//build-system:ios_sim_arm64": platform_shared_flags + apple_specific_flags + arm64_specific_flags,
|
||||
"@platforms//os:linux": platform_shared_flags + linux_specific_flags + arm64_specific_flags,
|
||||
"//conditions:default": platform_shared_flags + apple_specific_flags + arm64_specific_flags,
|
||||
})
|
||||
|
||||
dcsctp_sources = [ "webrtc/net/dcsctp/" + path for path in [
|
||||
|
|
@ -2981,11 +2992,44 @@ fft4g_sources = [
|
|||
"fft4g/fft4g.cc",
|
||||
]
|
||||
|
||||
raw_combined_sources = webrtc_headers + webrtc_sources + webrtc_objcpp_sources
|
||||
combined_sources = [
|
||||
"webrtc/" + path for path in raw_combined_sources
|
||||
raw_combined_cpp_sources = webrtc_headers + webrtc_sources
|
||||
raw_combined_objcpp_sources = webrtc_objcpp_sources
|
||||
|
||||
# Platform-specific source files: GCD task queue on Apple, stdlib on Linux
|
||||
apple_only_cpp_sources = [
|
||||
"webrtc/rtc_base/task_queue_gcd.cc",
|
||||
"webrtc/rtc_base/task_queue_gcd.h",
|
||||
"webrtc/api/task_queue/default_task_queue_factory_gcd.cc",
|
||||
"webrtc/rtc_base/mac_ifaddrs_converter.cc",
|
||||
]
|
||||
|
||||
linux_only_cpp_sources = [
|
||||
"webrtc/rtc_base/task_queue_stdlib.cc",
|
||||
"webrtc/rtc_base/task_queue_stdlib.h",
|
||||
"webrtc/api/task_queue/default_task_queue_factory_stdlib.cc",
|
||||
]
|
||||
|
||||
# Files excluded from common sources because they are platform-specific
|
||||
platform_specific_excludes = [
|
||||
"rtc_base/task_queue_gcd.cc", "rtc_base/task_queue_gcd.h",
|
||||
"rtc_base/task_queue_stdlib.cc", "rtc_base/task_queue_stdlib.h",
|
||||
"rtc_base/mac_ifaddrs_converter.cc",
|
||||
"api/task_queue/default_task_queue_factory_gcd.cc",
|
||||
"api/task_queue/default_task_queue_factory_stdlib.cc",
|
||||
"api/task_queue/default_task_queue_factory_libevent.cc",
|
||||
"api/task_queue/default_task_queue_factory_win.cc",
|
||||
"api/task_queue/default_task_queue_factory_stdlib_or_libevent_experiment.cc",
|
||||
]
|
||||
|
||||
combined_cpp_sources = [
|
||||
"webrtc/" + path for path in raw_combined_cpp_sources
|
||||
if path not in platform_specific_excludes
|
||||
] + arch_specific_sources + fft4g_sources + dcsctp_sources
|
||||
|
||||
combined_objcpp_sources = [
|
||||
"webrtc/" + path for path in raw_combined_objcpp_sources
|
||||
]
|
||||
|
||||
genrule(
|
||||
name = "generate_field_trials_header",
|
||||
srcs = [
|
||||
|
|
@ -3118,13 +3162,15 @@ objc_library(
|
|||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
cc_library(
|
||||
name = "webrtc",
|
||||
enable_modules = True,
|
||||
module_name = "webrtc",
|
||||
srcs = combined_sources,
|
||||
srcs = combined_cpp_sources + select({
|
||||
"@platforms//os:linux": linux_only_cpp_sources,
|
||||
"//conditions:default": combined_objcpp_sources + apple_only_cpp_sources,
|
||||
}),
|
||||
copts = [
|
||||
"-w",
|
||||
"-include", "stdint.h",
|
||||
"-Ithird-party/webrtc/libsrtp/third_party/libsrtp/include",
|
||||
"-Ithird-party/webrtc/libsrtp/third_party/libsrtp/crypto/include",
|
||||
"-Ithird-party/webrtc/libsrtp",
|
||||
|
|
@ -3140,7 +3186,6 @@ objc_library(
|
|||
"-DSCTP_SIMPLE_ALLOCATOR",
|
||||
"-DSCTP_PROCESS_LEVEL_LOCKS",
|
||||
"-D__Userspace__",
|
||||
"-D__Userspace_os_Darwin",
|
||||
"-DPACKAGE_VERSION=\\\"\\\"",
|
||||
"-DHAVE_SCTP",
|
||||
"-DWEBRTC_HAVE_DCSCTP",
|
||||
|
|
@ -3168,20 +3213,49 @@ objc_library(
|
|||
"//third-party/webrtc/pffft",
|
||||
"//third-party/webrtc/libsrtp",
|
||||
"//third-party/webrtc/absl",
|
||||
] + select({
|
||||
"@platforms//os:linux": [],
|
||||
"//conditions:default": [":webrtc_platform_helpers"],
|
||||
}),
|
||||
linkopts = select({
|
||||
"@platforms//os:linux": ["-lpthread", "-lm"],
|
||||
"//conditions:default": [
|
||||
"-framework AVFoundation",
|
||||
"-framework AudioToolbox",
|
||||
"-framework VideoToolbox",
|
||||
"-framework CoreMedia",
|
||||
"-framework CoreVideo",
|
||||
"-framework CoreGraphics",
|
||||
"-framework QuartzCore",
|
||||
"-framework AppKit",
|
||||
"-weak_framework Network",
|
||||
"-weak_framework Metal",
|
||||
],
|
||||
}),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Minimal helpers needed by tgcalls C++ code on non-iOS platforms.
|
||||
# Separate from webrtc_objc to avoid pulling in iOS SDK dependencies.
|
||||
objc_library(
|
||||
name = "webrtc_platform_helpers",
|
||||
srcs = [
|
||||
"webrtc/rtc_base/system/gcd_helpers.m",
|
||||
"webrtc/rtc_base/system/cocoa_threading.mm",
|
||||
],
|
||||
sdk_frameworks = [
|
||||
"AVFoundation",
|
||||
"AudioToolbox",
|
||||
"VideoToolbox",
|
||||
"UIKit",
|
||||
"CoreMedia",
|
||||
"CoreVideo",
|
||||
"CoreGraphics",
|
||||
"QuartzCore",
|
||||
hdrs = [
|
||||
"webrtc/rtc_base/system/gcd_helpers.h",
|
||||
"webrtc/rtc_base/system/cocoa_threading.h",
|
||||
],
|
||||
weak_sdk_frameworks = [
|
||||
"Network",
|
||||
"Metal",
|
||||
copts = [
|
||||
"-w",
|
||||
"-Ithird-party/webrtc/webrtc/",
|
||||
"-Ithird-party/webrtc/absl",
|
||||
"-DWEBRTC_MAC",
|
||||
"-DWEBRTC_IOS",
|
||||
],
|
||||
deps = [
|
||||
"//third-party/webrtc/absl",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -808,13 +808,8 @@
|
|||
//
|
||||
// See also the upstream documentation:
|
||||
// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
|
||||
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
|
||||
#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
|
||||
#elif ABSL_HAVE_ATTRIBUTE(lifetimebound)
|
||||
#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
|
||||
#else
|
||||
// Disabled: newer clang rejects lifetimebound on void-returning functions
|
||||
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
|
||||
#endif
|
||||
|
||||
// ABSL_ATTRIBUTE_TRIVIAL_ABI
|
||||
// Indicates that a type is "trivially relocatable" -- meaning it can be
|
||||
|
|
|
|||
16
third-party/yasm/BUILD
vendored
16
third-party/yasm/BUILD
vendored
|
|
@ -16,7 +16,7 @@ genrule(
|
|||
cmd_bash =
|
||||
"""
|
||||
set -x
|
||||
core_count=`PATH="$$PATH:/usr/sbin" sysctl -n hw.logicalcpu`
|
||||
core_count=$$(nproc 2>/dev/null || PATH="$$PATH:/usr/sbin" sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
|
||||
BUILD_DIR="$(RULEDIR)/build"
|
||||
rm -rf "$$BUILD_DIR"
|
||||
mkdir -p "$$BUILD_DIR"
|
||||
|
|
@ -25,14 +25,24 @@ set -x
|
|||
rm -rf "$$CMAKE_DIR"
|
||||
mkdir -p "$$CMAKE_DIR"
|
||||
tar -xf "$(location @cmake_tar_gz//file)" -C "$$CMAKE_DIR"
|
||||
|
||||
|
||||
# Find cmake: try system cmake first, then downloaded macOS cmake
|
||||
if command -v cmake >/dev/null 2>&1; then
|
||||
CMAKE_BIN="cmake"
|
||||
elif [ -d "$$CMAKE_DIR/cmake-4.1.2-macos-universal/CMake.app/Contents/bin" ]; then
|
||||
CMAKE_BIN="$$CMAKE_DIR/cmake-4.1.2-macos-universal/CMake.app/Contents/bin/cmake"
|
||||
else
|
||||
echo "cmake not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SOURCE_PATH="third-party/yasm/yasm-1.3.0"
|
||||
cp -R "$$SOURCE_PATH" "$$BUILD_DIR/"
|
||||
|
||||
pushd "$$BUILD_DIR/yasm-1.3.0"
|
||||
mkdir build
|
||||
cd build
|
||||
PATH="$$CMAKE_DIR/cmake-4.1.2-macos-universal/CMake.app/Contents/bin:$$PATH" cmake .. -DYASM_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DPYTHON_EXECUTABLE="$$(which python3)"
|
||||
"$$CMAKE_BIN" .. -DYASM_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DPYTHON_EXECUTABLE="$$(which python3)"
|
||||
make -j $$core_count
|
||||
popd
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue