Procházet zdrojové kódy

完善sdt协议包及单元测试

tags/v1.1.0
waterliu99 před 5 roky
rodič
revize
a6f751eb35
8 změnil soubory, kde provedl 130 přidání a 47 odebrání
  1. +41
    -0
      src/JT1078.Hls.Test/TS_SDT_Package_Test.cs
  2. +8
    -8
      src/JT1078.Hls/Descriptors/TS_SDT_Service_Descriptor.cs
  3. +1
    -0
      src/JT1078.Hls/Enums/PackageType.cs
  4. +26
    -0
      src/JT1078.Hls/Enums/TS_SDT_Service_Descriptor_ServiceType.cs
  5. +1
    -1
      src/JT1078.Hls/Enums/TS_SDT_Service_RunningStatus.cs
  6. +3
    -2
      src/JT1078.Hls/TS_Header.cs
  7. +41
    -28
      src/JT1078.Hls/TS_SDT_Package.cs
  8. +9
    -8
      src/JT1078.Hls/TS_SDT_Service.cs

+ 41
- 0
src/JT1078.Hls.Test/TS_SDT_Package_Test.cs Zobrazit soubor

@@ -15,6 +15,47 @@ namespace JT1078.Hls.Test
[Fact]
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{
DescriptorTag=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);

}

[Fact]
public void Test() {
byte a = 0x01;
var b = (ushort)(a << 15);
}
}
}

src/JT1078.Hls/TS_SDT_Service_Descriptor.cs → src/JT1078.Hls/Descriptors/TS_SDT_Service_Descriptor.cs Zobrazit soubor

@@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JT1078.Hls
namespace JT1078.Hls.Descriptors
{
/// <summary>
/// 业务描述服务描述
@@ -14,7 +14,7 @@ namespace JT1078.Hls
public class TS_SDT_Service_Descriptor : ITSMessagePackFormatter
{
/// <summary>
///
/// 业务描述符
/// 8bit
/// </summary>
public byte DescriptorTag { get; set; } = 0x48;
@@ -22,12 +22,12 @@ namespace JT1078.Hls
///
/// 8bit
/// </summary>
internal byte DescriptorLength { get; set; } = 0x12;
internal byte DescriptorLength { get; set; }
/// <summary>
///
/// 8bit
/// </summary>
internal byte ServiceType { get; set; } = 0x01;
internal TS_SDT_Service_Descriptor_ServiceType ServiceType { get; set; } = TS_SDT_Service_Descriptor_ServiceType.数字电视业务;
/// <summary>
///
/// 8bit
@@ -52,14 +52,14 @@ namespace JT1078.Hls
{
writer.WriteByte(DescriptorTag);
writer.Skip(1,out var position);
writer.WriteByte(ServiceType);
writer.WriteByte((byte)ServiceType);
writer.Skip(1, out var serviceProviderLengthPosition);
writer.WriteString(ServiceProvider);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - serviceProviderLengthPosition), serviceProviderLengthPosition);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - serviceProviderLengthPosition-1), serviceProviderLengthPosition);
writer.Skip(1, out int SeviceNameLengthPosition);
writer.WriteString(ServiceName);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - SeviceNameLengthPosition), SeviceNameLengthPosition);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - position), position);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - SeviceNameLengthPosition-1), SeviceNameLengthPosition);
writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - position-1), position);
}
}
}

+ 1
- 0
src/JT1078.Hls/Enums/PackageType.cs Zobrazit soubor

@@ -11,5 +11,6 @@ namespace JT1078.Hls.Enums
Data_Start=3,
Data_Segment = 4,
Data_End = 5,
SDT=6
}
}

+ 26
- 0
src/JT1078.Hls/Enums/TS_SDT_Service_Descriptor_ServiceType.cs Zobrazit soubor

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

namespace JT1078.Hls.Enums
{
/// <summary>
/// 服务描述类型
/// </summary>
public enum TS_SDT_Service_Descriptor_ServiceType:byte
{
保留以后使用=0x00,
数字电视业务 = 0x01,
数字无线声音业务 = 0x02,
图文电视业务 = 0x03,
NVOD参考业务 = 0x04,
NVOD时间平移业务 = 0x05,
镶嵌业务 = 0x06,
PAL编码信号 = 0x07,
SECAM编码信号 = 0x08,
D_D2_MAC = 0x09,
FM无线 = 0x0A,
NTSC编码信号 = 0x0B,
数据广播业务 = 0x0C,
}
}

src/JT1078.Hls/Enums/RunningStatus.cs → src/JT1078.Hls/Enums/TS_SDT_Service_RunningStatus.cs Zobrazit soubor

@@ -7,7 +7,7 @@ namespace JT1078.Hls.Enums
/// <summary>
/// 运行状态
/// </summary>
public enum RunningStatus
public enum TS_SDT_Service_RunningStatus
{
未定义=0,
未运行=1,

+ 3
- 2
src/JT1078.Hls/TS_Header.cs Zobrazit soubor

@@ -32,7 +32,7 @@ namespace JT1078.Hls
/// pid值
/// 13bit
/// </summary>
public ushort PID { get; set; }
public ushort PID { get; set; } = 0x0011;
/// <summary>
/// 传输加扰控制
/// 2bit
@@ -69,7 +69,8 @@ namespace JT1078.Hls
if(PackageType== PackageType.PAT ||
PackageType == PackageType.PMT ||
PackageType == PackageType.Data_Start ||
PackageType == PackageType.Data_End)
PackageType == PackageType.Data_End ||
PackageType == PackageType.SDT)
{
if (Adaptation != null)
{


+ 41
- 28
src/JT1078.Hls/TS_SDT_Package.cs Zobrazit soubor

@@ -16,70 +16,81 @@ namespace JT1078.Hls
{
public TS_Header Header { get; set; }
/// <summary>
///
/// 表标识符
/// 可以是0x42,表示描述的是当前流的信息,也可以是0x46,表示是其他流的信息
/// 8bit
/// </summary>
public byte TableId { get; set; } = 0x42;
/// <summary>
///
/// 段语法指示符
/// 1bit
/// </summary>
internal byte SectionSyntaxIndicator { get; set; }
internal byte SectionSyntaxIndicator { get; set; } = 0x01;
/// <summary>
///
/// 保留未来使用
/// 1bit
/// </summary>
internal byte ReservedFutureUse1 { get; set; }
internal byte ReservedFutureUse1 { get; set; } = 0x01;
/// <summary>
///
/// 保留位,防止控制字冲突,一般是''0'',也有可能是''1''
/// 2bit
/// </summary>
internal byte Reserved1 { get; set; }
internal byte Reserved1 { get; set; } = 0x03;
/// <summary>
/// 后面数据的长度
/// 段长度 从transport_stream_id开始,到CRC_32结束(包含)
/// 12bit
/// </summary>
public ushort SectionLength { get; set; }
/// <summary>
/// 传输流ID
/// 传输流标识符
/// 同 PAT表中的 TransportStreamId 和PMT表中 ProgramNumber
/// 16bit
/// </summary>
internal ushort TransportStreamId { get; set; }
internal ushort TransportStreamId { get; set; }
/// <summary>
///
/// 保留位
/// 2bit
/// </summary>
internal byte Reserved2 { get; set; }
internal byte Reserved2 { get; set; }= 0x03;
/// <summary>
///
/// 版本号
/// 标识子表的版本号。当子表包含的信息发生变化时, version_number 加 1。当值增至 31 时,复位为 0。
/// 当 current_next_indicator 置“1”时,则 version_number 为当前使用的子表的版本号。
/// 当 current_next_indicator 置“0”时,则 version_number 为下一个使用的子表的版本号。
/// 5bit
/// </summary>
public byte VersionNumber { get; set; }
public byte VersionNumber { get; set; } = 0x00;
/// <summary>
///
/// 当前后续指示符
/// 当被置“1”时,表示当前子表 正被使用。
/// 当其置“0”时,表示所传子表尚未被使用,它是下一个将被使用的子表。
/// 1bit
/// </summary>
public byte CurrentNextIndicator { get; set; }
public byte CurrentNextIndicator { get; set; } = 0x00;
/// <summary>
///
/// 段号
/// 子表中的第一个段的 section_number 标 为 “ 0x00 ”。
/// 每增加一个具有相同的 table_id 、 transport_stream_id 和original_network_id 的段,section_number 就加 1。
/// bit8
/// </summary>
internal byte SectionNumber { get; set; }
internal byte SectionNumber { get; set; }=0x00;
/// <summary>
///
/// 最后段号
/// 表示所属的子表的最后一个段(即段号最大的段)的段号。
/// bit8
/// </summary>
internal byte LastSectionNumber { get; set; }
internal byte LastSectionNumber { get; set; } = 0x00;
/// <summary>
///
/// bit8
/// 原始网络标识符
/// 原始传输系统的 network_id
/// bit16
/// </summary>
internal ushort OriginalNetworkId { get; set; }
internal ushort OriginalNetworkId { get; set; }
/// <summary>
///
/// 1Byte
/// 保留未来使用位
/// bit8
/// </summary>
internal byte ReservedFutureUse2 { get; set; }
internal byte ReservedFutureUse2 { get; set; } = 0xFF;
public List<TS_SDT_Service> Services { get; set; }

/// <summary>
@@ -89,6 +100,8 @@ namespace JT1078.Hls

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);
@@ -101,9 +114,9 @@ namespace JT1078.Hls
{
service.ToBuffer(ref writer);
}
ushort servicesLength =(ushort)( writer.GetCurrentPosition() - SectionLengthPosition);
ushort servicesLength =(ushort)( writer.GetCurrentPosition() - SectionLengthPosition-2);
const int crcLength = 4;
writer.WriteUInt16Return((ushort)(SectionSyntaxIndicator<<15 | ReservedFutureUse1<<14 | servicesLength+ crcLength), SectionLengthPosition);
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());


+ 9
- 8
src/JT1078.Hls/TS_SDT_Service.cs Zobrazit soubor

@@ -1,4 +1,5 @@
using JT1078.Hls.Enums;
using JT1078.Hls.Descriptors;
using JT1078.Hls.Enums;
using JT1078.Hls.Interfaces;
using JT1078.Hls.MessagePack;
using System;
@@ -20,37 +21,37 @@ namespace JT1078.Hls
/// </summary>
internal ushort ServiceId { get; set; }
/// <summary>
///
/// 保留将来使用
/// 6bit
/// </summary>
internal byte ReservedFutureUse { get; set; }
internal byte ReservedFutureUse { get; set; } = 0x3F;
/// <summary>
/// EIT 时间表标志
/// 置“1”时,表示业务的 EIT 时间表信息存在于当前 TS 中(一个 EIT 时间表子表两次出现的最大时间间隔信息见 ETR 211)。
/// 置“0”时,表示业务的 EIT 时间表信息不在当前 TS 中
/// 1bit
/// </summary>
internal byte EITScheduleFlag { get; set; }
internal byte EITScheduleFlag { get; set; } = 0x00;
/// <summary>
/// EIT 当前后续标志
/// 置“1”时,表示业务的 EIT 当前后续信息存在于当前 TS 中(一个 EIT 当前后续子表两次出现的最大时间间隔信息见ETR 211)
/// 置“0”时,表示业务的 EIT 当前后续信息不在当前 TS 中。
/// 1bit
/// </summary>
public byte EITPresentFollowingFlag { get; set; }
public byte EITPresentFollowingFlag { get; set; } = 0x00;
/// <summary>
/// 运行状态
/// 对于一个 NVOD 业务,running_status 的值都置“0”
/// 3bit
/// </summary>
internal RunningStatus RunningStatus { get; set; }
internal TS_SDT_Service_RunningStatus RunningStatus { get; set; }
/// <summary>
/// 自由条件接收模式
/// 置“0”时,表示业务的所有组件都未被加扰
/// 置“1”时,表示一路或多路码流的接收由 CA 系统控制。
/// 1bit
/// </summary>
internal byte FreeCAMode { get; set; }
internal byte FreeCAMode { get; set; } = 0x00;
/// <summary>
/// 描述符循环长度
/// 指出从本字段的下一个字节开始的描述符的总字节长度。
@@ -69,7 +70,7 @@ namespace JT1078.Hls
{
descriptor.ToBuffer(ref writer);
}
DescriptorsLoopLength = (ushort)(writer.GetCurrentPosition() - position);
DescriptorsLoopLength = (ushort)(writer.GetCurrentPosition() - position-2);
writer.WriteUInt16Return((ushort)((ushort)RunningStatus << 13 | (ushort)FreeCAMode << 12 | DescriptorsLoopLength), position);
}
}


Načítá se…
Zrušit
Uložit