Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions Sources/LiveKit/Extensions/Sendable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ extension LKRTCCallbackLogger: @unchecked Swift.Sendable {}

// MARK: Collections

extension NSHashTable: @unchecked Swift.Sendable {} // cannot specify Obj-C generics
extension NSMapTable: @unchecked Swift.Sendable {} // cannot specify Obj-C generics
#if swift(<6.2)
extension Dictionary: Swift.Sendable where Key: Sendable, Value: Sendable {}
#endif

// MARK: AV

extension AVCaptureDevice: @unchecked Swift.Sendable {}
extension AVCaptureDevice.Format: @unchecked Swift.Sendable {}
extension CVPixelBuffer: @unchecked Swift.Sendable {}
2 changes: 1 addition & 1 deletion Sources/LiveKit/Track/Track.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public class Track: NSObject, @unchecked Sendable, Loggable {
var rtpReceiver: LKRTCRtpReceiver?

// All VideoRendererAdapters attached to this track, key/value for direct removal.
var videoRendererAdapters = NSMapTable<VideoRenderer, VideoRendererAdapter>.weakToStrongObjects()
var videoRendererAdapters = MapTable<VideoRenderer, VideoRendererAdapter>.weakToStrongObjects()
}

let _state: StateSync<State>
Expand Down
54 changes: 54 additions & 0 deletions Sources/LiveKit/Types/MapTable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2025 LiveKit
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Foundation

/// A thin unchecked sendable wrapper around NSMapTable.
final class MapTable<KeyType, ObjectType>: @unchecked Sendable where KeyType: AnyObject, ObjectType: AnyObject {
init(_ mapTable: NSMapTable<KeyType, ObjectType>) {
self.mapTable = mapTable
}

class func weakToStrongObjects() -> MapTable<KeyType, ObjectType> {
.init(.weakToStrongObjects())
}

func object(forKey aKey: KeyType?) -> ObjectType? {
mapTable.object(forKey: aKey)
}

func removeObject(forKey aKey: KeyType?) {
mapTable.removeObject(forKey: aKey)
}

func setObject(_ anObject: ObjectType?, forKey aKey: KeyType?) {
mapTable.setObject(anObject, forKey: aKey)
}

var count: Int {
mapTable.count
}

func objectEnumerator() -> NSEnumerator? {
mapTable.objectEnumerator()
}

func removeAllObjects() {
mapTable.removeAllObjects()
}

private let mapTable: NSMapTable<KeyType, ObjectType>
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,18 @@ public final class BackgroundBlurVideoProcessor: NSObject, @unchecked Sendable,
private func cacheMask(inputBuffer: CVPixelBuffer, inputDimensions: CGSize) {
guard frameCount % segmentationFrameInterval == 0 else { return }

struct PixelBufferHolder: @unchecked Sendable {
let buffer: CVPixelBuffer
}
let inputBuffer = PixelBufferHolder(buffer: inputBuffer)
segmentationQueue.async {
#if LK_SIGNPOSTS
os_signpost(.begin, log: self.signpostLog, name: #function)
defer {
os_signpost(.end, log: self.signpostLog, name: #function)
}
#endif
try? self.segmentationRequestHandler.perform([self.segmentationRequest], on: inputBuffer)
try? self.segmentationRequestHandler.perform([self.segmentationRequest], on: inputBuffer.buffer)

guard let maskPixelBuffer = self.segmentationRequest.results?.first?.pixelBuffer else { return }
let maskImage = CIImage(cvPixelBuffer: maskPixelBuffer)
Expand Down
Loading