Fixed logic bug in DVB-SIS handling.
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 2m37s

This commit is contained in:
Fey 2025-12-23 15:41:39 +01:00
parent 004c17ab91
commit d115e4efcb
7 changed files with 102 additions and 96 deletions

View File

@ -83,7 +83,7 @@ public class CapturedTests : Feyllure
} }
[TestMethod] [TestMethod]
public void Rcs2Nip() public void GseRcs2()
{ {
FileStream streamSample = GetStreamSample("telstar12v-bfbs-000000.ts"); FileStream streamSample = GetStreamSample("telstar12v-bfbs-000000.ts");
ProcessSample(streamSample); ProcessSample(streamSample);
@ -91,6 +91,22 @@ public class CapturedTests : Feyllure
//32559 //32559
} }
[TestMethod]
public void BadrDvbSis()
{
FileStream streamSample = GetStreamSample("badr_12563v_dvb-sis.ts");
ProcessSample(streamSample);
streamSample.Close();
}
[TestMethod]
public void Eutelsat5DvbSis()
{
FileStream streamSample = GetStreamSample("eutelsat5_12522v_dvb-sis.ts");
ProcessSample(streamSample);
streamSample.Close();
}
private void ProcessSample(Stream sample) private void ProcessSample(Stream sample)

View File

@ -10,7 +10,7 @@ namespace skyscraper8.DvbSis
{ {
internal class NullSisHandler : SisHandler internal class NullSisHandler : SisHandler
{ {
public void OnSisCat(int sourcePid, SisCatContainer catContainer) public void OnSisCat(int sourcePid, ushort sourceProgram, SisCatContainer catContainer)
{ {
} }
@ -19,7 +19,7 @@ namespace skyscraper8.DvbSis
} }
public void OnSisEit(int sourcePid, SisEitContainer eitContainer) public void OnSisEit(int sourcePid, ushort sourceProgram, SisEitContainer eitContainer)
{ {
} }
@ -28,24 +28,24 @@ namespace skyscraper8.DvbSis
{ {
} }
public void OnSisNit(int sourcePid, SisNitContainer nitContainer) public void OnSisNit(int sourcePid, ushort sourceProgram, SisNitContainer nitContainer)
{ {
} }
public void OnSisPat(int sourcePid, SisPatContainer patContainer) public void OnSisPat(int sourcePid, ushort sourceProgram, SisPatContainer patContainer)
{ {
} }
public void OnSisPmt(int sourcePid, SisPmtContainer pmtContainer) public void OnSisPmt(int sourcePid, ushort sourceProgram, SisPmtContainer pmtContainer)
{ {
} }
public void OnSisSdt(int sourcePid, SisSdtContainer sdtContainer) public void OnSisSdt(int sourcePid, ushort sourceProgram, SisSdtContainer sdtContainer)
{ {
} }
public void OnSisTdt(int sourcePid, SisTdtContainer tdtContainer) public void OnSisTdt(int sourcePid, ushort sourceProgram, SisTdtContainer tdtContainer)
{ {
} }
@ -54,7 +54,7 @@ namespace skyscraper8.DvbSis
{ {
} }
public void OnSisTot(int sourcePid, SisTotContainer totContainer) public void OnSisTot(int sourcePid, ushort sourceProgram, SisTotContainer totContainer)
{ {
} }
} }

View File

@ -10,16 +10,16 @@ namespace skyscraper8.DvbSis
{ {
public interface SisHandler public interface SisHandler
{ {
void OnSisCat(int sourcePid, SisCatContainer catContainer); void OnSisCat(int sourcePid, ushort sourceProgram, SisCatContainer catContainer);
void OnSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci); void OnSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci);
void OnSisEit(int sourcePid, SisEitContainer eitContainer); void OnSisEit(int sourcePid, ushort sourceProgram, SisEitContainer eitContainer);
void OnSisFti(int relatedPid, _0xF0_FramingTimingInformation fti); void OnSisFti(int relatedPid, _0xF0_FramingTimingInformation fti);
void OnSisNit(int sourcePid, SisNitContainer nitContainer); void OnSisNit(int sourcePid, ushort sourceProgram, SisNitContainer nitContainer);
void OnSisPat(int sourcePid, SisPatContainer patContainer); void OnSisPat(int sourcePid, ushort sourceProgram, SisPatContainer patContainer);
void OnSisPmt(int sourcePid, SisPmtContainer pmtContainer); void OnSisPmt(int sourcePid, ushort sourceProgram, SisPmtContainer pmtContainer);
void OnSisSdt(int sourcePid, SisSdtContainer sdtContainer); void OnSisSdt(int sourcePid, ushort sourceProgram, SisSdtContainer sdtContainer);
void OnSisTdt(int sourcePid, SisTdtContainer tdtContainer); void OnSisTdt(int sourcePid, ushort sourceProgram, SisTdtContainer tdtContainer);
void OnSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp); void OnSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp);
void OnSisTot(int sourcePid, SisTotContainer totContainer); void OnSisTot(int sourcePid, ushort sourceProgram, SisTotContainer totContainer);
} }
} }

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace skyscraper8.DvbSis
{
internal class SisPid
{
public SisPid(int pid)
{
this.PID = pid;
}
public int PID { get; }
public override bool Equals(object? obj)
{
return obj is SisPid pid &&
PID == pid.PID;
}
public override int GetHashCode()
{
return HashCode.Combine(PID);
}
public override string ToString()
{
return String.Format("DVB-SIS PID 0x{0:X4}", PID);
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace skyscraper8.DvbSis
{
internal class SisProgramIdentifier
{
public SisProgramIdentifier(ushort program)
{
this.Program = program;
}
public int Program { get; }
public override bool Equals(object? obj)
{
return obj is SisProgramIdentifier pid &&
Program == pid.Program;
}
public override int GetHashCode()
{
return HashCode.Combine(Program);
}
public override string ToString()
{
return String.Format("DVB-SIS Program {0}", Program);
}
}
}

View File

@ -11,12 +11,14 @@ namespace skyscraper8.DvbSis
{ {
internal class SisPsiHandler : IPsiProcessor internal class SisPsiHandler : IPsiProcessor
{ {
public SisPsiHandler(SisHandler handler) public SisPsiHandler(SisHandler handler, ushort parentProgram)
{ {
_handler = handler; _handler = handler;
_parentProgram = parentProgram;
} }
private SisHandler _handler; private SisHandler _handler;
private ushort _parentProgram;
public void GatherPsi(PsiSection section, int sourcePid) public void GatherPsi(PsiSection section, int sourcePid)
{ {
@ -26,50 +28,50 @@ namespace skyscraper8.DvbSis
SisPatContainer patContainer = new SisPatContainer(); SisPatContainer patContainer = new SisPatContainer();
PatParser patParser = new PatParser(patContainer); PatParser patParser = new PatParser(patContainer);
patParser.GatherPsi(section, 0); patParser.GatherPsi(section, 0);
_handler.OnSisPat(sourcePid, patContainer); _handler.OnSisPat(sourcePid, _parentProgram, patContainer);
break; break;
case 0x01: case 0x01:
SisCatContainer catContainer = new SisCatContainer(); SisCatContainer catContainer = new SisCatContainer();
CatParser catParser = new CatParser(catContainer); CatParser catParser = new CatParser(catContainer);
catParser.GatherPsi(section, 0); catParser.GatherPsi(section, 0);
_handler.OnSisCat(sourcePid, catContainer); _handler.OnSisCat(sourcePid, _parentProgram, catContainer);
break; break;
case 0x02: case 0x02:
SisPmtContainer pmtContainer = new SisPmtContainer(); SisPmtContainer pmtContainer = new SisPmtContainer();
PmtParser pmtParser = new PmtParser(pmtContainer); PmtParser pmtParser = new PmtParser(pmtContainer);
pmtParser.GatherPsi(section, 0); pmtParser.GatherPsi(section, 0);
_handler.OnSisPmt(sourcePid, pmtContainer); _handler.OnSisPmt(sourcePid, _parentProgram, pmtContainer);
break; break;
case 0x40: case 0x40:
SisNitContainer nitContainer = new SisNitContainer(); SisNitContainer nitContainer = new SisNitContainer();
NitParser nitParser = new NitParser(nitContainer); NitParser nitParser = new NitParser(nitContainer);
nitParser.GatherPsi(section, 0); nitParser.GatherPsi(section, 0);
_handler.OnSisNit(sourcePid, nitContainer); _handler.OnSisNit(sourcePid, _parentProgram, nitContainer);
break; break;
case 0x42: case 0x42:
SisSdtContainer sdtContainer = new SisSdtContainer(); SisSdtContainer sdtContainer = new SisSdtContainer();
SdtParser sdtParser = new SdtParser(sdtContainer); SdtParser sdtParser = new SdtParser(sdtContainer);
sdtParser.GatherPsi(section, 0); sdtParser.GatherPsi(section, 0);
_handler.OnSisSdt(sourcePid, sdtContainer); _handler.OnSisSdt(sourcePid, _parentProgram, sdtContainer);
break; break;
case 0x4e: case 0x4e:
case 0x50: case 0x50:
SisEitContainer eitContainer = new SisEitContainer(); SisEitContainer eitContainer = new SisEitContainer();
EitParser eitParser = new EitParser(eitContainer); EitParser eitParser = new EitParser(eitContainer);
eitParser.GatherPsi(section, sourcePid); eitParser.GatherPsi(section, sourcePid);
_handler.OnSisEit(sourcePid, eitContainer); _handler.OnSisEit(sourcePid, _parentProgram, eitContainer);
break; break;
case 0x70: case 0x70:
SisTdtContainer tdtContainer = new SisTdtContainer(); SisTdtContainer tdtContainer = new SisTdtContainer();
TimetableParser tdtParser = new TimetableParser(tdtContainer, null); TimetableParser tdtParser = new TimetableParser(tdtContainer, null);
tdtParser.GatherPsi(section, sourcePid); tdtParser.GatherPsi(section, sourcePid);
_handler.OnSisTdt(sourcePid, tdtContainer); _handler.OnSisTdt(sourcePid, _parentProgram, tdtContainer);
break; break;
case 0x73: case 0x73:
SisTotContainer totContainer = new SisTotContainer(); SisTotContainer totContainer = new SisTotContainer();
TimetableParser totParser = new TimetableParser(null, totContainer); TimetableParser totParser = new TimetableParser(null, totContainer);
totParser.GatherPsi(section, sourcePid); totParser.GatherPsi(section, sourcePid);
_handler.OnSisTot(sourcePid, totContainer); _handler.OnSisTot(sourcePid, _parentProgram, totContainer);
break; break;
default: default:
throw new NotImplementedException(String.Format("Table ID 0x{0:X2} in DVB-SIS PSI/SI not supported yet. To get this fixed, please share a sample of this stream.", section.TableId)); throw new NotImplementedException(String.Format("Table ID 0x{0:X2} in DVB-SIS PSI/SI not supported yet. To get this fixed, please share a sample of this stream.", section.TableId));

View File

@ -34,11 +34,8 @@ using skyscraper5.Rds.Messages;
using skyscraper5.Scte35; using skyscraper5.Scte35;
using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Net; using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Net.Pcap;
using skyscraper5.Skyscraper.Plugins; using skyscraper5.Skyscraper.Plugins;
using skyscraper5.Skyscraper.Scraper.FrameGrabber; using skyscraper5.Skyscraper.Scraper.FrameGrabber;
using skyscraper5.Skyscraper.Scraper.Storage;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
using skyscraper5.Skyscraper.Scraper.Storage.Utilities; using skyscraper5.Skyscraper.Scraper.Storage.Utilities;
using skyscraper5.Skyscraper.Scraper.StreamAutodetection; using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
using skyscraper5.Skyscraper.Scraper.Utils; using skyscraper5.Skyscraper.Scraper.Utils;
@ -48,8 +45,6 @@ using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model.Descriptors; using skyscraper5.src.InteractionChannel.Model.Descriptors;
using skyscraper5.src.Mpeg2; using skyscraper5.src.Mpeg2;
using skyscraper5.src.Mpeg2.PacketFilter; using skyscraper5.src.Mpeg2.PacketFilter;
using skyscraper5.src.Privates;
using skyscraper5.src.Skyscraper;
using skyscraper5.src.Skyscraper.Scraper.Dns; using skyscraper5.src.Skyscraper.Scraper.Dns;
using skyscraper5.src.Teletext; using skyscraper5.src.Teletext;
using skyscraper5.T2MI; using skyscraper5.T2MI;
@ -65,17 +60,11 @@ using skyscraper8.Ietf.Rfc4236_ULE;
using skyscraper8.Ses; using skyscraper8.Ses;
using skyscraper8.Skyscraper.Scraper.Storage; using skyscraper8.Skyscraper.Scraper.Storage;
using skyscraper8.yo3explorer; using skyscraper8.yo3explorer;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Reflection; using System.Reflection;
using System.Security.Policy;
using System.Text; using System.Text;
using MimeKit; using MimeKit;
using skyscraper5.src.InteractionChannel.Model2; using skyscraper5.src.InteractionChannel.Model2;
@ -84,7 +73,6 @@ using skyscraper8.Experimentals.NdsSsu;
using skyscraper8.Experimentals.OtvSsu; using skyscraper8.Experimentals.OtvSsu;
using skyscraper8.GS; using skyscraper8.GS;
using skyscraper8.GSE; using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ieee802_1AB; using skyscraper8.Ieee802_1AB;
using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model2;
@ -711,7 +699,7 @@ namespace skyscraper5.Skyscraper.Scraper
DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, dsaciHandler)); DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, dsaciHandler));
break; break;
case StreamType.SisPsiTables: case StreamType.SisPsiTables:
SisPsiHandler sisPsiHandler = new SisPsiHandler(this); SisPsiHandler sisPsiHandler = new SisPsiHandler(this, result.ProgramNumber);
DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, sisPsiHandler)); DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, sisPsiHandler));
break; break;
default: default:
@ -3330,19 +3318,19 @@ namespace skyscraper5.Skyscraper.Scraper
logger.WarnFormat("Found a DOCSIS Dynamic Service Addition. Those aren't supported yet. It would be great if you could share a sample of this stream, so those can be implemented."); logger.WarnFormat("Found a DOCSIS Dynamic Service Addition. Those aren't supported yet. It would be great if you could share a sample of this stream, so those can be implemented.");
} }
private SkyscraperContext GetSisContext(int sourcePid) private SkyscraperContext GetSisContext(ushort sisService)
{ {
if (subSkyscrapers == null) if (subSkyscrapers == null)
subSkyscrapers = new Dictionary<object, SkyscraperContext>(); subSkyscrapers = new Dictionary<object, SkyscraperContext>();
SisPid sisContext = new SisPid(sourcePid); SisProgramIdentifier sisContext = new SisProgramIdentifier(sisService);
if (subSkyscrapers.ContainsKey(sisContext)) if (subSkyscrapers.ContainsKey(sisContext))
{ {
return subSkyscrapers[sisContext]; return subSkyscrapers[sisContext];
} }
else else
{ {
LogEvent(SkyscraperContextEvent.DvbSisDaughterSitePsi, String.Format("Additional terrestrial PSI/SI tables on PID 0x{0:X4}", sourcePid)); LogEvent(SkyscraperContextEvent.DvbSisDaughterSitePsi, String.Format("Additional terrestrial PSI/SI tables for SIS Program {0}", sisService));
SkyscraperContext child = new SkyscraperContext(new TsContext(), this.DataStorage, this.ObjectStorage); SkyscraperContext child = new SkyscraperContext(new TsContext(), this.DataStorage, this.ObjectStorage);
child.IsChild = true; child.IsChild = true;
child.ChildName = sisContext.ToString(); child.ChildName = sisContext.ToString();
@ -3351,11 +3339,11 @@ namespace skyscraper5.Skyscraper.Scraper
} }
} }
public void OnSisCat(int sourcePid, SisCatContainer catContainer) public void OnSisCat(int sourcePid, ushort sourceProgram, SisCatContainer catContainer)
{ {
if (catContainer.CaDescriptors.Count > 0) if (catContainer.CaDescriptors.Count > 0)
{ {
SkyscraperContext skyscraperContext = GetSisContext(sourcePid); SkyscraperContext skyscraperContext = GetSisContext(sourceProgram);
foreach(CaDescriptor catEntry in catContainer.CaDescriptors) foreach(CaDescriptor catEntry in catContainer.CaDescriptors)
{ {
@ -3389,9 +3377,9 @@ namespace skyscraper5.Skyscraper.Scraper
} }
} }
public void OnSisEit(int sourcePid, SisEitContainer eitContainer) public void OnSisEit(int sourcePid, ushort sourceProgram, SisEitContainer eitContainer)
{ {
SkyscraperContext skyscraperContext = GetSisContext(sourcePid); SkyscraperContext skyscraperContext = GetSisContext(sourceProgram);
if (eitContainer.NetworkId.HasValue) if (eitContainer.NetworkId.HasValue)
skyscraperContext.SetNetworkId(eitContainer.NetworkId.Value); skyscraperContext.SetNetworkId(eitContainer.NetworkId.Value);
if (eitContainer.TransportStreamId.HasValue) if (eitContainer.TransportStreamId.HasValue)
@ -3421,9 +3409,9 @@ namespace skyscraper5.Skyscraper.Scraper
_sisFtiData[relatedPid] = fti.Plps; _sisFtiData[relatedPid] = fti.Plps;
} }
public void OnSisNit(int sourcePid, SisNitContainer nitContainer) public void OnSisNit(int sourcePid, ushort sourceProgram, SisNitContainer nitContainer)
{ {
SkyscraperContext skyscraperContext = GetSisContext(sourcePid); SkyscraperContext skyscraperContext = GetSisContext(sourceProgram);
if (nitContainer.NetworkId.HasValue) if (nitContainer.NetworkId.HasValue)
skyscraperContext.SetNetworkId(nitContainer.NetworkId.Value); skyscraperContext.SetNetworkId(nitContainer.NetworkId.Value);
if (nitContainer.Network != null) if (nitContainer.Network != null)
@ -3437,9 +3425,9 @@ namespace skyscraper5.Skyscraper.Scraper
} }
} }
public void OnSisPat(int sourcePid, SisPatContainer patContainer) public void OnSisPat(int sourcePid, ushort sourceProgram, SisPatContainer patContainer)
{ {
SkyscraperContext skyscraperContext = GetSisContext(sourcePid); SkyscraperContext skyscraperContext = GetSisContext(sourceProgram);
if (patContainer.NetworkPid.HasValue) if (patContainer.NetworkPid.HasValue)
skyscraperContext.NetworkPidFromPat(patContainer.NetworkPid.Value); skyscraperContext.NetworkPidFromPat(patContainer.NetworkPid.Value);
if (patContainer.TransportStreamId.HasValue) if (patContainer.TransportStreamId.HasValue)
@ -3452,15 +3440,15 @@ namespace skyscraper5.Skyscraper.Scraper
} }
public void OnSisPmt(int sourcePid, SisPmtContainer pmtContainer) public void OnSisPmt(int sourcePid, ushort sourceProgram, SisPmtContainer pmtContainer)
{ {
SkyscraperContext context = GetSisContext(sourcePid); SkyscraperContext context = GetSisContext(sourceProgram);
context.PmtEvent(pmtContainer.ProgramMapping, 0); context.PmtEvent(pmtContainer.ProgramMapping, 0);
} }
public void OnSisSdt(int sourcePid, SisSdtContainer sdtContainer) public void OnSisSdt(int sourcePid, ushort sourceProgram, SisSdtContainer sdtContainer)
{ {
SkyscraperContext context = GetSisContext(sourcePid); SkyscraperContext context = GetSisContext(sourceProgram);
if (sdtContainer.NetworkId.HasValue) if (sdtContainer.NetworkId.HasValue)
context.SetNetworkId(sdtContainer.NetworkId.Value); context.SetNetworkId(sdtContainer.NetworkId.Value);
@ -3476,11 +3464,11 @@ namespace skyscraper5.Skyscraper.Scraper
} }
} }
public void OnSisTdt(int sourcePid, SisTdtContainer tdtContainer) public void OnSisTdt(int sourcePid, ushort sourceProgram, SisTdtContainer tdtContainer)
{ {
if (tdtContainer.UtcTime.HasValue) if (tdtContainer.UtcTime.HasValue)
{ {
SkyscraperContext context = GetSisContext(sourcePid); SkyscraperContext context = GetSisContext(sourceProgram);
context.OnTdtTime(tdtContainer.UtcTime.Value); context.OnTdtTime(tdtContainer.UtcTime.Value);
} }
} }
@ -3510,11 +3498,11 @@ namespace skyscraper5.Skyscraper.Scraper
} }
} }
public void OnSisTot(int sourcePid, SisTotContainer totContainer) public void OnSisTot(int sourcePid, ushort sourceProgram, SisTotContainer totContainer)
{ {
if (totContainer.LocalTimeOffset != null) if (totContainer.LocalTimeOffset != null)
{ {
SkyscraperContext context = GetSisContext(sourcePid); SkyscraperContext context = GetSisContext(sourceProgram);
context.OnTotTime(totContainer.UtcTime, totContainer.LocalTimeOffset); context.OnTotTime(totContainer.UtcTime, totContainer.LocalTimeOffset);
} }
} }