From c333bdcf016a02d0da9ad13663bee99f2038dd46 Mon Sep 17 00:00:00 2001 From: waterliu99 Date: Tue, 19 May 2020 19:05:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9ESDT=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT1078.Hls/TS_SDT_Package.cs | 123 ++++++++++++++++++++ src/JT1078.Hls/TS_SDT_Service_.cs | 123 ++++++++++++++++++++ src/JT1078.Hls/TS_SDT_Service_Descriptor.cs | 123 ++++++++++++++++++++ 3 files changed, 369 insertions(+) create mode 100644 src/JT1078.Hls/TS_SDT_Package.cs create mode 100644 src/JT1078.Hls/TS_SDT_Service_.cs create mode 100644 src/JT1078.Hls/TS_SDT_Service_Descriptor.cs diff --git a/src/JT1078.Hls/TS_SDT_Package.cs b/src/JT1078.Hls/TS_SDT_Package.cs new file mode 100644 index 0000000..80cac8e --- /dev/null +++ b/src/JT1078.Hls/TS_SDT_Package.cs @@ -0,0 +1,123 @@ +using JT1078.Hls.Enums; +using JT1078.Hls.Interfaces; +using JT1078.Hls.MessagePack; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace JT1078.Hls +{ + /// + /// 业务描述表 + /// + public class TS_SDT_Package : ITSMessagePackFormatter + { + public TS_Header Header { get; set; } + /// + /// PAT表固定为0x00 + /// 8bit + /// + public byte TableId { get; set; } = 0x42; + /// + /// 固定为二进制1 + /// 1bit + /// + internal byte SectionSyntaxIndicator { get; set; } + /// + /// + /// 1bit + /// + internal byte ReservedFutureUse1 { get; set; } + /// + /// + /// 2bit + /// + internal byte Reserved1 { get; set; } + /// + /// 后面数据的长度 + /// 12bit + /// + public ushort SectionLength { get; set; } + /// + /// 传输流ID + /// 16bit + /// + internal ushort TransportStreamId { get; set; } = 0x0001; + /// + /// + /// 2bit + /// + internal byte Reserved2 { get; set; } + /// + /// 版本号, + /// 5bit + /// + public byte VersionNumber { get; set; } + /// + /// + /// 1bit + /// + public byte CurrentNextIndicator { get; set; } + /// + /// + /// bit8 + /// + internal byte SectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal byte LastSectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal ushort OriginalNetworkId { get; set; } + /// + /// + /// 1Byte + /// + internal byte ReservedFutureUse2 { get; set; } + public List Services { get; set; } + + /// + /// 前面数据的CRC32校验码 + /// + public uint CRC32 { get; set; } + + public void ToBuffer(ref TSMessagePackWriter writer) + { + Header.PackageType = PackageType.PAT; + 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()); + } + } +} diff --git a/src/JT1078.Hls/TS_SDT_Service_.cs b/src/JT1078.Hls/TS_SDT_Service_.cs new file mode 100644 index 0000000..e347080 --- /dev/null +++ b/src/JT1078.Hls/TS_SDT_Service_.cs @@ -0,0 +1,123 @@ +using JT1078.Hls.Enums; +using JT1078.Hls.Interfaces; +using JT1078.Hls.MessagePack; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace JT1078.Hls +{ + /// + /// 业务描述服务 + /// + public class TS_SDT_Service : ITSMessagePackFormatter + { + public TS_Header Header { get; set; } + /// + /// PAT表固定为0x00 + /// 8bit + /// + public byte TableId { get; set; } = 0x42; + /// + /// 固定为二进制1 + /// 1bit + /// + internal byte SectionSyntaxIndicator { get; set; } + /// + /// + /// 1bit + /// + internal byte ReservedFutureUse1 { get; set; } + /// + /// + /// 2bit + /// + internal byte Reserved1 { get; set; } + /// + /// 后面数据的长度 + /// 12bit + /// + public ushort SectionLength { get; set; } + /// + /// 传输流ID + /// 16bit + /// + internal ushort TransportStreamId { get; set; } = 0x0001; + /// + /// + /// 2bit + /// + internal byte Reserved2 { get; set; } + /// + /// 版本号, + /// 5bit + /// + public byte VersionNumber { get; set; } + /// + /// + /// 1bit + /// + public byte CurrentNextIndicator { get; set; } + /// + /// + /// bit8 + /// + internal byte SectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal byte LastSectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal ushort OriginalNetworkId { get; set; } + /// + /// + /// 1Byte + /// + internal byte ReservedFutureUse2 { get; set; } + public List Services { get; set; } + + /// + /// 前面数据的CRC32校验码 + /// + public uint CRC32 { get; set; } + + public void ToBuffer(ref TSMessagePackWriter writer) + { + Header.PackageType = PackageType.PAT; + 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()); + } + } +} diff --git a/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs b/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs new file mode 100644 index 0000000..19e0406 --- /dev/null +++ b/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs @@ -0,0 +1,123 @@ +using JT1078.Hls.Enums; +using JT1078.Hls.Interfaces; +using JT1078.Hls.MessagePack; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace JT1078.Hls +{ + /// + /// 业务描述服务描述 + /// + public class TS_SDT_Service_Descriptor : ITSMessagePackFormatter + { + public TS_Header Header { get; set; } + /// + /// PAT表固定为0x00 + /// 8bit + /// + public byte TableId { get; set; } = 0x42; + /// + /// 固定为二进制1 + /// 1bit + /// + internal byte SectionSyntaxIndicator { get; set; } + /// + /// + /// 1bit + /// + internal byte ReservedFutureUse1 { get; set; } + /// + /// + /// 2bit + /// + internal byte Reserved1 { get; set; } + /// + /// 后面数据的长度 + /// 12bit + /// + public ushort SectionLength { get; set; } + /// + /// 传输流ID + /// 16bit + /// + internal ushort TransportStreamId { get; set; } = 0x0001; + /// + /// + /// 2bit + /// + internal byte Reserved2 { get; set; } + /// + /// 版本号, + /// 5bit + /// + public byte VersionNumber { get; set; } + /// + /// + /// 1bit + /// + public byte CurrentNextIndicator { get; set; } + /// + /// + /// bit8 + /// + internal byte SectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal byte LastSectionNumber { get; set; } + /// + /// + /// bit8 + /// + internal ushort OriginalNetworkId { get; set; } + /// + /// + /// 1Byte + /// + internal byte ReservedFutureUse2 { get; set; } + public List Services { get; set; } + + /// + /// 前面数据的CRC32校验码 + /// + public uint CRC32 { get; set; } + + public void ToBuffer(ref TSMessagePackWriter writer) + { + Header.PackageType = PackageType.PAT; + 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()); + } + } +}