public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteArray(PESStartCode); writer.WriteByte(StreamId); writer.WriteUInt16(PESPacketLength); writer.WriteByte(Flag1); writer.WriteByte((byte)PTS_DTS_Flag); if (PTS_DTS_Flag == PTS_DTS_Flags.all) { writer.WriteByte(10); writer.WriteInt5(ToPTS()); writer.WriteInt5(ToDTS()); } else if (PTS_DTS_Flag == PTS_DTS_Flags.pts) { writer.WriteByte(5); writer.WriteInt5(ToPTS()); } else if (PTS_DTS_Flag == PTS_DTS_Flags.dts) { writer.WriteByte(5); writer.WriteInt5(ToDTS()); } Payload.ToBuffer(ref writer); }
public byte[] CreatePMT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PMT_Package package = new TS_PMT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = 0; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 4096; package.TableId = 0x02; package.Components = new List <TS_PMT_Component>(); package.Components.Add(new TS_PMT_Component { StreamType = StreamType.h264, ElementaryPID = 256, ESInfoLength = 0 }); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
internal void CreateSegmentPES(ref TSMessagePackWriter writer, byte[] nalu, byte counter) { TS_Segment_Package package = new TS_Segment_Package(); package.Header = new TS_Header(); package.Header.PID = 256; package.Header.ContinuityCounter = counter; package.Header.PayloadUnitStartIndicator = 0; package.Payload = nalu; //这个很重要,需要控制 //package.Header.AdaptationFieldControl= AdaptationFieldControl.同时带有自适应域和有效负载 //这个很重要,填充大小 //package.Header.Adaptation.FillSize if (nalu.Length < FiexdSegmentPESLength) { package.Header.Adaptation = new TS_AdaptationInfo(); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.FillSize = (byte)(FiexdSegmentPESLength - nalu.Length); package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; } else { package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; } package.Payload = nalu; package.ToBuffer(ref writer); }
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>(); public byte[] CreatePAT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PAT_Package package = new TS_PAT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = PATCounter.AddOrUpdate(jt1078Package.GetKey(), 0, (a, b) => { if (b > 0xf) { return(0); } else { return((byte)(b + 1)); } }); package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 0; TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public void ToBuffer(ref TSMessagePackWriter writer) { Header.ToBuffer(ref writer); writer.WriteByte(TableId); //SectionSyntaxIndicator Zero Reserved1 SectionLength //1 0 11 0000 0000 0000 //(ushort)(0b_1011_0000_0000_0000 | SectionLength) writer.Skip(2, out int SectionLengthPosition); writer.WriteUInt16(TransportStreamId); //Reserved2 VersionNumber CurrentNextIndicator //11 00000 1 var a = 0xC0 & (Reserved2 << 6); var b = 0x3E & (VersionNumber << 3); var c = (byte)(a | b | CurrentNextIndicator); writer.WriteByte(c); writer.WriteByte(SectionNumber); writer.WriteByte(LastSectionNumber); if (Programs != null) { foreach (var program in Programs) { program.ToBuffer(ref writer); } } const int crcLength = 4; writer.WriteUInt16Return((ushort)(0b_1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2) + crcLength), SectionLengthPosition); //打包ts流时PAT和PMT表是没有adaptation field的,不够的长度直接补0xff即可。 //ts header(4B) + adaptation field length(1) writer.WriteCRC32(5); var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition(); writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray()); }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte(SyncByte); //TransportErrorIndicator PayloadUnitStartIndicator TransportPriority PID //0 1 0 0000 0000 0000 0 //writer.WriteUInt16((ushort)((0b_0100_0000_0000_0000 & (PayloadUnitStartIndicator<<14)) | PID)); writer.WriteUInt16((ushort)((TransportErrorIndicator << 15) | (PayloadUnitStartIndicator << 14) | PID)); writer.WriteByte((byte)((byte)AdaptationFieldControl | ContinuityCounter)); if (PackageType == PackageType.PAT || PackageType == PackageType.PMT || PackageType == PackageType.Data_Start || PackageType == PackageType.Data_End || PackageType == PackageType.SDT) { if (Adaptation != null) { writer.Skip(1, out int AdaptationLengthPosition); Adaptation.ToBuffer(ref writer); writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - AdaptationLengthPosition - 1), AdaptationLengthPosition); } else { writer.WriteByte(0); } } }
public void ToBuffer(ref TSMessagePackWriter writer) { Header.PackageType = PackageType.SDT; Header.ToBuffer(ref writer); writer.WriteByte(TableId); writer.Skip(2, out int SectionLengthPosition); writer.WriteUInt16(TransportStreamId); writer.WriteByte((byte)(Reserved2 << 6 | VersionNumber << 1 | CurrentNextIndicator)); writer.WriteByte(SectionNumber); writer.WriteByte(LastSectionNumber); writer.WriteUInt16(OriginalNetworkId); writer.WriteByte(ReservedFutureUse2); foreach (var service in Services) { service.ToBuffer(ref writer); } ushort servicesLength = (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2); const int crcLength = 4; writer.WriteUInt16Return((ushort)(SectionSyntaxIndicator << 15 | ReservedFutureUse1 << 14 | Reserved1 << 12 | servicesLength + crcLength), SectionLengthPosition); writer.WriteCRC32(5); var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition(); writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray()); }
public byte[] CreatePAT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PAT_Package package = new TS_PAT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = 0; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 0; package.Programs = new List <TS_PAT_Program>(); package.Programs.Add(new TS_PAT_Program() { ProgramNumber = 0x0001, PID = 0x1000, }); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
private byte[] CreateTsData(JT1078Package jt1078Package, bool isNeedHeader, Span <byte> span) { var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 2048); TSMessagePackWriter tSMessagePackWriter = new TSMessagePackWriter(buff); if (TsFirst1078PackageDic.TryGetValue(jt1078Package.SIM, out var firstTimespan)) { if ((jt1078Package.Timestamp - firstTimespan) > 10 * 1000) { //按设定的时间(默认为10秒)切分ts文件 } var pes = tSEncoder.CreatePES(jt1078Package, 188); tSMessagePackWriter.WriteArray(pes); } else { var sdt = tSEncoder.CreateSDT(jt1078Package); tSMessagePackWriter.WriteArray(sdt); var pat = tSEncoder.CreatePAT(jt1078Package); tSMessagePackWriter.WriteArray(pat); var pmt = tSEncoder.CreatePMT(jt1078Package); tSMessagePackWriter.WriteArray(pmt); var pes = tSEncoder.CreatePES(jt1078Package, 188); tSMessagePackWriter.WriteArray(pes); } return(buff); }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteArray(NALU0x09); if (NALUs != null) { foreach (var nalu in NALUs) { writer.WriteArray(nalu); } } }
/// <summary> /// 生成ts和m3u8文件 /// </summary> /// <param name="jt1078Package"></param> public void CreateTsData(JT1078Package jt1078Package) { string key = jt1078Package.GetKey(); string hlsFileDirectory = m3U8Option.HlsFileDirectory; string m3u8FileName = Path.Combine(hlsFileDirectory, key, m3U8Option.M3U8FileName); if (!File.Exists(m3u8FileName)) { File.Create(m3u8FileName); //创建m3u8文件 } var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 1024); TSMessagePackWriter tSMessagePackWriter = new TSMessagePackWriter(buff); try { var curTsFileInfo = CreateTsFileInfo(key); if (!curTsFileInfo.IsCreateTsFile) { var pes = tSEncoder.CreatePES(jt1078Package); tSMessagePackWriter.WriteArray(pes); CreateTsFile(curTsFileInfo.FileName, key, tSMessagePackWriter.FlushAndGetArray()); curTsFileInfo.Duration = (jt1078Package.Timestamp - curTsFileInfo.TsFirst1078PackageTimeStamp) / 1000.0; //按设定的时间(默认为10秒)切分ts文件 if (curTsFileInfo.Duration > m3U8Option.TsFileMaxSecond) { var tsFileInfoQueue = ManageTsFileInfo(key, curTsFileInfo); CreateM3U8File(curTsFileInfo, tsFileInfoQueue); var newTsFileInfo = new TsFileInfo { IsCreateTsFile = true, Duration = 0, TsFileSerialNo = ++curTsFileInfo.TsFileSerialNo }; curTsFileInfoDic.TryUpdate(key, newTsFileInfo, curTsFileInfo); } } else { curTsFileInfo.IsCreateTsFile = false; curTsFileInfo.TsFirst1078PackageTimeStamp = jt1078Package.Timestamp; curTsFileInfo.FileName = $"{curTsFileInfo.TsFileSerialNo}.ts"; var sdt = tSEncoder.CreateSDT(jt1078Package); tSMessagePackWriter.WriteArray(sdt); var pat = tSEncoder.CreatePAT(jt1078Package); tSMessagePackWriter.WriteArray(pat); var pmt = tSEncoder.CreatePMT(jt1078Package); tSMessagePackWriter.WriteArray(pmt); var pes = tSEncoder.CreatePES(jt1078Package); tSMessagePackWriter.WriteArray(pes); CreateTsFile(curTsFileInfo.FileName, key, tSMessagePackWriter.FlushAndGetArray()); } } finally { TSArrayPool.Return(buff); } }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteUInt16(ServiceId); writer.WriteByte((byte)(ReservedFutureUse << 2 | EITScheduleFlag << 1 | EITPresentFollowingFlag)); writer.Skip(2, out var position); foreach (var descriptor in Descriptors) { descriptor.ToBuffer(ref writer); } DescriptorsLoopLength = (ushort)(writer.GetCurrentPosition() - position - 2); writer.WriteUInt16Return((ushort)((ushort)RunningStatus << 13 | (ushort)FreeCAMode << 12 | DescriptorsLoopLength), position); }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte((byte)PCRIncluded); if (PCRIncluded == PCRInclude.包含) { writer.WriteInt6(ToPCR()); } if (FillSize > 0) { writer.WriteArray(Enumerable.Range(0, FillSize).Select(s => (byte)0xFF).ToArray()); } }
public override void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte(Tag); writer.Skip(1, out var position); writer.WriteByte((byte)ServiceType); writer.Skip(1, out var serviceProviderLengthPosition); writer.WriteString(ServiceProvider); writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - serviceProviderLengthPosition - 1), serviceProviderLengthPosition); writer.Skip(1, out int SeviceNameLengthPosition); writer.WriteString(ServiceName); writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - SeviceNameLengthPosition - 1), SeviceNameLengthPosition); writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - position - 1), position); }
public void ToBufferTest1() { //47 41 00 30 07 50 00 00 7B 0C 7E 00 00 00 01 E0 00 00 80 C0 0A 31 00 09 08 97 11 00 07 D8 61 00 00 00 01 09 F0 00 00 00 01 67 64 00 1F AC D9 40 88 1E 68 40 00 00 03 01 80 00 00 57 83 C6 0C 65 80 00 00 00 01 68 EB E3 CB 22 C0 00 00 01 06 05 FF FF AB DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF 78 32 36 34 20 2D 20 63 6F 72 65 20 31 35 38 20 72 32 39 38 34 20 33 37 35 39 66 63 62 20 2D 20 48 2E 32 36 34 2F 4D 50 45 47 2D 34 20 41 56 43 20 63 6F 64 65 63 20 2D 20 43 6F 70 79 6C 65 66 74 20 32 30 30 33 2D 32 30 31 39 20 2D 20 68 74 74 70 3A 2F 2F 77 77 77 2E //47 41 00 30 07 50 00 00 7B 0C 7E 00 00 00 01 E0 00 00 80 C0 0A 31 00 09 08 97 11 00 07 D8 61 00 00 00 01 09 F0 00 00 00 01 67 64 00 1F AC D9 40 88 1E 68 40 00 00 03 01 80 00 00 57 83 C6 0C 65 80 00 00 00 01 68 EB E3 CB 22 C0 00 00 01 06 05 FF FF AB DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF 78 32 36 34 20 2D 20 63 6F 72 65 20 31 35 38 20 72 32 39 38 34 20 33 37 35 39 66 63 62 20 2D 20 48 2E 32 36 34 2F 4D 50 45 47 2D 34 20 41 56 43 20 63 6F 64 65 63 20 2D 20 43 6F 70 79 6C 65 66 74 20 32 30 30 33 2D 32 30 31 39 20 2D 20 68 74 74 70 3A 2F 2F 77 77 77 2E //47 41 00 30 07 50 00 00 7B 0C 7E 00 00 00 01 E0 00 00 80 C0 0A 00 00 02 04 4B 00 00 01 EC 30 00 00 00 01 09 FF 000000016764001FACD940881E6840000003018000005783C60C65800000000168EBE3CB22C00000010605FFFFABDC45E9BDE6D948B7962CD820D923EEEF78323634202D20636F7265203135382072323938342033373539666362202D20482E3236342F4D5045472D342041564320636F646563202D20436F70796C65667420323030332D32303139202D20687474703A2F2F7777772E //47 //41 00 //30 //07 //50 //00 00 7B 0C 7E //00 //00 00 01 //E0 //00 00 //80 //C0 //0A //31 00 09 08 97 //11 00 07 D8 61 //00 00 00 01 //09 //F0 //00 00 00 01 67 64 00 1F AC D9 40 88 1E 68 40 00 00 03 01 80 00 00 57 83 C6 0C 65 80 00 00 00 01 68 EB E3 CB 22 C0 00 00 01 06 05 FF FF AB DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF 78 32 36 34 20 2D 20 63 6F 72 65 20 31 35 38 20 72 32 39 38 34 20 33 37 35 39 66 63 62 20 2D 20 48 2E 32 36 34 2F 4D 50 45 47 2D 34 20 41 56 43 20 63 6F 64 65 63 20 2D 20 43 6F 70 79 6C 65 66 74 20 32 30 30 33 2D 32 30 31 39 20 2D 20 68 74 74 70 3A 2F 2F 77 77 77 2E TS_Package package = new TS_Package(); package.Header = new TS_Header(); package.Header.PID = 0x100; package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; package.Header.ContinuityCounter = 0; package.Header.PackageType = PackageType.Data_Start; package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Header.Adaptation.Timestamp = 18900000; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload = new PES_Package(); package.Payload.PTS = 132171; package.Payload.DTS = 126000; package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; package.Payload.Payload = new ES_Package(); package.Payload.Payload.NALUs = new List <byte[]>(); package.Payload.Payload.NALUs.Add("00 00 00 01 67 64 00 1F AC D9 40 88 1E 68 40 00 00 03 01 80 00 00 57 83 C6 0C 65 80 00 00 00 01 68 EB E3 CB 22 C0 00 00 01 06 05 FF FF AB DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF 78 32 36 34 20 2D 20 63 6F 72 65 20 31 35 38 20 72 32 39 38 34 20 33 37 35 39 66 63 62 20 2D 20 48 2E 32 36 34 2F 4D 50 45 47 2D 34 20 41 56 43 20 63 6F 64 65 63 20 2D 20 43 6F 70 79 6C 65 66 74 20 32 30 30 33 2D 32 30 31 39 20 2D 20 68 74 74 70 3A 2F 2F 77 77 77 2E".ToHexBytes()); TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]); package.ToBuffer(ref writer); var patData = writer.FlushAndGetArray().ToHexString(); }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte((byte)StreamType); writer.WriteUInt16((ushort)(0b_1110_0000_0000_0000 | ElementaryPID)); if (Descriptor == null) { writer.WriteUInt16((ushort)(0b_1111_0000_0000_0000 | ESInfoLength)); } else { writer.Skip(2, out int ESInfoLengthPosition); Descriptor.ToBuffer(ref writer); ESInfoLength = (ushort)(writer.GetCurrentPosition() - ESInfoLengthPosition - 2); writer.WriteUInt16Return((ushort)(0b_1111_0000_0000_0000 | ESInfoLength), ESInfoLengthPosition); } }
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte(SyncByte); //TransportErrorIndicator PayloadUnitStartIndicator TransportPriority PID //0 1 0 0000 0000 0000 0 writer.WriteUInt16((ushort)(0b_0100_0000_0000_0000 | PID)); writer.WriteByte((byte)((byte)AdaptationFieldControl | ContinuityCounter)); if (Adaptation != null) { writer.Skip(1, out int AdaptationLengthPosition); Adaptation.ToBuffer(ref writer); writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - AdaptationLengthPosition - 1), AdaptationLengthPosition); } else { writer.WriteByte(0); } }
public override void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteByte(Tag); if (ISO_639_Language_Infos != null) { writer.Skip(1, out int DescriptorLengthPosition); foreach (var item in ISO_639_Language_Infos) { writer.WriteUInt3(item.ISO_639_Language_Code >> 8); writer.WriteByte(item.Audio_Type); } writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - DescriptorLengthPosition - 1), DescriptorLengthPosition); } else { writer.WriteByte(0); } }
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>(); public byte[] CreateSDT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_SDT_Package package = new TS_SDT_Package(); package.Header = new TS_Header(); package.Header.PID = 0x0011; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.ContinuityCounter = 0; package.TableId = 0x42; package.TransportStreamId = 0x0001; package.VersionNumber = 0; package.CurrentNextIndicator = 0x01; package.SectionNumber = 0x00; package.LastSectionNumber = 0x00; package.OriginalNetworkId = 0xFF01; package.Services = new List <TS_SDT_Service>(); package.Services.Add(new TS_SDT_Service() { ServiceId = 0x0001, EITScheduleFlag = 0x00, EITPresentFollowingFlag = 0x00, RunningStatus = TS_SDT_Service_RunningStatus.运行, FreeCAMode = 0x00, Descriptors = new List <TS_SDT_Service_Descriptor> { new TS_SDT_Service_Descriptor { Tag = 0x48, ServiceType = TS_SDT_Service_Descriptor_ServiceType.数字电视业务, ServiceProvider = ServiceProvider, ServiceName = ServiceName } } }); TSMessagePackWriter writer = new TSMessagePackWriter(buffer); package.ToBuffer(ref writer); return(writer.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
internal void CreateSegmentPES(ref TSMessagePackWriter writer, byte[] nalu, byte counter) { TS_Segment_Package package = new TS_Segment_Package(); package.Header = new TS_Header(); package.Header.PID = 256; package.Header.ContinuityCounter = counter; package.Header.PayloadUnitStartIndicator = 0; package.Payload = nalu; //这个很重要,需要控制 //package.Header.AdaptationFieldControl= AdaptationFieldControl.同时带有自适应域和有效负载 //这个很重要,填充大小 //package.Header.Adaptation.FillSize //AdaptationLengthPosition + PCRIncluded //1 + 1 if (nalu.Length < (FiexdSegmentPESLength)) { int size = FiexdSegmentPESLength - 1 - 1 - nalu.Length; package.Header.PackageType = PackageType.Data_End; if (size < 0) { // nalu剩余183字节的时候 // 头部4个字节 + 自适应域长度1字节(0)+183 =188 package.Header.AdaptationFieldControl = AdaptationFieldControl.仅含自适应域_无有效负载; } else { package.Header.Adaptation = new TS_AdaptationInfo(); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.FillSize = (byte)(size); package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; } } else { package.Header.PackageType = PackageType.Data_Segment; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; } package.Payload = nalu; package.ToBuffer(ref writer); }
public void ToBufferTest() { TS_SDT_Package package = new TS_SDT_Package(); package.Header = new TS_Header(); package.Header.PID = 0x0011; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.ContinuityCounter = 0; package.TableId = 0x42; package.TransportStreamId = 0x0001; package.VersionNumber = 0; package.CurrentNextIndicator = 0x01; package.SectionNumber = 0x00; package.LastSectionNumber = 0x00; package.OriginalNetworkId = 0xFF01; package.Services = new List <TS_SDT_Service>(); package.Services.Add(new TS_SDT_Service() { ServiceId = 0x0001, EITScheduleFlag = 0x00, EITPresentFollowingFlag = 0x00, RunningStatus = TS_SDT_Service_RunningStatus.运行, FreeCAMode = 0x00, Descriptors = new List <Descriptors.TS_SDT_Service_Descriptor> { new Descriptors.TS_SDT_Service_Descriptor { Tag = 0x48, ServiceType = TS_SDT_Service_Descriptor_ServiceType.数字电视业务, ServiceProvider = "FFmpeg", ServiceName = "Service01" } } }); TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]); package.ToBuffer(ref writer); var patData = writer.FlushAndGetArray().ToHexString(); Assert.Equal("47 40 11 10 00 42 F0 25 00 01 C1 00 00 FF 01 FF 00 01 FC 80 14 48 12 01 06 46 46 6D 70 65 67 09 53 65 72 76 69 63 65 30 31 77 7C 43 CA FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF".Replace(" ", ""), patData); }
public void ToBufferTest() { //47 40 00 10 00 00 B0 0D 00 01 C1 00 00 00 01 F0 00 2A B1 04 B2 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF //----------PAT //47 //40 00 //10 //00 //00 //B0 0D //00 01 //C1 //00 //00 //00 01 //F0 00 //2A B1 04 B2 TS_PAT_Package package = new TS_PAT_Package(); package.Header = new TS_Header(); package.Header.PID = 0; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.ContinuityCounter = 0; package.TableId = 0; package.TransportStreamId = 0x0001; package.VersionNumber = 0; package.Programs = new List <TS_PAT_Program>(); package.Programs.Add(new TS_PAT_Program() { ProgramNumber = 0x0001, PID = 0x1000, }); TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]); package.ToBuffer(ref writer); var patData = writer.FlushAndGetArray().ToHexString(); Assert.Equal("47 40 00 10 00 00 B0 0D 00 01 C1 00 00 00 01 F0 00 2A B1 04 B2 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF".Replace(" ", ""), patData); }
public void ToBuffer(ref TSMessagePackWriter writer) { Header.ToBuffer(ref writer); Payload.ToBuffer(ref writer); }
public void ToBuffer(ref TSMessagePackWriter writer) { Header.ToBuffer(ref writer); writer.WriteArray(Payload); }
public abstract void ToBuffer(ref TSMessagePackWriter writer);
public void ToBuffer(ref TSMessagePackWriter writer) { writer.WriteUInt16(ProgramNumber); writer.WriteUInt16((ushort)(0b_1110_0000_0000_0000 | PID)); }
public void ToBufferTest() { //47 50 00 10 00 02 B0 1D 00 01 C1 00 00 E1 00 F0 00 1B E1 00 F0 00 0F E1 01 F0 06 0A 04 75 6E 64 00 08 7D E8 77 //47 //50 00 //10 //00 //02 //B0 1D //00 01 //C1 //00 //00 //E1 00 //F0 00 //1B //E1 00 // F0 00 //0F //E1 01 // F0 06 // 0A // 04 // 75 6E 64 00 //08 7D E8 77 TS_PMT_Package package = new TS_PMT_Package(); package.Header = new TS_Header(); package.Header.PID = 4096; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.ContinuityCounter = 0; package.TableId = 0x02; package.ProgramNumber = 0x0001; package.PCR_PID = 256; package.Components = new List <TS_PMT_Component>(); package.Components.Add(new TS_PMT_Component() { StreamType = StreamType.h264, ElementaryPID = 256, }); package.Components.Add(new TS_PMT_Component() { StreamType = StreamType.aac, ElementaryPID = 257, Descriptor = new ISO_639_Language_Descriptor { ISO_639_Language_Infos = new List <ISO_639_Language_Descriptor.ISO_639_Language_Info>() { new ISO_639_Language_Descriptor.ISO_639_Language_Info { Audio_Type = 0, ISO_639_Language_Code = BinaryPrimitives.ReadUInt32BigEndian(new byte[] { 0x75, 0x6E, 0x64, 0x00 }) } } } }); TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]); package.ToBuffer(ref writer); var pmtData = writer.FlushAndGetArray().ToHexString(); Assert.Equal("47 50 00 10 00 02 B0 1D 00 01 C1 00 00 E1 00 F0 00 1B E1 00 F0 00 0F E1 01 F0 06 0A 04 75 6E 64 00 08 7D E8 77 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ".Replace(" ", ""), pmtData); }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //ts header 4 totalLength += 4; package.Header.PID = 256; string key = jt1078Package.GetKey(); if (VideoCounter.TryGetValue(key, out byte counter)) { if (counter > 0xf) { counter = 0; } package.Header.ContinuityCounter = counter++; VideoCounter.TryUpdate(key, counter, counter); } else { package.Header.ContinuityCounter = counter++; VideoCounter.TryAdd(key, counter); } package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Payload = new PES_Package(); package.Payload.StreamId = 0xe0; package.Payload.PESPacketLength = 0; //PESStartCode + StreamId + PESPacketLength //3 + 1 + 2 totalLength += (3 + 1 + 2); package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧) { //ts header adaptation //PCRIncluded + PCR //1 + 5 totalLength += (1 + 5); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.PCR = jt1078Package.LastIFrameInterval; package.Payload.DTS = jt1078Package.LastIFrameInterval; package.Payload.PTS = jt1078Package.LastIFrameInterval; } else { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = jt1078Package.LastFrameInterval; package.Payload.PTS = jt1078Package.LastFrameInterval; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 totalLength += 12; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter++); } else { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter++); index += segmentFullSize; } } VideoCounter.TryUpdate(key, counter, counter); } return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //ts header 4 totalLength += 4; package.Header.PID = 256; package.Header.PackageType = PackageType.Data_Start; string key = jt1078Package.GetKey(); if (VideoCounter.TryGetValue(key, out byte counter)) { if (counter > 0xf) { counter = 0; } } else { VideoCounter.Add(key, counter); } package.Header.ContinuityCounter = counter; counter++; package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Payload = new PES_Package(); package.Payload.StreamId = 0xe0; package.Payload.PESPacketLength = 0; //PESStartCode + StreamId+ Flag1 + PTS_DTS_Flag + PESPacketLength //3 + 1 + 1 + 1 + 2 totalLength += (3 + 1 + 1 + 1 + 2); package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; long timestamp = (long)jt1078Package.Timestamp; if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧) { //ts header adaptation //PCRIncluded + Timestamp //1 + 6 totalLength += (1 + 6); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.Timestamp = timestamp; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastIFrameInterval * H264DefaultHZ; } else if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastFrameInterval * H264DefaultHZ; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 = 12 totalLength += 12; totalLength += TSConstants.FiexdESPackageHeaderLength; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter); index += FiexdSegmentPESLength; } else { var nalu = dataReader.Slice(index, segmentFullSize).ToArray(); //当等于183字节的时候 //12698D08E8DBDBCDF6C6FA19DD88490E908D687D1755BE87DF82754BE2D245270569310B3030A4904DF1883ED09A68CA1C79BC4B97642B5BC095A55E56868D05370D3BC8B7B60B4642A486B6852656C01FFADACEF4BD4320E8BE9C54D44177A433CC37493FA1D8ACD0164E92454D03B6EC0617B133AEF43B599BF85632AB9B5FF671F0DDAA07E8F279F5639BA88E3FFFFCE1D3351FAF43DF23BCEB7E3B2CAB3EABAED23B25097B7F51FF38E8D0EBAB589CEC42B0440EB8 //if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) //{ // string hex = dataReader.Slice(index, segmentFullSize).ToArray().ToHexString(); //} CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter); index += segmentFullSize; } counter++; } } VideoCounter[key] = counter; return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }