From 0cddb3b085919d5a15dc1edbb5e38a3db25cf05c Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Thu, 25 Jun 2026 21:59:06 +0200 Subject: [PATCH] Added an optional feature to procecss MPE Packets multi-threaded. --- .../MultiprotocolEncapsulationDecoder.cs | 135 ++++++++++++------ 1 file changed, 94 insertions(+), 41 deletions(-) diff --git a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs index df64e9e..caf8aa8 100644 --- a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs +++ b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs @@ -17,64 +17,117 @@ namespace skyscraper5.Dvb.DataBroadcasting class MultiprotocolEncapsulationDecoder : IPsiProcessor { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private const bool ENABLE_MULTITHREADING = false; public IMultiprotocolEncapsulationEventHandler EventHandler { get; } public MultiprotocolEncapsulationDecoder(IMultiprotocolEncapsulationEventHandler eventHandler) { EventHandler = eventHandler; + restartRequired = true; } public void GatherPsi(PsiSection section, int sourcePid) { - MemoryStream ms = new MemoryStream(section.GetDataCopy(), false); - if (ms.Length < 12) - return; - byte tableId = ms.ReadUInt8(); - - ushort readUInt16Be = ms.ReadUInt16BE(); - bool sectionSyntaxIndicator = (readUInt16Be & 0x8000) != 0; - bool privateIndicator = (readUInt16Be & 0x4000) != 0; - int sectionLength = readUInt16Be & 0x0fff; - - byte[] macAddress = new byte[6]; - macAddress[5] = ms.ReadUInt8(); - macAddress[4] = ms.ReadUInt8(); - - byte readUInt8 = ms.ReadUInt8(); - int payloadScramblingControl = (readUInt8 & 0x30) >> 4; - if (payloadScramblingControl != 0) - return; //We don't know how to unscramble these. - int addressScramblingControl = (readUInt8 & 0x0c) >> 2; - bool llcSnap = (readUInt8 & 0x02) != 0; - bool currentNextIndicator = (readUInt8 & 0x01) != 0; - - byte sectionNumber = ms.ReadUInt8(); - byte lastSectionNumber = ms.ReadUInt8(); - macAddress[3] = ms.ReadUInt8(); - macAddress[2] = ms.ReadUInt8(); - macAddress[1] = ms.ReadUInt8(); - macAddress[0] = ms.ReadUInt8(); - - long length = ms.GetAvailableBytes() - 4; - if (length <= 0) + if (!ENABLE_MULTITHREADING) { - return; - } - - EnsureVirtualNetworkIdentifier(sourcePid); - byte[] payload = ms.ReadBytes(length); - if (llcSnap) - { - HandleLlcSnap(sourcePid, macAddress, payload); + GatherPsiEx(section, sourcePid); } else { - HandleIpDatagram(sourcePid,payload); - } + if (_actionQueue == null) + _actionQueue = new Queue(); + lock (_actionQueue) + { + _actionQueue.Enqueue(() => { GatherPsiEx(section, sourcePid); }); + } + + if (restartRequired) + { + restartRequired = false; + _actionQueueThread = new Thread(SeperatedThreadFunction); + _actionQueueThread.Name = String.Format("MPE Decoder Thread for PID 0x{0:X4}", sourcePid); + _actionQueueThread.Start(); + } + } } + private void GatherPsiEx(PsiSection section, int sourcePid) + { + MemoryStream ms = new MemoryStream(section.GetDataCopy(), false); + if (ms.Length < 12) + return; + byte tableId = ms.ReadUInt8(); + + ushort readUInt16Be = ms.ReadUInt16BE(); + bool sectionSyntaxIndicator = (readUInt16Be & 0x8000) != 0; + bool privateIndicator = (readUInt16Be & 0x4000) != 0; + int sectionLength = readUInt16Be & 0x0fff; + + byte[] macAddress = new byte[6]; + macAddress[5] = ms.ReadUInt8(); + macAddress[4] = ms.ReadUInt8(); + + byte readUInt8 = ms.ReadUInt8(); + int payloadScramblingControl = (readUInt8 & 0x30) >> 4; + if (payloadScramblingControl != 0) + return; //We don't know how to unscramble these. + int addressScramblingControl = (readUInt8 & 0x0c) >> 2; + bool llcSnap = (readUInt8 & 0x02) != 0; + bool currentNextIndicator = (readUInt8 & 0x01) != 0; + + byte sectionNumber = ms.ReadUInt8(); + byte lastSectionNumber = ms.ReadUInt8(); + macAddress[3] = ms.ReadUInt8(); + macAddress[2] = ms.ReadUInt8(); + macAddress[1] = ms.ReadUInt8(); + macAddress[0] = ms.ReadUInt8(); + + long length = ms.GetAvailableBytes() - 4; + if (length <= 0) + { + return; + } + + EnsureVirtualNetworkIdentifier(sourcePid); + byte[] payload = ms.ReadBytes(length); + if (llcSnap) + { + HandleLlcSnap(sourcePid, macAddress, payload); + } + else + { + HandleIpDatagram(sourcePid, payload); + } + } + + private Thread _actionQueueThread; + private Queue _actionQueue; + private bool restartRequired; + private void SeperatedThreadFunction() + { + while (true) + { + int remainingElements = 0; + lock (_actionQueue) + { + remainingElements = _actionQueue.Count; + } + if (remainingElements == 0) + { + break; + } + + Action action = null; + lock (_actionQueue) + { + action = _actionQueue.Dequeue(); + } + action(); + } + restartRequired = true; + } private bool announcedLlcTraffic; private void HandleLlcSnap(int sourcePid, byte[] macAddress, byte[] payload)