From 3668cad724a77d40af1f1f911919d96ef74201f5 Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Sun, 23 Nov 2025 21:23:41 +0100 Subject: [PATCH] Patch overdumped MPEG-DASH segments. --- skyscraper8/DvbNip/DvbNipUtilities.cs | 29 ++++++++++++++++--- skyscraper8/Ietf/FLUTE/FluteListener.cs | 9 ++++-- .../Ietf/{ => FLUTE}/FluteListenerMime.cs | 3 +- skyscraper8/Ietf/FLUTE/FluteListenerStream.cs | 22 ++++++++++++-- .../Skyscraper/Scraper/SkyscraperContext.cs | 7 ++++- 5 files changed, 59 insertions(+), 11 deletions(-) rename skyscraper8/Ietf/{ => FLUTE}/FluteListenerMime.cs (90%) diff --git a/skyscraper8/DvbNip/DvbNipUtilities.cs b/skyscraper8/DvbNip/DvbNipUtilities.cs index 109bbe8..c0c49ae 100644 --- a/skyscraper8/DvbNip/DvbNipUtilities.cs +++ b/skyscraper8/DvbNip/DvbNipUtilities.cs @@ -1,13 +1,14 @@ -using System; +using log4net; +using MimeKit; +using skyscraper5.Skyscraper.IO; +using skyscraper8.Ietf.FLUTE; +using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; -using MimeKit; -using skyscraper5.Skyscraper.IO; -using skyscraper8.Ietf.FLUTE; namespace skyscraper8.DvbNip { @@ -15,6 +16,7 @@ namespace skyscraper8.DvbNip { private DvbNipUtilities() { } + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); private static XmlSerializer multicastGatewayConfigurationXmlSerializer; public static bool IsXml(Stream s) @@ -225,5 +227,24 @@ namespace skyscraper8.DvbNip } throw new NotImplementedException(); } + + public static FluteListener PatchMpegDashSegment(FluteListener listener) + { + Stream stream = listener.ToStream(); + stream.Position = stream.Length - 1; + byte readUInt8 = stream.ReadUInt8(); + if (readUInt8 != 0) + return listener; + + logger.WarnFormat("MPEG-DASH segment {0} is overdumped. It will be patched to become playable.", listener.FileAssociation.ContentLocation); + stream.Position = stream.Length - 1; + while (stream.ReadUInt8() == 0) + { + stream.Position -= 2; + } + + listener.TrimmedLength = stream.Position; + return listener; + } } } diff --git a/skyscraper8/Ietf/FLUTE/FluteListener.cs b/skyscraper8/Ietf/FLUTE/FluteListener.cs index 1c232c4..23d161f 100644 --- a/skyscraper8/Ietf/FLUTE/FluteListener.cs +++ b/skyscraper8/Ietf/FLUTE/FluteListener.cs @@ -119,7 +119,7 @@ namespace skyscraper8.Ietf.FLUTE } - internal bool IsComplete() + internal virtual bool IsComplete() { if (_disabled) return false; @@ -165,7 +165,11 @@ namespace skyscraper8.Ietf.FLUTE blockPayloads.Sort(new FluteBlockComparer()); level1 = new FluteListenerStream(blockPayloads); } - + if (TrimmedLength.HasValue) + { + level1.SetLength(TrimmedLength.Value); + } + if (FileAssociation != null) { switch(FileAssociation.ContentEncoding) @@ -288,5 +292,6 @@ namespace skyscraper8.Ietf.FLUTE } public double LastReportedProgress { get; internal set; } + public long? TrimmedLength { get; set; } } } diff --git a/skyscraper8/Ietf/FluteListenerMime.cs b/skyscraper8/Ietf/FLUTE/FluteListenerMime.cs similarity index 90% rename from skyscraper8/Ietf/FluteListenerMime.cs rename to skyscraper8/Ietf/FLUTE/FluteListenerMime.cs index db4b936..f8c9ba1 100644 --- a/skyscraper8/Ietf/FluteListenerMime.cs +++ b/skyscraper8/Ietf/FLUTE/FluteListenerMime.cs @@ -4,9 +4,8 @@ using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; -using skyscraper8.Ietf.FLUTE; -namespace skyscraper8.Ietf +namespace skyscraper8.Ietf.FLUTE { internal class FluteListenerMime : FluteListener { diff --git a/skyscraper8/Ietf/FLUTE/FluteListenerStream.cs b/skyscraper8/Ietf/FLUTE/FluteListenerStream.cs index 64c28c4..d57efd3 100644 --- a/skyscraper8/Ietf/FLUTE/FluteListenerStream.cs +++ b/skyscraper8/Ietf/FLUTE/FluteListenerStream.cs @@ -118,9 +118,17 @@ namespace skyscraper8.Ietf.FLUTE return currentPosition; } + private bool _isLengthLimited; + private long _limitedLength; public override void SetLength(long value) { - throw new NotSupportedException("Can't modify the length of a ModuleInfo"); + if (value > myModuleLength) + { + throw new ArgumentOutOfRangeException(String.Format("Argument must be between 0 and {0}", myModuleLength)); + } + + _limitedLength = value; + _isLengthLimited = true; } public override void Write(byte[] buffer, int offset, int count) @@ -131,7 +139,17 @@ namespace skyscraper8.Ietf.FLUTE public override bool CanRead => true; public override bool CanSeek => true; public override bool CanWrite => false; - public override long Length => myModuleLength; + + public override long Length + { + get + { + if (_isLengthLimited) + return _limitedLength; + else + return myModuleLength; + } + } public override long Position { diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index bd98081..6ed2b04 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -86,7 +86,6 @@ using skyscraper8.GS; using skyscraper8.GSE; using skyscraper8.GSE.GSE; using skyscraper8.Ieee802_1AB; -using skyscraper8.Ietf; using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model2.Descriptors; @@ -2778,6 +2777,12 @@ namespace skyscraper5.Skyscraper.Scraper knownNipSegments[ep] = new List(); knownNipSegments[ep].Add(listener.FileAssociation.ContentLocation); } + + if (extension.Equals(".m4s")) + { + listener = DvbNipUtilities.PatchMpegDashSegment(listener); + } + ObjectStorage.DvbNipFileArrival(carrier, listener); }