96 lines
2.4 KiB
C#
96 lines
2.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using skyscraper5.Mpeg2.Descriptors;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.T2MI;
|
|
using skyscraper8.GSE;
|
|
using skyscraper8.Skyscraper.Scraper;
|
|
|
|
namespace skyscraper8.GS.SiminnRadiomidun
|
|
{
|
|
internal class SiminnRadiomidunReader : IMisHandler
|
|
{
|
|
public SiminnRadiomidunReader(GsContextDto context)
|
|
{
|
|
this.packetQueue = new Queue<Tuple<BBHeader,MemoryStream>>();
|
|
this.isInSync = false;
|
|
this.subTsKey = new SiminnRadiomidunSubTsIdentifier(context.GetMisId());
|
|
this.Context = context;
|
|
}
|
|
|
|
private bool isInSync;
|
|
private Queue<Tuple<BBHeader, MemoryStream>> packetQueue;
|
|
private MemoryStream currentItem;
|
|
private SiminnRadiomidunSubTsIdentifier subTsKey;
|
|
|
|
public long PacketQueueSize
|
|
{
|
|
get
|
|
{
|
|
if (packetQueue == null)
|
|
return 0;
|
|
|
|
return packetQueue.Select(x => x.Item2.Length).Sum();
|
|
}
|
|
}
|
|
|
|
public GsContextDto Context { get; set; }
|
|
|
|
public void PushFrame(BBHeader bbHeader, ReadOnlySpan<byte> readOnlySpan)
|
|
{
|
|
if (packetQueue == null)
|
|
packetQueue = new Queue<Tuple<BBHeader, MemoryStream>>();
|
|
|
|
packetQueue.Enqueue(new Tuple<BBHeader, MemoryStream>(bbHeader,new MemoryStream(readOnlySpan.Slice(0,bbHeader.DataFieldLength).ToArray(), true)));
|
|
|
|
while (PacketQueueSize > 8192)
|
|
{
|
|
if (!isInSync)
|
|
{
|
|
Tuple<BBHeader, MemoryStream> dequeue = packetQueue.Dequeue();
|
|
currentItem = dequeue.Item2;
|
|
currentItem.Position = dequeue.Item1.SyncD;
|
|
isInSync = true;
|
|
}
|
|
|
|
byte[] outputPacketBuffer = new byte[188];
|
|
int result = currentItem.Read(outputPacketBuffer, 0, 188);
|
|
if (result == 188)
|
|
{
|
|
OutputPacket(outputPacketBuffer);
|
|
}
|
|
else
|
|
{
|
|
int bytesNeeded = 188 - result;
|
|
Tuple<BBHeader, MemoryStream> dequeue = packetQueue.Dequeue();
|
|
if (bytesNeeded == dequeue.Item1.SyncD)
|
|
{
|
|
//We're still in sync!
|
|
syncSucess++;
|
|
currentItem = dequeue.Item2;
|
|
currentItem.Read(outputPacketBuffer, result, bytesNeeded);
|
|
OutputPacket(outputPacketBuffer);
|
|
}
|
|
else
|
|
{
|
|
//sync loss, let's discard the packet
|
|
syncFail++;
|
|
currentItem = dequeue.Item2;
|
|
currentItem.Position = dequeue.Item1.SyncD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private ulong syncSucess, syncFail;
|
|
private void OutputPacket(byte[] buffer)
|
|
{
|
|
buffer[0] = 0x47;
|
|
Context.TsOutput.OnSubTsPacket(subTsKey, buffer);
|
|
}
|
|
}
|
|
}
|