Rewrote and decluttered TsPacket class.
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 9s

This commit is contained in:
feyris-tan 2026-03-11 23:32:44 +01:00
parent 8adf5d4ff1
commit b50eb3b5e6
29 changed files with 511 additions and 316 deletions

View File

@ -8,11 +8,14 @@ using System.Reflection.Metadata.Ecma335;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using ImGuiNET; using ImGuiNET;
using moe.yo3explorer.skyscraper8.DVBI.Model;
using SDL2Demo.Net; using SDL2Demo.Net;
using skyscraper5.Docsis; using skyscraper5.Docsis;
using skyscraper5.Dvb.DataBroadcasting.IntModel;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs; using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors; using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Psi.Model; using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Dvb.SystemSoftwareUpdate.Model;
using skyscraper5.Mhp; using skyscraper5.Mhp;
using skyscraper5.Mhp.Descriptors; using skyscraper5.Mhp.Descriptors;
using skyscraper5.Mhp.Si; using skyscraper5.Mhp.Si;
@ -27,9 +30,17 @@ using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper;
using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.src.Skyscraper.FrequencyListGenerator;
using skyscraper5.Teletext.Wss; using skyscraper5.Teletext.Wss;
using skyscraper8.DvbNip;
using skyscraper8.DvbNip.UiIntegration;
using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ietf.FLUTE;
using skyscraper8.Ses;
using skyscraper8.Skyscraper.Drawing; using skyscraper8.Skyscraper.Drawing;
using skyscraper8.Skyscraper.FrequencyListGenerator; using skyscraper8.Skyscraper.FrequencyListGenerator;
using skyscraper8.Skyscraper.Scraper;
using testdrid.SdlWrapper; using testdrid.SdlWrapper;
using Platform = skyscraper5.Dvb.DataBroadcasting.IntModel.Platform;
namespace SDL2Demo.Forms namespace SDL2Demo.Forms
{ {
@ -550,7 +561,12 @@ namespace SDL2Demo.Forms
patEntry.pmt = result; patEntry.pmt = result;
} }
public void NotifyMpeTraffic(IpTrafficInfo iti, byte[] ipv4PacketLength)
{
throw new NotImplementedException();
}
private string pmtTabBarUuid; private string pmtTabBarUuid;
public void RenderPmt() public void RenderPmt()
{ {
@ -1151,7 +1167,12 @@ namespace SDL2Demo.Forms
dsmCcDisplay.Remove(id); dsmCcDisplay.Remove(id);
} }
} }
public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid)
{
throw new NotImplementedException();
}
private void RenderDataCarousels() private void RenderDataCarousels()
{ {
if (dsmCcDisplay == null) if (dsmCcDisplay == null)
@ -2182,7 +2203,107 @@ namespace SDL2Demo.Forms
throw new NotImplementedException(); throw new NotImplementedException();
} }
public TaskQueue Tasks { get; set; } public void NotifyNit(NitNetwork nitNetwork)
{
throw new NotImplementedException();
}
public void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis)
{
throw new NotImplementedException();
}
public void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational)
{
throw new NotImplementedException();
}
public void OnSsuNotification(UpdateNotificationGroup common, UpdateNotificationTarget target, ushort programNumber)
{
throw new NotImplementedException();
}
public void OnBbframe(BBHeader bbHeader, byte[] payload)
{
throw new NotImplementedException();
}
public void OnDetectionOfInnerTs(SkyscraperContext child, object identifier)
{
throw new NotImplementedException();
}
public void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label)
{
throw new NotImplementedException();
}
public void OnDvbNipFileArrival(FluteUiHandle fuh)
{
throw new NotImplementedException();
}
public void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier,
MulticastGatewayConfigurationType multicastGatewayConfiguration)
{
throw new NotImplementedException();
}
public void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation)
{
throw new NotImplementedException();
}
public void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest)
{
throw new NotImplementedException();
}
public void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation,
ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime)
{
throw new NotImplementedException();
}
public void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1,
string serviceListId2)
{
throw new NotImplementedException();
}
public void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile)
{
throw new NotImplementedException();
}
public void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation,
NetworkInformationFileType networkInformationFile)
{
throw new NotImplementedException();
}
public void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation,
ServiceInformationFileType serviceInformationFile)
{
throw new NotImplementedException();
}
public void OnDvbNipFileAnnouncement(FDTInstanceType flute)
{
throw new NotImplementedException();
}
public void OnAstraSgtList(SgtList list)
{
throw new NotImplementedException();
}
public void OnAstraSgtService(SgtService child)
{
throw new NotImplementedException();
}
public TaskQueue Tasks { get; set; }
private ushort? ResolveCaId(ProgramMapping patValuePmt, SdtCoordinate sdt) private ushort? ResolveCaId(ProgramMapping patValuePmt, SdtCoordinate sdt)
{ {

View File

@ -33,8 +33,19 @@ using System.Numerics;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Serialization; using System.Xml.Serialization;
using moe.yo3explorer.skyscraper8.DVBI.Model;
using skyscraper5.Dvb.DataBroadcasting.IntModel;
using skyscraper5.Dvb.SystemSoftwareUpdate.Model;
using skyscraper8.DvbNip;
using skyscraper8.DvbNip.UiIntegration;
using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ietf.FLUTE;
using skyscraper8.Ses;
using skyscraper8.Skyscraper.Scraper;
using testdrid.SdlWrapper; using testdrid.SdlWrapper;
using static SDL2Demo.Jobs.Blindscan; using static SDL2Demo.Jobs.Blindscan;
using Platform = skyscraper5.Dvb.DataBroadcasting.IntModel.Platform;
namespace SDL2Demo.Jobs namespace SDL2Demo.Jobs
{ {
@ -452,6 +463,11 @@ namespace SDL2Demo.Jobs
patEntry.pmt = result; patEntry.pmt = result;
} }
public void NotifyMpeTraffic(IpTrafficInfo iti, byte[] ipv4PacketLength)
{
throw new NotImplementedException();
}
private string pmtTabBarUuid; private string pmtTabBarUuid;
public void RenderPmt() public void RenderPmt()
@ -996,6 +1012,11 @@ namespace SDL2Demo.Jobs
} }
} }
public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid)
{
throw new NotImplementedException();
}
private void RenderDataCarousels() private void RenderDataCarousels()
{ {
@ -1800,6 +1821,106 @@ namespace SDL2Demo.Jobs
return !foundFrequenciesWindow.doNotAutoZap; return !foundFrequenciesWindow.doNotAutoZap;
} }
public void NotifyNit(NitNetwork nitNetwork)
{
throw new NotImplementedException();
}
public void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis)
{
throw new NotImplementedException();
}
public void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational)
{
throw new NotImplementedException();
}
public void OnSsuNotification(UpdateNotificationGroup common, UpdateNotificationTarget target, ushort programNumber)
{
throw new NotImplementedException();
}
public void OnBbframe(BBHeader bbHeader, byte[] payload)
{
throw new NotImplementedException();
}
public void OnDetectionOfInnerTs(SkyscraperContext child, object identifier)
{
throw new NotImplementedException();
}
public void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label)
{
throw new NotImplementedException();
}
public void OnDvbNipFileArrival(FluteUiHandle fuh)
{
throw new NotImplementedException();
}
public void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier,
MulticastGatewayConfigurationType multicastGatewayConfiguration)
{
throw new NotImplementedException();
}
public void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation)
{
throw new NotImplementedException();
}
public void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest)
{
throw new NotImplementedException();
}
public void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation,
ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime)
{
throw new NotImplementedException();
}
public void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1,
string serviceListId2)
{
throw new NotImplementedException();
}
public void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile)
{
throw new NotImplementedException();
}
public void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation,
NetworkInformationFileType networkInformationFile)
{
throw new NotImplementedException();
}
public void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation,
ServiceInformationFileType serviceInformationFile)
{
throw new NotImplementedException();
}
public void OnDvbNipFileAnnouncement(FDTInstanceType flute)
{
throw new NotImplementedException();
}
public void OnAstraSgtList(SgtList list)
{
throw new NotImplementedException();
}
public void OnAstraSgtService(SgtService child)
{
throw new NotImplementedException();
}
public TaskQueue Tasks { get; set; } public TaskQueue Tasks { get; set; }
internal JobContext jobContext; internal JobContext jobContext;

View File

@ -26,14 +26,10 @@ namespace skyscraper5.Abertis
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
byte[] packetPayload = packet.Payload; Span<byte> payload = packet.GetPayload();
MemoryStream ms = new MemoryStream(packetPayload);
if (packet.AdaptionFieldControl == 3)
{
ms.ReadByte();
}
MemoryStream ms = new MemoryStream(payload.ToArray(), false);
int syncLossCheck = 0; int syncLossCheck = 0;
while (ms.GetAvailableBytes() > 0) while (ms.GetAvailableBytes() > 0)
{ {

View File

@ -88,21 +88,24 @@ namespace skyscraper5.Docsis
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
if (packet.AdaptionFieldControl != 1) TsAdaptionField adaptionField = packet.AdaptionField;
Span<byte> payload = packet.GetPayload();
if (adaptionField != null || payload == null)
{ {
PacketLoss(); PacketLoss();
return; return;
} }
bool packetPayloadUnitStart = packet.PayloadUnitStart; bool packetPayloadUnitStart = packet.PayloadUnitStart;
MemoryStream ms = new MemoryStream(packet.Payload, false); MemoryStream ms = new MemoryStream(payload.ToArray(), false);
if (!currentPayloadUnitPresent && !packetPayloadUnitStart) if (!currentPayloadUnitPresent && !packetPayloadUnitStart)
return; return;
if (!currentPayloadUnitPresent && packetPayloadUnitStart) if (!currentPayloadUnitPresent && packetPayloadUnitStart)
{ {
ms.Position = packet.PayloadStartOffset; ms.Position = packet.PID;
currentPayloadUnitPresent = true; currentPayloadUnitPresent = true;
currentPayloadBuffer = new MemoryStream(); currentPayloadBuffer = new MemoryStream();
} }

View File

@ -9,114 +9,32 @@ namespace skyscraper5.Dvb.DataBroadcasting.IntModel
{ {
public class IpMacNotification public class IpMacNotification
{ {
public IpMacNotification(Platform platform, int targetType, string targetName, Operational operational) public IpMacNotification(Platform platform, Target target, Operational operational)
{
Platform = platform;
Target = target;
Operational = operational;
}
public Platform Platform { get; }
public Target Target { get; }
public Operational Operational { get; }
public static IEnumerable<IpMacNotification> FlatMap(Platform platform, Target target, Operational operational)
{ {
PlatformName = platform.Name; yield return new IpMacNotification(platform, target, operational);
PlatformProviderName = platform.ProviderName;
PlatformProviderNameLanguageCode = platform.ProviderNameLanguageCode;
PlatformActionType = platform.ActionType;
PlatformNameLanguageCode = platform.NameLanguageCode;
PlatformId = platform.PlatformId;
PlatformProcessingOrder = platform.ProcessingOrder;
TargetType = targetType;
TargetName = targetName;
OperationalNetworkId = operational.NetworkId;
OperationalMpeFecAlgorithm = operational.MpeFecAlgorithm;
OperationalComponentTag = operational.ComponentTag;
OperationalTransportStreamId = operational.TransportStreamId;
OperationalTimeSliceFecId = operational.TimeSliceFecId;
OperationalTimeSlicing = operational.TimeSlicing;
OperationalOriginalNetworkId = operational.OriginalNetworkId;
OperationalServiceId = operational.ServiceId;
OperationalTimeSliceFrameSize = operational.TimeSliceFrameSize;
OperationalTimeSliceMaxAverageRate = operational.TimeSliceMaxAverageRate;
OperationalTimeSliceMaxBurstDuration = operational.TimeSliceMaxBurstDuration;
} }
public byte? OperationalTimeSliceMaxBurstDuration { get; set; } public override bool Equals(object? obj)
{
return obj is IpMacNotification notification &&
EqualityComparer<Platform>.Default.Equals(Platform, notification.Platform) &&
EqualityComparer<Target>.Default.Equals(Target, notification.Target);
}
public int? OperationalTimeSliceMaxAverageRate { get; set; } public override int GetHashCode()
{
public int? OperationalTimeSliceFrameSize { get; set; } return HashCode.Combine(Platform, Target);
}
public ushort? OperationalServiceId { get; set; } }
public ushort? OperationalOriginalNetworkId { get; set; }
public bool? OperationalTimeSlicing { get; set; }
public int? OperationalTimeSliceFecId { get; set; }
public ushort? OperationalTransportStreamId { get; set; }
public byte? OperationalComponentTag { get; set; }
public int? OperationalMpeFecAlgorithm { get; set; }
public ushort? OperationalNetworkId { get; set; }
public string TargetName { get; set; }
public int TargetType { get; set; }
public byte PlatformProcessingOrder { get; set; }
public uint PlatformId { get; set; }
public string PlatformNameLanguageCode { get; set; }
public byte PlatformActionType { get; set; }
public string PlatformProviderNameLanguageCode { get; set; }
public string PlatformProviderName { get; set; }
public string PlatformName { get; set; }
public static IEnumerable<IpMacNotification> FlatMap(Platform platform, Target target, Operational operational)
{
int results = 0;
if (target.AllReceivers)
{
yield return new IpMacNotification(platform, -1, null, operational);
yield break;
}
if (target.TargetIpSlashes != null)
{
foreach (CidrSubnet targetTargetIpSlash in target.TargetIpSlashes)
{
results++;
yield return new IpMacNotification(platform, 1, targetTargetIpSlash.ToString(), operational);
}
}
if (results == 0)
{
throw new NotImplementedException("Some Targets are not implemented properly.");
}
}
protected bool Equals(IpMacNotification other)
{
return TargetName == other.TargetName && TargetType == other.TargetType && PlatformId == other.PlatformId;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((IpMacNotification)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(TargetName, TargetType, PlatformId);
}
}
} }

View File

@ -27,5 +27,16 @@ namespace skyscraper5.Dvb.DataBroadcasting.IntModel
PlatformId = platformId; PlatformId = platformId;
ProcessingOrder = processingOrder; ProcessingOrder = processingOrder;
} }
}
public override bool Equals(object? obj)
{
return obj is Platform platform &&
PlatformId == platform.PlatformId;
}
public override int GetHashCode()
{
return HashCode.Combine(PlatformId);
}
}
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Skyscraper.Net; using skyscraper5.Skyscraper.Net;
@ -14,5 +15,46 @@ namespace skyscraper5.Dvb.DataBroadcasting.IntModel
//Was Loop empty? //Was Loop empty?
public bool AllReceivers { get; set; } public bool AllReceivers { get; set; }
}
public override bool Equals(object? obj)
{
return obj is Target target &&
EqualityComparer<List<CidrSubnet>>.Default.Equals(TargetIpSlashes, target.TargetIpSlashes) &&
AllReceivers == target.AllReceivers;
}
public override int GetHashCode()
{
return HashCode.Combine(TargetIpSlashes, AllReceivers);
}
public uint GenerateId()
{
if (AllReceivers)
return uint.MaxValue;
foreach(CidrSubnet subnet in TargetIpSlashes)
{
IPAddress ipAddress = subnet.IpAddress;
byte[] bytes = ipAddress.GetAddressBytes();
return BitConverter.ToUInt32(bytes);
}
throw new NotImplementedException(String.Format("Failed to derive an identifier for a IP/MAC Notification target. This is a bug, the developers would need a sample of this TS to fix this."));
}
public override string ToString()
{
if (AllReceivers)
return "<All Receivers>";
StringBuilder sb = new StringBuilder();
foreach (CidrSubnet subnet in TargetIpSlashes)
{
sb.Append(subnet.ToString());
sb.Append(",");
}
return sb.ToString();
}
}
} }

View File

@ -30,7 +30,7 @@ namespace skyscraper8.GSE
private bool annoncementDone; private bool annoncementDone;
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
byte[] packets = packet.RawPacket; byte[] packets = packet.GetRawPacket();
int pid = packets[1]; int pid = packets[1];
pid &= 0x01f; pid &= 0x01f;
pid <<= 8; pid <<= 8;

View File

@ -30,7 +30,9 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
if (packet.AdaptionFieldControl != 1) TsAdaptionField packetAdaptionField = packet.AdaptionField;
Span<byte> packetPayload = packet.GetPayload();
if (packetAdaptionField != null || packetPayload == null)
{ {
_eventHandler.OnUleError(_pid, 2); _eventHandler.OnUleError(_pid, 2);
return; return;
@ -44,7 +46,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
if (reassemblyMode) if (reassemblyMode)
{ {
int availableBytes = Math.Min(184, reassemblyRemainingBytes); int availableBytes = Math.Min(184, reassemblyRemainingBytes);
reassemblyStream.Write(packet.RawPacket, 4, availableBytes); reassemblyStream.Write(packetPayload.ToArray(), 4, availableBytes);
reassemblyRemainingBytes -= availableBytes; reassemblyRemainingBytes -= availableBytes;
if (reassemblyRemainingBytes == 0) if (reassemblyRemainingBytes == 0)
{ {
@ -68,7 +70,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
{ {
bool multipleSndusInPacket = false; bool multipleSndusInPacket = false;
MemoryStream payload = new MemoryStream(packet.RawPacket, false); MemoryStream payload = new MemoryStream(packet.GetRawPacket(), false);
payload.Position += 4; payload.Position += 4;
byte nextPacketOffset = payload.ReadUInt8(); byte nextPacketOffset = payload.ReadUInt8();
if (!reassemblyMode) if (!reassemblyMode)

View File

@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace skyscraper8.Json
{
public class IpAddressJsonConverter : JsonConverter<IPAddress>
{
public override IPAddress? ReadJson(JsonReader reader, Type objectType, IPAddress? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
string s = (string)reader.Value;
return IPAddress.Parse(s);
}
public override void WriteJson(JsonWriter writer, IPAddress? value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
}
}

View File

@ -52,8 +52,9 @@ namespace skyscraper8.Mpeg2.PacketFilter
} }
int retsize = 0; int retsize = 0;
byte[] unscrambled = new byte[packet.Payload.Length]; Span<byte> scrambledPayload = packet.GetPayload();
csa2.DecryptImpl(packet.Payload, packet.Payload.Length, unscrambled, unscrambled.Length, ref retsize); byte[] unscrambled = new byte[scrambledPayload.Length];
csa2.DecryptImpl(scrambledPayload, scrambledPayload.Length, unscrambled, unscrambled.Length, ref retsize);
packet.SetUnscrambled(unscrambled); packet.SetUnscrambled(unscrambled);
return true; return true;

View File

@ -20,7 +20,8 @@ namespace skyscraper5.src.Mpeg2.PacketFilter
{ {
if (recordingBufferedStream != null) if (recordingBufferedStream != null)
{ {
recordingBufferedStream.Write(packet.RawPacket, 0, packet.RawPacket.Length); byte[] rawPacket = packet.GetRawPacket();
recordingBufferedStream.Write(rawPacket, 0, rawPacket.Length);
} }
return true; return true;
} }

View File

@ -11,16 +11,16 @@ namespace skyscraper5.Mpeg2
internal void Analyze(TsPacket packet) internal void Analyze(TsPacket packet)
{ {
if (packet.Adaption == null) if (packet.AdaptionField == null)
return; return;
if (!packet.Adaption.Valid) if (!packet.AdaptionField.Valid)
return; return;
if (!packet.Adaption.PcrPresent) if (!packet.AdaptionField.PcrPresent)
return; return;
if (StartPcr == null) if (StartPcr == null)
{ {
StartPcr = packet.Adaption.PCR; StartPcr = packet.AdaptionField.PCR;
SourcePid = packet.PID; SourcePid = packet.PID;
StartRealTime = DateTime.Now; StartRealTime = DateTime.Now;
} }
@ -28,7 +28,7 @@ namespace skyscraper5.Mpeg2
{ {
if (packet.PID == SourcePid) if (packet.PID == SourcePid)
{ {
LastPcr = packet.Adaption.PCR; LastPcr = packet.AdaptionField.PCR;
LastRealTime = DateTime.Now; LastRealTime = DateTime.Now;
} }
} }

View File

@ -18,7 +18,7 @@ namespace skyscraper5.Mpeg2
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
if (packet.Payload == null) if (packet.GetPayload() == null)
return; return;
pushed++; pushed++;
@ -32,7 +32,8 @@ namespace skyscraper5.Mpeg2
} }
ms = new MemoryStream(); ms = new MemoryStream();
ms.WriteByte(0); ms.WriteByte(0);
ms.Write(packet.Payload, 0, packet.Payload.Length); Span<byte> payload = packet.GetPayload();
ms.Write(payload.ToArray(), 0, payload.Length);
} }
else else
@ -44,7 +45,8 @@ namespace skyscraper5.Mpeg2
} }
else else
{ {
ms.Write(packet.Payload, 0, packet.Payload.Length); Span<byte> payload = packet.GetPayload();
ms.Write(payload.ToArray(), 0, payload.Length);
} }
} }
} }

View File

@ -18,7 +18,7 @@ namespace skyscraper5.Mpeg2
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
if (packet.Payload == null) if (packet.GetPayload() == null)
return; return;
if (packet.PID != pid) if (packet.PID != pid)
return; return;
@ -40,11 +40,17 @@ namespace skyscraper5.Mpeg2
} }
} }
MemoryStream payload = new MemoryStream(packet.Payload); MemoryStream payload = new MemoryStream(packet.GetPayload().ToArray(), false);
long available = payload.Length - payload.Position; long available = payload.Length - payload.Position;
if (psiJustStarted) if (psiJustStarted)
{ {
long startOffset = packet.PayloadStartOffset; payload.Position = 0;
byte payloadUnitStartOffset = payload.ReadUInt8();
available--;
payload.Position += payloadUnitStartOffset;
available -= payloadUnitStartOffset;
long startOffset = 0;
if (startOffset > 0) if (startOffset > 0)
{ {
startOffset = payload.Position + startOffset; startOffset = payload.Position + startOffset;
@ -102,6 +108,11 @@ namespace skyscraper5.Mpeg2
payload.Position--; payload.Position--;
if (payloadPos != 0xff) if (payloadPos != 0xff)
newSection = true; newSection = true;
if (payload.Position == 0)
{
payload.Position++;
available--;
}
} }
if (newSection) if (newSection)

View File

@ -5,28 +5,24 @@ using skyscraper5.Skyscraper.IO;
namespace skyscraper5.Mpeg2 namespace skyscraper5.Mpeg2
{ {
public class DvbAdaptionField : Validatable public class TsAdaptionField : Validatable
{ {
public DvbAdaptionField(Stream binaryReader, bool TEI) public TsAdaptionField(Span<byte> adaptionField, bool TEI)
{ {
byte adaptionFieldLength = binaryReader.ReadUInt8(); byte adaptionFieldLength = (byte)adaptionField.Length;
if (adaptionFieldLength > 183) if (adaptionFieldLength > 183)
{ {
Valid = false; Valid = false;
return; return;
} }
byte[] adaptionField = binaryReader.ReadBytes(adaptionFieldLength);
RawAdaptionField = adaptionField;
binaryReader = new MemoryStream(adaptionField);
this.Length = adaptionFieldLength;
if (adaptionFieldLength == 0) if (adaptionFieldLength == 0)
{ {
Valid = true; Valid = true;
return; //Seems valid according to ISO 13818-1 return; //Seems valid according to ISO 13818-1
} }
byte bitmask = binaryReader.ReadUInt8(); byte bitmask = adaptionField[0];
Discontinuity = ((bitmask & 0x80) >> 7) != 0; Discontinuity = ((bitmask & 0x80) >> 7) != 0;
RandomAccess = ((bitmask & 0x40) >> 6) != 0; RandomAccess = ((bitmask & 0x40) >> 6) != 0;
PriorityIndicator = ((bitmask & 0x20) >> 5) != 0; PriorityIndicator = ((bitmask & 0x20) >> 5) != 0;
@ -36,6 +32,7 @@ namespace skyscraper5.Mpeg2
TransportPrivateDataPresent = ((bitmask & 0x02) >> 1) != 0; TransportPrivateDataPresent = ((bitmask & 0x02) >> 1) != 0;
AdaptionFieldExtensionPresent = ((bitmask & 0x01)) != 0; AdaptionFieldExtensionPresent = ((bitmask & 0x01)) != 0;
MemoryStream binaryReader = new MemoryStream(adaptionField.ToArray(), 1, adaptionFieldLength - 1);
if (PcrPresent) if (PcrPresent)
{ {
if (binaryReader.GetAvailableBytes() < 6) if (binaryReader.GetAvailableBytes() < 6)
@ -179,6 +176,5 @@ namespace skyscraper5.Mpeg2
public bool PcrPresent { get; private set; } public bool PcrPresent { get; private set; }
public byte Length { get; private set; } public byte Length { get; private set; }
public byte[] RawAdaptionField { get; private set; }
} }
} }

View File

@ -123,7 +123,7 @@ namespace skyscraper5.Mpeg2
private bool EnsureContinuity(TsPacket packet) private bool EnsureContinuity(TsPacket packet)
{ {
//Found in ISO 13818-1.pdf, page 38 //Found in ISO 13818-1.pdf, page 38
if (packet.AdaptionFieldControl == 2 || packet.AdaptionFieldControl == 0) if (packet.GetPayload() != null)
return true; return true;
if (packet.PID == 0x1fff) if (packet.PID == 0x1fff)
@ -295,11 +295,11 @@ namespace skyscraper5.Mpeg2
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void InjectIntoPcrMonitor(TsPacket tspacket) private void InjectIntoPcrMonitor(TsPacket tspacket)
{ {
if (tspacket.Adaption == null) if (tspacket.AdaptionField == null)
return; return;
if (!tspacket.Adaption.Valid) if (!tspacket.AdaptionField.Valid)
return; return;
if (!tspacket.Adaption.PcrPresent) if (!tspacket.AdaptionField.PcrPresent)
return; return;
if (PcrMonitor != null) if (PcrMonitor != null)

View File

@ -9,124 +9,78 @@ namespace skyscraper5.Mpeg2
{ {
public TsPacket(byte[] buffer) public TsPacket(byte[] buffer)
{ {
Serial = serialGen++;
RawPacket = (byte[])buffer.Clone();
if (buffer.Length != 188) if (buffer.Length != 188)
throw new ArgumentException("buffer.Length != 188"); throw new ArgumentException("Invalid buffer length");
MemoryStream br = new MemoryStream(buffer, false);
uint anInt = br.ReadUInt32BE();
uint syncBytes = (anInt & 0xff000000) >> 24;
if (syncBytes != 'G')
{
throw new InvalidTsPacketException();
}
TEI = (((anInt & 0x800000)) >> 23) != 0;
PayloadUnitStart = (((anInt & 0x400000)) >> 22) != 0;
Priority = ((anInt & 0x200000)) >> 21;
PID = ((anInt & 0x1fff00)) >> 8;
TSC = ((anInt & 0xc0)) >> 6;
AdaptionFieldControl = ((anInt & 0x30)) >> 4;
Continuity = ((anInt & 0xf));
if (PID == 0x1FFF)
{
return;
}
if (TEI)
return;
if ((buffer[3] & 0x20) != 0)
{
//Skip adaption field if present
}
if ((buffer[1] & 0x40) != 0)
{
//Unit start
}
PayloadOffset = 4;
if (PayloadUnitStart)
{
PayloadStartOffset = buffer[4] & 0xff;
PayloadOffset++;
}
switch (AdaptionFieldControl) if (buffer[0] != 0x47)
throw new ArgumentException("Buffer is not a TS packet");
rawPacket = buffer;
TEI = (buffer[1] & 0x80) != 0;
PayloadUnitStart = (buffer[1] & 0x40) != 0;
TransportPriority = (buffer[1] & 0x20) != 0;
PID = (uint)((buffer[1] & 0x1f) << 8) | buffer[2];
TSC = ((buffer[3] & 0xc0) >> 6);
int AdaptionFieldControl = ((buffer[3] & 0x30) >> 4);
Continuity = (byte)(buffer[3] & 0x0f);
bool hasAdaptionField = (AdaptionFieldControl & 0x02) != 0;
bool hasPayloadField = (AdaptionFieldControl & 0x01) != 0;
int ptr = 4;
if (hasAdaptionField)
{ {
case 1: byte adaptionFieldLength = buffer[ptr++];
br.Position = PayloadOffset; int maxLength = 188 - ptr;
long PayloadLengthB = 188 - PayloadOffset; if (adaptionFieldLength > maxLength)
Payload = br.ReadBytes(PayloadLengthB); {
break; TEI = true;
case 2: return;
Adaption = new DvbAdaptionField(br, TEI); }
if (!Adaption.Valid) Span<byte> adaptionField = buffer.AsSpan(ptr, adaptionFieldLength);
TEI = true; ptr += adaptionFieldLength;
break; AdaptionField = new TsAdaptionField(adaptionField, TEI);
case 3: }
Adaption = new DvbAdaptionField(br, TEI);
if (!Adaption.Valid) if (hasPayloadField)
{ {
TEI = true; PayloadOffset = ptr;
break;
}
PayloadOffset += Adaption.Length;
br.Position = PayloadOffset;
long PayloadLength = (188 - PayloadOffset);
Payload = br.ReadBytes((int)PayloadLength);
break;
default:
TEI = true;
break;
} }
} }
private static ulong serialGen; public byte Continuity { get; set; }
public DvbAdaptionField Adaption { get; private set; }
public bool TEI { get; private set; } public int TSC { get; set; }
public bool PayloadUnitStart { get; private set; }
public uint Priority { get; private set; }
public uint PID { get; private set; }
/// <summary> public uint PID { get; set; }
/// 0 = not scrambled
/// 1 = reserved
/// 2 = scrambled, even key
/// 3 = scrambled, odd key
/// </summary>
public uint TSC { get; internal set; }
public uint AdaptionFieldControl { get; private set; }
public uint Continuity { get; private set; }
public int PayloadStartOffset { get; private set; }
public byte[] Payload { get; private set; }
public bool PayloadFlagSet => AdaptionFieldControl == 1 || AdaptionFieldControl == 3;
public byte[] RawPacket { get; private set; }
public ulong Serial { get; private set; }
public int PayloadOffset { get; private set; } public bool TransportPriority { get; set; }
/// <summary> public bool PayloadUnitStart { get; set; }
/// Retrieving the raw packet, including adaption field and Payload, but without the four byte header.
/// </summary> public bool TEI { get; set; }
/// <returns></returns>
public byte[] GetBody() public TsAdaptionField AdaptionField { get; set; }
private int PayloadOffset;
private byte[] rawPacket;
public Span<byte> GetPayload()
{ {
byte[] buffer = new byte[184]; if (PayloadOffset == 0)
Array.Copy(RawPacket, 4, buffer, 0, 184); return null;
return buffer;
return rawPacket.AsSpan(PayloadOffset);
} }
public void SetUnscrambled(byte[] unscrambledPayload) public void SetUnscrambled(byte[] unscrambled)
{ {
TSC = 0; throw new NotSupportedException("We aren't doing anything illegal, m'kay?");
Payload = unscrambledPayload; }
Array.Copy(unscrambledPayload, 0, RawPacket, PayloadOffset, unscrambledPayload.Length);
RawPacket[3] &= 0x3f; public byte[] GetRawPacket()
{
return rawPacket;
} }
} }
} }

View File

@ -116,13 +116,16 @@ namespace skyscraper5
{ {
FileInfo fi = new FileInfo(args[1]); FileInfo fi = new FileInfo(args[1]);
FileStream fstream = fi.OpenRead(); FileStream fstream = fi.OpenRead();
MultiprotocolEncapsulationDecoder mpeDecoder = new MultiprotocolEncapsulationDecoder(null);
PsiDecoder psiDecoder = new PsiDecoder(0x1019, mpeDecoder);
TsContext mpeg2 = new TsContext(); TsContext mpeg2 = new TsContext();
mpeg2.RegisterPacketProcessor(0x1019, psiDecoder);
SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage()); SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage());
skyscraper.InitalizeFilterChain(); skyscraper.InitalizeFilterChain();
skyscraper.IngestFromStream(fstream);
MultiprotocolEncapsulationDecoder mpeDecoder = new MultiprotocolEncapsulationDecoder(skyscraper);
PsiDecoder psiDecoder = new PsiDecoder(0x1019, mpeDecoder);
mpeg2.RegisterPacketProcessor(0x1019, psiDecoder);
skyscraper.IngestFromStream(fstream);
} }
if (args[0].Equals("aactest")) if (args[0].Equals("aactest"))
{ {

View File

@ -2,7 +2,7 @@
"profiles": { "profiles": {
"skyscraper8": { "skyscraper8": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "bumutest \"C:\\devel\\skyscraper8-testsuite\\12168_pid1019only.ts\"", "commandLineArgs": "\"C:\\devel\\skyscraper8-testsuite\\express_3928L_t2mi.ts\"",
"remoteDebugEnabled": false "remoteDebugEnabled": false
}, },
"Container (Dockerfile)": { "Container (Dockerfile)": {

View File

@ -15,12 +15,12 @@ namespace skyscraper8.Skyscraper.Math
if (entropyCalculatorStreams == null) if (entropyCalculatorStreams == null)
entropyCalculatorStreams = new EntropyCalculatorStream[0x1fff]; entropyCalculatorStreams = new EntropyCalculatorStream[0x1fff];
if (packet.PayloadFlagSet) if (packet.GetPayload() != null)
{ {
uint pid = packet.PID; uint pid = packet.PID;
if (entropyCalculatorStreams[pid] == null) if (entropyCalculatorStreams[pid] == null)
entropyCalculatorStreams[pid] = new EntropyCalculatorStream(); entropyCalculatorStreams[pid] = new EntropyCalculatorStream();
entropyCalculatorStreams[pid].Write(packet.Payload); entropyCalculatorStreams[pid].Write(packet.GetPayload());
} }
return true; return true;
} }

View File

@ -30,7 +30,7 @@ namespace skyscraper5.Skyscraper
if (annoncementDone) if (annoncementDone)
return; return;
byte[] packets = packet.RawPacket; byte[] packets = packet.GetRawPacket();
int pid = (packets[1]); int pid = (packets[1]);
pid &= 0x01f; pid &= 0x01f;
pid <<= 8; pid <<= 8;

View File

@ -2226,7 +2226,7 @@ namespace skyscraper5.Skyscraper.Scraper
if (!DataStorage.TestForIpMacNotification(notification)) if (!DataStorage.TestForIpMacNotification(notification))
{ {
DataStorage.StoreIpMacNotification(notification); DataStorage.StoreIpMacNotification(notification);
LogEvent(SkyscraperContextEvent.IpMacNotification, String.Format("{0} -> {1}", platform.Name, notification.TargetName)); LogEvent(SkyscraperContextEvent.IpMacNotification, String.Format("{0} -> {1}", platform.Name, notification.Target.ToString()));
} }
} }
} }

View File

@ -721,14 +721,14 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem
public bool TestForIpMacNotification(IpMacNotification notification) public bool TestForIpMacNotification(IpMacNotification notification)
{ {
string path = Path.Combine(rootDirectory.FullName, "INT", String.Format("{0}.json", notification.PlatformId)); string path = Path.Combine(rootDirectory.FullName, "INT", String.Format("{0}_{1}.json", notification.Platform.PlatformId, notification.Target.GenerateId()));
return File.Exists(path); return File.Exists(path);
} }
public void StoreIpMacNotification(IpMacNotification notification) public void StoreIpMacNotification(IpMacNotification notification)
{ {
string path = Path.Combine(rootDirectory.FullName, "INT", String.Format("{0}.json", notification.PlatformId)); string path = Path.Combine(rootDirectory.FullName, "INT", String.Format("{0}_{1}.json", notification.Platform.PlatformId, notification.Target.GenerateId()));
FileInfo fi = new FileInfo(path); FileInfo fi = new FileInfo(path);
EnsureDirectoryExists(fi.Directory); EnsureDirectoryExists(fi.Directory);
File.WriteAllText(fi.FullName, JsonConvert.SerializeObject(notification, Formatting.Indented, jsonSerializerSettings)); File.WriteAllText(fi.FullName, JsonConvert.SerializeObject(notification, Formatting.Indented, jsonSerializerSettings));
} }

View File

@ -1,41 +1,30 @@
using System; using skyscraper5.Dvb.DataBroadcasting.IntModel;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace skyscraper5.Skyscraper.Scraper.Storage.Utilities namespace skyscraper5.Skyscraper.Scraper.Storage.Utilities
{ {
public class DatabaseKeyInt : IEquatable<DatabaseKeyInt> public class DatabaseKeyInt
{ {
public DatabaseKeyInt(uint id) private uint platformId;
{ private uint targetId;
Id = id;
}
public uint Id { get; } public DatabaseKeyInt(uint platformId, uint v)
{
this.platformId = platformId;
this.targetId = v;
}
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return Equals(obj as DatabaseKeyInt); return obj is DatabaseKeyInt @int &&
} platformId == @int.platformId &&
targetId == @int.targetId;
}
public bool Equals(DatabaseKeyInt other) public override int GetHashCode()
{ {
return other is not null && return HashCode.Combine(platformId, targetId);
Id == other.Id; }
} }
public override int GetHashCode()
{
return HashCode.Combine(Id);
}
public static bool operator ==(DatabaseKeyInt left, DatabaseKeyInt right)
{
return EqualityComparer<DatabaseKeyInt>.Default.Equals(left, right);
}
public static bool operator !=(DatabaseKeyInt left, DatabaseKeyInt right)
{
return !(left == right);
}
}
} }

View File

@ -22,7 +22,9 @@ namespace skyscraper5.Skyscraper.Scraper.Utils
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
outputFile.Write(packet.RawPacket, 0, packet.RawPacket.Length); Span<byte> payload = packet.GetPayload();
outputFile.Write(payload.ToArray(), 0, payload.Length);
outputFile.Flush(); outputFile.Flush();
} }
} }

View File

@ -39,9 +39,10 @@ namespace skyscraper5.Skyscraper.Scraper.Utils
} }
} }
} }
Span<byte> payload = packet.GetPayload();
targetPs = new MemoryStream(); targetPs = new MemoryStream();
targetPs.WriteByte((byte)packet.PayloadStartOffset); targetPs.Write(payload);
targetPs.Write(packet.Payload, 0, packet.Payload.Length);
} }
else else
@ -53,7 +54,8 @@ namespace skyscraper5.Skyscraper.Scraper.Utils
} }
else else
{ {
targetPs.Write(packet.Payload, 0, packet.Payload.Length); Span<byte> payload = packet.GetPayload();
targetPs.Write(payload);
} }
} }
} }

View File

@ -95,8 +95,8 @@ namespace skyscraper5.Skyscraper
try try
{ {
byte[] packetRawPacket = packet.RawPacket; byte[] packetRawPacket = packet.GetRawPacket();
tcpClient.Client.Send(packet.RawPacket); tcpClient.Client.Send(packetRawPacket);
} }
catch (SocketException se) catch (SocketException se)
{ {

View File

@ -33,20 +33,16 @@ namespace skyscraper5.T2MI
private long inputPacketsPushed; private long inputPacketsPushed;
private long outputPacketsPushed; private long outputPacketsPushed;
private T2MIEventHandler t2MiEventHandler; private T2MIEventHandler t2MiEventHandler;
private bool firstPacketFound;
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
{ {
inputPacketsPushed++; inputPacketsPushed++;
bool packetPayloadUnitStart = packet.PayloadUnitStart; bool packetPayloadUnitStart = packet.PayloadUnitStart;
int offset = 4; if (!firstPacketFound && packetPayloadUnitStart)
if (packet.Adaption != null) firstPacketFound = true;
{
offset += packet.Adaption.Length;
offset++;
}
MemoryStream ms = new MemoryStream(packet.RawPacket, false); MemoryStream ms = new MemoryStream(packet.GetPayload().ToArray(), false);
ms.Position = offset;
int partsProcessed = 0; int partsProcessed = 0;
byte offsetAccordingToPus = 0; byte offsetAccordingToPus = 0;
if (packetPayloadUnitStart) if (packetPayloadUnitStart)