Browse Source

1.增加es包编码

2.增加PMT描述信息
3.增加PAT和PMT的编码测试
tags/v1.1.0
SmallChi(Koike) 5 years ago
parent
commit
ed6dea8508
21 changed files with 332 additions and 100 deletions
  1. BIN
      doc/video/demo.264
  2. +6
    -0
      src/JT1078.Hls.Test/JT1078.Hls.Test.csproj
  3. +53
    -0
      src/JT1078.Hls.Test/TS_PAT_Package_Test.cs
  4. +80
    -0
      src/JT1078.Hls.Test/TS_PMT_Package_Test.cs
  5. +31
    -0
      src/JT1078.Hls.Test/TS_Package_Test.cs
  6. +0
    -55
      src/JT1078.Hls.Test/UnitTest1.cs
  7. BIN
      src/JT1078.Hls.Test/file/demo.264
  8. +15
    -0
      src/JT1078.Hls/Descriptors/DescriptorBase.cs
  9. +49
    -0
      src/JT1078.Hls/Descriptors/ISO_639_Language_Descriptor.cs
  10. +2
    -4
      src/JT1078.Hls/ES_Package.cs
  11. +5
    -5
      src/JT1078.Hls/Enums/AdaptationFieldControl.cs
  12. +1
    -0
      src/JT1078.Hls/Enums/PCRInclude.cs
  13. +5
    -1
      src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
  14. +15
    -0
      src/JT1078.Hls/TSConstants.cs
  15. +9
    -1
      src/JT1078.Hls/TS_AdaptationInfo.cs
  16. +3
    -3
      src/JT1078.Hls/TS_Header.cs
  17. +13
    -7
      src/JT1078.Hls/TS_PAT_Package.cs
  18. +2
    -2
      src/JT1078.Hls/TS_PAT_Program.cs
  19. +17
    -6
      src/JT1078.Hls/TS_PMT_Component.cs
  20. +16
    -10
      src/JT1078.Hls/TS_PMT_Package.cs
  21. +10
    -6
      src/JT1078.Hls/TS_Package.cs

BIN
doc/video/demo.264 View File


+ 6
- 0
src/JT1078.Hls.Test/JT1078.Hls.Test.csproj View File

@@ -17,4 +17,10 @@
<ProjectReference Include="..\JT1078.Hls\JT1078.Hls.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="file\demo.264">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 53
- 0
src/JT1078.Hls.Test/TS_PAT_Package_Test.cs View File

@@ -0,0 +1,53 @@
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>
/// 使用demo0.ts
/// </summary>
public class TS_PAT_Package_Test
{
[Fact]
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);
}
}
}

+ 80
- 0
src/JT1078.Hls.Test/TS_PMT_Package_Test.cs View File

@@ -0,0 +1,80 @@
using JT1078.Hls.Descriptors;
using JT1078.Hls.Enums;
using JT1078.Hls.MessagePack;
using JT1078.Protocol.Extensions;
using System;
using System.Collections.Generic;
using Xunit;
using System.Buffers.Binary;

namespace JT1078.Hls.Test
{
/// <summary>
/// 使用demo0.ts
/// </summary>
public class TS_PMT_Package_Test
{
[Fact]
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);
}
}
}

+ 31
- 0
src/JT1078.Hls.Test/TS_Package_Test.cs View File

@@ -0,0 +1,31 @@
using JT1078.Hls.Descriptors;
using JT1078.Hls.Enums;
using JT1078.Hls.MessagePack;
using JT1078.Protocol.Extensions;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using Xunit;

namespace JT1078.Hls.Test
{
/// <summary>
/// 使用demo0.ts
/// </summary>
public class TS_Package_Test
{
[Fact]
public void ToBufferTest()
{
TS_Package package = new TS_Package();
package.Header = new TS_Header();
package.Header.PID = 4096;
package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载;
package.Header.PayloadUnitStartIndicator = 1;
package.Header.ContinuityCounter = 0;
TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]);
package.ToBuffer(ref writer);
var psData = writer.FlushAndGetArray().ToHexString();
}
}
}

+ 0
- 55
src/JT1078.Hls.Test/UnitTest1.cs View File

@@ -1,55 +0,0 @@
using System;
using Xunit;

namespace JT1078.Hls.Test
{
public class UnitTest1
{
[Fact]
public void Test1()
{

}
//---------PMT
//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

//----------PAT
//47 40 00 10 00 00 B0 0D 00 01 C1 00 00 00 01 F0 00 2A B1 04 B2
//47
//40 00
//10
//00
//00
//B0 0D
//00 01
//C1
//00
//00
//00 01
//F0 00
//2A B1 04 B2
}
}

BIN
src/JT1078.Hls.Test/file/demo.264 View File


+ 15
- 0
src/JT1078.Hls/Descriptors/DescriptorBase.cs View File

@@ -0,0 +1,15 @@
using JT1078.Hls.Formatters;
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Hls.Descriptors
{
public abstract class DescriptorBase : ITSMessagePackFormatter
{
public abstract byte Tag { get; set; }
public abstract byte Length { get; set; }
public abstract void ToBuffer(ref TSMessagePackWriter writer);
}
}

+ 49
- 0
src/JT1078.Hls/Descriptors/ISO_639_Language_Descriptor.cs View File

@@ -0,0 +1,49 @@
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Hls.Descriptors
{
/// <summary>
/// 2.6.18 ISO 639 language descripto
/// </summary>
public class ISO_639_Language_Descriptor : DescriptorBase
{
public override byte Tag { get; set; } = 0x0A;
public override byte Length { get; set; }

public List<ISO_639_Language_Info> ISO_639_Language_Infos { get; set; }

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);
}
}

public class ISO_639_Language_Info
{
/// <summary>
/// 24bit
/// </summary>
public uint ISO_639_Language_Code { get; set; }
/// <summary>
/// 8bit
/// </summary>
public byte Audio_Type { get; set; }
}
}
}

+ 2
- 4
src/JT1078.Hls/ES_Package.cs View File

@@ -1,6 +1,5 @@
using JT1078.Hls.Formatters;
using JT1078.Hls.MessagePack;
using JT1078.Protocol.H264;
using System;
using System.Collections.Generic;
using System.Text;
@@ -11,7 +10,7 @@ namespace JT1078.Hls
{
public static byte[] NALU0X09 = new byte[] { 0x00, 0x00, 0x00, 0x01, 0x09, 0xFF };
public byte[] NALU0x09 { get; set; } = NALU0X09;
public List<H264NALU> NALUs { get; set; }
public List<byte[]> NALUs { get; set; }
public void ToBuffer(ref TSMessagePackWriter writer)
{
writer.WriteArray(NALU0x09);
@@ -19,8 +18,7 @@ namespace JT1078.Hls
{
foreach(var nalu in NALUs)
{
writer.WriteArray(nalu.StartCodePrefix);
writer.WriteArray(nalu.RawData);
writer.WriteArray(nalu);
}
}
}


+ 5
- 5
src/JT1078.Hls/Enums/AdaptationFieldControl.cs View File

@@ -4,11 +4,11 @@ using System.Text;

namespace JT1078.Hls.Enums
{
public enum AdaptationFieldControl
public enum AdaptationFieldControl:byte
{
保留= 0000_0000,
无自适应域_仅含有效负载 = 0001_0000,
仅含自适应域_无有效负载 = 0010_0000,
同时带有自适应域和有效负载 = 0011_0000,
保留= 0b_0000_0000,
无自适应域_仅含有效负载 = 0b_0001_0000,
仅含自适应域_无有效负载 = 0b_0010_0000,
同时带有自适应域和有效负载 = 0b_0011_0000,
}
}

+ 1
- 0
src/JT1078.Hls/Enums/PCRInclude.cs View File

@@ -6,6 +6,7 @@ namespace JT1078.Hls.Enums
{
/// <summary>
/// 取0x50表示包含PCR或0x40表示不包含PCR
/// 注意:关键帧需要加pcr
/// </summary>
public enum PCRInclude:byte
{


+ 5
- 1
src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Buffers.Binary;

namespace JT1078.Hls.MessagePack
@@ -127,9 +129,11 @@ namespace JT1078.Hls.MessagePack
}
var crcSpan = writer.Written.Slice(start);
uint crc = 0xFFFFFFFF;
byte j = 0;
for (int i = 0; i < crcSpan.Length; i++)
{
crc = (crc << 8) ^ Util.crcTable[(crc >> 24) ^ crcSpan[i]];
j = (byte)(((crc >> 24) ^ crcSpan[i]) & 0xff);
crc = (crc << 8) ^ Util.crcTable[j];
}
WriteUInt32(crc);
}


+ 15
- 0
src/JT1078.Hls/TSConstants.cs View File

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

namespace JT1078.Hls
{
public static class TSConstants
{
/// <summary>
/// 固定包长度
/// </summary>
public const int FiexdPackageLength = 188;
}
}

+ 9
- 1
src/JT1078.Hls/TS_AdaptationInfo.cs View File

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

namespace JT1078.Hls
@@ -19,7 +20,10 @@ namespace JT1078.Hls
/// 5B
/// </summary>
public long PCR { get; set; }

/// <summary>
/// 填充字节大小
/// </summary>
public byte FillSize { get; set; }
public void ToBuffer(ref TSMessagePackWriter writer)
{
writer.WriteByte((byte)PCRIncluded);
@@ -27,6 +31,10 @@ namespace JT1078.Hls
{
writer.WriteInt5(PCR);
}
if (FillSize > 0)
{
writer.WriteArray(Enumerable.Range(0, FillSize).Select(s => (byte)0xFF).ToArray());
}
}
}
}

+ 3
- 3
src/JT1078.Hls/TS_Header.cs View File

@@ -34,7 +34,7 @@ namespace JT1078.Hls
/// </summary>
public ushort PID { get; set; }
/// <summary>
/// 传输优先级,0为低优先级,1为高优先级,通常取0
/// 传输加扰控制
/// 2bit
/// </summary>
internal byte TransportScramblingControl { get; set; } = 0;
@@ -62,8 +62,8 @@ namespace JT1078.Hls
writer.WriteByte(SyncByte);
//TransportErrorIndicator PayloadUnitStartIndicator TransportPriority PID
//0 1 0 0000 0000 0000 0
writer.WriteUInt16((ushort)(0100_0000_0000_0000 | PID));
writer.WriteByte((byte)((int)AdaptationFieldControl | ContinuityCounter));
writer.WriteUInt16((ushort)(0b_0100_0000_0000_0000 | PID));
writer.WriteByte((byte)((byte)AdaptationFieldControl | ContinuityCounter));
if (Adaptation != null)
{
writer.Skip(1, out int AdaptationLengthPosition);


+ 13
- 7
src/JT1078.Hls/TS_PAT_Package.cs View File

@@ -2,6 +2,7 @@
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JT1078.Hls
@@ -11,6 +12,7 @@ namespace JT1078.Hls
/// </summary>
public class TS_PAT_Package : ITSMessagePackFormatter
{
public TS_Header Header { get; set; }
/// <summary>
/// PAT表固定为0x00
/// 8bit
@@ -76,18 +78,17 @@ namespace JT1078.Hls

public void ToBuffer(ref TSMessagePackWriter writer)
{
Header.ToBuffer(ref writer);
writer.WriteByte(TableId);
//SectionSyntaxIndicator Zero Reserved1 SectionLength
//1 0 11 0000 0000 0000
//(ushort)(1011_0000_0000_0000 | SectionLength)
// todo:
//writer.WriteUInt16((ushort)(1011_0000_0000_0000 | SectionLength));
//(ushort)(0b_1011_0000_0000_0000 | SectionLength)
writer.Skip(2, out int SectionLengthPosition);
writer.WriteUInt16(TransportStreamId);
//Reserved2 VersionNumber CurrentNextIndicator
//11 00000 1
var a = Reserved2 & 0xC0;
var b = VersionNumber & 0x3E;
var a = 0xC0 & (Reserved2 << 6);
var b = 0x3E & (VersionNumber << 3);
var c = (byte)(a | b | CurrentNextIndicator);
writer.WriteByte(c);
writer.WriteByte(SectionNumber);
@@ -99,8 +100,13 @@ namespace JT1078.Hls
program.ToBuffer(ref writer);
}
}
writer.WriteUInt16Return((ushort)(1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2)), SectionLengthPosition);
writer.WriteCRC32(SectionLengthPosition);
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());
}
}
}

+ 2
- 2
src/JT1078.Hls/TS_PAT_Program.cs View File

@@ -15,7 +15,7 @@ namespace JT1078.Hls
public ushort ProgramNumber { get; set; }
/// <summary>
/// 固定为二进制111(7)
/// 1110_0000_0000_0000
/// 0b_1110_0000_0000_0000
/// 3bit
/// </summary>
internal byte Reserved1 { get; set; } = 0x07;
@@ -28,7 +28,7 @@ namespace JT1078.Hls
public void ToBuffer(ref TSMessagePackWriter writer)
{
writer.WriteUInt16(ProgramNumber);
writer.WriteUInt16((ushort)(1110_0000_0000_0000 | PID));
writer.WriteUInt16((ushort)(0b_1110_0000_0000_0000 | PID));
}
}
}

+ 17
- 6
src/JT1078.Hls/TS_PMT_Component.cs View File

@@ -1,4 +1,5 @@
using JT1078.Hls.Enums;
using JT1078.Hls.Descriptors;
using JT1078.Hls.Enums;
using JT1078.Hls.Formatters;
using JT1078.Hls.MessagePack;
using System;
@@ -16,7 +17,7 @@ namespace JT1078.Hls
public StreamType StreamType { get; set; }
/// <summary>
/// 固定为二进制111(7)
/// 0111_0000_0000_0000
/// 0b_1110_0000_0000_0000
/// 3bit
/// </summary>
internal byte Reserved1 { get; set; } = 0x07;
@@ -27,7 +28,7 @@ namespace JT1078.Hls
public ushort ElementaryPID { get; set; }
/// <summary>
/// 固定为二进制1111(15)
/// 1111_0000_0000_0000
/// 0b_1111_0000_0000_0000
/// 4bit
/// </summary>
internal byte Reserved2 { get; set; } = 0x0F;
@@ -36,12 +37,22 @@ namespace JT1078.Hls
/// 12bit
/// </summary>
internal ushort ESInfoLength { get; set; } = 0x000;
public DescriptorBase Descriptor { get; set; }
public void ToBuffer(ref TSMessagePackWriter writer)
{
writer.WriteByte((byte)StreamType);
writer.WriteUInt16((ushort)(0111_0000_0000_0000| ElementaryPID));
writer.WriteUInt16((ushort)(1111_0000_0000_0000| ESInfoLength));
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);
}
}
}
}

+ 16
- 10
src/JT1078.Hls/TS_PMT_Package.cs View File

@@ -2,6 +2,7 @@
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JT1078.Hls
@@ -11,6 +12,7 @@ namespace JT1078.Hls
/// </summary>
public class TS_PMT_Package : ITSMessagePackFormatter
{
public TS_Header Header { get; set; }
/// <summary>
/// PMT表取值随意
/// 8bit
@@ -93,28 +95,27 @@ namespace JT1078.Hls
public uint CRC32 { get; set; }
public void ToBuffer(ref TSMessagePackWriter writer)
{
Header.ToBuffer(ref writer);
writer.WriteByte(TableId);
//SectionSyntaxIndicator Zero Reserved1 SectionLength
//1 0 11 0000 0000 0000
//(ushort)(1011_0000_0000_0000 | SectionLength)
// todo:
//writer.WriteUInt16((ushort)(1011_0000_0000_0000 | SectionLength));
//(ushort)(0b_1011_0000_0000_0000 | SectionLength)
writer.Skip(2, out int SectionLengthPosition);
writer.WriteUInt16(ProgramNumber);
//Reserved2 VersionNumber CurrentNextIndicator
//11 00000 1
var a = Reserved2 & 0xC0;
var b = VersionNumber & 0x3E;
var c=(byte)(a | b | CurrentNextIndicator);
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);
//Reserved3 PCR_PID
//111 0000 0000 0000 0
writer.WriteUInt16((ushort)(0111_0000_0000_0000 | PCR_PID));
writer.WriteUInt16((ushort)(0b_1110_0000_0000_0000 | PCR_PID));
//Reserved4 ProgramInfoLength
//1111 0000 0000 0000
writer.WriteUInt16((ushort)(1111_0000_0000_0000 | ProgramInfoLength));
writer.WriteUInt16((ushort)(0b_1111_0000_0000_0000 | ProgramInfoLength));
if (Components != null)
{
foreach(var component in Components)
@@ -122,8 +123,13 @@ namespace JT1078.Hls
component.ToBuffer(ref writer);
}
}
writer.WriteUInt16Return((ushort)(1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2)), SectionLengthPosition);
writer.WriteCRC32(SectionLengthPosition);
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());
}
}
}

+ 10
- 6
src/JT1078.Hls/TS_Package.cs View File

@@ -1,17 +1,21 @@
using JT1078.Protocol.H264;
using JT1078.Hls.Formatters;
using JT1078.Hls.MessagePack;
using JT1078.Protocol.H264;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Hls
{
public class TS_Package
public class TS_Package : ITSMessagePackFormatter
{
public TS_Header Header { get; set; }
public PES_Package Payload { get; set; }
/// <summary>
/// 填充字节,取值0xff
/// </summary>
public byte[] Fill { get; set; }

public void ToBuffer(ref TSMessagePackWriter writer)
{
Header.ToBuffer(ref writer);
Payload.ToBuffer(ref writer);
}
}
}

Loading…
Cancel
Save