feat(avlivewire): skeleton and video codecs

Add SkeletonPayload (91 ARKit joints + per-joint validity) and
VideoPayload (one HEVC access unit + keyframe flag) with
big-endian encode/decode. Reuses Task 2 Data/UInt32 helpers.
This commit is contained in:
L'électron rare
2026-05-18 15:44:11 +02:00
parent 0ab7c56036
commit ec4be7bd1f
2 changed files with 90 additions and 0 deletions
@@ -0,0 +1,65 @@
import Foundation
import simd
/// 91 ARKit joints in world space + a per-joint validity flag.
public struct SkeletonPayload: Equatable {
public static let jointCount = 91
/// 91 * 3 * 4 bytes (floats) + 91 validity bytes.
public static let byteCount = jointCount * 12 + jointCount
public var joints: [SIMD3<Float>]
public var valid: [Bool]
public init() {
joints = Array(repeating: .zero, count: Self.jointCount)
valid = Array(repeating: false, count: Self.jointCount)
}
public func encoded() -> Data {
var d = Data(capacity: Self.byteCount)
for j in joints {
d.appendBE(j.x.bitPattern); d.appendBE(j.y.bitPattern)
d.appendBE(j.z.bitPattern)
}
for v in valid { d.append(v ? 1 : 0) }
return d
}
public init?(decoding data: Data) {
guard data.count == Self.byteCount else { return nil }
let b = [UInt8](data)
self.init()
var o = 0
for i in 0..<Self.jointCount {
func f() -> Float {
let v = Float(bitPattern:
UInt32(bigEndianBytes: b[o..<o+4]))
o += 4; return v
}
joints[i] = SIMD3(f(), f(), f())
}
for i in 0..<Self.jointCount { valid[i] = b[o + i] != 0 }
}
}
/// One HEVC access unit + a keyframe flag.
public struct VideoPayload: Equatable {
public var isKeyframe: Bool
public var data: Data
public init(isKeyframe: Bool, data: Data) {
self.isKeyframe = isKeyframe; self.data = data
}
public func encoded() -> Data {
var d = Data([isKeyframe ? 1 : 0])
d.append(data)
return d
}
public init?(decoding data: Data) {
guard let first = data.first else { return nil }
isKeyframe = first != 0
self.data = data.dropFirst()
}
}
@@ -0,0 +1,25 @@
import XCTest
@testable import AVLiveWire
final class WirePayloadsTests: XCTestCase {
func testSkeletonRoundTrip() {
var f = SkeletonPayload()
f.joints[0] = SIMD3(1, 2, 3)
f.valid[0] = true
f.joints[90] = SIMD3(-4, 5, -6)
f.valid[90] = true
let decoded = SkeletonPayload(decoding: f.encoded())
XCTAssertEqual(decoded, f)
}
func testSkeletonRejectsWrongSize() {
XCTAssertNil(SkeletonPayload(decoding: Data([0, 1, 2])))
}
func testVideoPayloadRoundTrip() {
let p = VideoPayload(isKeyframe: true,
data: Data([9, 8, 7, 6]))
let decoded = VideoPayload(decoding: p.encoded())
XCTAssertEqual(decoded, p)
}
}