瀏覽代碼

完善SDT协议包

tags/v1.1.0
waterliu99 5 年之前
父節點
當前提交
23cffcda70
共有 9 個文件被更改,包括 170 次插入232 次删除
  1. +20
    -0
      src/JT1078.Hls.Test/TS_SDT_Package_Test.cs
  2. +19
    -0
      src/JT1078.Hls/Enums/RunningStatus.cs
  3. +3
    -0
      src/JT1078.Hls/JT1078.Hls.csproj
  4. +6
    -0
      src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
  5. +6
    -0
      src/JT1078.Hls/TSConstants.cs
  6. +16
    -27
      src/JT1078.Hls/TS_SDT_Package.cs
  7. +76
    -0
      src/JT1078.Hls/TS_SDT_Service.cs
  8. +0
    -123
      src/JT1078.Hls/TS_SDT_Service_.cs
  9. +24
    -82
      src/JT1078.Hls/TS_SDT_Service_Descriptor.cs

+ 20
- 0
src/JT1078.Hls.Test/TS_SDT_Package_Test.cs 查看文件

@@ -0,0 +1,20 @@
using JT1078.Hls.Enums;
using JT1078.Hls.MessagePack;
using JT1078.Protocol.Extensions;
using System;
using System.Collections.Generic;
using Xunit;

namespace JT1078.Hls.Test
{
/// <summary>
/// ʹÓÃdoc/video/demo0.ts
/// </summary>
public class TS_SDT_Package_Test
{
[Fact]
public void ToBufferTest()
{
}
}
}

+ 19
- 0
src/JT1078.Hls/Enums/RunningStatus.cs 查看文件

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Hls.Enums
{
/// <summary>
/// 运行状态
/// </summary>
public enum RunningStatus
{
未定义=0,
未运行=1,
几秒后开始=2,
暂停=3,
运行=4,

}
}

+ 3
- 0
src/JT1078.Hls/JT1078.Hls.csproj 查看文件

@@ -33,4 +33,7 @@
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
</ItemGroup>
</Project>

+ 6
- 0
src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs 查看文件

@@ -163,5 +163,11 @@ namespace JT1078.Hls.MessagePack
{
return writer.WrittenCount;
}
public void WriteString(string value)
{
byte[] codeBytes = TSConstants.Encoding.GetBytes(value);
codeBytes.CopyTo(writer.Free);
writer.Advance(codeBytes.Length);
}
}
}

+ 6
- 0
src/JT1078.Hls/TSConstants.cs 查看文件

@@ -6,6 +6,12 @@ namespace JT1078.Hls
{
public static class TSConstants
{
static TSConstants()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding = Encoding.GetEncoding("GBK");
}
public static Encoding Encoding { get; }
/// <summary>
/// 固定包长度
/// </summary>


+ 16
- 27
src/JT1078.Hls/TS_SDT_Package.cs 查看文件

@@ -3,6 +3,7 @@ using JT1078.Hls.Interfaces;
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;

@@ -15,12 +16,12 @@ namespace JT1078.Hls
{
public TS_Header Header { get; set; }
/// <summary>
/// PAT表固定为0x00
///
/// 8bit
/// </summary>
public byte TableId { get; set; } = 0x42;
/// <summary>
/// 固定为二进制1
///
/// 1bit
/// </summary>
internal byte SectionSyntaxIndicator { get; set; }
@@ -43,14 +44,14 @@ namespace JT1078.Hls
/// 传输流ID
/// 16bit
/// </summary>
internal ushort TransportStreamId { get; set; } = 0x0001;
internal ushort TransportStreamId { get; set; }
/// <summary>
///
/// 2bit
/// </summary>
internal byte Reserved2 { get; set; }
/// <summary>
/// 版本号,
///
/// 5bit
/// </summary>
public byte VersionNumber { get; set; }
@@ -79,7 +80,7 @@ namespace JT1078.Hls
/// 1Byte
/// </summary>
internal byte ReservedFutureUse2 { get; set; }
public List<TS_SDT_Service_Descriptor> Services { get; set; }
public List<TS_SDT_Service> Services { get; set; }

/// <summary>
/// 前面数据的CRC32校验码
@@ -88,33 +89,21 @@ namespace JT1078.Hls

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((byte)(Reserved2 << 6 | VersionNumber << 1 | CurrentNextIndicator));
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.WriteUInt16(OriginalNetworkId);
writer.WriteByte(ReservedFutureUse2);
foreach (var service in Services)
{
service.ToBuffer(ref writer);
}
ushort servicesLength =(ushort)( writer.GetCurrentPosition() - SectionLengthPosition);
const int crcLength = 4;
writer.WriteUInt16Return((ushort)(SectionSyntaxIndicator<<15 | ReservedFutureUse1<<14 | servicesLength+ crcLength), SectionLengthPosition);
writer.WriteCRC32(5);
var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition();
writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray());


+ 76
- 0
src/JT1078.Hls/TS_SDT_Service.cs 查看文件

@@ -0,0 +1,76 @@
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
{
/// <summary>
/// 业务描述服务
/// </summary>
public class TS_SDT_Service : ITSMessagePackFormatter
{
/// <summary>
/// 业务标识符
/// 用于在 TS 流中识别不同的业务。service_id 与program_map_section 中的 program_number 取同一值
/// 16bit
/// </summary>
internal ushort ServiceId { get; set; }
/// <summary>
///
/// 6bit
/// </summary>
internal byte ReservedFutureUse { get; set; }
/// <summary>
/// EIT 时间表标志
/// 置“1”时,表示业务的 EIT 时间表信息存在于当前 TS 中(一个 EIT 时间表子表两次出现的最大时间间隔信息见 ETR 211)。
/// 置“0”时,表示业务的 EIT 时间表信息不在当前 TS 中
/// 1bit
/// </summary>
internal byte EITScheduleFlag { get; set; }
/// <summary>
/// EIT 当前后续标志
/// 置“1”时,表示业务的 EIT 当前后续信息存在于当前 TS 中(一个 EIT 当前后续子表两次出现的最大时间间隔信息见ETR 211)
/// 置“0”时,表示业务的 EIT 当前后续信息不在当前 TS 中。
/// 1bit
/// </summary>
public byte EITPresentFollowingFlag { get; set; }
/// <summary>
/// 运行状态
/// 对于一个 NVOD 业务,running_status 的值都置“0”
/// 3bit
/// </summary>
internal RunningStatus RunningStatus { get; set; }
/// <summary>
/// 自由条件接收模式
/// 置“0”时,表示业务的所有组件都未被加扰
/// 置“1”时,表示一路或多路码流的接收由 CA 系统控制。
/// 1bit
/// </summary>
internal byte FreeCAMode { get; set; }
/// <summary>
/// 描述符循环长度
/// 指出从本字段的下一个字节开始的描述符的总字节长度。
/// 12bit
/// </summary>
public ushort DescriptorsLoopLength { get; set; }
public List<TS_SDT_Service_Descriptor> Descriptors { get; set; }

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);
writer.WriteUInt16Return((ushort)(((ushort)RunningStatus << 13) | ((ushort)FreeCAMode << 12) | DescriptorsLoopLength), position);
}
}
}

+ 0
- 123
src/JT1078.Hls/TS_SDT_Service_.cs 查看文件

@@ -1,123 +0,0 @@
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
{
/// <summary>
/// 业务描述服务
/// </summary>
public class TS_SDT_Service : ITSMessagePackFormatter
{
public TS_Header Header { get; set; }
/// <summary>
/// PAT表固定为0x00
/// 8bit
/// </summary>
public byte TableId { get; set; } = 0x42;
/// <summary>
/// 固定为二进制1
/// 1bit
/// </summary>
internal byte SectionSyntaxIndicator { get; set; }
/// <summary>
///
/// 1bit
/// </summary>
internal byte ReservedFutureUse1 { get; set; }
/// <summary>
///
/// 2bit
/// </summary>
internal byte Reserved1 { get; set; }
/// <summary>
/// 后面数据的长度
/// 12bit
/// </summary>
public ushort SectionLength { get; set; }
/// <summary>
/// 传输流ID
/// 16bit
/// </summary>
internal ushort TransportStreamId { get; set; } = 0x0001;
/// <summary>
///
/// 2bit
/// </summary>
internal byte Reserved2 { get; set; }
/// <summary>
/// 版本号,
/// 5bit
/// </summary>
public byte VersionNumber { get; set; }
/// <summary>
///
/// 1bit
/// </summary>
public byte CurrentNextIndicator { get; set; }
/// <summary>
///
/// bit8
/// </summary>
internal byte SectionNumber { get; set; }
/// <summary>
///
/// bit8
/// </summary>
internal byte LastSectionNumber { get; set; }
/// <summary>
///
/// bit8
/// </summary>
internal ushort OriginalNetworkId { get; set; }
/// <summary>
///
/// 1Byte
/// </summary>
internal byte ReservedFutureUse2 { get; set; }
public List<TS_PAT_Program> Services { get; set; }

/// <summary>
/// 前面数据的CRC32校验码
/// </summary>
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());
}
}
}

+ 24
- 82
src/JT1078.Hls/TS_SDT_Service_Descriptor.cs 查看文件

@@ -13,111 +13,53 @@ namespace JT1078.Hls
/// </summary>
public class TS_SDT_Service_Descriptor : ITSMessagePackFormatter
{
public TS_Header Header { get; set; }
/// <summary>
/// PAT表固定为0x00
/// 8bit
/// </summary>
public byte TableId { get; set; } = 0x42;
/// <summary>
/// 固定为二进制1
/// 1bit
/// </summary>
internal byte SectionSyntaxIndicator { get; set; }
/// <summary>
///
/// 1bit
/// </summary>
internal byte ReservedFutureUse1 { get; set; }
/// <summary>
///
/// 2bit
/// </summary>
internal byte Reserved1 { get; set; }
/// <summary>
/// 后面数据的长度
/// 12bit
/// </summary>
public ushort SectionLength { get; set; }
/// <summary>
/// 传输流ID
/// 16bit
/// 8bit
/// </summary>
internal ushort TransportStreamId { get; set; } = 0x0001;
public byte DescriptorTag { get; set; } = 0x48;
/// <summary>
///
/// 2bit
/// </summary>
internal byte Reserved2 { get; set; }
/// <summary>
/// 版本号,
/// 5bit
/// 8bit
/// </summary>
public byte VersionNumber { get; set; }
internal byte DescriptorLength { get; set; } = 0x12;
/// <summary>
///
/// 1bit
/// 8bit
/// </summary>
public byte CurrentNextIndicator { get; set; }
internal byte ServiceType { get; set; } = 0x01;
/// <summary>
///
/// bit8
/// 8bit
/// </summary>
internal byte SectionNumber { get; set; }
internal byte ServiceProviderLength { get; set; }
/// <summary>
///
/// bit8
/// ServiceProviderLength
/// </summary>
internal byte LastSectionNumber { get; set; }
public string ServiceProvider { get; set; }
/// <summary>
///
/// bit8
/// 8bit
/// </summary>
internal ushort OriginalNetworkId { get; set; }
internal byte ServiceNameLenth { get; set; }
/// <summary>
///
/// 1Byte
/// ServiceNameLenth
/// </summary>
internal byte ReservedFutureUse2 { get; set; }
public List<TS_PAT_Program> Services { get; set; }

/// <summary>
/// 前面数据的CRC32校验码
/// </summary>
public uint CRC32 { get; set; }

internal string ServiceName { 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());
writer.WriteByte(DescriptorTag);
writer.Skip(1,out var position);
writer.WriteByte(ServiceType);
writer.Skip(1, out var serviceProviderLengthPosition);
writer.WriteString(ServiceProvider);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - serviceProviderLengthPosition), serviceProviderLengthPosition);
writer.Skip(1, out int SeviceNameLengthPosition);
writer.WriteString(ServiceName);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - SeviceNameLengthPosition), SeviceNameLengthPosition);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - position), position);
}
}
}

Loading…
取消
儲存