/// <summary> /// 生成ts和m3u8文件 /// </summary> /// <param name="jt1078Package"></param> public void CreateTsData(JT1078Package jt1078Package) { string key = jt1078Package.GetKey(); string hlsFileDirectory = m3U8Option.HlsFileDirectory; string m3u8FileName = Path.Combine(hlsFileDirectory, key, m3U8Option.M3U8FileName); if (!File.Exists(m3u8FileName)) { File.Create(m3u8FileName); //创建m3u8文件 } var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 1024); TSMessagePackWriter tSMessagePackWriter = new TSMessagePackWriter(buff); try { var curTsFileInfo = CreateTsFileInfo(key); if (!curTsFileInfo.IsCreateTsFile) { var pes = tSEncoder.CreatePES(jt1078Package); tSMessagePackWriter.WriteArray(pes); CreateTsFile(curTsFileInfo.FileName, key, tSMessagePackWriter.FlushAndGetArray()); curTsFileInfo.Duration = (jt1078Package.Timestamp - curTsFileInfo.TsFirst1078PackageTimeStamp) / 1000.0; //按设定的时间(默认为10秒)切分ts文件 if (curTsFileInfo.Duration > m3U8Option.TsFileMaxSecond) { var tsFileInfoQueue = ManageTsFileInfo(key, curTsFileInfo); CreateM3U8File(curTsFileInfo, tsFileInfoQueue); var newTsFileInfo = new TsFileInfo { IsCreateTsFile = true, Duration = 0, TsFileSerialNo = ++curTsFileInfo.TsFileSerialNo }; curTsFileInfoDic.TryUpdate(key, newTsFileInfo, curTsFileInfo); } } else { curTsFileInfo.IsCreateTsFile = false; curTsFileInfo.TsFirst1078PackageTimeStamp = jt1078Package.Timestamp; curTsFileInfo.FileName = $"{curTsFileInfo.TsFileSerialNo}.ts"; var sdt = tSEncoder.CreateSDT(jt1078Package); tSMessagePackWriter.WriteArray(sdt); var pat = tSEncoder.CreatePAT(jt1078Package); tSMessagePackWriter.WriteArray(pat); var pmt = tSEncoder.CreatePMT(jt1078Package); tSMessagePackWriter.WriteArray(pmt); var pes = tSEncoder.CreatePES(jt1078Package); tSMessagePackWriter.WriteArray(pes); CreateTsFile(curTsFileInfo.FileName, key, tSMessagePackWriter.FlushAndGetArray()); } } finally { TSArrayPool.Return(buff); } }
public byte[] CreatePMT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PMT_Package package = new TS_PMT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = 0; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 4096; package.TableId = 0x02; package.Components = new List <TS_PMT_Component>(); package.Components.Add(new TS_PMT_Component { StreamType = StreamType.h264, ElementaryPID = 256, ESInfoLength = 0 }); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public byte[] CreatePAT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PAT_Package package = new TS_PAT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = 0; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 0; package.Programs = new List <TS_PAT_Program>(); package.Programs.Add(new TS_PAT_Program() { ProgramNumber = 0x0001, PID = 0x1000, }); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>(); public byte[] CreatePAT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PAT_Package package = new TS_PAT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = PATCounter.AddOrUpdate(jt1078Package.GetKey(), 0, (a, b) => { if (b > 0xf) { return(0); } else { return((byte)(b + 1)); } }); package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 0; TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public void ToBufferTest1() { //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 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 //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 TS_Package package = new TS_Package(); package.Header = new TS_Header(); package.Header.PID = 0x100; package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; package.Header.ContinuityCounter = 0; package.Header.PackageType = PackageType.Data_Start; package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Header.Adaptation.Timestamp = 18900000; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload = new PES_Package(); package.Payload.PTS = 132171; package.Payload.DTS = 126000; package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; package.Payload.Payload = new ES_Package(); package.Payload.Payload.NALUs = new List <byte[]>(); package.Payload.Payload.NALUs.Add("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".ToHexBytes()); TSMessagePackWriter writer = new TSMessagePackWriter(new byte[188]); package.ToBuffer(ref writer); var patData = writer.FlushAndGetArray().ToHexString(); }
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>(); public byte[] CreateSDT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { 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 <TS_SDT_Service_Descriptor> { new TS_SDT_Service_Descriptor { Tag = 0x48, ServiceType = TS_SDT_Service_Descriptor_ServiceType.数字电视业务, ServiceProvider = ServiceProvider, ServiceName = ServiceName } } }); TSMessagePackWriter writer = new TSMessagePackWriter(buffer); package.ToBuffer(ref writer); return(writer.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
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 { Tag = 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); }
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); }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //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 (counter > 0xf) { counter = 0; } } else { VideoCounter.Add(key, counter); } package.Header.ContinuityCounter = counter; 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+ 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; long timestamp = (long)jt1078Package.Timestamp; if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧) { //ts header adaptation //PCRIncluded + Timestamp //1 + 6 totalLength += (1 + 6); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.Timestamp = timestamp; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastIFrameInterval * H264DefaultHZ; } else if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastFrameInterval * H264DefaultHZ; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 = 12 totalLength += 12; totalLength += TSConstants.FiexdESPackageHeaderLength; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter); index += FiexdSegmentPESLength; } else { var nalu = dataReader.Slice(index, segmentFullSize).ToArray(); //当等于183字节的时候 //12698D08E8DBDBCDF6C6FA19DD88490E908D687D1755BE87DF82754BE2D245270569310B3030A4904DF1883ED09A68CA1C79BC4B97642B5BC095A55E56868D05370D3BC8B7B60B4642A486B6852656C01FFADACEF4BD4320E8BE9C54D44177A433CC37493FA1D8ACD0164E92454D03B6EC0617B133AEF43B599BF85632AB9B5FF671F0DDAA07E8F279F5639BA88E3FFFFCE1D3351FAF43DF23BCEB7E3B2CAB3EABAED23B25097B7F51FF38E8D0EBAB589CEC42B0440EB8 //if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) //{ // string hex = dataReader.Slice(index, segmentFullSize).ToArray().ToHexString(); //} CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter); index += segmentFullSize; } counter++; } } VideoCounter[key] = counter; return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //ts header 4 totalLength += 4; package.Header.PID = 256; string key = jt1078Package.GetKey(); if (VideoCounter.TryGetValue(key, out byte counter)) { if (counter > 0xf) { counter = 0; } package.Header.ContinuityCounter = counter++; VideoCounter.TryUpdate(key, counter, counter); } else { package.Header.ContinuityCounter = counter++; VideoCounter.TryAdd(key, 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); 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); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.PCR = jt1078Package.LastIFrameInterval; package.Payload.DTS = jt1078Package.LastIFrameInterval; package.Payload.PTS = jt1078Package.LastIFrameInterval; } else { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = jt1078Package.LastFrameInterval; package.Payload.PTS = jt1078Package.LastFrameInterval; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 totalLength += 12; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter++); } else { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter++); index += segmentFullSize; } } VideoCounter.TryUpdate(key, counter, counter); } return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
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); }