feyris-tan ef86554f9a Import
2025-05-12 22:09:16 +02:00

457 lines
15 KiB
C#

using Newtonsoft.Json;
using skyscraper5.Docsis;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Mhp.Si.Model;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Mpeg2.Psi.Model;
using skyscraper5.Scte35;
using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
using skyscraper5.Teletext.Wss;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace skyscraper5.UI.Overrides
{
internal class Form1UiJunction : ISkyscraperUiJunction
{
private INodeEngine form1;
public Dictionary<uint, string> SdtNames { get; private set; }
public Dictionary<int, uint> PidToPrograms { get; private set; }
private JsonSerializerSettings jsonSerializerSettings;
public Dictionary<int, string> UsageLabels { get; private set; }
public Form1UiJunction(INodeEngine form1)
{
this.form1 = form1;
this.jsonSerializerSettings = new JsonSerializerSettings();
this.jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore;
this.jsonSerializerSettings.Formatting = Formatting.Indented;
SetPidUsage(0x0000, "PAT");
SetPidUsage(0x0001, "CAT");
SetPidUsage(0x0002, "TSDT");
SetPidUsage(0x0010, "NIT");
SetPidUsage(0x0011, "SDT/BAT");
SetPidUsage(0x0012, "EIT/CIT");
SetPidUsage(0x0013, "RST");
SetPidUsage(0x0014, "TDT/TOT");
SetPidUsage(0x0015, "network synchronization");
SetPidUsage(0x0016, "RNT");
SetPidUsage(0x001c, "link-local inband signalling");
SetPidUsage(0x001d, "measurement");
SetPidUsage(0x001e, "DIT");
SetPidUsage(0x001f, "SIT");
}
private void SetPidUsage(int pid, string name)
{
if (UsageLabels == null)
UsageLabels = new Dictionary<int, string>();
UsageLabels[pid] = name;
}
public void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion)
{
throw new NotImplementedException();
}
public void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion)
{
throw new NotImplementedException();
}
public void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion, double moduleInfoDownloadProgress)
{
throw new NotImplementedException();
}
public void DsmCcVfs(VfsFile vfsFile)
{
SkyscraperUiNode dsmCcNode = form1.EnsureNodeExists("DSM-CC");
form1.SetIcon(dsmCcNode, 1);
string outName = String.Format("DSM-CC\\Object Carousels\\PID 0x{0:X4}\\{1}", vfsFile.SourcePid, vfsFile.Name);
string[] args = outName.Split("\\");
form1.EnsureNodeExists(args);
}
public IEnumerable<HumanReadableService> GetServices()
{
throw new NotImplementedException();
}
public void NotifyAit(AitApplication aitApplication)
{
SkyscraperUiNode applicationNode = form1.EnsureNodeExists("AIT", aitApplication.TryGetName());
form1.SetIcon((SkyscraperUiNode)applicationNode.Parent, 1);
}
private Dictionary<ushort, string> bats;
public void NotifyBat(BatBouquet batBouquet)
{
if (bats == null)
bats = new Dictionary<ushort, string>();
string name = String.Format("{0} ({1})", batBouquet.BouquetId, batBouquet.BouquetName);
if (!bats.ContainsKey(batBouquet.BouquetId))
bats.Add(batBouquet.BouquetId, name);
SkyscraperUiNode bouquetNode = form1.EnsureNodeExists("BAT", name);
form1.SetIcon((SkyscraperUiNode)bouquetNode.Parent, 1);
form1.SetIcon(bouquetNode, 7);
}
public void NotifyBatTs(ushort batBouquetBouquetId, BatTransportStream child)
{
string name = bats[batBouquetBouquetId];
string name2 = String.Format("TS #{0}", child.TransportStreamId);
SkyscraperUiNode batTsNode = form1.EnsureNodeExists("BAT", name, name2);
form1.SetIcon(batTsNode, 4);
}
public void NotifyBlockstreamCarrier()
{
throw new NotImplementedException();
}
public void NotifyCat(CaDescriptor caDescriptor)
{
string systemName = CaSystemNames.GetHumanReadableName(caDescriptor.CaSystemId);
string caName = String.Format("0x{0:X4} ({1})",caDescriptor.CaSystemId,systemName);
SkyscraperUiNode catNode = form1.EnsureNodeExists("CAT", caName);
if (!catNode.FillOutComplete)
{
form1.SetIcon((SkyscraperUiNode)catNode.Parent, 1);
form1.SetIcon(catNode, 6);
catNode.DetailedText = JsonConvert.SerializeObject(caDescriptor, jsonSerializerSettings);
SetPidUsage(caDescriptor.CaPid, String.Format("{0} ECM/EMM", systemName));
catNode.FillOutComplete = true;
}
}
public void NotifyDocsisCarrier(DocsisEnvironment docsisEnvironment)
{
throw new NotImplementedException();
}
public void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm)
{
throw new NotImplementedException();
}
public void NotifyEvent(EitEvent eitEvent)
{
SkyscraperUiNode serviceNode = form1.EnsureNodeExists("EIT", eitEvent.StartTime.ToShortDateString(), eitEvent.ServiceId.ToString());
form1.SetIcon((SkyscraperUiNode)serviceNode.Parent.Parent, 1);
form1.SetIcon((SkyscraperUiNode)serviceNode.Parent, 5);
form1.SetIcon(serviceNode, 8);
}
public void NotifyMpeTraffic(IpTrafficInfo iti, int ipv4PacketLength)
{
throw new NotImplementedException();
}
public void NotifyNit(NitTransportStream transportStream)
{
SkyscraperUiNode nitNode = form1.EnsureNodeExists("NIT", transportStream.RenderForUi());
if (!nitNode.FillOutComplete)
{
nitNode.DetailedText = JsonConvert.SerializeObject(nitNode, jsonSerializerSettings);
nitNode.FillOutComplete = true;
form1.SetIcon((SkyscraperUiNode)nitNode.Parent, 1);
form1.SetIcon(nitNode, 4);
}
}
public void NotifyPatProgram(int pmtPid, ushort programId)
{
string name = String.Format("PMT PID 0x{0:X4} - Program {0}", programId, pmtPid);
SkyscraperUiNode patNode = form1.EnsureNodeExists("PAT", name);
form1.SetIcon((SkyscraperUiNode)patNode.Parent, 1);
}
public void NotifyPmtProgram(ProgramMapping result, int pmtPid)
{
string name = String.Format("PMT PID 0x{0:X4} - Program {0}", result.ProgramNumber,pmtPid);
SkyscraperUiNode programNode = form1.EnsureNodeExists("PAT",name);
if (!programNode.FillOutComplete)
{
form1.RunOnUiThread(() => form1.EnsureNodeExists("PAT").Expand());
if (!programNode.FillOutComplete)
{
programNode.DetailedText = JsonConvert.SerializeObject(result, jsonSerializerSettings);
programNode.FillOutComplete = true;
}
string sdtName = null;
form1.RunOnUiThread(() => sdtName = TrySdtFromPmt(result.ProgramNumber));
if (sdtName != null)
{
form1.EnsureNodeExists("PAT", name, String.Format("SDT: {0}", sdtName));
form1.RunOnUiThread(() => programNode.Expand());
}
foreach (ProgramMappingStream pmtEntry in result.Streams)
{
string name2 = String.Format("PID 0x{0:X4}", pmtEntry.ElementaryPid);
SkyscraperUiNode pidNode = form1.EnsureNodeExists("PAT", name, name2);
form1.SetIcon((SkyscraperUiNode)pidNode.Parent, 8);
pidNode.DetailedText = JsonConvert.SerializeObject(pmtEntry, jsonSerializerSettings);
if (PidToPrograms == null)
PidToPrograms = new Dictionary<int, uint>();
PidToPrograms.Add(pmtEntry.ElementaryPid, result.ProgramNumber);
SetPidUsage(pmtEntry.ElementaryPid, StreamTypeAsString(pmtEntry,result.PrivateDataSpecifier));
}
PidToPrograms.Add(pmtPid, result.ProgramNumber);
SetPidUsage(pmtPid, "PMT");
programNode.FillOutComplete = true;
}
}
private string TrySdtFromPmt(ushort programNumber)
{
if (!form1.TestForNode("SDT"))
return null;
SkyscraperUiNode sdtNode = form1.EnsureNodeExists("SDT");
foreach(TreeNode node in sdtNode.Nodes)
{
string prefix = String.Format("{0} ", programNumber);
if (node.Text.StartsWith(prefix))
{
string result = node.Text.Substring(node.Text.Length);
return result;
}
}
return null;
}
public void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert)
{
throw new NotImplementedException();
}
public void NotifyScte35(ushort programNumber, TimeSignal spliceInsert)
{
throw new NotImplementedException();
}
public void NotifySdtService(SdtService sdtService)
{
string name = String.Format("{0} {1}", sdtService.ServiceId, sdtService.ServiceName);
SkyscraperUiNode node = form1.EnsureNodeExists("SDT", name);
if (!node.FillOutComplete)
{
if (SdtNames == null)
SdtNames = new Dictionary<uint, string>();
SdtNames.Add(sdtService.ServiceId, sdtService.ServiceName);
node.DetailedText = JsonConvert.SerializeObject(sdtService, jsonSerializerSettings);
form1.RunOnUiThread(new Action(() => { TrySdtToPmt(sdtService.ServiceId, sdtService.ServiceName); }));
form1.SetIcon((SkyscraperUiNode)node.Parent, 1);
node.FillOutComplete = true;
}
}
private void TrySdtToPmt(uint programNo, string serviceName)
{
if (!form1.TestForNode("PAT"))
return;
string query = String.Format(" {0}", programNo);
SkyscraperUiNode patNode = form1.EnsureNodeExists("PAT");
foreach(TreeNode node in patNode.Nodes)
{
if (node.Text.EndsWith(query))
{
SkyscraperUiNode childNode = new SkyscraperUiNode();
childNode.Text = String.Format("SDT: {0}", serviceName);
node.Nodes.Add(childNode);
break;
}
}
}
public void NotifyStreamTypeDetection(string contestantTag, int pid)
{
throw new NotImplementedException();
}
public void NotifyTdt(DateTime utcTime)
{
SkyscraperUiNode skyscraperUiNode = form1.EnsureNodeExists("TDT");
form1.SetIcon(skyscraperUiNode, 1);
if (skyscraperUiNode.Nodes.Count == 0)
{
SkyscraperUiNode child = new SkyscraperUiNode();
child.Text = utcTime.ToString();
form1.RunOnUiThread(() =>
{
skyscraperUiNode.Nodes.Add(child);
skyscraperUiNode.Expand();
}
);
form1.SetIcon(child, 3);
}
else
{
SkyscraperUiNode oldChild = (SkyscraperUiNode)skyscraperUiNode.Nodes[0];
form1.RunOnUiThread(() => oldChild.Text = utcTime.ToString());
}
}
public void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod)
{
SkyscraperUiNode skyscraperUiNode = form1.EnsureNodeExists("TOT");
form1.SetIcon(skyscraperUiNode, 1);
if (skyscraperUiNode.Nodes.Count == 0)
{
SkyscraperUiNode child = new SkyscraperUiNode();
child.Text = utcTime.ToString();
form1.RunOnUiThread(() =>
{
skyscraperUiNode.Nodes.Add(child);
skyscraperUiNode.Expand();
}
);
if (!child.FillOutComplete)
{
form1.SetIcon(child, 3);
child.DetailedText = JsonConvert.SerializeObject(ltod, jsonSerializerSettings);
}
}
else
{
SkyscraperUiNode oldChild = (SkyscraperUiNode)skyscraperUiNode.Nodes[0];
form1.RunOnUiThread(() => oldChild.Text = utcTime.ToString());
}
}
public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock)
{
throw new NotImplementedException();
}
public void SetGseMode()
{
throw new NotImplementedException();
}
public void SetMemorySaverMode(bool saveMemory)
{
throw new NotImplementedException();
}
public void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, int mappingStreamElementaryPid, byte[] imageData)
{
throw new NotImplementedException();
}
private string StreamTypeAsString(ProgramMappingStream stream, uint? parentRegistrationFormatIdentifier)
{
if (stream.StreamType == PmtStreamType.H262)
return "MPEG-2 Video";
if (stream.AvcStillPresent.HasValue)
return "MPEG-4 Video";
if (stream.AudioType.HasValue)
{
switch (stream.AudioType)
{
case AudioType.CleanEffects: return "Audio";
case AudioType.HearingImpaired: return "Audio (for hearing impaired)";
case AudioType.VisualImpairedCommentary: return "Audio (for visually impaired)";
}
}
if (stream.StreamType == PmtStreamType.AvcVideoStream)
{
return "MPEG-4 Video";
}
if (stream.StreamType == PmtStreamType.Iso11172Audio)
{
return "Audio";
}
if (stream.StreamType == PmtStreamType.Iso13818_3Audio)
return "MPEG-2 Audio";
if (stream.StreamType == PmtStreamType.Iso13818_7AudioADTS)
return "AAC Audio";
if (stream.StreamType == PmtStreamType.HevcVideoStream)
return "H.265 Video";
if (stream.StreamType == PmtStreamType.Iso13818_1PesPackets && stream.Ac4ChannelMode.HasValue)
return "Dolby AC-4 Audio";
if (stream.StreamType == PmtStreamType.Iso13818_1PesPackets && stream.BSID.HasValue)
return "Dolby AC-3 Audio";
if (stream.StreamType == PmtStreamType.Iso14496_3Audio && stream.AacProfileAndLevel.HasValue)
return "AAC Audio";
if ((int)stream.StreamType == 0x81 && stream.ComponentType.HasValue)
return "Dolby AC-3 Audio";
if (stream.Teletexts != null)
return "Teletext";
if (stream.Applications != null)
return "Red-button Application";
if (stream.DataBroadcastId == 0x0123)
return "Red-button Application";
if (stream.DataBroadcastId == 0x000a)
return "System Software Update";
if (stream.StreamType == PmtStreamType.Iso13818_1PesPackets && stream.Subtitlings != null && stream.Subtitlings.Length > 0)
return "Subtitle";
if (stream.DataBroadcastId == 0xf0)
return "MHP Application";
if (stream.FormatIdentifier.HasValue && stream.FormatIdentifier == 0x43554549 && (int)stream.StreamType == 0x86)
return "Advertising Metadata";
if ((int)stream.StreamType == 0x86 && parentRegistrationFormatIdentifier.HasValue && parentRegistrationFormatIdentifier.Value == 0x43554549)
return "Advertising Metadata";
if (stream.DataBroadcastId == 0x0007)
return "Object Carousel";
if (stream.StreamType == PmtStreamType.Iso13818_1PesPackets && stream.VbiData != null)
return "Teletext";
if ((byte)stream.StreamType == 0x89 && stream.AncillaryDataDescriptor != null && stream.AncillaryDataDescriptor.RdsOnly)
return "Radio Data Service";
if (stream.DataBroadcastId.HasValue && stream.DataBroadcastId.Value == 0x0005 /*&& stream.StreamType == PmtStreamType.Iso13818_6TypeD*/)
return "Multiprotocol Encapsulation";
if (stream.DataBroadcastId == 0x0106)
return "MHEG-5";
if (stream.DataBroadcastId == 0x000b)
return "IP/MAC Notification";
if (stream.RelatedContentDescriptorPresent.HasValue)
if (stream.RelatedContentDescriptorPresent.Value && stream.StreamType == PmtStreamType.Iso13818_1PrivateSections)
return "Related Content Table Information";
if (stream.NumT2MiStreams.HasValue && stream.StreamType == PmtStreamType.Iso13818_1PesPackets)
return "T2-MI";
return String.Format("??? (Type 0x{0:X2})", (int)stream.StreamType);
}
}
}