From f5b8a76803473791aa5d44b4f7b1a93467a1e893 Mon Sep 17 00:00:00 2001 From: fey Date: Wed, 26 Aug 2026 22:09:40 +0200 Subject: [PATCH] Began implementing ISDB BIT. --- .../Descriptors/0x50_ComponentDescriptor.cs | 2 +- .../0x58_LocalTimeOffsetDescriptor.cs | 2 +- .../Dvb/Descriptors/0x7C_AacDescriptor.cs | 4 +-- .../Isdb/EventHandlers/IBitEventHandler.cs | 13 ++++++++ ...ventHandler.cs => IIsdbPmtEventHandler.cs} | 0 skyscraper8/Isdb/Matenro.cs | 32 ++++++++++++++++++- skyscraper8/Isdb/Parsers/BitParser.cs | 31 ++++++++++++++++++ skyscraper8/Isdb/Parsers/IsdbPmtParser.cs | 24 ++++++++++++++ .../Isdb/Subtitles/IIsdbSubtitleHandler.cs | 6 ++++ .../Isdb/Subtitles/IsdbSubtitlePesParser.cs | 11 +++++++ skyscraper8/Isdb/Tables/IsdbPmtStream.cs | 5 +++ .../0x06_DataStreamAlignmentDescriptor.cs | 2 +- .../Descriptors/0x28_AvcVideoDescriptor.cs | 4 +-- skyscraper8/Skyscraper/Scraper/StreamType.cs | 3 +- 14 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 skyscraper8/Isdb/EventHandlers/IBitEventHandler.cs rename skyscraper8/Isdb/EventHandlers/{IsdbPmtEventHandler.cs => IIsdbPmtEventHandler.cs} (100%) create mode 100644 skyscraper8/Isdb/Subtitles/IIsdbSubtitleHandler.cs create mode 100644 skyscraper8/Isdb/Subtitles/IsdbSubtitlePesParser.cs diff --git a/skyscraper8/Dvb/Descriptors/0x50_ComponentDescriptor.cs b/skyscraper8/Dvb/Descriptors/0x50_ComponentDescriptor.cs index 1e030dc..9be7b38 100644 --- a/skyscraper8/Dvb/Descriptors/0x50_ComponentDescriptor.cs +++ b/skyscraper8/Dvb/Descriptors/0x50_ComponentDescriptor.cs @@ -13,7 +13,7 @@ using skyscraper5.Skyscraper.Text; namespace skyscraper5.Dvb.Descriptors { [SkyscraperPlugin] - [TsDescriptor(0x50,"EIT","SDT")] + [TsDescriptor(0x50,"EIT","SDT", "ISDB PMT")] [BannedTable("PMT","TSDT","BAT")] public class ComponentDescriptor : TsDescriptor { diff --git a/skyscraper8/Dvb/Descriptors/0x58_LocalTimeOffsetDescriptor.cs b/skyscraper8/Dvb/Descriptors/0x58_LocalTimeOffsetDescriptor.cs index 496497e..f853b85 100644 --- a/skyscraper8/Dvb/Descriptors/0x58_LocalTimeOffsetDescriptor.cs +++ b/skyscraper8/Dvb/Descriptors/0x58_LocalTimeOffsetDescriptor.cs @@ -11,7 +11,7 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Dvb.Descriptors { [SkyscraperPlugin] - [TsDescriptor(0x58,"TOT")] + [TsDescriptor(0x58,"TOT", "ISDB TOT")] public class LocalTimeOffsetDescriptor : TsDescriptor { public LocalTimeOffsetDescriptor(byte[] buffer) diff --git a/skyscraper8/Dvb/Descriptors/0x7C_AacDescriptor.cs b/skyscraper8/Dvb/Descriptors/0x7C_AacDescriptor.cs index 953c3ce..c82941d 100644 --- a/skyscraper8/Dvb/Descriptors/0x7C_AacDescriptor.cs +++ b/skyscraper8/Dvb/Descriptors/0x7C_AacDescriptor.cs @@ -11,8 +11,8 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Dvb.Descriptors { [SkyscraperPlugin] - [TsDescriptor(0x7c,"PMT")] - class AacDescriptor : TsDescriptor + [TsDescriptor(0x7c,"PMT", "ISDB PMT")] + public class AacDescriptor : TsDescriptor { public AacDescriptor(byte[] buffer) { diff --git a/skyscraper8/Isdb/EventHandlers/IBitEventHandler.cs b/skyscraper8/Isdb/EventHandlers/IBitEventHandler.cs new file mode 100644 index 0000000..ccd23ab --- /dev/null +++ b/skyscraper8/Isdb/EventHandlers/IBitEventHandler.cs @@ -0,0 +1,13 @@ +namespace skyscraper8.Isdb.EventHandlers; + +public interface IBitEventHandler +{ + void BitError(BitErrors error); +} + +public enum BitErrors +{ + WrongTableId, + SyntaxIndicatorMissing, + SectionLengthWrong +} \ No newline at end of file diff --git a/skyscraper8/Isdb/EventHandlers/IsdbPmtEventHandler.cs b/skyscraper8/Isdb/EventHandlers/IIsdbPmtEventHandler.cs similarity index 100% rename from skyscraper8/Isdb/EventHandlers/IsdbPmtEventHandler.cs rename to skyscraper8/Isdb/EventHandlers/IIsdbPmtEventHandler.cs diff --git a/skyscraper8/Isdb/Matenro.cs b/skyscraper8/Isdb/Matenro.cs index 2fd4fd4..9eef8df 100644 --- a/skyscraper8/Isdb/Matenro.cs +++ b/skyscraper8/Isdb/Matenro.cs @@ -11,6 +11,7 @@ using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Scraper; using skyscraper8.Isdb.EventHandlers; using skyscraper8.Isdb.Psi; +using skyscraper8.Isdb.Subtitles; using skyscraper8.Isdb.Tables; using skyscraper8.Skyscraper.Scraper.Storage; @@ -165,9 +166,16 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd public void OnTotTime(DateTime utcTime, LocalTimeOffsetDescriptor ltod) { + if (!_networkPid.HasValue) + return; + + if (!_transportStreamId.HasValue) + return; + throw new NotImplementedException(); } + private bool[] pidsReferencedByPmt; private List storedPmts; public void PmtEvent(IsdbPmt result, int sourcePid) { @@ -193,6 +201,12 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd foreach (IsdbPmtStream pmtStream in result.Streams) { + if (pidsReferencedByPmt == null) + pidsReferencedByPmt = new bool[0x2000]; + if (pidsReferencedByPmt[sourcePid]) + continue; + + pidsReferencedByPmt[sourcePid] = true; StreamType streamType = DetectStreamType(pmtStream); switch (streamType) { @@ -200,11 +214,14 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd continue; case StreamType.Audio: continue; + case StreamType.IsdbSubtitles: + case StreamType.IsdbTeletext: + DvbContext.RegisterPacketProcessor(pmtStream.ElementaryPid, new PesDecoder(new IsdbSubtitlePesParser())); + continue; default: throw new NotImplementedException(String.Format("Could not figure out what to do with a {0} stream. It would be great if you could share a sample of this stream, so I can try to implement this.", streamType)); } } - throw new NotImplementedException(); } private StreamType DetectStreamType(IsdbPmtStream pmtStream) @@ -217,12 +234,25 @@ public class Matenro : IPatEventHandler, ICatEventHandler, IBatEventHandler, ISd { switch (pmtStream.DataComponent.DataComponentId) { + case 0x0008: + //STD-B24 + //Sub-clause 9.6.1, Part 3, Vol. 1 + return StreamType.IsdbTeletext; case 0x0012: + //Sub-clause 9.6.1, Part 3, Vol. 1 + //content descriptor = Sub-clause 9.6.2, Part 3, Vol. 1 return StreamType.IsdbSubtitles; default: throw new IsdbException(String.Format("Unknown ISDB Data Component 0x{0:X4}", pmtStream.DataComponent.DataComponentId)); } } + + if (pmtStream.StreamType == PmtStreamType.H262) + return StreamType.Video; + if (pmtStream.StreamType == PmtStreamType.Iso13818_3Audio) + return StreamType.Audio; + if (pmtStream.StreamType == PmtStreamType.Iso11172Video) + return StreamType.Video; throw new IsdbException(String.Format("Could not detect stream type for PID 0x{0:X4}. It would be great if you could share a sample of this stream, so I can try to implement this.", pmtStream.ElementaryPid)); } diff --git a/skyscraper8/Isdb/Parsers/BitParser.cs b/skyscraper8/Isdb/Parsers/BitParser.cs index f56e3c8..229041b 100644 --- a/skyscraper8/Isdb/Parsers/BitParser.cs +++ b/skyscraper8/Isdb/Parsers/BitParser.cs @@ -1,11 +1,42 @@ using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.IO; +using skyscraper8.Isdb.EventHandlers; namespace skyscraper8.Isdb.Psi; public class BitParser : IPsiProcessor { + private IBitEventHandler eventHandler; public void GatherPsi(PsiSection section, int sourcePid) { + byte[] data = section.GetDataCopy(); + MemoryStream ms = new MemoryStream(data); + byte tableId = ms.ReadUInt8(); + if (tableId != 0xc4) + { + eventHandler.BitError(BitErrors.WrongTableId); + return; + } + + ushort sectionLength = ms.ReadUInt16BE(); + bool sectionSyntaxIndicator = (sectionLength & 0x8000) != 0; + if (!sectionSyntaxIndicator) + { + eventHandler.BitError(BitErrors.SyntaxIndicatorMissing); + return; + } + + sectionLength &= 0x0fff; + long actualSectionLength = ms.GetAvailableBytes(); + if (sectionLength > actualSectionLength) + { + eventHandler.BitError(BitErrors.SectionLengthWrong); + return; + } + + //continue on 6-STD-B10v5_13-E1.pdf, page 123 + + throw new NotImplementedException(); } } \ No newline at end of file diff --git a/skyscraper8/Isdb/Parsers/IsdbPmtParser.cs b/skyscraper8/Isdb/Parsers/IsdbPmtParser.cs index 20b1346..b092973 100644 --- a/skyscraper8/Isdb/Parsers/IsdbPmtParser.cs +++ b/skyscraper8/Isdb/Parsers/IsdbPmtParser.cs @@ -134,6 +134,30 @@ public class IsdbPmtParser(IIsdbPmtEventHandler handler, int pmtPid, ushort prog else throw new NotImplementedException("Multiple Data components are not yet supported - it would be great if you could share a sample recording of this stream so I can implement this."); break; + case ComponentDescriptor cd: + if (streamChild.Component == null) + streamChild.Component = cd; + else + throw new NotImplementedException("Multiple components in one stream are not yet supported - it would be great if you could share a sample recording of this stream so I can implement this."); + break; + case DataStreamAlignmentDescriptor dsad: + if (streamChild.DataStreamAlignmentType == null) + streamChild.DataStreamAlignmentType = dsad.AlignmentType; + else + throw new NotImplementedException("Multiple Data Stream Alignments in one stream are not yet supported - it would be great if you could share a sample recording of this stream so I can implement this."); + break; + case AvcVideoDescriptor avd: + if (streamChild.AvcVideo == null) + streamChild.AvcVideo = avd; + else + throw new NotImplementedException("Multi AVC Videos in one stream are not supported yet - it would be great if you could implement this."); + break; + case AacDescriptor ad: + if (streamChild.Aac == null) + streamChild.Aac = ad; + else + throw new NotImplementedException("Multi AAC Audios in one stream are not supported yet - it would be great if you could implement this."); + break; default: throw new NotImplementedException("Unknown descriptor type in ISDB PMT: " + descriptor.GetType() + " - it would be fabulous if you could share a sample of this stream so this can be implemented!"); } diff --git a/skyscraper8/Isdb/Subtitles/IIsdbSubtitleHandler.cs b/skyscraper8/Isdb/Subtitles/IIsdbSubtitleHandler.cs new file mode 100644 index 0000000..5782869 --- /dev/null +++ b/skyscraper8/Isdb/Subtitles/IIsdbSubtitleHandler.cs @@ -0,0 +1,6 @@ +namespace skyscraper8.Isdb.Subtitles; + +public interface IIsdbSubtitleHandler +{ + +} \ No newline at end of file diff --git a/skyscraper8/Isdb/Subtitles/IsdbSubtitlePesParser.cs b/skyscraper8/Isdb/Subtitles/IsdbSubtitlePesParser.cs new file mode 100644 index 0000000..a1275e2 --- /dev/null +++ b/skyscraper8/Isdb/Subtitles/IsdbSubtitlePesParser.cs @@ -0,0 +1,11 @@ +using skyscraper5.Mpeg2; + +namespace skyscraper8.Isdb.Subtitles; + +class IsdbSubtitlePesParser : IPesProcessor +{ + public void ProcessPesPacket(PesPacket packet) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/skyscraper8/Isdb/Tables/IsdbPmtStream.cs b/skyscraper8/Isdb/Tables/IsdbPmtStream.cs index 0c5f2e9..21625ee 100644 --- a/skyscraper8/Isdb/Tables/IsdbPmtStream.cs +++ b/skyscraper8/Isdb/Tables/IsdbPmtStream.cs @@ -1,3 +1,4 @@ +using skyscraper5.Dvb.Descriptors; using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Psi.Model; using skyscraper8.Isdb.Descriptors; @@ -11,4 +12,8 @@ public class IsdbPmtStream(PmtStreamType streamType, int elementaryPid) public byte? StreamIdentifierComponentTag { get; set; } public Iso639LanguageDescriptor Iso639Language { get; set; } public _0xFD_DataComponentDescriptor DataComponent { get; set; } + public ComponentDescriptor Component { get; set; } + public byte? DataStreamAlignmentType { get; set; } + public AvcVideoDescriptor AvcVideo { get; set; } + public AacDescriptor Aac { get; set; } } \ No newline at end of file diff --git a/skyscraper8/Mpeg2/Descriptors/0x06_DataStreamAlignmentDescriptor.cs b/skyscraper8/Mpeg2/Descriptors/0x06_DataStreamAlignmentDescriptor.cs index 3389203..c50de1e 100644 --- a/skyscraper8/Mpeg2/Descriptors/0x06_DataStreamAlignmentDescriptor.cs +++ b/skyscraper8/Mpeg2/Descriptors/0x06_DataStreamAlignmentDescriptor.cs @@ -9,7 +9,7 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Mpeg2.Descriptors { [SkyscraperPlugin] - [TsDescriptor(0x06,"PMT")] + [TsDescriptor(0x06,"PMT", "ISDB PMT")] [BannedTable("TSDT")] class DataStreamAlignmentDescriptor : TsDescriptor { diff --git a/skyscraper8/Mpeg2/Descriptors/0x28_AvcVideoDescriptor.cs b/skyscraper8/Mpeg2/Descriptors/0x28_AvcVideoDescriptor.cs index 3d2d7df..7320efd 100644 --- a/skyscraper8/Mpeg2/Descriptors/0x28_AvcVideoDescriptor.cs +++ b/skyscraper8/Mpeg2/Descriptors/0x28_AvcVideoDescriptor.cs @@ -10,8 +10,8 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Mpeg2.Descriptors { [SkyscraperPlugin] - [TsDescriptor(0x28,"PMT")] - class AvcVideoDescriptor : TsDescriptor + [TsDescriptor(0x28,"PMT", "ISDB PMT")] + public class AvcVideoDescriptor : TsDescriptor { public AvcVideoDescriptor(byte[] buffer) { diff --git a/skyscraper8/Skyscraper/Scraper/StreamType.cs b/skyscraper8/Skyscraper/Scraper/StreamType.cs index 2bb0426..d29f790 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamType.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamType.cs @@ -33,6 +33,7 @@ namespace skyscraper5.Skyscraper.Scraper SisFramingAndTiming, SisDaughterSiteAdapterConfiguration, SisPsiTables, - IsdbSubtitles + IsdbSubtitles, + IsdbTeletext } }