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]
public void Rcs2Nip()
public void GseRcs2()
{
FileStream streamSample = GetStreamSample("telstar12v-bfbs-000000.ts");
ProcessSample(streamSample);
@ -91,6 +91,22 @@ public class CapturedTests : Feyllure
//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)

View File

@ -10,7 +10,7 @@ namespace skyscraper8.DvbSis
{
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
{
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 OnSisEit(int sourcePid, SisEitContainer eitContainer);
void OnSisEit(int sourcePid, ushort sourceProgram, SisEitContainer eitContainer);
void OnSisFti(int relatedPid, _0xF0_FramingTimingInformation fti);
void OnSisNit(int sourcePid, SisNitContainer nitContainer);
void OnSisPat(int sourcePid, SisPatContainer patContainer);
void OnSisPmt(int sourcePid, SisPmtContainer pmtContainer);
void OnSisSdt(int sourcePid, SisSdtContainer sdtContainer);
void OnSisTdt(int sourcePid, SisTdtContainer tdtContainer);
void OnSisNit(int sourcePid, ushort sourceProgram, SisNitContainer nitContainer);
void OnSisPat(int sourcePid, ushort sourceProgram, SisPatContainer patContainer);
void OnSisPmt(int sourcePid, ushort sourceProgram, SisPmtContainer pmtContainer);
void OnSisSdt(int sourcePid, ushort sourceProgram, SisSdtContainer sdtContainer);
void OnSisTdt(int sourcePid, ushort sourceProgram, SisTdtContainer tdtContainer);
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
{
public SisPsiHandler(SisHandler handler)
public SisPsiHandler(SisHandler handler, ushort parentProgram)
{
_handler = handler;
_parentProgram = parentProgram;
}
private SisHandler _handler;
private ushort _parentProgram;
public void GatherPsi(PsiSection section, int sourcePid)
{
@ -26,50 +28,50 @@ namespace skyscraper8.DvbSis
SisPatContainer patContainer = new SisPatContainer();
PatParser patParser = new PatParser(patContainer);
patParser.GatherPsi(section, 0);
_handler.OnSisPat(sourcePid, patContainer);
_handler.OnSisPat(sourcePid, _parentProgram, patContainer);
break;
case 0x01:
SisCatContainer catContainer = new SisCatContainer();
CatParser catParser = new CatParser(catContainer);
catParser.GatherPsi(section, 0);
_handler.OnSisCat(sourcePid, catContainer);
_handler.OnSisCat(sourcePid, _parentProgram, catContainer);
break;
case 0x02:
SisPmtContainer pmtContainer = new SisPmtContainer();
PmtParser pmtParser = new PmtParser(pmtContainer);
pmtParser.GatherPsi(section, 0);
_handler.OnSisPmt(sourcePid, pmtContainer);
_handler.OnSisPmt(sourcePid, _parentProgram, pmtContainer);
break;
case 0x40:
SisNitContainer nitContainer = new SisNitContainer();
NitParser nitParser = new NitParser(nitContainer);
nitParser.GatherPsi(section, 0);
_handler.OnSisNit(sourcePid, nitContainer);
_handler.OnSisNit(sourcePid, _parentProgram, nitContainer);
break;
case 0x42:
SisSdtContainer sdtContainer = new SisSdtContainer();
SdtParser sdtParser = new SdtParser(sdtContainer);
sdtParser.GatherPsi(section, 0);
_handler.OnSisSdt(sourcePid, sdtContainer);
_handler.OnSisSdt(sourcePid, _parentProgram, sdtContainer);
break;
case 0x4e:
case 0x50:
SisEitContainer eitContainer = new SisEitContainer();
EitParser eitParser = new EitParser(eitContainer);
eitParser.GatherPsi(section, sourcePid);
_handler.OnSisEit(sourcePid, eitContainer);
_handler.OnSisEit(sourcePid, _parentProgram, eitContainer);
break;
case 0x70:
SisTdtContainer tdtContainer = new SisTdtContainer();
TimetableParser tdtParser = new TimetableParser(tdtContainer, null);
tdtParser.GatherPsi(section, sourcePid);
_handler.OnSisTdt(sourcePid, tdtContainer);
_handler.OnSisTdt(sourcePid, _parentProgram, tdtContainer);
break;
case 0x73:
SisTotContainer totContainer = new SisTotContainer();
TimetableParser totParser = new TimetableParser(null, totContainer);
totParser.GatherPsi(section, sourcePid);
_handler.OnSisTot(sourcePid, totContainer);
_handler.OnSisTot(sourcePid, _parentProgram, totContainer);
break;
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));

View File

@ -34,11 +34,8 @@ using skyscraper5.Rds.Messages;
using skyscraper5.Scte35;
using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Net.Pcap;
using skyscraper5.Skyscraper.Plugins;
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.StreamAutodetection;
using skyscraper5.Skyscraper.Scraper.Utils;
@ -48,8 +45,6 @@ using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model.Descriptors;
using skyscraper5.src.Mpeg2;
using skyscraper5.src.Mpeg2.PacketFilter;
using skyscraper5.src.Privates;
using skyscraper5.src.Skyscraper;
using skyscraper5.src.Skyscraper.Scraper.Dns;
using skyscraper5.src.Teletext;
using skyscraper5.T2MI;
@ -65,17 +60,11 @@ using skyscraper8.Ietf.Rfc4236_ULE;
using skyscraper8.Ses;
using skyscraper8.Skyscraper.Scraper.Storage;
using skyscraper8.yo3explorer;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Security.Policy;
using System.Text;
using MimeKit;
using skyscraper5.src.InteractionChannel.Model2;
@ -84,7 +73,6 @@ using skyscraper8.Experimentals.NdsSsu;
using skyscraper8.Experimentals.OtvSsu;
using skyscraper8.GS;
using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ieee802_1AB;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
@ -711,7 +699,7 @@ namespace skyscraper5.Skyscraper.Scraper
DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, dsaciHandler));
break;
case StreamType.SisPsiTables:
SisPsiHandler sisPsiHandler = new SisPsiHandler(this);
SisPsiHandler sisPsiHandler = new SisPsiHandler(this, result.ProgramNumber);
DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, new PsiDecoder(mappingStream.ElementaryPid, sisPsiHandler));
break;
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.");
}
private SkyscraperContext GetSisContext(int sourcePid)
private SkyscraperContext GetSisContext(ushort sisService)
{
if (subSkyscrapers == null)
subSkyscrapers = new Dictionary<object, SkyscraperContext>();
SisPid sisContext = new SisPid(sourcePid);
SisProgramIdentifier sisContext = new SisProgramIdentifier(sisService);
if (subSkyscrapers.ContainsKey(sisContext))
{
return subSkyscrapers[sisContext];
}
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);
child.IsChild = true;
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)
{
SkyscraperContext skyscraperContext = GetSisContext(sourcePid);
SkyscraperContext skyscraperContext = GetSisContext(sourceProgram);
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)
skyscraperContext.SetNetworkId(eitContainer.NetworkId.Value);
if (eitContainer.TransportStreamId.HasValue)
@ -3421,9 +3409,9 @@ namespace skyscraper5.Skyscraper.Scraper
_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)
skyscraperContext.SetNetworkId(nitContainer.NetworkId.Value);
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)
skyscraperContext.NetworkPidFromPat(patContainer.NetworkPid.Value);
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);
}
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)
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)
{
SkyscraperContext context = GetSisContext(sourcePid);
SkyscraperContext context = GetSisContext(sourceProgram);
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)
{
SkyscraperContext context = GetSisContext(sourcePid);
SkyscraperContext context = GetSisContext(sourceProgram);
context.OnTotTime(totContainer.UtcTime, totContainer.LocalTimeOffset);
}
}