diff --git a/HaishinKit.xcodeproj/project.pbxproj b/HaishinKit.xcodeproj/project.pbxproj index 327ecd26e..0f3942d21 100644 --- a/HaishinKit.xcodeproj/project.pbxproj +++ b/HaishinKit.xcodeproj/project.pbxproj @@ -164,6 +164,7 @@ BC34E00225EBB59C005F975A /* Logboard.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC34DFD125EBB12C005F975A /* Logboard.xcframework */; }; BC34FA0B286CB90A00EFAF27 /* PiPHKView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC34FA0A286CB90A00EFAF27 /* PiPHKView.swift */; }; BC37861D2C0F7B9900D79263 /* CMFormatDescription+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC37861C2C0F7B9900D79263 /* CMFormatDescription+Extension.swift */; }; + BC3786232C10CA9B00D79263 /* NALUnitReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC3786222C10CA9B00D79263 /* NALUnitReader.swift */; }; BC3802122AB5E770001AE399 /* IOVideoCaptureUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC3802112AB5E770001AE399 /* IOVideoCaptureUnit.swift */; }; BC3802142AB5E7CC001AE399 /* IOAudioCaptureUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC3802132AB5E7CC001AE399 /* IOAudioCaptureUnit.swift */; }; BC3802192AB6AD79001AE399 /* IOAudioMixerTrackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC3802182AB6AD79001AE399 /* IOAudioMixerTrackTests.swift */; }; @@ -239,12 +240,12 @@ BCABED1F2BDD097F00CC7E73 /* IOAudioMixer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3D687812B80302B00E6A28E /* IOAudioMixer.swift */; }; BCABED212BDE23C600CC7E73 /* AudioNode+DebugExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCABED202BDE23C600CC7E73 /* AudioNode+DebugExtension.swift */; }; BCB976DF26107B5600C9A649 /* TSField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB976DE26107B5600C9A649 /* TSField.swift */; }; - BCB9773F2621812800C9A649 /* AVCFormatStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB9773E2621812800C9A649 /* AVCFormatStream.swift */; }; + BCB9773F2621812800C9A649 /* ISOTypeBufferUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB9773E2621812800C9A649 /* ISOTypeBufferUtil.swift */; }; BCC1A72B264FAC1800661156 /* ESSpecificData.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC1A72A264FAC1800661156 /* ESSpecificData.swift */; }; BCC4F4152AD6FC1100954EF5 /* IOTellyUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC4F4142AD6FC1100954EF5 /* IOTellyUnit.swift */; }; BCC4F43D2ADB966800954EF5 /* NetStreamSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE0E33B2AD369410082C16F /* NetStreamSwitcher.swift */; }; BCC9E9092636FF7400948774 /* DataBufferTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC9E9082636FF7400948774 /* DataBufferTests.swift */; }; - BCCBCE9529A7C9C90095B51C /* AVCFormatStreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCCBCE9429A7C9C90095B51C /* AVCFormatStreamTests.swift */; }; + BCCBCE9529A7C9C90095B51C /* ISOTypeBufferUtilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCCBCE9429A7C9C90095B51C /* ISOTypeBufferUtilTests.swift */; }; BCCBCE9729A90D880095B51C /* AVCNALUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCCBCE9629A90D880095B51C /* AVCNALUnit.swift */; }; BCCBCE9B29A9D96A0095B51C /* NALUnitReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCCBCE9A29A9D96A0095B51C /* NALUnitReaderTests.swift */; }; BCCC45992AA289FA0016EFE8 /* SRTHaishinKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCC45982AA289FA0016EFE8 /* SRTHaishinKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -611,6 +612,7 @@ BC34DFD125EBB12C005F975A /* Logboard.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Logboard.xcframework; path = Carthage/Build/Logboard.xcframework; sourceTree = ""; }; BC34FA0A286CB90A00EFAF27 /* PiPHKView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPHKView.swift; sourceTree = ""; }; BC37861C2C0F7B9900D79263 /* CMFormatDescription+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CMFormatDescription+Extension.swift"; sourceTree = ""; }; + BC3786222C10CA9B00D79263 /* NALUnitReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NALUnitReader.swift; sourceTree = ""; }; BC3802112AB5E770001AE399 /* IOVideoCaptureUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOVideoCaptureUnit.swift; sourceTree = ""; }; BC3802132AB5E7CC001AE399 /* IOAudioCaptureUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOAudioCaptureUnit.swift; sourceTree = ""; }; BC3802182AB6AD79001AE399 /* IOAudioMixerTrackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOAudioMixerTrackTests.swift; sourceTree = ""; }; @@ -667,11 +669,11 @@ BCABED1D2BDCC79000CC7E73 /* SRTMuxer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRTMuxer.swift; sourceTree = ""; }; BCABED202BDE23C600CC7E73 /* AudioNode+DebugExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AudioNode+DebugExtension.swift"; sourceTree = ""; }; BCB976DE26107B5600C9A649 /* TSField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSField.swift; sourceTree = ""; }; - BCB9773E2621812800C9A649 /* AVCFormatStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVCFormatStream.swift; sourceTree = ""; }; + BCB9773E2621812800C9A649 /* ISOTypeBufferUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISOTypeBufferUtil.swift; sourceTree = ""; }; BCC1A72A264FAC1800661156 /* ESSpecificData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESSpecificData.swift; sourceTree = ""; }; BCC4F4142AD6FC1100954EF5 /* IOTellyUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOTellyUnit.swift; sourceTree = ""; }; BCC9E9082636FF7400948774 /* DataBufferTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBufferTests.swift; sourceTree = ""; }; - BCCBCE9429A7C9C90095B51C /* AVCFormatStreamTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVCFormatStreamTests.swift; sourceTree = ""; }; + BCCBCE9429A7C9C90095B51C /* ISOTypeBufferUtilTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISOTypeBufferUtilTests.swift; sourceTree = ""; }; BCCBCE9629A90D880095B51C /* AVCNALUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVCNALUnit.swift; sourceTree = ""; }; BCCBCE9A29A9D96A0095B51C /* NALUnitReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NALUnitReaderTests.swift; sourceTree = ""; }; BCCC45962AA289FA0016EFE8 /* SRTHaishinKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SRTHaishinKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -859,16 +861,16 @@ children = ( BC7C56D029A78D4F00C41A9B /* ADTSHeaderTests.swift */, BC3E384329C216BB007CD972 /* ADTSReaderTests.swift */, - BCCBCE9429A7C9C90095B51C /* AVCFormatStreamTests.swift */, 2917CB652104CA2800F6823A /* AudioSpecificConfigTests.swift */, + BC1720A82C03473200F65941 /* AVCDecoderConfigurationRecordTests.swift */, BC7C56C629A7701F00C41A9B /* ESSpecificDataTests.swift */, BC1DC5112A04E46E00E928ED /* HEVCDecoderConfigurationRecordTests.swift */, + BCCBCE9429A7C9C90095B51C /* ISOTypeBufferUtilTests.swift */, BCCBCE9A29A9D96A0095B51C /* NALUnitReaderTests.swift */, 290EA8951DFB619600053022 /* PacketizedElementaryStreamTests.swift */, 290EA8971DFB619600053022 /* TSPacketTests.swift */, 290EA8961DFB619600053022 /* TSProgramTests.swift */, BC7C56C229A1F28700C41A9B /* TSReaderTests.swift */, - BC1720A82C03473200F65941 /* AVCDecoderConfigurationRecordTests.swift */, ); path = ISO; sourceTree = ""; @@ -1286,12 +1288,13 @@ BC7C56CC29A786AE00C41A9B /* ADTS.swift */, 29B8767D1CD70AE800FC07DA /* AudioSpecificConfig.swift */, 29B8767E1CD70AE800FC07DA /* AVCDecoderConfigurationRecord.swift */, - BCB9773E2621812800C9A649 /* AVCFormatStream.swift */, BCCBCE9629A90D880095B51C /* AVCNALUnit.swift */, 29B876B91CD70B3900FC07DA /* CRC32.swift */, BCC1A72A264FAC1800661156 /* ESSpecificData.swift */, BC1DC5092A039B4400E928ED /* HEVCDecoderConfigurationRecord.swift */, BC1DC5132A05428800E928ED /* HEVCNALUnit.swift */, + BCB9773E2621812800C9A649 /* ISOTypeBufferUtil.swift */, + BC3786222C10CA9B00D79263 /* NALUnitReader.swift */, 29B876801CD70AE800FC07DA /* PacketizedElementaryStream.swift */, BCB976DE26107B5600C9A649 /* TSField.swift */, 29B876821CD70AE800FC07DA /* TSPacket.swift */, @@ -1775,7 +1778,7 @@ files = ( BC4914AE28DDF445009E2DF6 /* VTDecompressionSession+Extension.swift in Sources */, 29B876B11CD70B2800FC07DA /* RTMPMessage.swift in Sources */, - BCB9773F2621812800C9A649 /* AVCFormatStream.swift in Sources */, + BCB9773F2621812800C9A649 /* ISOTypeBufferUtil.swift in Sources */, BC83A4732403D83B006BDE06 /* VTCompressionSession+Extension.swift in Sources */, BC4914A228DDD33D009E2DF6 /* VTSessionConvertible.swift in Sources */, 2915EC4D1D85BB8C00621092 /* RTMPTSocket.swift in Sources */, @@ -1866,6 +1869,7 @@ BCA3A5252BC4ED220083BBB1 /* RTMPTimestamp.swift in Sources */, BC7C56BB299E595000C41A9B /* VideoCodecSettings.swift in Sources */, 29B876881CD70AE800FC07DA /* TSPacket.swift in Sources */, + BC3786232C10CA9B00D79263 /* NALUnitReader.swift in Sources */, BC22EEEE2AAF50F200E3406D /* Codec.swift in Sources */, 29B876BE1CD70B3900FC07DA /* EventDispatcher.swift in Sources */, BC2828AF2AA322E400741013 /* AVFrameRateRange+Extension.swift in Sources */, @@ -1902,7 +1906,7 @@ buildActionMask = 2147483647; files = ( 290EA89B1DFB619600053022 /* TSPacketTests.swift in Sources */, - BCCBCE9529A7C9C90095B51C /* AVCFormatStreamTests.swift in Sources */, + BCCBCE9529A7C9C90095B51C /* ISOTypeBufferUtilTests.swift in Sources */, 290EA8A91DFB61E700053022 /* ByteArrayTests.swift in Sources */, BC0587C12BD2A123006751C8 /* IOAudioMixerBySingleTrackTests.swift in Sources */, 295018221FFA1C9D00358E10 /* CMAudioSampleBufferFactory.swift in Sources */, diff --git a/Sources/ISO/AVCNALUnit.swift b/Sources/ISO/AVCNALUnit.swift index 910cf12de..2d861f985 100644 --- a/Sources/ISO/AVCNALUnit.swift +++ b/Sources/ISO/AVCNALUnit.swift @@ -18,7 +18,7 @@ enum AVCNALUnitType: UInt8, Equatable { } // MARK: - -struct AVCNALUnit: Equatable { +struct AVCNALUnit: NALUnit, Equatable { let refIdc: UInt8 let type: AVCNALUnitType let payload: Data @@ -41,31 +41,11 @@ struct AVCNALUnit: Equatable { } } -class AVCNALUnitReader { - static let defaultStartCodeLength: Int = 4 - static let defaultNALUnitHeaderLength: Int32 = 4 - - var nalUnitHeaderLength: Int32 = AVCNALUnitReader.defaultNALUnitHeaderLength - - func read(_ data: Data) -> [AVCNALUnit] { - var units: [AVCNALUnit] = [] - var lastIndexOf = data.count - 1 - for i in (2.. CMFormatDescription? { - let units = read(data).filter { $0.type == .pps || $0.type == .sps } +extension [AVCNALUnit] { + func makeFormatDescription(_ nalUnitHeaderLength: Int32 = 4) -> CMFormatDescription? { guard - let pps = units.first(where: { $0.type == .pps }), - let sps = units.first(where: { $0.type == .sps }) else { + let pps = first(where: { $0.type == .pps }), + let sps = first(where: { $0.type == .sps }) else { return nil } var formatDescription: CMFormatDescription? diff --git a/Sources/ISO/HEVCNALUnit.swift b/Sources/ISO/HEVCNALUnit.swift index 438e2ef5e..07f197429 100644 --- a/Sources/ISO/HEVCNALUnit.swift +++ b/Sources/ISO/HEVCNALUnit.swift @@ -1,8 +1,88 @@ +import CoreMedia import Foundation enum HEVCNALUnitType: UInt8 { - case unspec = 0 + case codedSliceTrailN = 0 + case codedSliceTrailR = 1 + case codedSliceTsaN = 2 + case codedSliceTsaR = 3 + case codedSliceStsaN = 4 + case codedSliceStsaR = 5 + case codedSliceRadlN = 6 + case codedSliceRadlR = 7 + case codedSliceRaslN = 8 + case codedSliceRsslR = 9 + /// 10...15 Reserved case vps = 32 case sps = 33 case pps = 34 + case accessUnitDelimiter = 35 + case unspec = 0xFF +} + +struct HEVCNALUnit: NALUnit, Equatable { + let type: HEVCNALUnitType + let temporalIdPlusOne: UInt8 + let payload: Data + + init(_ data: Data) { + self.init(data, length: data.count) + } + + init(_ data: Data, length: Int) { + self.type = HEVCNALUnitType(rawValue: (data[0] & 0x7e) >> 1) ?? .unspec + self.temporalIdPlusOne = data[1] & 0b00011111 + self.payload = data.subdata(in: 2.. CMFormatDescription? { + guard + let vps = first(where: { $0.type == .vps }), + let sps = first(where: { $0.type == .sps }), + let pps = first(where: { $0.type == .pps }) else { + return nil + } + return vps.data.withUnsafeBytes { (vpsBuffer: UnsafeRawBufferPointer) -> CMFormatDescription? in + guard let vpsBaseAddress = vpsBuffer.baseAddress else { + return nil + } + return sps.data.withUnsafeBytes { (spsBuffer: UnsafeRawBufferPointer) -> CMFormatDescription? in + guard let spsBaseAddress = spsBuffer.baseAddress else { + return nil + } + return pps.data.withUnsafeBytes { (ppsBuffer: UnsafeRawBufferPointer) -> CMFormatDescription? in + guard let ppsBaseAddress = ppsBuffer.baseAddress else { + return nil + } + var formatDescriptionOut: CMFormatDescription? + let pointers: [UnsafePointer] = [ + vpsBaseAddress.assumingMemoryBound(to: UInt8.self), + spsBaseAddress.assumingMemoryBound(to: UInt8.self), + ppsBaseAddress.assumingMemoryBound(to: UInt8.self) + ] + let sizes: [Int] = [vpsBuffer.count, spsBuffer.count, ppsBuffer.count] + let status = CMVideoFormatDescriptionCreateFromHEVCParameterSets( + allocator: kCFAllocatorDefault, + parameterSetCount: pointers.count, + parameterSetPointers: pointers, + parameterSetSizes: sizes, + nalUnitHeaderLength: nalUnitHeaderLength, + extensions: nil, + formatDescriptionOut: &formatDescriptionOut + ) + return formatDescriptionOut + } + } + } + } } diff --git a/Sources/ISO/AVCFormatStream.swift b/Sources/ISO/ISOTypeBufferUtil.swift similarity index 92% rename from Sources/ISO/AVCFormatStream.swift rename to Sources/ISO/ISOTypeBufferUtil.swift index 1635178a7..1532e1019 100644 --- a/Sources/ISO/AVCFormatStream.swift +++ b/Sources/ISO/ISOTypeBufferUtil.swift @@ -1,6 +1,6 @@ import Foundation -struct AVCFormatStream { +struct ISOTypeBufferUtil { let data: Data init(data: Data) { @@ -33,7 +33,7 @@ struct AVCFormatStream { return result } - static func toNALFileFormat(_ data: inout Data) -> Data { + static func toNALFileFormat(_ data: inout Data) { var lastIndexOf = data.count - 1 for i in (2..(_ data: inout Data, type: T.Type) -> [T] { + var units: [T] = .init() + var lastIndexOf = data.count - 1 + for i in (2.. CMFormatDescription? { + switch type { + case .h264: + let units = read(&data, type: AVCNALUnit.self) + return units.makeFormatDescription(nalUnitHeaderLength) + case .h265: + let units = read(&data, type: HEVCNALUnit.self) + return units.makeFormatDescription(nalUnitHeaderLength) + default: + return nil + } + } +} diff --git a/Sources/ISO/PacketizedElementaryStream.swift b/Sources/ISO/PacketizedElementaryStream.swift index 003a3c920..9f3341dcf 100644 --- a/Sources/ISO/PacketizedElementaryStream.swift +++ b/Sources/ISO/PacketizedElementaryStream.swift @@ -24,6 +24,7 @@ enum PESPTSDTSIndicator: UInt8 { struct PESOptionalHeader { static let fixedSectionSize: Int = 3 static let defaultMarkerBits: UInt8 = 2 + static let offset = CMTime(value: 3, timescale: 30) var markerBits: UInt8 = PESOptionalHeader.defaultMarkerBits var scramblingControl: UInt8 = 0 @@ -58,7 +59,7 @@ struct PESOptionalHeader { ptsDtsIndicator |= 0x01 } if (ptsDtsIndicator & 0x02) == 0x02 { - let pts = Int64((presentationTimeStamp.seconds - base) * Double(TSTimestamp.resolution)) + let pts = Int64((presentationTimeStamp.seconds + Self.offset.seconds - base) * Double(TSTimestamp.resolution)) optionalFields += TSTimestamp.encode(pts, ptsDtsIndicator << 4) } if (ptsDtsIndicator & 0x01) == 0x01 { @@ -215,7 +216,18 @@ struct PacketizedElementaryStream: PESPacketHeader { data.append(contentsOf: [0x00, 0x00, 0x00, 0x01, 0x09, 0x30]) } if let dataBytes = try? dataBuffer.dataBytes() { - let stream = AVCFormatStream(data: dataBytes) + let stream = ISOTypeBufferUtil(data: dataBytes) + data.append(stream.toByteStream()) + } + case .hevc: + if !sampleBuffer.isNotSync { + sampleBuffer.formatDescription?.parameterSets.forEach { + data.append(contentsOf: [0x00, 0x00, 0x00, 0x01]) + data.append(contentsOf: $0) + } + } + if let dataBytes = try? dataBuffer.dataBytes() { + let stream = ISOTypeBufferUtil(data: dataBytes) data.append(stream.toByteStream()) } default: @@ -327,8 +339,8 @@ struct PacketizedElementaryStream: PESPacketHeader { var blockBuffer: CMBlockBuffer? var sampleSizes: [Int] = [] switch streamType { - case .h264: - _ = AVCFormatStream.toNALFileFormat(&data) + case .h264, .h265: + ISOTypeBufferUtil.toNALFileFormat(&data) blockBuffer = data.makeBlockBuffer(advancedBy: 0) sampleSizes.append(blockBuffer?.dataLength ?? 0) case .adtsAac: diff --git a/Sources/ISO/TSReader.swift b/Sources/ISO/TSReader.swift index dc0910a0b..a18d00a71 100644 --- a/Sources/ISO/TSReader.swift +++ b/Sources/ISO/TSReader.swift @@ -15,10 +15,10 @@ public class TSReader { private var pat: TSProgramAssociation? { didSet { - guard let PAT = pat else { + guard let pat else { return } - for (channel, PID) in PAT.programs { + for (channel, PID) in pat.programs { programs[PID] = channel } if logger.isEnabledFor(level: .trace) { @@ -38,9 +38,9 @@ public class TSReader { } } } - private var nalUnitReader = AVCNALUnitReader() private var programs: [UInt16: UInt16] = [:] private var esSpecData: [UInt16: ESSpecificData] = [:] + private var nalUnitReader = NALUnitReader() private var formatDescriptions: [UInt16: CMFormatDescription] = [:] private var packetizedElementaryStreams: [UInt16: PacketizedElementaryStream] = [:] private var previousPresentationTimeStamps: [UInt16: CMTime] = [:] @@ -103,7 +103,7 @@ public class TSReader { defer { packetizedElementaryStreams[id] = nil } - let formatDescription = makeFormatDescription(data, pes: pes) + let formatDescription = makeFormatDescription(data, pes: &pes) if let formatDescription, formatDescriptions[id] != formatDescription { formatDescriptions[id] = formatDescription delegate?.reader(self, id: id, didRead: formatDescription) @@ -111,13 +111,16 @@ public class TSReader { var isNotSync = true switch data.streamType { case .h264: - let units = nalUnitReader.read(pes.data) + let units = nalUnitReader.read(&pes.data, type: AVCNALUnit.self) if let unit = units.first(where: { $0.type == .idr || $0.type == .slice }) { var data = Data([0x00, 0x00, 0x00, 0x01]) data.append(unit.data) pes.data = data } isNotSync = !units.contains { $0.type == .idr } + case .h265: + let units = nalUnitReader.read(&pes.data, type: HEVCNALUnit.self) + isNotSync = units.contains { $0.type == .sps } case .adtsAac: isNotSync = false default: @@ -133,12 +136,12 @@ public class TSReader { return sampleBuffer } - private func makeFormatDescription(_ data: ESSpecificData, pes: PacketizedElementaryStream) -> CMFormatDescription? { + private func makeFormatDescription(_ data: ESSpecificData, pes: inout PacketizedElementaryStream) -> CMFormatDescription? { switch data.streamType { case .adtsAac: return ADTSHeader(data: pes.data).makeFormatDescription() - case .h264: - return nalUnitReader.makeFormatDescription(pes.data) + case .h264, .h265: + return nalUnitReader.makeFormatDescription(&pes.data, type: data.streamType) default: return nil } diff --git a/Sources/ISO/TSWriter.swift b/Sources/ISO/TSWriter.swift index b30baefd3..d47493f1f 100644 --- a/Sources/ISO/TSWriter.swift +++ b/Sources/ISO/TSWriter.swift @@ -33,7 +33,7 @@ public final class TSWriter { var data = ESSpecificData() data.streamType = audioFormat.formatDescription.streamType data.elementaryPID = kTSWriter_defaultAudioPID - PMT.elementaryStreamSpecificData.append(data) + pmt.elementaryStreamSpecificData.append(data) audioContinuityCounter = 0 writeProgramIfNeeded() } @@ -47,18 +47,18 @@ public final class TSWriter { var data = ESSpecificData() data.streamType = videoFormat.streamType data.elementaryPID = kTSWriter_defaultVideoPID - PMT.elementaryStreamSpecificData.append(data) + pmt.elementaryStreamSpecificData.append(data) videoContinuityCounter = 0 writeProgramIfNeeded() } } - private(set) var PAT: TSProgramAssociation = { + private(set) var pat: TSProgramAssociation = { let PAT: TSProgramAssociation = .init() PAT.programs = [1: kTSWriter_defaultPMTPID] return PAT }() - private(set) var PMT: TSProgramMap = .init() + private(set) var pmt: TSProgramMap = .init() private var PCRPID: UInt16 = kTSWriter_defaultVideoPID private var canWriteFor: Bool { guard !expectedMedias.isEmpty else { @@ -144,9 +144,9 @@ public final class TSWriter { audioContinuityCounter = 0 videoContinuityCounter = 0 PCRPID = kTSWriter_defaultVideoPID - PAT.programs.removeAll() - PAT.programs = [1: kTSWriter_defaultPMTPID] - PMT = TSProgramMap() + pat.programs.removeAll() + pat.programs = [1: kTSWriter_defaultPMTPID] + pmt = TSProgramMap() videoTimeStamp = .invalid audioTimeStamp = .invalid clockTimeStamp = .zero @@ -191,11 +191,11 @@ public final class TSWriter { } private func writeProgram() { - PMT.PCRPID = PCRPID + pmt.PCRPID = PCRPID var bytes = Data() var packets: [TSPacket] = [] - packets.append(contentsOf: PAT.arrayOfPackets(kTSWriter_defaultPATPID)) - packets.append(contentsOf: PMT.arrayOfPackets(kTSWriter_defaultPMTPID)) + packets.append(contentsOf: pat.arrayOfPackets(kTSWriter_defaultPATPID)) + packets.append(contentsOf: pmt.arrayOfPackets(kTSWriter_defaultPMTPID)) for packet in packets { bytes.append(packet.data) } diff --git a/Tests/ISO/AVCFormatStreamTests.swift b/Tests/ISO/ISOTypeBufferUtilTests.swift similarity index 61% rename from Tests/ISO/AVCFormatStreamTests.swift rename to Tests/ISO/ISOTypeBufferUtilTests.swift index 90e1f3ea4..ea4510bd1 100644 --- a/Tests/ISO/AVCFormatStreamTests.swift +++ b/Tests/ISO/ISOTypeBufferUtilTests.swift @@ -3,15 +3,17 @@ import XCTest @testable import HaishinKit -final class AVFFormatStreamTests: XCTestCase { +final class ISOTypeBufferUtilTests: XCTestCase { func testToNALFileFormat_4() { var data = Data([0, 0, 0, 1, 10, 10, 0, 0, 0, 1, 3, 3, 2, 0, 0, 0, 1, 5, 5, 5]) - XCTAssertEqual(AVCFormatStream.toNALFileFormat(&data).bytes, Data([0, 0, 0, 2, 10, 10, 0, 0, 0, 3, 3, 3, 2, 0, 0, 0, 3, 5, 5, 5]).bytes) + ISOTypeBufferUtil.toNALFileFormat(&data) + XCTAssertEqual(data.bytes, Data([0, 0, 0, 2, 10, 10, 0, 0, 0, 3, 3, 3, 2, 0, 0, 0, 3, 5, 5, 5]).bytes) } func testToNALFileFormat_3() { var data = Data([0, 0, 1, 10, 10, 0, 0, 1, 3, 3, 2, 0, 0, 1, 5, 5, 5]) - XCTAssertEqual(AVCFormatStream.toNALFileFormat(&data).bytes, Data([0, 0, 2, 10, 10, 0, 0, 3, 3, 3, 2, 0, 0, 3, 5, 5, 5]).bytes) + ISOTypeBufferUtil.toNALFileFormat(&data) + XCTAssertEqual(data.bytes, Data([0, 0, 2, 10, 10, 0, 0, 3, 3, 3, 2, 0, 0, 3, 5, 5, 5]).bytes) } func testToNALFileFormat() { @@ -21,12 +23,14 @@ final class AVFFormatStreamTests: XCTestCase { data[1] = 0 data[2] = 0 data[3] = 1 - XCTAssertEqual(AVCFormatStream.toNALFileFormat(&data).bytes, expected.bytes) + ISOTypeBufferUtil.toNALFileFormat(&data) + XCTAssertEqual(data.bytes, expected.bytes) } func testToNALFileFormat_3video() { var data = Data([0, 0, 1, 33, 254, 120, 9, 224, 183, 253, 84, 22, 127, 170, 130, 207, 245, 80, 70, 125, 76, 125, 95, 250, 168, 44, 255, 85, 5, 159, 234, 160, 160, 250, 147, 253, 84, 22, 127, 170, 130, 195, 235, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 8, 143, 168, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 34, 62, 162, 191, 213, 65, 17, 248, 175, 245, 80, 153, 248, 103, 253, 84, 17, 31, 81, 95, 234, 160, 179, 253, 84, 16, 31, 148, 250, 159, 253, 84, 16, 31, 140, 255, 85, 4, 71, 226, 191, 213, 65, 89, 255, 253, 84, 16, 31, 140, 255, 85, 5, 159, 234, 160, 179, 253, 84, 50, 125, 103, 225, 47, 245, 80, 89, 254, 170, 29, 63, 31, 254, 170, 11, 63, 213, 65, 17, 245, 21, 254, 170, 27, 63, 16, 125, 68, 64, 201, 255, 213, 65, 81, 245, 95, 234, 161, 243, 234, 52, 87, 245, 80, 225, 245, 8, 127, 170, 130, 207, 245, 80, 86, 127, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 67, 199, 212, 199, 226, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 21, 31, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 39, 213, 255, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 224]) - XCTAssertEqual(AVCFormatStream.toNALFileFormat(&data).bytes, Data([0, 1, 73, 33, 254, 120, 9, 224, 183, 253, 84, 22, 127, 170, 130, 207, 245, 80, 70, 125, 76, 125, 95, 250, 168, 44, 255, 85, 5, 159, 234, 160, 160, 250, 147, 253, 84, 22, 127, 170, 130, 195, 235, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 8, 143, 168, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 34, 62, 162, 191, 213, 65, 17, 248, 175, 245, 80, 153, 248, 103, 253, 84, 17, 31, 81, 95, 234, 160, 179, 253, 84, 16, 31, 148, 250, 159, 253, 84, 16, 31, 140, 255, 85, 4, 71, 226, 191, 213, 65, 89, 255, 253, 84, 16, 31, 140, 255, 85, 5, 159, 234, 160, 179, 253, 84, 50, 125, 103, 225, 47, 245, 80, 89, 254, 170, 29, 63, 31, 254, 170, 11, 63, 213, 65, 17, 245, 21, 254, 170, 27, 63, 16, 125, 68, 64, 201, 255, 213, 65, 81, 245, 95, 234, 161, 243, 234, 52, 87, 245, 80, 225, 245, 8, 127, 170, 130, 207, 245, 80, 86, 127, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 67, 199, 212, 199, 226, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 21, 31, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 39, 213, 255, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 224]).bytes) + ISOTypeBufferUtil.toNALFileFormat(&data) + XCTAssertEqual(data.bytes, Data([0, 1, 73, 33, 254, 120, 9, 224, 183, 253, 84, 22, 127, 170, 130, 207, 245, 80, 70, 125, 76, 125, 95, 250, 168, 44, 255, 85, 5, 159, 234, 160, 160, 250, 147, 253, 84, 22, 127, 170, 130, 195, 235, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 8, 143, 168, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 34, 62, 162, 191, 213, 65, 17, 248, 175, 245, 80, 153, 248, 103, 253, 84, 17, 31, 81, 95, 234, 160, 179, 253, 84, 16, 31, 148, 250, 159, 253, 84, 16, 31, 140, 255, 85, 4, 71, 226, 191, 213, 65, 89, 255, 253, 84, 16, 31, 140, 255, 85, 5, 159, 234, 160, 179, 253, 84, 50, 125, 103, 225, 47, 245, 80, 89, 254, 170, 29, 63, 31, 254, 170, 11, 63, 213, 65, 17, 245, 21, 254, 170, 27, 63, 16, 125, 68, 64, 201, 255, 213, 65, 81, 245, 95, 234, 161, 243, 234, 52, 87, 245, 80, 225, 245, 8, 127, 170, 130, 207, 245, 80, 86, 127, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 67, 199, 212, 199, 226, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 21, 31, 175, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 39, 213, 255, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 253, 84, 22, 127, 170, 130, 207, 245, 80, 89, 254, 170, 11, 63, 213, 65, 103, 250, 168, 44, 255, 85, 5, 159, 234, 160, 179, 224]).bytes) } } diff --git a/Tests/ISO/NALUnitReaderTests.swift b/Tests/ISO/NALUnitReaderTests.swift index 746757e25..f04d03b2d 100644 --- a/Tests/ISO/NALUnitReaderTests.swift +++ b/Tests/ISO/NALUnitReaderTests.swift @@ -6,25 +6,25 @@ import XCTest final class NALUnitReaderTests: XCTestCase { func testMain() { - let data = Data([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, 151, 218, 93, 118, 157, 216, 67, 142, 2, 95, 69, 134, 167, 106, 101, 67, 112, 72, 120, 144, 105, 148, 234, 94, 74, 154, 149, 190, 13, 10, 88, 148, 169, 56, 46, 152, 176, 173, 110, 22, 215, 35, 18, 203, 125, 158, 16, 25, 228, 163, 26, 63, 30, 3, 96, 123, 237, 109, 12, 174, 216, 184, 25, 33, 123, 175, 69, 154, 240, 37, 168, 99, 38, 144, 221, 227, 119, 206, 215, 149, 111, 250, 180, 134, 78, 85, 50, 129, 178, 93, 255, 227, 144, 100, 156, 113, 113, 235, 47, 242, 68, 236, 109, 135, 87, 84, 178, 184, 163, 161, 170, 184, 84, 68, 113, 213, 73, 180, 25, 1, 77, 13, 222, 138, 69, 24, 104, 255, 218, 76, 224, 26, 122, 0, 231, 230, 203, 211, 172, 224, 26, 184, 69, 180, 123, 221, 8, 182, 241, 202, 193, 169, 120, 208, 135, 31, 82, 168, 125, 93, 207, 207, 109, 14, 243, 179, 97, 102, 58, 243, 14, 152, 13, 231, 30, 221, 177, 9, 72, 68, 212, 196, 71, 223, 142, 0, 248, 116, 139, 133, 210, 142, 83, 112, 87, 53, 138, 103, 202, 169, 112, 27, 7, 213, 152, 144, 207, 141, 84, 183, 121, 30, 128, 64, 95, 28, 10, 88, 116, 188, 83, 127, 181, 57, 47, 5, 19, 62, 132, 173, 201, 203, 170, 68, 224, 135, 134, 58, 206, 71, 77, 98, 77, 150, 225, 111, 103, 65, 84, 29, 176, 97, 72, 182, 151, 220, 153, 39, 247, 78, 136, 9, 166, 140, 221, 243, 68, 139, 229, 236, 189, 181, 124, 7, 35, 230, 139, 247, 223, 16, 78, 15, 189, 12, 144, 241, 169, 170, 166, 232, 17, 221, 212, 71, 69, 95, 122, 9, 36, 153, 246, 136, 111, 36, 50, 56, 118, 181, 240, 100, 5, 137, 252, 23, 244, 131, 41, 190, 128, 198, 134, 232, 40, 242, 214, 82, 69, 9, 168, 59, 179, 254, 220, 234, 16, 1, 170, 182, 214, 131, 169, 124, 91, 19, 65, 162, 179, 8, 98, 204, 219, 240, 6, 79, 49, 67, 120, 31, 236, 103, 167, 108, 213, 69, 193, 226, 66, 66, 242, 52, 18, 161, 42, 164, 133, 191, 82, 156, 2, 204, 75, 254, 217, 111, 215, 140, 157, 195, 195, 112, 120, 165, 163, 136, 125, 92, 195, 182, 99, 106, 220]) - let reader = AVCNALUnitReader() - let units = reader.read(data) + var data = Data([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, 151, 218, 93, 118, 157, 216, 67, 142, 2, 95, 69, 134, 167, 106, 101, 67, 112, 72, 120, 144, 105, 148, 234, 94, 74, 154, 149, 190, 13, 10, 88, 148, 169, 56, 46, 152, 176, 173, 110, 22, 215, 35, 18, 203, 125, 158, 16, 25, 228, 163, 26, 63, 30, 3, 96, 123, 237, 109, 12, 174, 216, 184, 25, 33, 123, 175, 69, 154, 240, 37, 168, 99, 38, 144, 221, 227, 119, 206, 215, 149, 111, 250, 180, 134, 78, 85, 50, 129, 178, 93, 255, 227, 144, 100, 156, 113, 113, 235, 47, 242, 68, 236, 109, 135, 87, 84, 178, 184, 163, 161, 170, 184, 84, 68, 113, 213, 73, 180, 25, 1, 77, 13, 222, 138, 69, 24, 104, 255, 218, 76, 224, 26, 122, 0, 231, 230, 203, 211, 172, 224, 26, 184, 69, 180, 123, 221, 8, 182, 241, 202, 193, 169, 120, 208, 135, 31, 82, 168, 125, 93, 207, 207, 109, 14, 243, 179, 97, 102, 58, 243, 14, 152, 13, 231, 30, 221, 177, 9, 72, 68, 212, 196, 71, 223, 142, 0, 248, 116, 139, 133, 210, 142, 83, 112, 87, 53, 138, 103, 202, 169, 112, 27, 7, 213, 152, 144, 207, 141, 84, 183, 121, 30, 128, 64, 95, 28, 10, 88, 116, 188, 83, 127, 181, 57, 47, 5, 19, 62, 132, 173, 201, 203, 170, 68, 224, 135, 134, 58, 206, 71, 77, 98, 77, 150, 225, 111, 103, 65, 84, 29, 176, 97, 72, 182, 151, 220, 153, 39, 247, 78, 136, 9, 166, 140, 221, 243, 68, 139, 229, 236, 189, 181, 124, 7, 35, 230, 139, 247, 223, 16, 78, 15, 189, 12, 144, 241, 169, 170, 166, 232, 17, 221, 212, 71, 69, 95, 122, 9, 36, 153, 246, 136, 111, 36, 50, 56, 118, 181, 240, 100, 5, 137, 252, 23, 244, 131, 41, 190, 128, 198, 134, 232, 40, 242, 214, 82, 69, 9, 168, 59, 179, 254, 220, 234, 16, 1, 170, 182, 214, 131, 169, 124, 91, 19, 65, 162, 179, 8, 98, 204, 219, 240, 6, 79, 49, 67, 120, 31, 236, 103, 167, 108, 213, 69, 193, 226, 66, 66, 242, 52, 18, 161, 42, 164, 133, 191, 82, 156, 2, 204, 75, 254, 217, 111, 215, 140, 157, 195, 195, 112, 120, 165, 163, 136, 125, 92, 195, 182, 99, 106, 220]) + let reader = NALUnitReader() + let units = reader.read(&data, type: AVCNALUnit.self) let sps = units.first(where: { $0.type == .sps }) XCTAssertEqual(sps?.data.bytes, [103, 77, 64, 13, 218, 5, 7, 236, 4, 64, 0, 0, 3, 0, 64, 0, 0, 7, 131, 197, 10, 168]) - XCTAssertNotNil(reader.makeFormatDescription(data)) + XCTAssertNotNil(reader.makeFormatDescription(&data, type: .h264)) } func testSlice_startCode3() { - let data = Data([0, 0, 1, 65, 226, 8, 13, 224, 179, 253, 15, 80, 87, 254, 170, 10, 255, 213, 65, 95, 250, 168, 43, 255, 85, 5, 127, 234, 160, 175, 253, 84, 21, 255, 170, 130, 10, 197, 255, 170, 134, 250, 37, 66, 31, 232, 170, 28, 59, 199, 255, 170, 135, 42, 122, 250, 11, 143, 255, 85, 5, 127, 234, 160, 175, 253, 84, 43, 208, 134, 33, 111, 244, 37, 66, 221, 88, 190, 147, 21, 200, 236, 47, 210, 127, 166, 196, 119, 250, 168, 43, 255, 85, 5, 127, 234, 160, 175, 253, 84, 21, 255, 170, 130, 191, 245, 80, 87, 254, 170, 10, 255, 213, 65, 95, 250, 168, 43, 248]) - let reader = AVCNALUnitReader() - let units = reader.read(data) + var data = Data([0, 0, 1, 65, 226, 8, 13, 224, 179, 253, 15, 80, 87, 254, 170, 10, 255, 213, 65, 95, 250, 168, 43, 255, 85, 5, 127, 234, 160, 175, 253, 84, 21, 255, 170, 130, 10, 197, 255, 170, 134, 250, 37, 66, 31, 232, 170, 28, 59, 199, 255, 170, 135, 42, 122, 250, 11, 143, 255, 85, 5, 127, 234, 160, 175, 253, 84, 43, 208, 134, 33, 111, 244, 37, 66, 221, 88, 190, 147, 21, 200, 236, 47, 210, 127, 166, 196, 119, 250, 168, 43, 255, 85, 5, 127, 234, 160, 175, 253, 84, 21, 255, 170, 130, 191, 245, 80, 87, 254, 170, 10, 255, 213, 65, 95, 250, 168, 43, 248]) + let reader = NALUnitReader() + let units = reader.read(&data, type: AVCNALUnit.self) XCTAssertEqual([65, 226, 8, 13], units.first?.data.bytes[0..<4]) XCTAssertTrue(units.contains(where: { $0.type == .slice })) } func testSPSPPS_startCode3() { - let data = Data([0, 0, 1, 39, 66, 0, 30, 171, 64, 88, 25, 242, 203, 53, 1, 1, 1, 2, 0, 0, 1, 40, 206, 60, 128, 0, 0, 1, 39, 66, 0, 30, 171, 64, 88, 25, 242, 203, 53, 1, 1, 1, 2, 0, 0, 1, 40, 206, 60, 128, 0, 0, 1, 101, 184, 32, 3, 255, 255, 254, 30, 30, 40, 0, 8, 162, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 175, 255, 227, 240, 65, 192, 1, 16, 101, 17, 204, 73, 101, 165, 194, 60, 154, 126, 49, 8, 164, 150, 125, 247, 223, 125, 247, 223, 125, 247, 223, 125, 247, 223, 127, 255, 138, 252, 16, 120, 0, 55, 178, 27, 153, 226, 14, 166, 169, 75, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 193, 63, 255, 134, 166, 0, 0, 128, 200, 0, 8, 17, 0, 1, 96, 242, 96, 19, 129, 190, 129, 218, 96, 235, 136, 1, 198, 4, 169, 254, 196, 184, 65, 20, 5, 128, 176, 30, 2, 0, 160, 2, 32, 166, 47, 196, 70, 248, 176, 128, 1, 5, 23, 44, 129, 0, 128, 61, 204, 4, 163, 208, 131, 132, 72, 82, 216, 66, 185, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 224, 31, 255, 96, 174, 0, 9, 168, 2, 235, 144, 14, 120, 97, 73, 182, 124, 161, 0, 0, 32, 32, 0, 2, 12, 64, 0, 32, 65, 65, 134, 48, 150, 0, 2, 1, 128, 6, 2, 0, 19, 128, 18, 51, 13, 97, 202, 112, 8, 110, 242, 1, 128, 6, 185, 128, 130, 164, 24, 117, 238, 64, 27, 154, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 233, 235, 174, 186, 235, 175, 255, 255, 130, 239, 0, 7, 24, 27, 56, 90, 108, 195, 52, 5, 156, 12, 212, 90, 62, 1, 23, 128, 8, 35, 201, 76, 218, 71, 9, 31, 159, 253, 221, 199, 65, 220, 0, 24, 152, 156, 8, 30, 102, 87, 136, 225, 17, 170, 242, 109, 0, 88, 97, 19, 133, 35, 14, 179, 217, 217, 188, 212, 50, 138, 112, 86, 161, 151, 215, 56, 73, 126, 108, 130, 28, 45, 172, 222, 5, 7, 27, 252, 215, 255, 121, 11, 86, 3, 2, 86, 156, 239, 209, 189, 183, 117, 226, 29, 21, 192, 236, 87, 16, 153, 48, 100, 226, 90, 243, 160, 0, 100, 129, 102, 20, 1, 17, 64, 38, 251, 224, 128, 1, 0, 25, 192, 240, 160, 62, 54, 11, 90, 25, 108, 164, 6, 82, 223, 19, 200, 0, 4, 0, 136, 131, 97, 133, 147, 194, 128, 35, 135, 110, 31, 255, 234, 131, 191, 85, 162, 0, 1, 0, 61, 111, 224, 82, 52, 69, 101, 187, 238, 215, 255, 131, 0, 79, 136, 142, 24, 190, 138, 230, 192, 9, 218, 71, 116]) - let reader = AVCNALUnitReader() - XCTAssertNotNil(reader.makeFormatDescription(data)) + var data = Data([0, 0, 1, 39, 66, 0, 30, 171, 64, 88, 25, 242, 203, 53, 1, 1, 1, 2, 0, 0, 1, 40, 206, 60, 128, 0, 0, 1, 39, 66, 0, 30, 171, 64, 88, 25, 242, 203, 53, 1, 1, 1, 2, 0, 0, 1, 40, 206, 60, 128, 0, 0, 1, 101, 184, 32, 3, 255, 255, 254, 30, 30, 40, 0, 8, 162, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 251, 239, 190, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 175, 255, 227, 240, 65, 192, 1, 16, 101, 17, 204, 73, 101, 165, 194, 60, 154, 126, 49, 8, 164, 150, 125, 247, 223, 125, 247, 223, 125, 247, 223, 125, 247, 223, 127, 255, 138, 252, 16, 120, 0, 55, 178, 27, 153, 226, 14, 166, 169, 75, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 193, 63, 255, 134, 166, 0, 0, 128, 200, 0, 8, 17, 0, 1, 96, 242, 96, 19, 129, 190, 129, 218, 96, 235, 136, 1, 198, 4, 169, 254, 196, 184, 65, 20, 5, 128, 176, 30, 2, 0, 160, 2, 32, 166, 47, 196, 70, 248, 176, 128, 1, 5, 23, 44, 129, 0, 128, 61, 204, 4, 163, 208, 131, 132, 72, 82, 216, 66, 185, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 224, 31, 255, 96, 174, 0, 9, 168, 2, 235, 144, 14, 120, 97, 73, 182, 124, 161, 0, 0, 32, 32, 0, 2, 12, 64, 0, 32, 65, 65, 134, 48, 150, 0, 2, 1, 128, 6, 2, 0, 19, 128, 18, 51, 13, 97, 202, 112, 8, 110, 242, 1, 128, 6, 185, 128, 130, 164, 24, 117, 238, 64, 27, 154, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 235, 174, 186, 233, 235, 174, 186, 235, 175, 255, 255, 130, 239, 0, 7, 24, 27, 56, 90, 108, 195, 52, 5, 156, 12, 212, 90, 62, 1, 23, 128, 8, 35, 201, 76, 218, 71, 9, 31, 159, 253, 221, 199, 65, 220, 0, 24, 152, 156, 8, 30, 102, 87, 136, 225, 17, 170, 242, 109, 0, 88, 97, 19, 133, 35, 14, 179, 217, 217, 188, 212, 50, 138, 112, 86, 161, 151, 215, 56, 73, 126, 108, 130, 28, 45, 172, 222, 5, 7, 27, 252, 215, 255, 121, 11, 86, 3, 2, 86, 156, 239, 209, 189, 183, 117, 226, 29, 21, 192, 236, 87, 16, 153, 48, 100, 226, 90, 243, 160, 0, 100, 129, 102, 20, 1, 17, 64, 38, 251, 224, 128, 1, 0, 25, 192, 240, 160, 62, 54, 11, 90, 25, 108, 164, 6, 82, 223, 19, 200, 0, 4, 0, 136, 131, 97, 133, 147, 194, 128, 35, 135, 110, 31, 255, 234, 131, 191, 85, 162, 0, 1, 0, 61, 111, 224, 82, 52, 69, 101, 187, 238, 215, 255, 131, 0, 79, 136, 142, 24, 190, 138, 230, 192, 9, 218, 71, 116]) + let reader = NALUnitReader() + XCTAssertNotNil(reader.makeFormatDescription(&data, type: .h264)) } }