@mentra/acs-meeting 3.2.0-dev.137 → 3.2.0-dev.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/AcsFrameSender.swift +59 -59
- package/ios/AcsMeeting.podspec +60 -0
- package/ios/AcsMeetingModule.swift +602 -470
- package/ios/PcmBridge.swift +49 -0
- package/package.json +1 -1
package/ios/AcsFrameSender.swift
CHANGED
|
@@ -5,70 +5,70 @@ import Foundation
|
|
|
5
5
|
/// Fresh Swift sender on ACS iOS RawOutgoingVideoStream + CVPixelBuffer.
|
|
6
6
|
/// No RealWear code (they have no iOS equivalent).
|
|
7
7
|
final class AcsFrameSender: NSObject {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
private var stream: VirtualOutgoingVideoStream?
|
|
9
|
+
private var running = false
|
|
10
|
+
private var lastSent: CFTimeInterval = 0
|
|
11
|
+
private let sendGate = VideoSendGate()
|
|
12
|
+
private let stateLock = NSLock()
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
func send(_ pixelBuffer: CVPixelBuffer) {
|
|
24
|
-
stateLock.lock()
|
|
25
|
-
guard running, let stream else {
|
|
26
|
-
stateLock.unlock()
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
let fps = stream.format.framesPerSecond
|
|
30
|
-
let now = CFAbsoluteTimeGetCurrent()
|
|
31
|
-
if lastSent > 0, now - lastSent < 1.0 / Double(max(fps, 1)) {
|
|
32
|
-
stateLock.unlock()
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
guard let token = sendGate.acquire() else {
|
|
36
|
-
stateLock.unlock()
|
|
37
|
-
return
|
|
14
|
+
func attach(_ stream: VirtualOutgoingVideoStream) {
|
|
15
|
+
detach()
|
|
16
|
+
stateLock.lock()
|
|
17
|
+
self.stream = stream
|
|
18
|
+
lastSent = 0
|
|
19
|
+
stateLock.unlock()
|
|
20
|
+
stream.delegate = self
|
|
38
21
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
22
|
+
|
|
23
|
+
func send(_ pixelBuffer: CVPixelBuffer) {
|
|
24
|
+
stateLock.lock()
|
|
25
|
+
guard running, let stream else {
|
|
26
|
+
stateLock.unlock()
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
let fps = stream.format.framesPerSecond
|
|
30
|
+
let now = CFAbsoluteTimeGetCurrent()
|
|
31
|
+
if lastSent > 0, now - lastSent < 1.0 / Double(max(fps, 1)) {
|
|
32
|
+
stateLock.unlock()
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
guard let token = sendGate.acquire() else {
|
|
36
|
+
stateLock.unlock()
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
lastSent = now
|
|
40
|
+
stateLock.unlock()
|
|
41
|
+
let frame = RawVideoFrameBuffer()
|
|
42
|
+
frame.buffer = pixelBuffer
|
|
43
|
+
frame.streamFormat = stream.format
|
|
44
|
+
frame.timestampInTicks = stream.timestampInTicks
|
|
45
|
+
stream.send(frame: frame) { [sendGate] error in
|
|
46
|
+
// Keep the source pixels alive until ACS finishes reading the frame.
|
|
47
|
+
withExtendedLifetime(pixelBuffer) { frame.dispose() }
|
|
48
|
+
sendGate.release(token)
|
|
49
|
+
if let error { NSLog("ACS-SPIKE send frame failed: \(error)") }
|
|
50
|
+
}
|
|
50
51
|
}
|
|
51
|
-
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
func detach() {
|
|
54
|
+
stateLock.lock()
|
|
55
|
+
running = false
|
|
56
|
+
// Drop the delegate on the previous stream so a late STOPPED from a prior
|
|
57
|
+
// call cannot freeze outgoing video for the current meeting.
|
|
58
|
+
let previous = stream
|
|
59
|
+
stream = nil
|
|
60
|
+
sendGate.reset()
|
|
61
|
+
stateLock.unlock()
|
|
62
|
+
previous?.delegate = nil
|
|
63
|
+
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
extension AcsFrameSender: VirtualOutgoingVideoStreamDelegate {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
func virtualOutgoingVideoStream(_ virtualOutgoingVideoStream: VirtualOutgoingVideoStream, didChangeState _: VideoStreamStateChangedEventArgs) {
|
|
68
|
+
stateLock.lock()
|
|
69
|
+
defer { stateLock.unlock() }
|
|
70
|
+
guard virtualOutgoingVideoStream === stream else { return }
|
|
71
|
+
running = virtualOutgoingVideoStream.state == .started
|
|
72
|
+
NSLog("ACS-SPIKE iOS raw video state=\(virtualOutgoingVideoStream.state)")
|
|
73
|
+
}
|
|
74
74
|
}
|
package/ios/AcsMeeting.podspec
CHANGED
|
@@ -22,6 +22,66 @@ Pod::Spec.new do |s|
|
|
|
22
22
|
s.frameworks = 'AVFoundation', 'AudioToolbox', 'CoreMedia', 'CoreVideo', 'UIKit'
|
|
23
23
|
s.pod_target_xcconfig = {
|
|
24
24
|
'DEFINES_MODULE' => 'YES',
|
|
25
|
+
# Calling's umbrella does #import <AzureCommunicationCommon/AzureCommunicationCommon-Swift.h>.
|
|
26
|
+
# Vendored Common headers must resolve inside their framework module.
|
|
27
|
+
# Source-built pods retain the public-header compatibility fallback, and
|
|
28
|
+
# only the static-lib fallback needs a header-only framework.
|
|
29
|
+
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/AzureCommunicationCommon" "${PODS_CONFIGURATION_BUILD_DIR}/AzureCommunicationCommon" "${PODS_CONFIGURATION_BUILD_DIR}/AcsMeeting"',
|
|
30
|
+
'HEADER_SEARCH_PATHS' => '$(inherited) "${PODS_CONFIGURATION_BUILD_DIR}" "${PODS_CONFIGURATION_BUILD_DIR}/AzureCommunicationCommon"',
|
|
25
31
|
}
|
|
32
|
+
s.script_phases = [
|
|
33
|
+
{
|
|
34
|
+
:name => 'Expose AzureCommunicationCommon Swift header',
|
|
35
|
+
:execution_position => :before_compile,
|
|
36
|
+
:script => %(
|
|
37
|
+
set -e
|
|
38
|
+
# CocoaPods stages the slice for the current platform/architecture here.
|
|
39
|
+
# Do not pick a device or simulator slice directly from the pod sources.
|
|
40
|
+
XC_HDR="${PODS_XCFRAMEWORKS_BUILD_DIR}/AzureCommunicationCommon/AzureCommunicationCommon.framework/Headers/AzureCommunicationCommon-Swift.h"
|
|
41
|
+
FW_HDR="${PODS_CONFIGURATION_BUILD_DIR}/AzureCommunicationCommon/AzureCommunicationCommon.framework/Headers/AzureCommunicationCommon-Swift.h"
|
|
42
|
+
STATIC_HDR="${PODS_CONFIGURATION_BUILD_DIR}/AzureCommunicationCommon/Swift Compatibility Header/AzureCommunicationCommon-Swift.h"
|
|
43
|
+
if [ -f "$XC_HDR" ]; then
|
|
44
|
+
SRC="$XC_HDR"
|
|
45
|
+
elif [ -f "$FW_HDR" ]; then
|
|
46
|
+
SRC="$FW_HDR"
|
|
47
|
+
elif [ -f "$STATIC_HDR" ]; then
|
|
48
|
+
SRC="$STATIC_HDR"
|
|
49
|
+
else
|
|
50
|
+
echo "error: AzureCommunicationCommon-Swift.h missing (Common must build first)"
|
|
51
|
+
echo "looked for: $XC_HDR"
|
|
52
|
+
echo "looked for: $FW_HDR"
|
|
53
|
+
echo "looked for: $STATIC_HDR"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
# This phase runs on every build, so only write when the bytes actually
|
|
57
|
+
# differ. An unconditional cp refreshes the mtime of a public header and
|
|
58
|
+
# makes Xcode recompile every dependent target for no reason.
|
|
59
|
+
copy_if_changed() {
|
|
60
|
+
if [ ! -f "$2" ] || ! cmp -s "$1" "$2"; then
|
|
61
|
+
mkdir -p "$(dirname "$2")"
|
|
62
|
+
cp -f "$1" "$2"
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
# Never write a fake AzureCommunicationCommon.framework into BUILT_PRODUCTS_DIR.
|
|
66
|
+
# CocoaPods' embed script prefers ${BUILT_PRODUCTS_DIR}/$(basename) and would
|
|
67
|
+
# then codesign an empty header-only bundle ("bundle format unrecognized").
|
|
68
|
+
rm -rf "${PODS_CONFIGURATION_BUILD_DIR}/AzureCommunicationCommon.framework"
|
|
69
|
+
PUBLIC_HDR="${PODS_ROOT}/Headers/Public/AzureCommunicationCommon/AzureCommunicationCommon-Swift.h"
|
|
70
|
+
if [ -f "$XC_HDR" ]; then
|
|
71
|
+
# A loose copy shadows the vendored framework's modular header. Clang
|
|
72
|
+
# then imports its credential into Calling as a second Swift type,
|
|
73
|
+
# incompatible with Common.CommunicationTokenCredential. Remove copies
|
|
74
|
+
# left by earlier builds and let the framework search path resolve it.
|
|
75
|
+
rm -f "$PUBLIC_HDR"
|
|
76
|
+
else
|
|
77
|
+
copy_if_changed "$SRC" "$PUBLIC_HDR"
|
|
78
|
+
fi
|
|
79
|
+
if [ ! -f "$XC_HDR" ] && [ ! -f "$FW_HDR" ]; then
|
|
80
|
+
FAKE_HEADERS="${PODS_CONFIGURATION_BUILD_DIR}/AcsMeeting/AzureCommunicationCommon.framework/Headers"
|
|
81
|
+
copy_if_changed "$SRC" "$FAKE_HEADERS/AzureCommunicationCommon-Swift.h"
|
|
82
|
+
fi
|
|
83
|
+
),
|
|
84
|
+
},
|
|
85
|
+
]
|
|
26
86
|
s.source_files = '*.{h,m,mm,swift}', 'PolicyKit/Sources/AcsAudioPolicy/*.swift'
|
|
27
87
|
end
|