Use Data insted of [UInt8]
This commit is contained in:
parent
0ae7ecac7c
commit
286ee4d94c
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
protocol BytesConvertible {
|
||||
var bytes:[UInt8] { get set }
|
||||
protocol DataConvertible {
|
||||
var data:Data { get set }
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
|
|
@ -39,22 +39,3 @@ extension CMSampleBuffer {
|
|||
return CMSampleBufferGetPresentationTimeStamp(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension CMSampleBuffer: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
get {
|
||||
guard let buffer:CMBlockBuffer = dataBuffer else {
|
||||
return []
|
||||
}
|
||||
var bytes:UnsafeMutablePointer<Int8>? = nil
|
||||
var length:Int = 0
|
||||
guard CMBlockBufferGetDataPointer(buffer, 0, nil, &length, &bytes) == noErr else {
|
||||
return []
|
||||
}
|
||||
return Array(Data(bytes: bytes!, count: length))
|
||||
}
|
||||
set {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
extension ExpressibleByIntegerLiteral {
|
||||
var bytes:[UInt8] {
|
||||
var value:Self = self
|
||||
let s:Int = MemoryLayout<`Self`>.size
|
||||
return withUnsafeMutablePointer(to: &value) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: s) {
|
||||
Array(UnsafeBufferPointer(start: $0, count: s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data:Data {
|
||||
var value:Self = self
|
||||
let s:Int = MemoryLayout<`Self`>.size
|
||||
|
@ -21,14 +11,6 @@ extension ExpressibleByIntegerLiteral {
|
|||
}
|
||||
}
|
||||
|
||||
init(bytes:[UInt8]) {
|
||||
self = bytes.withUnsafeBufferPointer {
|
||||
$0.baseAddress!.withMemoryRebound(to: Self.self, capacity: 1) {
|
||||
$0.pointee
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init(data:Data) {
|
||||
let diff:Int = MemoryLayout<Self>.size - data.count
|
||||
if (0 < diff) {
|
||||
|
|
|
@ -3,21 +3,28 @@ import AVFoundation
|
|||
import VideoToolbox
|
||||
|
||||
struct AVCFormatStream {
|
||||
var bytes:[UInt8] = []
|
||||
let data:Data
|
||||
|
||||
init(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
|
||||
func toByteStream() -> [UInt8] {
|
||||
let buffer:ByteArray = ByteArray(bytes: bytes)
|
||||
var result:[UInt8] = []
|
||||
init?(data:Data?) {
|
||||
guard let data:Data = data else {
|
||||
return nil
|
||||
}
|
||||
self.init(data: data)
|
||||
}
|
||||
|
||||
func toByteStream() -> Data {
|
||||
let buffer:ByteArray = ByteArray(data: data)
|
||||
var result:Data = Data()
|
||||
while (0 < buffer.bytesAvailable) {
|
||||
do {
|
||||
buffer.position += 2
|
||||
let length:Int = try Int(buffer.readUInt16())
|
||||
result.append(contentsOf: [0x00, 0x00, 0x00, 0x01])
|
||||
result.append(contentsOf: try buffer.readBytes(length))
|
||||
result.append(try buffer.readBytes(length))
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
}
|
||||
|
@ -70,7 +77,7 @@ struct AVCConfigurationRecord {
|
|||
}
|
||||
|
||||
init(data: Data) {
|
||||
self.bytes = data.bytes
|
||||
self.data = data
|
||||
}
|
||||
|
||||
func createFormatDescription(_ formatDescriptionOut: UnsafeMutablePointer<CMFormatDescription?>) -> OSStatus {
|
||||
|
@ -93,9 +100,9 @@ struct AVCConfigurationRecord {
|
|||
}
|
||||
}
|
||||
|
||||
extension AVCConfigurationRecord: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension AVCConfigurationRecord: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
let buffer:ByteArray = ByteArray()
|
||||
.writeUInt8(configurationVersion)
|
||||
|
@ -107,18 +114,18 @@ extension AVCConfigurationRecord: BytesConvertible {
|
|||
for i in 0..<sequenceParameterSets.count {
|
||||
buffer
|
||||
.writeUInt16(UInt16(sequenceParameterSets[i].count))
|
||||
.writeBytes(sequenceParameterSets[i])
|
||||
.writeBytes(Data(sequenceParameterSets[i]))
|
||||
}
|
||||
buffer.writeUInt8(UInt8(pictureParameterSets.count))
|
||||
for i in 0..<pictureParameterSets.count {
|
||||
buffer
|
||||
.writeUInt16(UInt16(pictureParameterSets[i].count))
|
||||
.writeBytes(pictureParameterSets[i])
|
||||
.writeBytes(Data(pictureParameterSets[i]))
|
||||
}
|
||||
return buffer.bytes
|
||||
return buffer.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
configurationVersion = try buffer.readUInt8()
|
||||
AVCProfileIndication = try buffer.readUInt8()
|
||||
|
@ -129,12 +136,12 @@ extension AVCConfigurationRecord: BytesConvertible {
|
|||
let numOfSequenceParameterSets:UInt8 = numOfSequenceParameterSetsWithReserved & ~AVCConfigurationRecord.reserveNumOfSequenceParameterSets
|
||||
for _ in 0..<numOfSequenceParameterSets {
|
||||
let length:Int = Int(try buffer.readUInt16())
|
||||
sequenceParameterSets.append(try buffer.readBytes(length))
|
||||
sequenceParameterSets.append(try buffer.readBytes(length).bytes)
|
||||
}
|
||||
let numPictureParameterSets:UInt8 = try buffer.readUInt8()
|
||||
for _ in 0..<numPictureParameterSets {
|
||||
let length:Int = Int(try buffer.readUInt16())
|
||||
pictureParameterSets.append(try buffer.readBytes(length))
|
||||
pictureParameterSets.append(try buffer.readBytes(length).bytes)
|
||||
}
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
|
|
|
@ -260,7 +260,7 @@ final class MP4SampleSizeBox: MP4Box {
|
|||
|
||||
// MARK: -
|
||||
final class MP4ElementaryStreamDescriptorBox: MP4ContainerBox {
|
||||
var audioDecorderSpecificConfig:[UInt8] = []
|
||||
var audioDecorderSpecificConfig:Data = Data()
|
||||
|
||||
var tag:UInt8 = 0
|
||||
var tagSize:UInt8 = 0
|
||||
|
|
|
@ -22,20 +22,20 @@ enum NALType: UInt8 {
|
|||
struct NALUnit {
|
||||
var refIdc:UInt8 = 0
|
||||
var type:NALType = .unspec
|
||||
var payload:[UInt8] = []
|
||||
var payload:Data = Data()
|
||||
}
|
||||
|
||||
extension NALUnit: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension NALUnit: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
return ByteArray()
|
||||
.writeUInt8(refIdc << 5 | type.rawValue)
|
||||
.writeBytes(payload)
|
||||
.bytes
|
||||
.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
let byte:UInt8 = try buffer.readUInt8()
|
||||
refIdc = byte & 0x60 >> 5
|
||||
|
|
|
@ -5,11 +5,11 @@ import AVFoundation
|
|||
- seealso: https://en.wikipedia.org/wiki/Packetized_elementary_stream
|
||||
*/
|
||||
protocol PESPacketHeader {
|
||||
var startCode:[UInt8] { get set }
|
||||
var startCode:Data { get set }
|
||||
var streamID:UInt8 { get set }
|
||||
var packetLength:UInt16 { get set }
|
||||
var optionalPESHeader:PESOptionalHeader? { get set }
|
||||
var data:[UInt8] { get set }
|
||||
var data:Data { get set }
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
@ -39,14 +39,14 @@ struct PESOptionalHeader {
|
|||
var CRCFlag:Bool = false
|
||||
var extentionFlag:Bool = false
|
||||
var PESHeaderLength:UInt8 = 0
|
||||
var optionalFields:[UInt8] = []
|
||||
var stuffingBytes:[UInt8] = []
|
||||
var optionalFields:Data = Data()
|
||||
var stuffingBytes:Data = Data()
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init?(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
|
||||
mutating func setTimestamp(_ timestamp:CMTime, presentationTimeStamp:CMTime, decodeTimeStamp:CMTime) {
|
||||
|
@ -69,11 +69,11 @@ struct PESOptionalHeader {
|
|||
}
|
||||
}
|
||||
|
||||
extension PESOptionalHeader: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension PESOptionalHeader: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
var bytes:[UInt8] = [0x00, 0x00]
|
||||
var bytes:Data = Data([0x00, 0x00])
|
||||
bytes[0] |= markerBits << 6
|
||||
bytes[0] |= scramblingControl << 4
|
||||
bytes[0] |= (priority ? 1 : 0) << 3
|
||||
|
@ -92,12 +92,12 @@ extension PESOptionalHeader: BytesConvertible {
|
|||
.writeUInt8(PESHeaderLength)
|
||||
.writeBytes(optionalFields)
|
||||
.writeBytes(stuffingBytes)
|
||||
.bytes
|
||||
.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
var bytes:[UInt8] = try buffer.readBytes(PESOptionalHeader.fixedSectionSize)
|
||||
var bytes:Data = try buffer.readBytes(PESOptionalHeader.fixedSectionSize)
|
||||
markerBits = (bytes[0] & 0b11000000) >> 6
|
||||
scramblingControl = bytes[0] & 0b00110000 >> 4
|
||||
priority = bytes[0] & 0b00001000 == 0b00001000
|
||||
|
@ -130,7 +130,7 @@ extension PESOptionalHeader: CustomStringConvertible {
|
|||
// MARK: -
|
||||
struct PacketizedElementaryStream: PESPacketHeader {
|
||||
static let untilPacketLengthSize:Int = 6
|
||||
static let startCode:[UInt8] = [0x00, 0x00, 0x01]
|
||||
static let startCode:Data = Data([0x00, 0x00, 0x01])
|
||||
|
||||
static func create(_ sampleBuffer:CMSampleBuffer, timestamp:CMTime, config:Any?) -> PacketizedElementaryStream? {
|
||||
if let config:AudioSpecificConfig = config as? AudioSpecificConfig {
|
||||
|
@ -142,21 +142,52 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
return nil
|
||||
}
|
||||
|
||||
var startCode:[UInt8] = PacketizedElementaryStream.startCode
|
||||
var startCode:Data = PacketizedElementaryStream.startCode
|
||||
var streamID:UInt8 = 0
|
||||
var packetLength:UInt16 = 0
|
||||
var optionalPESHeader:PESOptionalHeader?
|
||||
var data:[UInt8] = []
|
||||
var data:Data = Data()
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
var payload:Data {
|
||||
get {
|
||||
return ByteArray()
|
||||
.writeBytes(startCode)
|
||||
.writeUInt8(streamID)
|
||||
.writeUInt16(packetLength)
|
||||
.writeBytes(optionalPESHeader?.data ?? Data())
|
||||
.writeBytes(data)
|
||||
.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
startCode = try buffer.readBytes(3)
|
||||
streamID = try buffer.readUInt8()
|
||||
packetLength = try buffer.readUInt16()
|
||||
optionalPESHeader = PESOptionalHeader(data: try buffer.readBytes(buffer.bytesAvailable))
|
||||
if let optionalPESHeader:PESOptionalHeader = optionalPESHeader {
|
||||
buffer.position = PacketizedElementaryStream.untilPacketLengthSize + 3 + Int(optionalPESHeader.PESHeaderLength)
|
||||
} else {
|
||||
buffer.position = PacketizedElementaryStream.untilPacketLengthSize
|
||||
}
|
||||
data = try buffer.readBytes(buffer.bytesAvailable)
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init?(payload:Data) {
|
||||
self.payload = payload
|
||||
if (startCode != PacketizedElementaryStream.startCode) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
init?(sampleBuffer:CMSampleBuffer, timestamp:CMTime, config:AudioSpecificConfig?) {
|
||||
let payload:[UInt8] = sampleBuffer.bytes
|
||||
guard let payload:Data = sampleBuffer.dataBuffer?.data else {
|
||||
return nil
|
||||
}
|
||||
data += config!.adts(payload.count)
|
||||
data += payload
|
||||
optionalPESHeader = PESOptionalHeader()
|
||||
|
@ -166,7 +197,7 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
presentationTimeStamp: sampleBuffer.presentationTimeStamp,
|
||||
decodeTimeStamp: sampleBuffer.decodeTimeStamp
|
||||
)
|
||||
packetLength = UInt16(data.count + optionalPESHeader!.bytes.count)
|
||||
packetLength = UInt16(data.count + optionalPESHeader!.data.count)
|
||||
}
|
||||
|
||||
init?(sampleBuffer:CMSampleBuffer, timestamp:CMTime, config:AVCConfigurationRecord?) {
|
||||
|
@ -177,7 +208,9 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
} else {
|
||||
data += [0x00, 0x00, 0x00, 0x01, 0x09, 0x30]
|
||||
}
|
||||
data += AVCFormatStream(bytes: sampleBuffer.bytes).toByteStream()
|
||||
if let stream:AVCFormatStream = AVCFormatStream(data: sampleBuffer.dataBuffer?.data) {
|
||||
data.append(stream.toByteStream())
|
||||
}
|
||||
optionalPESHeader = PESOptionalHeader()
|
||||
optionalPESHeader?.dataAlignmentIndicator = true
|
||||
optionalPESHeader?.setTimestamp(
|
||||
|
@ -185,11 +218,11 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
presentationTimeStamp: sampleBuffer.presentationTimeStamp,
|
||||
decodeTimeStamp: sampleBuffer.decodeTimeStamp
|
||||
)
|
||||
packetLength = UInt16(data.count + optionalPESHeader!.bytes.count)
|
||||
packetLength = UInt16(data.count + optionalPESHeader!.data.count)
|
||||
}
|
||||
|
||||
func arrayOfPackets(_ PID:UInt16, PCR:UInt64?) -> [TSPacket] {
|
||||
let payload:[UInt8] = bytes
|
||||
let payload:Data = data
|
||||
var packets:[TSPacket] = []
|
||||
|
||||
// start
|
||||
|
@ -212,7 +245,7 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
var packet:TSPacket = TSPacket()
|
||||
packet.PID = PID
|
||||
packet.payloadFlag = true
|
||||
packet.payload = Array<UInt8>(payload[index..<index.advanced(by: 184)])
|
||||
packet.payload = payload.subdata(in: index..<index.advanced(by: 184))
|
||||
packets.append(packet)
|
||||
}
|
||||
|
||||
|
@ -220,7 +253,7 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
case 0:
|
||||
break
|
||||
case 183:
|
||||
let remain:[UInt8] = Array<UInt8>(payload[payload.endIndex - r..<payload.endIndex - 1])
|
||||
let remain:Data = payload.subdata(in: payload.endIndex - r..<payload.endIndex - 1)
|
||||
var packet:TSPacket = TSPacket()
|
||||
packet.PID = PID
|
||||
packet.adaptationFieldFlag = true
|
||||
|
@ -233,10 +266,10 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
packet.adaptationFieldFlag = true
|
||||
packet.adaptationField = TSAdaptationField()
|
||||
packet.adaptationField?.compute()
|
||||
let _ = packet.fill([payload[payload.count - 1]], useAdaptationField: true)
|
||||
let _ = packet.fill(Data([payload[payload.count - 1]]), useAdaptationField: true)
|
||||
packets.append(packet)
|
||||
default:
|
||||
let remain:[UInt8] = Array<UInt8>(payload[payload.indices.suffix(from: payload.endIndex - r)])
|
||||
let remain:Data = Data(payload[payload.indices.suffix(payload.endIndex - r)])
|
||||
var packet:TSPacket = TSPacket()
|
||||
packet.PID = PID
|
||||
packet.adaptationFieldFlag = true
|
||||
|
@ -249,41 +282,9 @@ struct PacketizedElementaryStream: PESPacketHeader {
|
|||
return packets
|
||||
}
|
||||
|
||||
mutating func append(_ bytes:[UInt8]) -> Int {
|
||||
data += bytes
|
||||
return bytes.count
|
||||
}
|
||||
}
|
||||
|
||||
extension PacketizedElementaryStream: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
get {
|
||||
return ByteArray()
|
||||
.writeBytes(startCode)
|
||||
.writeUInt8(streamID)
|
||||
.writeUInt16(packetLength)
|
||||
.writeBytes(optionalPESHeader?.bytes ?? [])
|
||||
.writeBytes(data)
|
||||
.bytes
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
do {
|
||||
startCode = try buffer.readBytes(3)
|
||||
streamID = try buffer.readUInt8()
|
||||
packetLength = try buffer.readUInt16()
|
||||
optionalPESHeader = PESOptionalHeader(bytes: try buffer.readBytes(buffer.bytesAvailable))
|
||||
if let optionalPESHeader:PESOptionalHeader = optionalPESHeader {
|
||||
buffer.position = PacketizedElementaryStream.untilPacketLengthSize + 3 + Int(optionalPESHeader.PESHeaderLength)
|
||||
} else {
|
||||
buffer.position = PacketizedElementaryStream.untilPacketLengthSize
|
||||
}
|
||||
data = try buffer.readBytes(buffer.bytesAvailable)
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
}
|
||||
}
|
||||
mutating func append(_ data:Data) -> Int {
|
||||
self.data.append(data)
|
||||
return data.count
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import Foundation
|
|||
*/
|
||||
protocol PSIPointer {
|
||||
var pointerField:UInt8 { get set }
|
||||
var pointerFillerBytes:[UInt8] { get set }
|
||||
var pointerFillerBytes:Data { get set }
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
@ -23,7 +23,7 @@ protocol PSITableSyntax {
|
|||
var currentNextIndicator:Bool { get set }
|
||||
var sectionNumber:UInt8 { get set }
|
||||
var lastSectionNumber:UInt8 { get set }
|
||||
var data:[UInt8] { get set }
|
||||
var tableData:Data { get set }
|
||||
var crc32:UInt32 { get set }
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ class ProgramSpecific: PSIPointer, PSITableHeader, PSITableSyntax {
|
|||
|
||||
// MARK: PSIPointer
|
||||
var pointerField:UInt8 = 0
|
||||
var pointerFillerBytes:[UInt8] = []
|
||||
var pointerFillerBytes:Data = Data()
|
||||
|
||||
// MARK: PSITableHeader
|
||||
var tableID:UInt8 = 0
|
||||
|
@ -50,21 +50,70 @@ class ProgramSpecific: PSIPointer, PSITableHeader, PSITableSyntax {
|
|||
var currentNextIndicator:Bool = true
|
||||
var sectionNumber:UInt8 = 0
|
||||
var lastSectionNumber:UInt8 = 0
|
||||
var data:[UInt8] {
|
||||
var tableData:Data {
|
||||
get {
|
||||
return []
|
||||
return Data()
|
||||
}
|
||||
set {
|
||||
|
||||
}
|
||||
}
|
||||
var crc32:UInt32 = 0
|
||||
|
||||
var data:Data {
|
||||
get {
|
||||
let data:Data = self.data
|
||||
sectionLength = UInt16(data.count) + 9
|
||||
sectionSyntaxIndicator = data.count != 0
|
||||
let buffer:ByteArray = ByteArray()
|
||||
.writeUInt8(tableID)
|
||||
.writeUInt16(
|
||||
(sectionSyntaxIndicator ? 0x8000 : 0) |
|
||||
(privateBit ? 0x4000 : 0) |
|
||||
UInt16(ProgramSpecific.reservedBits) << 12 |
|
||||
sectionLength
|
||||
)
|
||||
.writeUInt16(tableIDExtension)
|
||||
.writeUInt8(
|
||||
ProgramSpecific.reservedBits << 6 |
|
||||
versionNumber << 1 |
|
||||
(currentNextIndicator ? 1 : 0)
|
||||
)
|
||||
.writeUInt8(sectionNumber)
|
||||
.writeUInt8(lastSectionNumber)
|
||||
.writeBytes(tableData)
|
||||
crc32 = CRC32.MPEG2.calculate(buffer.data)
|
||||
return Data([pointerField] + pointerFillerBytes) + buffer.writeUInt32(crc32).data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
var bytes:Data = Data()
|
||||
pointerField = try buffer.readUInt8()
|
||||
pointerFillerBytes = try buffer.readBytes(Int(pointerField))
|
||||
tableID = try buffer.readUInt8()
|
||||
bytes.append(try buffer.readBytes(2))
|
||||
sectionSyntaxIndicator = bytes[0] & 0x80 == 0x80
|
||||
privateBit = bytes[0] & 0x40 == 0x40
|
||||
sectionLength = UInt16(bytes[0] & 0x03) << 8 | UInt16(bytes[1])
|
||||
tableIDExtension = try buffer.readUInt16()
|
||||
versionNumber = try buffer.readUInt8()
|
||||
currentNextIndicator = versionNumber & 0x01 == 0x01
|
||||
versionNumber = (versionNumber & 0b00111110) >> 1
|
||||
sectionNumber = try buffer.readUInt8()
|
||||
lastSectionNumber = try buffer.readUInt8()
|
||||
tableData = try buffer.readBytes(Int(sectionLength - 9))
|
||||
crc32 = try buffer.readUInt32()
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init?(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
|
||||
func arrayOfPackets(_ PID:UInt16) -> [TSPacket] {
|
||||
|
@ -72,7 +121,7 @@ class ProgramSpecific: PSIPointer, PSITableHeader, PSITableSyntax {
|
|||
var packet:TSPacket = TSPacket()
|
||||
packet.payloadUnitStartIndicator = true
|
||||
packet.PID = PID
|
||||
let _ = packet.fill(bytes, useAdaptationField: false)
|
||||
let _ = packet.fill(data, useAdaptationField: false)
|
||||
packets.append(packet)
|
||||
return packets
|
||||
}
|
||||
|
@ -85,75 +134,22 @@ extension ProgramSpecific: CustomStringConvertible {
|
|||
}
|
||||
}
|
||||
|
||||
extension ProgramSpecific: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
get {
|
||||
let data:[UInt8] = self.data
|
||||
sectionLength = UInt16(data.count) + 9
|
||||
sectionSyntaxIndicator = data.count != 0
|
||||
let buffer:ByteArray = ByteArray()
|
||||
.writeUInt8(tableID)
|
||||
.writeUInt16(
|
||||
(sectionSyntaxIndicator ? 0x8000 : 0) |
|
||||
(privateBit ? 0x4000 : 0) |
|
||||
UInt16(ProgramSpecific.reservedBits) << 12 |
|
||||
sectionLength
|
||||
)
|
||||
.writeUInt16(tableIDExtension)
|
||||
.writeUInt8(
|
||||
ProgramSpecific.reservedBits << 6 |
|
||||
versionNumber << 1 |
|
||||
(currentNextIndicator ? 1 : 0)
|
||||
)
|
||||
.writeUInt8(sectionNumber)
|
||||
.writeUInt8(lastSectionNumber)
|
||||
.writeBytes(data)
|
||||
crc32 = CRC32.MPEG2.calculate(buffer.bytes)
|
||||
return [pointerField] + pointerFillerBytes + buffer.writeUInt32(crc32).bytes
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
do {
|
||||
var bytes:[UInt8] = []
|
||||
pointerField = try buffer.readUInt8()
|
||||
pointerFillerBytes = try buffer.readBytes(Int(pointerField))
|
||||
tableID = try buffer.readUInt8()
|
||||
bytes = try buffer.readBytes(2)
|
||||
sectionSyntaxIndicator = bytes[0] & 0x80 == 0x80
|
||||
privateBit = bytes[0] & 0x40 == 0x40
|
||||
sectionLength = UInt16(bytes[0] & 0x03) << 8 | UInt16(bytes[1])
|
||||
tableIDExtension = try buffer.readUInt16()
|
||||
versionNumber = try buffer.readUInt8()
|
||||
currentNextIndicator = versionNumber & 0x01 == 0x01
|
||||
versionNumber = (versionNumber & 0b00111110) >> 1
|
||||
sectionNumber = try buffer.readUInt8()
|
||||
lastSectionNumber = try buffer.readUInt8()
|
||||
data = try buffer.readBytes(Int(sectionLength - 9))
|
||||
crc32 = try buffer.readUInt32()
|
||||
} catch {
|
||||
logger.error("\(buffer)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
final class ProgramAssociationSpecific: ProgramSpecific {
|
||||
static let tableID:UInt8 = 0
|
||||
|
||||
var programs:[UInt16:UInt16] = [:]
|
||||
|
||||
override var data:[UInt8] {
|
||||
override var data:Data {
|
||||
get {
|
||||
let buffer:ByteArray = ByteArray()
|
||||
for (number, programMapPID) in programs {
|
||||
buffer.writeUInt16(number).writeUInt16(programMapPID | 0xe000)
|
||||
}
|
||||
return buffer.bytes
|
||||
return buffer.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
for _ in 0..<newValue.count / 4 {
|
||||
programs[try buffer.readUInt16()] = try buffer.readUInt16() & 0x1fff
|
||||
|
@ -179,34 +175,34 @@ final class ProgramMapSpecific: ProgramSpecific {
|
|||
tableID = ProgramMapSpecific.tableID
|
||||
}
|
||||
|
||||
override init?(bytes:[UInt8]) {
|
||||
override init?(data:Data) {
|
||||
super.init()
|
||||
self.bytes = bytes
|
||||
self.data = data
|
||||
}
|
||||
|
||||
override var data:[UInt8] {
|
||||
override var data:Data {
|
||||
get {
|
||||
mutex.lock()
|
||||
defer { mutex.unlock() }
|
||||
|
||||
var bytes:[UInt8] = []
|
||||
var bytes:Data = Data()
|
||||
elementaryStreamSpecificData.sort{ (lhs:ElementaryStreamSpecificData, rhs:ElementaryStreamSpecificData) -> Bool in
|
||||
return lhs.elementaryPID < rhs.elementaryPID
|
||||
}
|
||||
for data in elementaryStreamSpecificData {
|
||||
bytes += data.bytes
|
||||
for essd in elementaryStreamSpecificData {
|
||||
bytes.append(essd.data)
|
||||
}
|
||||
return ByteArray()
|
||||
.writeUInt16(PCRPID | 0xe000)
|
||||
.writeUInt16(programInfoLength | 0xf000)
|
||||
.writeBytes(bytes)
|
||||
.bytes
|
||||
.data
|
||||
}
|
||||
set {
|
||||
mutex.lock()
|
||||
defer { mutex.unlock() }
|
||||
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
PCRPID = try buffer.readUInt16() & 0x1fff
|
||||
programInfoLength = try buffer.readUInt16() & 0x03ff
|
||||
|
@ -214,7 +210,7 @@ final class ProgramMapSpecific: ProgramSpecific {
|
|||
var position:Int = 0
|
||||
while (0 < buffer.bytesAvailable) {
|
||||
position = buffer.position
|
||||
guard let data:ElementaryStreamSpecificData = ElementaryStreamSpecificData(bytes: try buffer.readBytes(buffer.bytesAvailable)) else {
|
||||
guard let data:ElementaryStreamSpecificData = ElementaryStreamSpecificData(data: try buffer.readBytes(buffer.bytesAvailable)) else {
|
||||
break
|
||||
}
|
||||
buffer.position = position + ElementaryStreamSpecificData.fixedHeaderSize + Int(data.ESInfoLength)
|
||||
|
@ -250,29 +246,29 @@ struct ElementaryStreamSpecificData {
|
|||
var streamType:UInt8 = 0
|
||||
var elementaryPID:UInt16 = 0
|
||||
var ESInfoLength:UInt16 = 0
|
||||
var ESDescriptors:[UInt8] = []
|
||||
var ESDescriptors:Data = Data()
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init?(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
}
|
||||
|
||||
extension ElementaryStreamSpecificData: BytesConvertible {
|
||||
extension ElementaryStreamSpecificData: DataConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
var data:Data {
|
||||
get {
|
||||
return ByteArray()
|
||||
.writeUInt8(streamType)
|
||||
.writeUInt16(elementaryPID | 0xe000)
|
||||
.writeUInt16(ESInfoLength | 0xf000)
|
||||
.writeBytes(ESDescriptors)
|
||||
.bytes
|
||||
.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
streamType = try buffer.readUInt8()
|
||||
elementaryPID = try buffer.readUInt16() & 0x0fff
|
||||
|
|
|
@ -48,11 +48,11 @@ class TSReader {
|
|||
}
|
||||
numberOfPackets += 1
|
||||
if (packet.PID == 0x0000) {
|
||||
PAT = ProgramAssociationSpecific(bytes: packet.payload)
|
||||
PAT = ProgramAssociationSpecific(data: packet.payload)
|
||||
continue
|
||||
}
|
||||
if let channel:UInt16 = dictionaryForPrograms[packet.PID] {
|
||||
PMT[channel] = ProgramMapSpecific(bytes: packet.payload)
|
||||
PMT[channel] = ProgramMapSpecific(data: packet.payload)
|
||||
continue
|
||||
}
|
||||
if let data:ElementaryStreamSpecificData = dictionaryForESSpecData[packet.PID] {
|
||||
|
@ -66,7 +66,7 @@ class TSReader {
|
|||
if let PES:PacketizedElementaryStream = packetizedElementaryStreams[packet.PID] {
|
||||
delegate?.didReadPacketizedElementaryStream(data, PES: PES)
|
||||
}
|
||||
packetizedElementaryStreams[packet.PID] = PacketizedElementaryStream(bytes: packet.payload)
|
||||
packetizedElementaryStreams[packet.PID] = PacketizedElementaryStream(payload: packet.payload)
|
||||
return
|
||||
}
|
||||
let _:Int? = packetizedElementaryStreams[packet.PID]?.append(packet.payload)
|
||||
|
|
|
@ -87,16 +87,17 @@ class TSWriter {
|
|||
packets[0].adaptationField?.randomAccessIndicator = !sampleBuffer.dependsOnOthers
|
||||
}
|
||||
|
||||
var bytes:[UInt8] = []
|
||||
var bytes:Data = Data()
|
||||
for var packet in packets {
|
||||
packet.continuityCounter = continuityCounters[PID]!
|
||||
continuityCounters[PID] = (continuityCounters[PID]! + 1) & 0x0f
|
||||
bytes += packet.bytes
|
||||
bytes.append(packet.data)
|
||||
}
|
||||
|
||||
nstry({
|
||||
self.currentFileHandle?.write(Data(bytes: UnsafePointer<UInt8>(bytes), count: bytes.count))
|
||||
self.currentFileHandle?.write(bytes)
|
||||
}){ exception in
|
||||
self.currentFileHandle?.write(Data(bytes: UnsafePointer<UInt8>(bytes), count: bytes.count))
|
||||
self.currentFileHandle?.write(bytes)
|
||||
logger.warning("\(exception)")
|
||||
}
|
||||
}
|
||||
|
@ -167,16 +168,16 @@ class TSWriter {
|
|||
currentFileHandle = try? FileHandle(forWritingTo: url)
|
||||
|
||||
PMT.PCRPID = PCRPID
|
||||
var bytes:[UInt8] = []
|
||||
var bytes:Data = Data()
|
||||
var packets:[TSPacket] = []
|
||||
packets += PAT.arrayOfPackets(TSWriter.defaultPATPID)
|
||||
packets += PMT.arrayOfPackets(TSWriter.defaultPMTPID)
|
||||
for packet in packets {
|
||||
bytes += packet.bytes
|
||||
bytes.append(packet.data)
|
||||
}
|
||||
|
||||
nstry({
|
||||
self.currentFileHandle?.write(Data(bytes: bytes, count: bytes.count))
|
||||
self.currentFileHandle?.write(bytes)
|
||||
}){ exception in
|
||||
logger.warning("\(exception)")
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ struct TSPacket {
|
|||
var payloadFlag:Bool = false
|
||||
var continuityCounter:UInt8 = 0
|
||||
var adaptationField:TSAdaptationField?
|
||||
var payload:[UInt8] = []
|
||||
var payload:Data = Data()
|
||||
|
||||
fileprivate var remain:Int {
|
||||
var adaptationFieldSize:Int = 0
|
||||
|
@ -33,34 +33,24 @@ struct TSPacket {
|
|||
init() {
|
||||
}
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
guard TSPacket.size == bytes.count else {
|
||||
return nil
|
||||
}
|
||||
self.bytes = bytes
|
||||
if (syncByte != TSPacket.defaultSyncByte) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
init?(data:Data) {
|
||||
guard TSPacket.size == data.count else {
|
||||
return nil
|
||||
}
|
||||
bytes = Array<UInt8>(UnsafeBufferPointer(start: (data as NSData).bytes.bindMemory(to: UInt8.self, capacity: data.count), count: data.count))
|
||||
self.data = data
|
||||
if (syncByte != TSPacket.defaultSyncByte) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
mutating func fill(_ data:[UInt8]?, useAdaptationField:Bool) -> Int {
|
||||
guard let data:[UInt8] = data else {
|
||||
payload += [UInt8](repeating: 0xff, count: remain)
|
||||
mutating func fill(_ data:Data?, useAdaptationField:Bool) -> Int {
|
||||
guard let data:Data = data else {
|
||||
payload.append(Data(count: remain))
|
||||
return 0
|
||||
}
|
||||
payloadFlag = true
|
||||
let length:Int = min(data.count, remain, 182)
|
||||
payload += Array<UInt8>(data[0..<length])
|
||||
payload.append(data[0..<length])
|
||||
if (remain == 0) {
|
||||
return length
|
||||
}
|
||||
|
@ -73,16 +63,16 @@ struct TSPacket {
|
|||
adaptationField?.compute()
|
||||
return length
|
||||
}
|
||||
payload += [UInt8](repeating: 0xff, count: remain)
|
||||
payload.append(Data(count: remain))
|
||||
return length
|
||||
}
|
||||
}
|
||||
|
||||
extension TSPacket: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension TSPacket: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
var bytes:[UInt8] = [syncByte, 0x00, 0x00, 0x00]
|
||||
var bytes:Data = Data([syncByte, 0x00, 0x00, 0x00])
|
||||
bytes[1] |= transportErrorIndicator ? 0x80 : 0
|
||||
bytes[1] |= payloadUnitStartIndicator ? 0x40 : 0
|
||||
bytes[1] |= transportPriority ? 0x20 : 0
|
||||
|
@ -94,14 +84,14 @@ extension TSPacket: BytesConvertible {
|
|||
bytes[3] |= continuityCounter
|
||||
return ByteArray()
|
||||
.writeBytes(bytes)
|
||||
.writeBytes(adaptationFieldFlag ? adaptationField!.bytes : [])
|
||||
.writeBytes(adaptationFieldFlag ? adaptationField!.data : Data())
|
||||
.writeBytes(payload)
|
||||
.bytes
|
||||
.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
var data:[UInt8] = try buffer.readBytes(4)
|
||||
var data:Data = try buffer.readBytes(4)
|
||||
syncByte = data[0]
|
||||
transportErrorIndicator = data[1] & 0x80 == 0x80
|
||||
payloadUnitStartIndicator = data[1] & 0x40 == 0x40
|
||||
|
@ -114,7 +104,7 @@ extension TSPacket: BytesConvertible {
|
|||
if (adaptationFieldFlag) {
|
||||
let length:Int = Int(try buffer.readUInt8())
|
||||
buffer.position -= 1
|
||||
adaptationField = TSAdaptationField(bytes: try buffer.readBytes(length + 1))
|
||||
adaptationField = TSAdaptationField(data: try buffer.readBytes(length + 1))
|
||||
}
|
||||
if (payloadFlag) {
|
||||
payload = try buffer.readBytes(buffer.bytesAvailable)
|
||||
|
@ -132,22 +122,22 @@ struct TSTimestamp {
|
|||
static let PTSMask:UInt8 = 0x10
|
||||
static let PTSDTSMask:UInt8 = 0x30
|
||||
|
||||
static func decode(_ bytes:[UInt8]) -> UInt64 {
|
||||
static func decode(_ data:Data) -> UInt64 {
|
||||
var result:UInt64 = 0
|
||||
result |= UInt64(bytes[0] & 0x0e) << 29
|
||||
result |= UInt64(bytes[1]) << 22 | UInt64(bytes[2] & 0xfe) << 14
|
||||
result |= UInt64(bytes[3]) << 7 | UInt64(bytes[3] & 0xfe) << 1
|
||||
result |= UInt64(data[0] & 0x0e) << 29
|
||||
result |= UInt64(data[1]) << 22 | UInt64(data[2] & 0xfe) << 14
|
||||
result |= UInt64(data[3]) << 7 | UInt64(data[3] & 0xfe) << 1
|
||||
return result
|
||||
}
|
||||
|
||||
static func encode(_ b:UInt64, _ m:UInt8) -> [UInt8] {
|
||||
var bytes:[UInt8] = [UInt8](repeating: 0x00, count: 5)
|
||||
bytes[0] = UInt8(truncatingBitPattern: b >> 29) | 0x01 | m
|
||||
bytes[1] = UInt8(truncatingBitPattern: b >> 22)
|
||||
bytes[2] = UInt8(truncatingBitPattern: b >> 14) | 0x01
|
||||
bytes[3] = UInt8(truncatingBitPattern: b >> 7)
|
||||
bytes[4] = UInt8(truncatingBitPattern: b << 1) | 0x01
|
||||
return bytes
|
||||
static func encode(_ b:UInt64, _ m:UInt8) -> Data {
|
||||
var data:Data = Data(count: 5)
|
||||
data[0] = UInt8(truncatingBitPattern: b >> 29) | 0x01 | m
|
||||
data[1] = UInt8(truncatingBitPattern: b >> 22)
|
||||
data[2] = UInt8(truncatingBitPattern: b >> 14) | 0x01
|
||||
data[3] = UInt8(truncatingBitPattern: b >> 7)
|
||||
data[4] = UInt8(truncatingBitPattern: b << 1) | 0x01
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,38 +146,38 @@ struct TSProgramClockReference {
|
|||
static let resolutionForBase:Int32 = 90 * 1000 // 90kHz
|
||||
static let resolutionForExtension:Int32 = 27 * 1000 * 1000 // 27MHz
|
||||
|
||||
static func decode(_ bytes:[UInt8]) -> (UInt64, UInt16) {
|
||||
static func decode(_ data:Data) -> (UInt64, UInt16) {
|
||||
var b:UInt64 = 0
|
||||
var e:UInt16 = 0
|
||||
b |= UInt64(bytes[0]) << 25
|
||||
b |= UInt64(bytes[1]) << 17
|
||||
b |= UInt64(bytes[2]) << 9
|
||||
b |= UInt64(bytes[3]) << 1
|
||||
b |= (bytes[4] & 0x80 == 0x80) ? 1 : 0
|
||||
e |= UInt16(bytes[4] & 0x01) << 8
|
||||
e |= UInt16(bytes[5])
|
||||
b |= UInt64(data[0]) << 25
|
||||
b |= UInt64(data[1]) << 17
|
||||
b |= UInt64(data[2]) << 9
|
||||
b |= UInt64(data[3]) << 1
|
||||
b |= (data[4] & 0x80 == 0x80) ? 1 : 0
|
||||
e |= UInt16(data[4] & 0x01) << 8
|
||||
e |= UInt16(data[5])
|
||||
return (b, e)
|
||||
}
|
||||
|
||||
static func encode(_ b:UInt64, _ e:UInt16) -> [UInt8] {
|
||||
var bytes:[UInt8] = [UInt8](repeating: 0, count: 6)
|
||||
bytes[0] = UInt8(truncatingBitPattern: b >> 25)
|
||||
bytes[1] = UInt8(truncatingBitPattern: b >> 17)
|
||||
bytes[2] = UInt8(truncatingBitPattern: b >> 9)
|
||||
bytes[3] = UInt8(truncatingBitPattern: b >> 1)
|
||||
bytes[4] = 0xff
|
||||
static func encode(_ b:UInt64, _ e:UInt16) -> Data {
|
||||
var data:Data = Data(count: 6)
|
||||
data[0] = UInt8(truncatingBitPattern: b >> 25)
|
||||
data[1] = UInt8(truncatingBitPattern: b >> 17)
|
||||
data[2] = UInt8(truncatingBitPattern: b >> 9)
|
||||
data[3] = UInt8(truncatingBitPattern: b >> 1)
|
||||
data[4] = 0xff
|
||||
if (b & 1 == 1) {
|
||||
bytes[4] |= 0x80
|
||||
data[4] |= 0x80
|
||||
} else {
|
||||
bytes[4] &= 0x7f
|
||||
data[4] &= 0x7f
|
||||
}
|
||||
if (UInt16(bytes[4] & 0x01) >> 8 == 1) {
|
||||
bytes[4] |= 1
|
||||
if (UInt16(data[4] & 0x01) >> 8 == 1) {
|
||||
data[4] |= 1
|
||||
} else {
|
||||
bytes[4] &= 0xfe
|
||||
data[4] &= 0xfe
|
||||
}
|
||||
bytes[5] = UInt8(truncatingBitPattern: e)
|
||||
return bytes
|
||||
data[5] = UInt8(truncatingBitPattern: e)
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,19 +202,19 @@ struct TSAdaptationField {
|
|||
var splicingPointFlag:Bool = false
|
||||
var transportPrivateDataFlag:Bool = false
|
||||
var adaptationFieldExtensionFlag:Bool = false
|
||||
var PCR:[UInt8] = []
|
||||
var OPCR:[UInt8] = []
|
||||
var PCR:Data = Data()
|
||||
var OPCR:Data = Data()
|
||||
var spliceCountdown:UInt8 = 0
|
||||
var transportPrivateDataLength:UInt8 = 0
|
||||
var transportPrivateData:[UInt8] = []
|
||||
var transportPrivateData:Data = Data()
|
||||
var adaptationExtension:TSAdaptationExtensionField?
|
||||
var stuffingBytes:[UInt8] = []
|
||||
var stuffingBytes:Data = Data()
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init?(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
|
||||
mutating func compute() {
|
||||
|
@ -240,14 +230,14 @@ struct TSAdaptationField {
|
|||
}
|
||||
|
||||
mutating func stuffing(_ size:Int) {
|
||||
stuffingBytes = [UInt8](repeating: 0xff, count: size)
|
||||
stuffingBytes = Data(count: size)
|
||||
length += UInt8(size)
|
||||
}
|
||||
}
|
||||
|
||||
extension TSAdaptationField: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension TSAdaptationField: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
var byte:UInt8 = 0
|
||||
byte |= discontinuityIndicator ? 0x80 : 0
|
||||
|
@ -274,12 +264,12 @@ extension TSAdaptationField: BytesConvertible {
|
|||
buffer.writeUInt8(transportPrivateDataLength).writeBytes(transportPrivateData)
|
||||
}
|
||||
if (adaptationFieldExtensionFlag) {
|
||||
buffer.writeBytes(adaptationExtension!.bytes)
|
||||
buffer.writeBytes(adaptationExtension!.data)
|
||||
}
|
||||
return buffer.writeBytes(stuffingBytes).bytes
|
||||
return buffer.writeBytes(stuffingBytes).data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
length = try buffer.readUInt8()
|
||||
let byte:UInt8 = try buffer.readUInt8()
|
||||
|
@ -307,7 +297,7 @@ extension TSAdaptationField: BytesConvertible {
|
|||
if (adaptationFieldExtensionFlag) {
|
||||
let length:Int = Int(try buffer.readUInt8())
|
||||
buffer.position -= 1
|
||||
adaptationExtension = TSAdaptationExtensionField(bytes: try buffer.readBytes(length + 1))
|
||||
adaptationExtension = TSAdaptationExtensionField(data: try buffer.readBytes(length + 1))
|
||||
}
|
||||
stuffingBytes = try buffer.readBytes(buffer.bytesAvailable)
|
||||
} catch {
|
||||
|
@ -334,16 +324,16 @@ struct TSAdaptationExtensionField {
|
|||
var legalTimeWindowOffset:UInt16 = 0
|
||||
var piecewiseRate:UInt32 = 0
|
||||
var spliceType:UInt8 = 0
|
||||
var DTSNextAccessUnit:[UInt8] = [UInt8](repeating: 0x00, count: 5)
|
||||
var DTSNextAccessUnit:Data = Data(count: 5)
|
||||
|
||||
init?(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
init?(data:Data) {
|
||||
self.data = data
|
||||
}
|
||||
}
|
||||
|
||||
extension TSAdaptationExtensionField: BytesConvertible {
|
||||
// MARK: BytesConvertible
|
||||
var bytes:[UInt8] {
|
||||
extension TSAdaptationExtensionField: DataConvertible {
|
||||
// MARK: DataConvertible
|
||||
var data:Data {
|
||||
get {
|
||||
let buffer:ByteArray = ByteArray()
|
||||
.writeUInt8(length)
|
||||
|
@ -362,12 +352,12 @@ extension TSAdaptationExtensionField: BytesConvertible {
|
|||
buffer
|
||||
.writeUInt8(spliceType)
|
||||
.writeUInt8(spliceType << 4 | DTSNextAccessUnit[0])
|
||||
.writeBytes(Array<UInt8>(DTSNextAccessUnit[1..<DTSNextAccessUnit.count]))
|
||||
.writeBytes(DTSNextAccessUnit.subdata(in: 1..<DTSNextAccessUnit.count))
|
||||
}
|
||||
return buffer.bytes
|
||||
return buffer.data
|
||||
}
|
||||
set {
|
||||
let buffer:ByteArray = ByteArray(bytes: newValue)
|
||||
let buffer:ByteArray = ByteArray(data: newValue)
|
||||
do {
|
||||
var byte:UInt8 = 0
|
||||
length = try buffer.readUInt8()
|
||||
|
|
|
@ -21,18 +21,6 @@ public class NetSocket: NSObject {
|
|||
private let lockQueue:DispatchQueue = DispatchQueue(label: "com.haishinkit.HaishinKit.NetSocket.lock")
|
||||
fileprivate var timeoutHandler:(() -> Void)?
|
||||
|
||||
@discardableResult
|
||||
final public func doOutput(bytes:[UInt8], locked:UnsafeMutablePointer<UInt32>? = nil) -> Int {
|
||||
OSAtomicAdd64(Int64(bytes.count), &queueBytesOut)
|
||||
lockQueue.async {
|
||||
self.doOutputProcess(UnsafePointer<UInt8>(bytes), maxLength: bytes.count)
|
||||
if (locked != nil) {
|
||||
OSAtomicAnd32Barrier(0, locked!)
|
||||
}
|
||||
}
|
||||
return bytes.count
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
final public func doOutput(data:Data, locked:UnsafeMutablePointer<UInt32>? = nil) -> Int {
|
||||
OSAtomicAdd64(Int64(data.count), &queueBytesOut)
|
||||
|
|
|
@ -215,7 +215,7 @@ extension AMF0Serializer: AMFSerializer {
|
|||
* @see 2.3 Boolean Type
|
||||
*/
|
||||
func serialize(_ value:Bool) -> Self {
|
||||
return writeBytes([Type.bool.rawValue, value ? 0x01 : 0x00])
|
||||
return writeBytes(Data([Type.bool.rawValue, value ? 0x01 : 0x00]))
|
||||
}
|
||||
|
||||
func deserialize() throws -> Bool {
|
||||
|
@ -319,7 +319,7 @@ extension AMF0Serializer: AMFSerializer {
|
|||
func serialize(_ value:[Any?]) -> Self {
|
||||
writeUInt8(Type.strictArray.rawValue)
|
||||
if value.isEmpty {
|
||||
writeBytes([0x00, 0x00, 0x00, 0x00])
|
||||
writeBytes(Data([0x00, 0x00, 0x00, 0x00]))
|
||||
return self
|
||||
}
|
||||
writeUInt32(UInt32(value.count))
|
||||
|
@ -345,7 +345,7 @@ extension AMF0Serializer: AMFSerializer {
|
|||
* @see 2.13 Date Type
|
||||
*/
|
||||
func serialize(_ value:Date) -> Self {
|
||||
return writeUInt8(Type.date.rawValue).writeDouble(value.timeIntervalSince1970 * 1000).writeBytes([0x00, 0x00])
|
||||
return writeUInt8(Type.date.rawValue).writeDouble(value.timeIntervalSince1970 * 1000).writeBytes(Data([0x00, 0x00]))
|
||||
}
|
||||
|
||||
func deserialize() throws -> Date {
|
||||
|
@ -373,7 +373,7 @@ extension AMF0Serializer: AMFSerializer {
|
|||
|
||||
@discardableResult
|
||||
fileprivate func serializeUTF8(_ value:String, _ isLong: Bool) -> Self {
|
||||
let utf8:[UInt8] = [UInt8](value.utf8)
|
||||
let utf8:Data = Data(value.utf8)
|
||||
if (isLong) {
|
||||
writeUInt32(UInt32(utf8.count))
|
||||
} else {
|
||||
|
|
|
@ -256,7 +256,7 @@ extension AMF3Serializer: AMFSerializer {
|
|||
return serializeU29(index << 1)
|
||||
}
|
||||
reference.objects.append(value)
|
||||
let utf8:[UInt8] = [UInt8](value.description.utf8)
|
||||
let utf8:Data = Data(value.description.utf8)
|
||||
return serialize(utf8.count << 1 | 0x01).writeBytes(utf8)
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,7 @@ extension AMF3Serializer: AMFSerializer {
|
|||
return serializeU29(index << 1)
|
||||
}
|
||||
reference.objects.append(value)
|
||||
let utf8:[UInt8] = [UInt8](value.description.utf8)
|
||||
let utf8:Data = Data(value.description.utf8)
|
||||
return serialize(utf8.count << 1 | 0x01).writeBytes(utf8)
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ extension AMF3Serializer: AMFSerializer {
|
|||
if let index:Int = reference.indexOf(value) {
|
||||
return serializeU29(index << 1)
|
||||
}
|
||||
let utf8:[UInt8] = [UInt8](value.utf8)
|
||||
let utf8:Data = Data(value.utf8)
|
||||
reference.strings.append(value)
|
||||
return serializeU29(utf8.count << 1 | 0x01).writeBytes(utf8)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ enum RTMPChunkType: UInt8 {
|
|||
if (streamId <= 319) {
|
||||
return Data([rawValue << 6 | 0b0000000, UInt8(streamId - 64)])
|
||||
}
|
||||
return Data([rawValue << 6 | 0b00111111] + (streamId - 64).bigEndian.bytes)
|
||||
return Data([rawValue << 6 | 0b00111111] + (streamId - 64).bigEndian.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,23 +6,23 @@ final class RTMPHandshake {
|
|||
|
||||
var timestamp:TimeInterval = 0
|
||||
|
||||
var c0c1packet:[UInt8] {
|
||||
var c0c1packet:Data {
|
||||
let packet:ByteArray = ByteArray()
|
||||
.writeUInt8(RTMPHandshake.protocolVersion)
|
||||
.writeInt32(Int32(timestamp))
|
||||
.writeBytes([0x00, 0x00, 0x00, 0x00])
|
||||
.writeBytes(Data([0x00, 0x00, 0x00, 0x00]))
|
||||
for _ in 0..<RTMPHandshake.sigSize - 8 {
|
||||
packet.writeUInt8(UInt8(arc4random_uniform(0xff)))
|
||||
}
|
||||
return packet.bytes
|
||||
return packet.data
|
||||
}
|
||||
|
||||
func c2packet(_ s0s1packet:[UInt8]) -> [UInt8] {
|
||||
let packet:ByteArray = ByteArray()
|
||||
.writeBytes(Array<UInt8>(s0s1packet[1...4]))
|
||||
func c2packet(_ s0s1packet:Data) -> Data {
|
||||
return ByteArray()
|
||||
.writeBytes(s0s1packet.subdata(in: 1..<5))
|
||||
.writeInt32(Int32(Date().timeIntervalSince1970 - timestamp))
|
||||
.writeBytes(Array<UInt8>(s0s1packet[9...RTMPHandshake.sigSize]))
|
||||
return packet.bytes
|
||||
.writeBytes(s0s1packet.subdata(in: 9..<RTMPHandshake.sigSize + 1))
|
||||
.data
|
||||
}
|
||||
|
||||
func clear() {
|
||||
|
|
|
@ -297,13 +297,13 @@ final class RTMPCommandMessage: RTMPMessage {
|
|||
for i in arguments {
|
||||
serializer.serialize(i)
|
||||
}
|
||||
super.payload = Data(serializer.bytes)
|
||||
super.payload = serializer.data
|
||||
serializer.clear()
|
||||
return super.payload
|
||||
}
|
||||
set {
|
||||
if (length == newValue.count) {
|
||||
serializer.writeBytes(newValue.bytes)
|
||||
serializer.writeBytes(newValue)
|
||||
serializer.position = 0
|
||||
do {
|
||||
if (type == .amf3Command) {
|
||||
|
@ -390,7 +390,7 @@ final class RTMPDataMessage: RTMPMessage {
|
|||
for arg in arguments {
|
||||
serializer.serialize(arg)
|
||||
}
|
||||
super.payload = Data(serializer.bytes)
|
||||
super.payload = serializer.data
|
||||
serializer.clear()
|
||||
|
||||
return super.payload
|
||||
|
@ -401,7 +401,7 @@ final class RTMPDataMessage: RTMPMessage {
|
|||
}
|
||||
|
||||
if (length == newValue.count) {
|
||||
serializer.writeBytes(newValue.bytes)
|
||||
serializer.writeBytes(newValue)
|
||||
serializer.position = 0
|
||||
if (type == .amf3Data) {
|
||||
serializer.position = 1
|
||||
|
@ -451,7 +451,7 @@ final class RTMPSharedObjectMessage: RTMPMessage {
|
|||
let objectEncoding:UInt8
|
||||
var sharedObjectName:String = ""
|
||||
var currentVersion:UInt32 = 0
|
||||
var flags:[UInt8] = [UInt8](repeating: 0x00, count: 8)
|
||||
var flags:Data = Data(count: 8)
|
||||
var events:[RTMPSharedObjectEvent] = []
|
||||
|
||||
override var payload:Data {
|
||||
|
@ -472,7 +472,7 @@ final class RTMPSharedObjectMessage: RTMPMessage {
|
|||
for event in events {
|
||||
event.serialize(&serializer)
|
||||
}
|
||||
super.payload = Data(serializer.bytes)
|
||||
super.payload = serializer.data
|
||||
serializer.clear()
|
||||
|
||||
return super.payload
|
||||
|
@ -483,7 +483,7 @@ final class RTMPSharedObjectMessage: RTMPMessage {
|
|||
}
|
||||
|
||||
if (length == newValue.count) {
|
||||
serializer.writeBytes(newValue.bytes)
|
||||
serializer.writeBytes(newValue)
|
||||
serializer.position = 0
|
||||
if (type == .amf3Shared) {
|
||||
serializer.position = 1
|
||||
|
@ -514,7 +514,7 @@ final class RTMPSharedObjectMessage: RTMPMessage {
|
|||
super.init(type: objectEncoding == 0x00 ? .amf0Shared : .amf3Shared)
|
||||
}
|
||||
|
||||
init(timestamp:UInt32, objectEncoding:UInt8, sharedObjectName:String, currentVersion:UInt32, flags:[UInt8], events:[RTMPSharedObjectEvent]) {
|
||||
init(timestamp:UInt32, objectEncoding:UInt8, sharedObjectName:String, currentVersion:UInt32, flags:Data, events:[RTMPSharedObjectEvent]) {
|
||||
self.objectEncoding = objectEncoding
|
||||
self.sharedObjectName = sharedObjectName
|
||||
self.currentVersion = currentVersion
|
||||
|
@ -665,7 +665,7 @@ final class RTMPVideoMessage: RTMPMessage {
|
|||
func enqueueSampleBuffer(_ stream: RTMPStream) {
|
||||
stream.videoTimestamp += Double(timestamp)
|
||||
|
||||
let compositionTimeoffset:Int32 = Int32(bytes: [0] + payload[2..<5]).bigEndian
|
||||
let compositionTimeoffset:Int32 = Int32(data: [0] + payload[2..<5]).bigEndian
|
||||
var timing:CMSampleTimingInfo = CMSampleTimingInfo(
|
||||
duration: CMTimeMake(Int64(timestamp), 1000),
|
||||
presentationTimeStamp: CMTimeMake(Int64(stream.videoTimestamp) + Int64(compositionTimeoffset), 1000),
|
||||
|
@ -691,7 +691,7 @@ final class RTMPVideoMessage: RTMPMessage {
|
|||
|
||||
func createFormatDescription(_ stream: RTMPStream) -> OSStatus {
|
||||
var config:AVCConfigurationRecord = AVCConfigurationRecord()
|
||||
config.bytes = Array<UInt8>(payload[FLVTagType.video.headerSize..<payload.count])
|
||||
config.data = payload.subdata(in: FLVTagType.video.headerSize..<payload.count)
|
||||
return config.createFormatDescription(&stream.mixer.videoIO.formatDescription)
|
||||
}
|
||||
}
|
||||
|
@ -739,7 +739,7 @@ final class RTMPUserControlMessage: RTMPMessage {
|
|||
}
|
||||
super.payload.removeAll()
|
||||
super.payload += event.bytes
|
||||
super.payload += value.bigEndian.bytes
|
||||
super.payload += value.bigEndian.data
|
||||
return super.payload
|
||||
}
|
||||
set {
|
||||
|
@ -750,7 +750,7 @@ final class RTMPUserControlMessage: RTMPMessage {
|
|||
if let event:Event = Event(rawValue: newValue[1]) {
|
||||
self.event = event
|
||||
}
|
||||
value = Int32(bytes: Array<UInt8>(newValue[2..<newValue.count])).bigEndian
|
||||
value = Int32(data: newValue[2..<newValue.count]).bigEndian
|
||||
}
|
||||
super.payload = newValue
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ extension RTMPMuxer: VideoEncoderDelegate {
|
|||
}
|
||||
let delta:Double = (videoTimestamp == kCMTimeZero ? 0 : decodeTimeStamp.seconds - videoTimestamp.seconds) * 1000
|
||||
var buffer:Data = Data([((keyframe ? FLVFrameType.key.rawValue : FLVFrameType.inter.rawValue) << 4) | FLVVideoCodec.avc.rawValue, FLVAVCPacketType.nal.rawValue])
|
||||
buffer.append(contentsOf: compositionTime.bigEndian.bytes[1..<4])
|
||||
buffer.append(contentsOf: compositionTime.bigEndian.data[1..<4])
|
||||
buffer.append(data)
|
||||
delegate?.sampleOutput(video: buffer, withTimestamp: delta, muxer: self)
|
||||
videoTimestamp = decodeTimeStamp
|
||||
|
@ -124,7 +124,7 @@ extension RTMPMuxer: MP4SamplerDelegate {
|
|||
case 0:
|
||||
let compositionTime:Int32 = 0
|
||||
var buffer:Data = Data([((keyframe ? FLVFrameType.key.rawValue : FLVFrameType.inter.rawValue) << 4) | FLVVideoCodec.avc.rawValue, FLVAVCPacketType.nal.rawValue])
|
||||
buffer.append(contentsOf: compositionTime.bigEndian.bytes[1..<4])
|
||||
buffer.append(contentsOf: compositionTime.bigEndian.data[1..<4])
|
||||
buffer.append(data)
|
||||
delegate?.sampleOutput(video: buffer, withTimestamp: currentTime, muxer: self)
|
||||
case 1:
|
||||
|
|
|
@ -210,7 +210,7 @@ open class RTMPSharedObject: EventDispatcher {
|
|||
objectEncoding: objectEncoding,
|
||||
sharedObjectName: name,
|
||||
currentVersion: succeeded ? 0 : currentVersion,
|
||||
flags: [persistence ? 0x01 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
||||
flags: Data([persistence ? 0x01 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
|
||||
events: events
|
||||
)
|
||||
)
|
||||
|
|
|
@ -58,7 +58,7 @@ final class RTMPSocket: NetSocket, RTMPSocketCompatible {
|
|||
override var connected:Bool {
|
||||
didSet {
|
||||
if (connected) {
|
||||
doOutput(bytes: handshake.c0c1packet)
|
||||
doOutput(data: handshake.c0c1packet)
|
||||
readyState = .versionSent
|
||||
return
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ final class RTMPSocket: NetSocket, RTMPSocketCompatible {
|
|||
if (inputBuffer.count < RTMPHandshake.sigSize + 1) {
|
||||
break
|
||||
}
|
||||
doOutput(bytes: handshake.c2packet(inputBuffer.bytes))
|
||||
doOutput(data: handshake.c2packet(inputBuffer))
|
||||
inputBuffer.removeSubrange(0...RTMPHandshake.sigSize)
|
||||
readyState = .ackSent
|
||||
if (RTMPHandshake.sigSize <= inputBuffer.count) {
|
||||
|
|
|
@ -13,7 +13,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
didSet {
|
||||
if (connected) {
|
||||
handshake.timestamp = Date().timeIntervalSince1970
|
||||
doOutput(bytes: handshake.c0c1packet)
|
||||
doOutput(data: handshake.c0c1packet)
|
||||
readyState = .versionSent
|
||||
return
|
||||
}
|
||||
|
@ -56,12 +56,12 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
private var baseURL:URL!
|
||||
private var session:URLSession!
|
||||
private var request:URLRequest!
|
||||
private var c2packet:[UInt8] = []
|
||||
private var c2packet:Data = Data()
|
||||
private var handshake:RTMPHandshake = RTMPHandshake()
|
||||
private let outputQueue:DispatchQueue = DispatchQueue(label: "com.haishinkit.HaishinKit.RTMPTSocket.output")
|
||||
private var connectionID:String?
|
||||
private var isRequesting:Bool = false
|
||||
private var outputBuffer:[UInt8] = []
|
||||
private var outputBuffer:Data = Data()
|
||||
private var lastResponse:Date = Date()
|
||||
private var lastRequestPathComponent:String?
|
||||
private var lastRequestData:Data?
|
||||
|
@ -95,8 +95,8 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
|
||||
outputQueue.sync {
|
||||
self.outputBuffer.append(contentsOf: bytes)
|
||||
if (!self.isRequesting) {
|
||||
self.doOutput(bytes: self.outputBuffer)
|
||||
if !self.isRequesting {
|
||||
self.doOutput(data: self.outputBuffer)
|
||||
self.outputBuffer.removeAll()
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
if (self.outputBuffer.isEmpty) {
|
||||
self.isRequesting = false
|
||||
} else {
|
||||
self.doOutput(bytes: outputBuffer)
|
||||
self.doOutput(data: outputBuffer)
|
||||
self.outputBuffer.removeAll()
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
if (inputBuffer.count < RTMPHandshake.sigSize + 1) {
|
||||
break
|
||||
}
|
||||
c2packet = handshake.c2packet(inputBuffer.bytes)
|
||||
c2packet = handshake.c2packet(inputBuffer)
|
||||
inputBuffer.removeSubrange(0...RTMPHandshake.sigSize)
|
||||
readyState = .ackSent
|
||||
fallthrough
|
||||
|
@ -262,14 +262,14 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
|
||||
@discardableResult
|
||||
final private func doOutput(bytes:[UInt8]) -> Int {
|
||||
final private func doOutput(data:Data) -> Int {
|
||||
guard let connectionID:String = connectionID, connected else {
|
||||
return 0
|
||||
}
|
||||
let index:Int64 = OSAtomicIncrement64(&self.index)
|
||||
doRequest("/send/\(connectionID)/\(index)", Data(c2packet + bytes), listen)
|
||||
doRequest("/send/\(connectionID)/\(index)", c2packet + data, listen)
|
||||
c2packet.removeAll()
|
||||
return bytes.count
|
||||
return data.count
|
||||
}
|
||||
|
||||
private func doRequest(_ pathComponent: String,_ data:Data,_ completionHandler: @escaping ((Data?, URLResponse?, Error?) -> Void)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
|
||||
protocol ByteArrayConvertible {
|
||||
|
||||
var bytes:[UInt8] { get }
|
||||
var data:Data { get }
|
||||
var length:Int { get set }
|
||||
var position:Int { get set }
|
||||
var bytesAvailable:Int { get }
|
||||
|
@ -53,8 +53,8 @@ protocol ByteArrayConvertible {
|
|||
func readUTF8Bytes(_ length:Int) throws -> String
|
||||
|
||||
@discardableResult
|
||||
func writeBytes(_ value:[UInt8]) -> Self
|
||||
func readBytes(_ length:Int) throws -> [UInt8]
|
||||
func writeBytes(_ value:Data) -> Self
|
||||
func readBytes(_ length:Int) throws -> Data
|
||||
|
||||
@discardableResult
|
||||
func clear() -> Self
|
||||
|
@ -79,26 +79,22 @@ open class ByteArray: ByteArrayConvertible {
|
|||
init() {
|
||||
}
|
||||
|
||||
init(bytes:[UInt8]) {
|
||||
self.bytes = bytes
|
||||
}
|
||||
|
||||
init(data:Data) {
|
||||
self.bytes = data.bytes
|
||||
self.data = data
|
||||
}
|
||||
|
||||
fileprivate(set) var bytes:[UInt8] = []
|
||||
fileprivate(set) var data:Data = Data()
|
||||
|
||||
open var length:Int {
|
||||
get {
|
||||
return bytes.count
|
||||
return data.count
|
||||
}
|
||||
set {
|
||||
switch true {
|
||||
case (bytes.count < newValue):
|
||||
bytes += [UInt8](repeating: 0, count: newValue - bytes.count)
|
||||
case (newValue < bytes.count):
|
||||
bytes = Array<UInt8>(bytes[0..<newValue])
|
||||
case (data.count < newValue):
|
||||
data.append(Data.init(count: newValue - data.count))
|
||||
case (newValue < data.count):
|
||||
data = data.subdata(in: 0..<newValue)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -108,15 +104,15 @@ open class ByteArray: ByteArrayConvertible {
|
|||
open var position:Int = 0
|
||||
|
||||
open var bytesAvailable:Int {
|
||||
return bytes.count - position
|
||||
return data.count - position
|
||||
}
|
||||
|
||||
open subscript(i: Int) -> UInt8 {
|
||||
get {
|
||||
return bytes[i]
|
||||
return data[i]
|
||||
}
|
||||
set {
|
||||
bytes[i] = newValue
|
||||
data[i] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,12 +123,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
defer {
|
||||
position += 1
|
||||
}
|
||||
return bytes[position]
|
||||
return data[position]
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeUInt8(_ value:UInt8) -> Self {
|
||||
return writeBytes([value])
|
||||
return writeBytes(value.data)
|
||||
}
|
||||
|
||||
open func readInt8() throws -> Int8 {
|
||||
|
@ -142,12 +138,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
defer {
|
||||
position += 1
|
||||
}
|
||||
return Int8(bitPattern: UInt8(bytes[position]))
|
||||
return Int8(bitPattern: UInt8(data[position]))
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeInt8(_ value:Int8) -> Self {
|
||||
return writeBytes([UInt8(bitPattern: value)])
|
||||
return writeBytes(UInt8(bitPattern: value).data)
|
||||
}
|
||||
|
||||
open func readUInt16() throws -> UInt16 {
|
||||
|
@ -155,12 +151,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfInt16
|
||||
return UInt16(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfInt16..<position])).bigEndian
|
||||
return UInt16(data: data[position - ByteArray.sizeOfInt16..<position]).bigEndian
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeUInt16(_ value:UInt16) -> Self {
|
||||
return writeBytes(value.bigEndian.bytes)
|
||||
return writeBytes(value.bigEndian.data)
|
||||
}
|
||||
|
||||
open func readInt16() throws -> Int16 {
|
||||
|
@ -168,12 +164,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfInt16
|
||||
return Int16(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfInt16..<position])).bigEndian
|
||||
return Int16(data: data[position - ByteArray.sizeOfInt16..<position]).bigEndian
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeInt16(_ value:Int16) -> Self {
|
||||
return writeBytes(value.bigEndian.bytes)
|
||||
return writeBytes(value.bigEndian.data)
|
||||
}
|
||||
|
||||
open func readUInt24() throws -> UInt32 {
|
||||
|
@ -181,12 +177,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfInt24
|
||||
return UInt32(bytes: ByteArray.fillZero + Array<UInt8>(bytes[position - ByteArray.sizeOfInt24..<position])).bigEndian
|
||||
return UInt32(data: ByteArray.fillZero + data[position - ByteArray.sizeOfInt24..<position]).bigEndian
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeUInt24(_ value:UInt32) -> Self {
|
||||
return writeBytes(Array<UInt8>(value.bigEndian.bytes[1...ByteArray.sizeOfInt24]))
|
||||
return writeBytes(value.bigEndian.data.subdata(in: 1..<ByteArray.sizeOfInt24 + 1))
|
||||
}
|
||||
|
||||
open func readUInt32() throws -> UInt32 {
|
||||
|
@ -194,12 +190,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfInt32
|
||||
return UInt32(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfInt32..<position])).bigEndian
|
||||
return UInt32(data: data[position - ByteArray.sizeOfInt32..<position]).bigEndian
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeUInt32(_ value:UInt32) -> Self {
|
||||
return writeBytes(value.bigEndian.bytes)
|
||||
return writeBytes(value.bigEndian.data)
|
||||
}
|
||||
|
||||
open func readInt32() throws -> Int32 {
|
||||
|
@ -207,12 +203,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfInt32
|
||||
return Int32(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfInt32..<position])).bigEndian
|
||||
return Int32(data: data[position - ByteArray.sizeOfInt32..<position]).bigEndian
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeInt32(_ value:Int32) -> Self {
|
||||
return writeBytes(value.bigEndian.bytes)
|
||||
return writeBytes(value.bigEndian.data)
|
||||
}
|
||||
|
||||
open func readDouble() throws -> Double {
|
||||
|
@ -220,12 +216,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfDouble
|
||||
return Double(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfDouble..<position].reversed()))
|
||||
return Double(data: Data(data.subdata(in: position - ByteArray.sizeOfDouble..<position).reversed()))
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeDouble(_ value:Double) -> Self {
|
||||
return writeBytes(value.bytes.reversed())
|
||||
return writeBytes(Data(value.data.reversed()))
|
||||
}
|
||||
|
||||
open func readFloat() throws -> Float {
|
||||
|
@ -233,12 +229,12 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += ByteArray.sizeOfFloat
|
||||
return Float(bytes: Array<UInt8>(bytes[position - ByteArray.sizeOfFloat..<position].reversed()))
|
||||
return Float(data: Data(data.subdata(in: position - ByteArray.sizeOfFloat..<position).reversed()))
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeFloat(_ value:Float) -> Self {
|
||||
return writeBytes(value.bytes.reversed())
|
||||
return writeBytes(Data(value.data.reversed()))
|
||||
}
|
||||
|
||||
open func readUTF8() throws -> String {
|
||||
|
@ -247,7 +243,7 @@ open class ByteArray: ByteArrayConvertible {
|
|||
|
||||
@discardableResult
|
||||
open func writeUTF8(_ value:String) throws -> Self {
|
||||
let utf8:[UInt8] = [UInt8](value.utf8)
|
||||
let utf8:Data = Data(value.utf8)
|
||||
return writeUInt16(UInt16(utf8.count)).writeBytes(utf8)
|
||||
}
|
||||
|
||||
|
@ -256,7 +252,8 @@ open class ByteArray: ByteArrayConvertible {
|
|||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += length
|
||||
guard let result:String = String(bytes: Array<UInt8>(bytes[position - length..<position]), encoding: String.Encoding.utf8) else {
|
||||
|
||||
guard let result:String = String(data: data.subdata(in: position - length..<position), encoding: .utf8) else {
|
||||
throw ByteArray.Error.parse
|
||||
}
|
||||
return result
|
||||
|
@ -264,28 +261,28 @@ open class ByteArray: ByteArrayConvertible {
|
|||
|
||||
@discardableResult
|
||||
open func writeUTF8Bytes(_ value:String) -> Self {
|
||||
return writeBytes([UInt8](value.utf8))
|
||||
return writeBytes(Data(value.utf8))
|
||||
}
|
||||
|
||||
open func readBytes(_ length:Int) throws -> [UInt8] {
|
||||
open func readBytes(_ length:Int) throws -> Data {
|
||||
guard length <= bytesAvailable else {
|
||||
throw ByteArray.Error.eof
|
||||
}
|
||||
position += length
|
||||
return Array<UInt8>(bytes[position - length..<position])
|
||||
return data.subdata(in: position - length..<position)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
open func writeBytes(_ value:[UInt8]) -> Self {
|
||||
if (position == bytes.count) {
|
||||
bytes.append(contentsOf: value)
|
||||
position = bytes.count
|
||||
open func writeBytes(_ value:Data) -> Self {
|
||||
if (position == data.count) {
|
||||
data.append(value)
|
||||
position = data.count
|
||||
return self
|
||||
}
|
||||
let length:Int = min(bytes.count, value.count)
|
||||
bytes[position..<position + length] = value[0..<length]
|
||||
if (length == bytes.count) {
|
||||
bytes.append(contentsOf: value[length..<value.count])
|
||||
let length:Int = min(data.count, value.count)
|
||||
data[position..<position + length] = value[0..<length]
|
||||
if (length == data.count) {
|
||||
data.append(value[length..<value.count])
|
||||
}
|
||||
position += value.count
|
||||
return self
|
||||
|
@ -294,28 +291,28 @@ open class ByteArray: ByteArrayConvertible {
|
|||
@discardableResult
|
||||
open func clear() -> Self {
|
||||
position = 0
|
||||
bytes.removeAll()
|
||||
data.removeAll()
|
||||
return self
|
||||
}
|
||||
|
||||
func sequence(_ length:Int, lambda:((ByteArray) -> Void)) {
|
||||
let r:Int = (bytes.count - position) % length
|
||||
for index in stride(from: bytes.startIndex.advanced(by: position), to: bytes.endIndex.advanced(by: -r), by: length) {
|
||||
lambda(ByteArray(bytes: Array<UInt8>(bytes[index..<index.advanced(by: length)])))
|
||||
let r:Int = (data.count - position) % length
|
||||
for index in stride(from: data.startIndex.advanced(by: position), to: data.endIndex.advanced(by: -r), by: length) {
|
||||
lambda(ByteArray(data: data.subdata(in: index..<index.advanced(by: length))))
|
||||
}
|
||||
if (0 < r) {
|
||||
lambda(ByteArray(bytes: Array<UInt8>(bytes[bytes.indices.suffix(from: bytes.endIndex - r)])))
|
||||
lambda(ByteArray(data: data.advanced(by: data.endIndex - r)))
|
||||
}
|
||||
}
|
||||
|
||||
func toUInt32() -> [UInt32] {
|
||||
let size:Int = MemoryLayout<UInt32>.size
|
||||
if ((bytes.endIndex - position) % size != 0) {
|
||||
if ((data.endIndex - position) % size != 0) {
|
||||
return []
|
||||
}
|
||||
var result:[UInt32] = []
|
||||
for index in stride(from: bytes.startIndex.advanced(by: position), to: bytes.endIndex, by: size) {
|
||||
result.append(UInt32(bytes: Array<UInt8>(bytes[index..<index.advanced(by: size)])))
|
||||
for index in stride(from: data.startIndex.advanced(by: position), to: data.endIndex, by: size) {
|
||||
result.append(UInt32(data: data[index..<index.advanced(by: size)]))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@ final class CRC32 {
|
|||
self.table = table
|
||||
}
|
||||
|
||||
func calculate(_ bytes:[UInt8]) -> UInt32 {
|
||||
return calculate(bytes, seed: nil)
|
||||
func calculate(_ data:Data) -> UInt32 {
|
||||
return calculate(data, seed: nil)
|
||||
}
|
||||
|
||||
func calculate(_ bytes:[UInt8], seed:UInt32?) -> UInt32 {
|
||||
func calculate(_ data:Data, seed:UInt32?) -> UInt32 {
|
||||
var crc:UInt32 = seed ?? 0xffffffff
|
||||
for i in 0..<bytes.count {
|
||||
crc = (crc << 8) ^ table[Int((crc >> 24) ^ (UInt32(bytes[i]) & 0xff) & 0xff)]
|
||||
for i in 0..<data.count {
|
||||
crc = (crc << 8) ^ table[Int((crc >> 24) ^ (UInt32(data[i]) & 0xff) & 0xff)]
|
||||
}
|
||||
return crc
|
||||
}
|
||||
|
|
|
@ -77,26 +77,24 @@ final class MD5 {
|
|||
return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))
|
||||
}
|
||||
|
||||
var bytes:[UInt8] {
|
||||
return a.bytes + b.bytes + c.bytes + d.bytes
|
||||
var data:Data {
|
||||
return a.data + b.data + c.data + d.data
|
||||
}
|
||||
}
|
||||
|
||||
static func base64(_ message:String) -> String {
|
||||
let result:[UInt8] = calculate(message)
|
||||
let data:Data = Data(bytes: UnsafePointer<UInt8>(result), count: result.count)
|
||||
return data.base64EncodedString(options: .lineLength64Characters)
|
||||
return calculate(message).base64EncodedString(options: .lineLength64Characters)
|
||||
}
|
||||
|
||||
static func calculate(_ message:String) -> [UInt8] {
|
||||
return calculate(ByteArray().writeUTF8Bytes(message).bytes)
|
||||
static func calculate(_ message:String) -> Data {
|
||||
return calculate(ByteArray().writeUTF8Bytes(message).data)
|
||||
}
|
||||
|
||||
static func calculate(_ bytes:[UInt8]) -> [UInt8] {
|
||||
static func calculate(_ data:Data) -> Data {
|
||||
var context:Context = Context()
|
||||
|
||||
let count:[UInt8] = UInt64(bytes.count * 8).bigEndian.bytes
|
||||
let message:ByteArray = ByteArray(bytes: bytes + [0x80])
|
||||
let count:Data = UInt64(data.count * 8).bigEndian.data
|
||||
let message:ByteArray = ByteArray(data: data + [0x80])
|
||||
message.length += 64 - (message.length % 64)
|
||||
message[message.length - 8] = count[7]
|
||||
message[message.length - 7] = count[6]
|
||||
|
@ -198,6 +196,6 @@ final class MD5 {
|
|||
context.d = context.d &+ ctx.d
|
||||
}
|
||||
|
||||
return context.bytes
|
||||
return context.data
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,9 @@ import XCTest
|
|||
|
||||
final class SwiftCoreExtensionTests: XCTestCase {
|
||||
func testInt32() {
|
||||
XCTAssertEqual(Int32.min, Int32(bytes: Int32.min.bytes))
|
||||
XCTAssertEqual(Int32.max, Int32(bytes: Int32.max.bytes))
|
||||
XCTAssertEqual(Int32.min, Int32(data: Int32.min.data))
|
||||
XCTAssertEqual(Int32.max, Int32(data: Int32.max.data))
|
||||
|
||||
|
||||
print(Int32.max)
|
||||
|
||||
print(Int32(data: Int32.max.data[0..<3]))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ import XCTest
|
|||
|
||||
final class PacketizedElementaryStreamTests: XCTestCase {
|
||||
|
||||
static let dataWithVideo:[UInt8] = [0, 0, 1, 224, 0, 0, 128, 128, 5, 33, 0, 7, 216, 97, 0, 0, 0, 1, 9, 240, 0, 0, 0, 1, 103, 77, 64, 13, 218, 5, 7, 236, 4, 64, 0, 0, 3, 0, 64, 0, 0, 7, 131, 197, 10, 168, 0, 0, 0, 1, 104, 239, 60, 128, 0, 0, 0, 1, 101, 136, 130, 1, 15, 250, 120, 30, 255, 244, 55, 157, 215, 115, 255, 239, 112, 39, 83, 211, 17, 103, 152, 229, 241, 131, 49, 7, 123, 10, 145, 184, 0, 0, 3, 3, 133, 122, 49, 20, 214, 115, 51, 202, 59, 43, 204, 79, 27, 229, 101, 135, 60, 234, 243, 78, 210, 98, 30, 252, 36, 38, 20, 202, 41, 121, 70, 45, 15, 54, 125, 153, 199, 236, 90, 142, 247, 27, 202, 17, 205, 77, 133, 21, 189, 212, 159, 87, 222, 100, 53, 75, 211, 139, 219, 83, 89, 59, 199, 242, 182, 18, 245, 72, 70, 50, 230, 58, 82, 122, 179, 121, 243, 232, 107, 206, 157, 13]
|
||||
static let dataWithVideo:Data = Data([0, 0, 1, 224, 0, 0, 128, 128, 5, 33, 0, 7, 216, 97, 0, 0, 0, 1, 9, 240, 0, 0, 0, 1, 103, 77, 64, 13, 218, 5, 7, 236, 4, 64, 0, 0, 3, 0, 64, 0, 0, 7, 131, 197, 10, 168, 0, 0, 0, 1, 104, 239, 60, 128, 0, 0, 0, 1, 101, 136, 130, 1, 15, 250, 120, 30, 255, 244, 55, 157, 215, 115, 255, 239, 112, 39, 83, 211, 17, 103, 152, 229, 241, 131, 49, 7, 123, 10, 145, 184, 0, 0, 3, 3, 133, 122, 49, 20, 214, 115, 51, 202, 59, 43, 204, 79, 27, 229, 101, 135, 60, 234, 243, 78, 210, 98, 30, 252, 36, 38, 20, 202, 41, 121, 70, 45, 15, 54, 125, 153, 199, 236, 90, 142, 247, 27, 202, 17, 205, 77, 133, 21, 189, 212, 159, 87, 222, 100, 53, 75, 211, 139, 219, 83, 89, 59, 199, 242, 182, 18, 245, 72, 70, 50, 230, 58, 82, 122, 179, 121, 243, 232, 107, 206, 157, 13])
|
||||
|
||||
func testPES() {
|
||||
let pes:PacketizedElementaryStream = PacketizedElementaryStream(bytes: PacketizedElementaryStreamTests.dataWithVideo)!
|
||||
XCTAssertEqual(pes.bytes, PacketizedElementaryStreamTests.dataWithVideo)
|
||||
let pes:PacketizedElementaryStream = PacketizedElementaryStream(payload: PacketizedElementaryStreamTests.dataWithVideo)!
|
||||
XCTAssertEqual(pes.payload, PacketizedElementaryStreamTests.dataWithVideo)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,17 +5,17 @@ import XCTest
|
|||
|
||||
final class ProgramSpecificTests: XCTestCase {
|
||||
|
||||
static let dataForPAT:[UInt8] = [0, 0, 176, 13, 0, 1, 193, 0, 0, 0, 1, 240, 0, 42, 177, 4, 178]
|
||||
static let dataForPMT:[UInt8] = [0, 2, 176, 29, 0, 1, 193, 0, 0, 225, 0, 240, 0, 27, 225, 0, 240, 0, 15, 225, 1, 240, 6, 10, 4, 117, 110, 100, 0, 8, 125, 232, 119]
|
||||
static let dataForPAT:Data = Data([0, 0, 176, 13, 0, 1, 193, 0, 0, 0, 1, 240, 0, 42, 177, 4, 178])
|
||||
static let dataForPMT:Data = Data([0, 2, 176, 29, 0, 1, 193, 0, 0, 225, 0, 240, 0, 27, 225, 0, 240, 0, 15, 225, 1, 240, 6, 10, 4, 117, 110, 100, 0, 8, 125, 232, 119])
|
||||
|
||||
func testPAT() {
|
||||
let pat:ProgramAssociationSpecific = ProgramAssociationSpecific(bytes: ProgramSpecificTests.dataForPAT)!
|
||||
let pat:ProgramAssociationSpecific = ProgramAssociationSpecific(data: ProgramSpecificTests.dataForPAT)!
|
||||
XCTAssertEqual(pat.programs, [1:4096])
|
||||
XCTAssertEqual(pat.bytes, ProgramSpecificTests.dataForPAT)
|
||||
XCTAssertEqual(pat.data, ProgramSpecificTests.dataForPAT)
|
||||
}
|
||||
|
||||
func testPMT() {
|
||||
let pmt:ProgramMapSpecific = ProgramMapSpecific(bytes: ProgramSpecificTests.dataForPMT)!
|
||||
XCTAssertEqual(pmt.bytes, ProgramSpecificTests.dataForPMT)
|
||||
let pmt:ProgramMapSpecific = ProgramMapSpecific(data: ProgramSpecificTests.dataForPMT)!
|
||||
XCTAssertEqual(pmt.data, ProgramSpecificTests.dataForPMT)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ import XCTest
|
|||
@testable import lf
|
||||
|
||||
final class TSTests: XCTestCase {
|
||||
static let dataWithMetadata:[UInt8] = [71, 64, 17, 16, 0, 66, 240, 37, 0, 1, 193, 0, 0, 0, 1, 255, 0, 1, 252, 128, 20, 72, 18, 1, 6, 70, 70, 109, 112, 101, 103, 9, 83, 101, 114, 118, 105, 99, 101, 48, 49, 167, 121, 160, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
|
||||
static let dataWithMetadata:Data = Data([71, 64, 17, 16, 0, 66, 240, 37, 0, 1, 193, 0, 0, 0, 1, 255, 0, 1, 252, 128, 20, 72, 18, 1, 6, 70, 70, 109, 112, 101, 103, 9, 83, 101, 114, 118, 105, 99, 101, 48, 49, 167, 121, 160, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255])
|
||||
|
||||
func testTSPacket() {
|
||||
let packetWithMetadata:TSPacket = TSPacket(bytes: TSTests.dataWithMetadata)!
|
||||
let packetWithMetadata:TSPacket = TSPacket(data: TSTests.dataWithMetadata)!
|
||||
XCTAssertEqual(packetWithMetadata.syncByte, TSPacket.defaultSyncByte)
|
||||
XCTAssertEqual(packetWithMetadata.PID, 17)
|
||||
XCTAssertEqual(packetWithMetadata.bytes, TSTests.dataWithMetadata)
|
||||
XCTAssertEqual(packetWithMetadata.data, TSTests.dataWithMetadata)
|
||||
}
|
||||
|
||||
func testTSReader() {
|
||||
|
@ -25,15 +25,15 @@ final class TSTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testTSProgramClockReference() {
|
||||
let data:[UInt8] = [0, 1, 66, 68, 126, 0]
|
||||
let data:Data = Data([0, 1, 66, 68, 126, 0])
|
||||
let (b, e) = TSProgramClockReference.decode(data)
|
||||
XCTAssertEqual(data, TSProgramClockReference.encode(b, e))
|
||||
}
|
||||
|
||||
func testTSTimestamp() {
|
||||
XCTAssertEqual(0, TSTimestamp.decode([49, 0, 1, 0, 1]))
|
||||
XCTAssertEqual(0, TSTimestamp.decode([17, 0, 1, 0, 1]))
|
||||
XCTAssertEqual([49, 0, 1, 0, 1], TSTimestamp.encode(0, TSTimestamp.PTSDTSMask))
|
||||
XCTAssertEqual([17, 0, 1, 0, 1], TSTimestamp.encode(0, TSTimestamp.PTSMask))
|
||||
XCTAssertEqual(0, TSTimestamp.decode(Data([49, 0, 1, 0, 1])))
|
||||
XCTAssertEqual(0, TSTimestamp.decode(Data([17, 0, 1, 0, 1])))
|
||||
XCTAssertEqual(Data([49, 0, 1, 0, 1]), TSTimestamp.encode(0, TSTimestamp.PTSDTSMask))
|
||||
XCTAssertEqual(Data([17, 0, 1, 0, 1]), TSTimestamp.encode(0, TSTimestamp.PTSMask))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,6 @@ final class CRC32Tests: XCTestCase {
|
|||
|
||||
func testMPEG2() {
|
||||
XCTAssertEqual(CRC32.MPEG2.table, CRC32Tests.tableOfMpeg2)
|
||||
XCTAssertEqual(716244146, CRC32.MPEG2.calculate([0, 176, 13, 0, 1, 193, 0, 0, 0, 1, 240, 0]))
|
||||
XCTAssertEqual(716244146, CRC32.MPEG2.calculate(Data([0, 176, 13, 0, 1, 193, 0, 0, 0, 1, 240, 0])))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import XCTest
|
|||
|
||||
final class MD5Tests: XCTestCase {
|
||||
|
||||
func hex(_ data:[UInt8]) -> String {
|
||||
func hex(_ data:Data) -> String {
|
||||
var hash:String = ""
|
||||
for i in 0..<data.count {
|
||||
hash += String(format: "%02x", data[i])
|
||||
|
|
|
@ -151,6 +151,8 @@
|
|||
299AE0E71D45003D00D26A49 /* RTSPSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299AE0E41D44EC7800D26A49 /* RTSPSocket.swift */; };
|
||||
299B131D1D35272D00A1E8F5 /* ScreenCaptureSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B131C1D35272D00A1E8F5 /* ScreenCaptureSession.swift */; };
|
||||
299B13271D3B751400A1E8F5 /* LFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B13261D3B751400A1E8F5 /* LFView.swift */; };
|
||||
299E044A1F1CE3870020DFBF /* ObjcExceptionBridging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 298F15BF1E9A5A18009226BA /* ObjcExceptionBridging.framework */; };
|
||||
299E044B1F1CE3870020DFBF /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2911F9BF1DE53F2A007FD1EC /* XCGLogger.framework */; };
|
||||
29A39C8E1D85BF6F007C27E9 /* BroadcastViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C831D85BF21007C27E9 /* BroadcastViewController.swift */; };
|
||||
29AF3FCF1D7C744C00E41212 /* NetStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AF3FCE1D7C744C00E41212 /* NetStream.swift */; };
|
||||
29AF3FD01D7C745200E41212 /* NetStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AF3FCE1D7C744C00E41212 /* NetStream.swift */; };
|
||||
|
@ -361,13 +363,6 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
2913B9581EAE518100F95645 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2945CBB41B4BE66000104112 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 29C932931CD76FD300283FC5;
|
||||
remoteInfo = "Example macOS";
|
||||
};
|
||||
2915EC6A1D85BDF100621092 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2945CBB41B4BE66000104112 /* Project object */;
|
||||
|
@ -670,6 +665,8 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
299E044A1F1CE3870020DFBF /* ObjcExceptionBridging.framework in Frameworks */,
|
||||
299E044B1F1CE3870020DFBF /* XCGLogger.framework in Frameworks */,
|
||||
29798E671CE610F500F5CBD0 /* lf.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1285,12 +1282,12 @@
|
|||
29798E561CE60E5300F5CBD0 /* Frameworks */,
|
||||
29798E571CE60E5300F5CBD0 /* Resources */,
|
||||
29798E551CE60E5300F5CBD0 /* Sources */,
|
||||
299E044F1F1CE3D90020DFBF /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
29798E601CE60E5300F5CBD0 /* PBXTargetDependency */,
|
||||
2913B9591EAE518100F95645 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Tests;
|
||||
productName = Tests;
|
||||
|
@ -1425,7 +1422,6 @@
|
|||
29798E581CE60E5300F5CBD0 = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
LastSwiftMigration = 0800;
|
||||
TestTargetID = 29C932931CD76FD300283FC5;
|
||||
};
|
||||
29B8761A1CD701F900FC07DA = {
|
||||
CreatedOnToolsVersion = 7.3;
|
||||
|
@ -1615,6 +1611,21 @@
|
|||
shellScript = "/usr/local/bin/carthage copy-frameworks";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
299E044F1F1CE3D90020DFBF /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/Carthage/Build/Mac/XCGLogger.framework",
|
||||
"$(SRCROOT)/Carthage/Build/Mac/ObjcExceptionBridging.framework",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/usr/local/bin/carthage copy-frameworks";
|
||||
};
|
||||
29F5FEA81DE2C76B00D0CCB4 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -2014,11 +2025,6 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
2913B9591EAE518100F95645 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 29C932931CD76FD300283FC5 /* Example macOS */;
|
||||
targetProxy = 2913B9581EAE518100F95645 /* PBXContainerItemProxy */;
|
||||
};
|
||||
2915EC6B1D85BDF100621092 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2915EC5E1D85BDF100621092 /* ScreencastUI */;
|
||||
|
@ -2329,7 +2335,6 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example macOS.app/Contents/MacOS/Example macOS";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -2350,7 +2355,6 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example macOS.app/Contents/MacOS/Example macOS";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue