瀏覽代碼

1.修改负载单元

2.递增计数器待完善
tags/v1.1.0
SmallChi(Koike) 5 年之前
父節點
當前提交
b6a922b787
共有 6 個檔案被更改,包括 82 行新增45 行删除
  1. +13
    -6
      src/JT1078.Hls.Test/TS_Package_Test.cs
  2. +0
    -9
      src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
  3. +4
    -0
      src/JT1078.Hls/TSConstants.cs
  4. +46
    -24
      src/JT1078.Hls/TSEncoder.cs
  5. +17
    -5
      src/JT1078.Hls/TS_AdaptationInfo.cs
  6. +2
    -1
      src/JT1078.Hls/TS_Header.cs

+ 13
- 6
src/JT1078.Hls.Test/TS_Package_Test.cs 查看文件

@@ -24,7 +24,7 @@ namespace JT1078.Hls.Test
//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 90 32 10 7E 00 00 00 01 E0 00 00 80 C0 0A 00 00 02 04 4B 00 00 01EC300000000109FF000000016764001FACD940881E6840000003018000005783C60C65800000000168EBE3CB22C00000010605FFFFABDC45E9BDE6D948B7962CD820D923EEEF78323634202D20636F7265203135382072323938342033373539666362202D20482E3236342F4D5045472D342041564320636F646563202D20436F70796C65667420323030332D32303139202D20687474703A2F2F7777772E
//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
@@ -54,7 +54,7 @@ namespace JT1078.Hls.Test
package.Header.PackageType = PackageType.Data_Start;
package.Header.PayloadUnitStartIndicator = 1;
package.Header.Adaptation = new TS_AdaptationInfo();
package.Header.Adaptation.PCR = 18900000;
package.Header.Adaptation.Timestamp = 18900000;
package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
package.Payload = new PES_Package();
package.Payload.PTS = 132171;
@@ -133,14 +133,21 @@ namespace JT1078.Hls.Test
{
if (isNeedFirstHeadler)
{
fileStream.Write(tSEncoder.CreatePAT(fullpackage));
fileStream.Write(tSEncoder.CreatePMT(fullpackage));
fileStream.Write(tSEncoder.CreatePES(fullpackage,1888));
var sdt = tSEncoder.CreateSDT(fullpackage);
string sdtHEX = sdt.ToHexString();
fileStream.Write(sdt);
var pat = tSEncoder.CreatePAT(fullpackage);
string patHEX = pat.ToHexString();
fileStream.Write(pat);
var pmt = tSEncoder.CreatePMT(fullpackage);
fileStream.Write(pmt);
var pes = tSEncoder.CreatePES(fullpackage, 18888);
fileStream.Write(pes);
isNeedFirstHeadler = false;
}
else
{
fileStream.Write(tSEncoder.CreatePES(fullpackage, 1888));
fileStream.Write(tSEncoder.CreatePES(fullpackage, 18888));
}
}
}


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

@@ -65,15 +65,6 @@ namespace JT1078.Hls.MessagePack
writer.Free[4] = (byte)(value);
writer.Advance(5);
}
public void WritePCR(long value)
{
writer.Free[0] = (byte)(value >> 25);
writer.Free[1] = (byte)((value >> 17) & 0xff);
writer.Free[2] = (byte)((value >> 9) & 0xff);
writer.Free[3] = (byte)((value >> 1) & 0xff);
writer.Free[4] = (byte)(((value & 0x1) << 7) | 0x7e);
writer.Advance(5);
}
public void WriteInt6(long value)
{
writer.Free[0] = (byte)(value >> 40);


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

@@ -16,6 +16,10 @@ namespace JT1078.Hls
/// 固定包长度
/// </summary>
public const int FiexdPackageLength = 188;
/// <summary>
/// 固定ES包头的长度
/// </summary>
public const int FiexdESPackageHeaderLength = 6;
}
}

+ 46
- 24
src/JT1078.Hls/TSEncoder.cs 查看文件

@@ -26,8 +26,12 @@ namespace JT1078.Hls
private const int FiexdSegmentPESLength = 184;
private const int FiexdTSLength = 188;
private const string ServiceProvider = "JTT1078";
private const string ServiceName = "Koike&TK";
private ConcurrentDictionary<string, byte> VideoCounter = new ConcurrentDictionary<string, byte>();
private const string ServiceName = "Koike&TK";
public TSEncoder()
{
VideoCounter = new ConcurrentDictionary<string, byte>(StringComparer.OrdinalIgnoreCase);
}
private ConcurrentDictionary<string, byte> VideoCounter;
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>();
public byte[] CreateSDT(JT1078Package jt1078Package, int minBufferSize = 188)
{
@@ -143,38 +147,41 @@ namespace JT1078.Hls
//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 (jt1078Package.Label3.DataType == JT1078DataType.视频P帧)
//{

//}
byte counter = VideoCounter.AddOrUpdate(key, 0, (a, b) =>
{
if (counter > 0xf)
if (b > 0xf)
{
counter = 0;
return 0;
}
package.Header.ContinuityCounter = counter++;
VideoCounter.TryUpdate(key, counter, counter);
}
else
{
package.Header.ContinuityCounter = counter++;
VideoCounter.TryAdd(key, counter);
}
else
{
return b;
}
});
package.Header.ContinuityCounter = 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);
//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;
if (jt1078Package.Label3.DataType== JT1078DataType.视频I帧)
{
//ts header adaptation
//PCRIncluded + PCR
//1 + 5
totalLength += (1 + 5);
//PCRIncluded + Timestamp
//1 + 6
totalLength += (1 + 6);
package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
package.Header.Adaptation.PCR = (long)jt1078Package.Timestamp;
package.Header.Adaptation.Timestamp = (long)jt1078Package.Timestamp;
package.Payload.DTS = jt1078Package.LastIFrameInterval;
package.Payload.PTS = jt1078Package.LastIFrameInterval;
}
@@ -189,8 +196,9 @@ namespace JT1078.Hls
package.Payload.PTS = jt1078Package.LastFrameInterval;
}
//Flag1 + PTS_DTS_Flag + DTS + PTS
//1 + 1 + 5 + 5
//1 + 1 + 5 + 5 = 12
totalLength += 12;
totalLength += TSConstants.FiexdESPackageHeaderLength;
//根据计算剩余的长度进行是否需要填充第一包
var remainingLength = FiexdTSLength - totalLength;
int index = 0;
@@ -202,6 +210,7 @@ namespace JT1078.Hls
package.Payload.Payload = new ES_Package();
if (fullSize < 0)
{
counter++;
//这个很重要,需要控制
package.Header.AdaptationFieldControl = AdaptationFieldControl.同时带有自适应域和有效负载;
//还差一点
@@ -212,6 +221,7 @@ namespace JT1078.Hls
}
else if(fullSize==0)
{
counter++;
//这个很重要,需要控制
package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载;
//刚刚好
@@ -230,7 +240,7 @@ namespace JT1078.Hls
package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray());
index += remainingLength;
package.ToBuffer(ref messagePackReader);
while(index!= jt1078Package.Bodies.Length)
while (index!= jt1078Package.Bodies.Length)
{
if (counter > 0xf)
{
@@ -248,8 +258,18 @@ namespace JT1078.Hls
index += segmentFullSize;
}
}
VideoCounter.TryUpdate(key, counter, counter);
}
VideoCounter.AddOrUpdate(key, counter, (a, b) =>
{
if (b > 0xf)
{
return 0;
}
else
{
return b;
}
});
return messagePackReader.FlushAndGetArray();
}
finally
@@ -274,7 +294,9 @@ namespace JT1078.Hls
package.Header.PackageType = PackageType.Data_End;
package.Header.Adaptation = new TS_AdaptationInfo();
package.Header.Adaptation.PCRIncluded = PCRInclude.不包含;
package.Header.Adaptation.FillSize = (byte)(FiexdSegmentPESLength - nalu.Length);
//AdaptationLengthPosition + PCRIncluded
//1 + 1
package.Header.Adaptation.FillSize = (byte)(FiexdSegmentPESLength - 1 - 1 - nalu.Length);
package.Header.AdaptationFieldControl = AdaptationFieldControl.同时带有自适应域和有效负载;
}
else


+ 17
- 5
src/JT1078.Hls/TS_AdaptationInfo.cs 查看文件

@@ -16,11 +16,12 @@ namespace JT1078.Hls
/// </summary>
public PCRInclude PCRIncluded { get; set; }
/// <summary>
/// JT1078时间戳
/// 第一包的数据、关键帧
/// Program Clock Reference,节目时钟参考,用于恢复出与编码端一致的系统时序时钟STC(System Time Clock)
/// 5B
/// </summary>
public long PCR { get; set; }
public long Timestamp { get; set; }
/// <summary>
/// 填充字节大小
/// </summary>
@@ -28,16 +29,27 @@ namespace JT1078.Hls
public void ToBuffer(ref TSMessagePackWriter writer)
{
writer.WriteByte((byte)PCRIncluded);
if (PCRIncluded== PCRInclude.包含)
if (PCRIncluded == PCRInclude.包含)
{
writer.WritePCR(PCR);
#warning PCR 0????
writer.WriteByte(0);
writer.WriteInt6(ToPCR());
}
if (FillSize > 0)
{
writer.WriteArray(Enumerable.Range(0, FillSize).Select(s => (byte)0xFF).ToArray());
}
}

/// <summary>
/// if(PCR_flag == '1'){
/// program_clock_reference_base 33 uimsbf
/// Reserved 6 bslbf
/// program_clock_reference_extension 9 uimsbf
/// }
/// </summary>
/// <returns></returns>
private long ToPCR()
{
return (Timestamp / 300 << 15 | 0x7E00);
}
}
}

+ 2
- 1
src/JT1078.Hls/TS_Header.cs 查看文件

@@ -64,7 +64,8 @@ namespace JT1078.Hls
writer.WriteByte(SyncByte);
//TransportErrorIndicator PayloadUnitStartIndicator TransportPriority PID
//0 1 0 0000 0000 0000 0
writer.WriteUInt16((ushort)(0b_0100_0000_0000_0000 | PID));
//writer.WriteUInt16((ushort)((0b_0100_0000_0000_0000 & (PayloadUnitStartIndicator<<14)) | PID));
writer.WriteUInt16((ushort)((PayloadUnitStartIndicator<<14) | PID));
writer.WriteByte((byte)((byte)AdaptationFieldControl | ContinuityCounter));
if(PackageType== PackageType.PAT ||
PackageType == PackageType.PMT ||


Loading…
取消
儲存