skyscraper8/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs
2025-09-14 21:47:58 +02:00

1805 lines
46 KiB
C#

using ImGuiNET;
using SDL2Demo;
using SDL2Demo.Forms;
using SDL2Demo.Jobs;
using SDL2Demo.Net;
using SDL2Demo.SdlWrapper;
using skyscraper5.Docsis;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Mhp.Descriptors;
using skyscraper5.Mhp.Si;
using skyscraper5.Mhp.Si.Model;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Mpeg2.Psi.Model;
using skyscraper5.Scte35;
using skyscraper5.Skyscraper.Equipment;
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
using skyscraper5.Skyscraper.Net;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
using skyscraper5.Teletext.Wss;
using skyscraper8.Skyscraper.Drawing;
using skyscraper8.Skyscraper.FrequencyListGenerator;
using skyscraper8.UI.ImGui.Forms;
using SkyscraperUI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using testdrid.SdlWrapper;
using static SDL2Demo.Jobs.Blindscan;
namespace SDL2Demo.Jobs
{
internal class InheritedBlindscanUiJunction : ISkyscraperUiJunction, IRenderable
{
#region During TS scraping
DateTime prev, next;
private bool secondTick;
public void Render()
{
prev = next;
next = DateTime.Now;
secondTick = prev.Second != next.Second;
RenderPat();
RenderSdt();
RenderNit();
RenderCat();
RenderPmt();
RenderTdt();
RenderEit();
RenderAit();
RenderTot();
RenderBat();
RenderObjectCarousels();
RenderMpe();
RenderDataCarousels();
}
private void ResetWindows()
{
HasSdt = false;
sdtDisplay = null;
sdtTableUuid = null;
HasPat = false;
TsType = 0;
patDisplay = null;
patTableUuid = null;
HasPmt = false;
pmtTabBarUuid = null;
nitDisplay = null;
nitTableUuid = null;
HasNit = false;
streamTypes = null;
caTableUuid = null;
caDisplay = null;
HasCat = false;
tdtDisplay = null;
HasTdt = false;
eitDisplay = null;
aitDisplay = null;
aitTableUuid = null;
HasAit = false;
totTime = null;
totDescriptor = null;
totDisplayUuid = null;
HasTot = false;
batDisplay = null;
HasBat = false;
displayObjectCarouselRoots = null;
HasDsmCc = false;
trafficInfoComparer = null;
mpeTableUuid = null;
mpeDisplays = null;
trafficInfoComparer = null;
mpeTableUuid = null;
mpeDisplays = null;
HasMpe = false;
dsmCcDisplay = null;
objectCarouselTableUuid = null;
if (framegrabWindows != null)
{
while (framegrabWindows.Count > 0)
{
PictureWindow pictureWindow = framegrabWindows.Dequeue();
pictureWindow.Dispose();
}
}
}
private void SafeText(string s)
{
if (string.IsNullOrEmpty(s))
{
ImGui.Text("<null>");
return;
}
if (string.IsNullOrWhiteSpace(s))
{
ImGui.Text("[null]");
return;
}
if (s.Contains("% "))
s = s.Replace("% ", "%% ");
ImGui.Text(s);
}
#region EIT
private struct EitEventCoordinate
{
public DateTime StartTime;
public ushort NetworkId;
public ushort ServiceId;
}
private struct EitDay
{
public DateTime Date;
public bool Visible;
public Guid tableGuid;
}
private class EitDayComparer : IComparer<EitDay>
{
public int Compare(EitDay x, EitDay y)
{
return x.Date.CompareTo(y.Date);
}
}
private class EitEventCoordinateComparer : IComparer<EitEventCoordinate>
{
public int Compare(EitEventCoordinate x, EitEventCoordinate y)
{
return x.StartTime.Ticks.CompareTo(y.StartTime.Ticks);
}
}
private bool HasEit;
private SortedList<EitDay, SortedList<EitEventCoordinate, string>> eitDisplay;
private void RenderEit()
{
if (eitDisplay == null)
return;
if (ImGui.Begin("Event Information Table"))
{
lock (eitDisplay)
{
foreach (KeyValuePair<EitDay, SortedList<EitEventCoordinate, string>> keyValuePair in eitDisplay)
{
EitDay day = keyValuePair.Key;
if (ImGui.CollapsingHeader(keyValuePair.Key.Date.ToLongDateString(), ref day.Visible))
{
if (day.tableGuid == Guid.Empty)
day.tableGuid = Guid.NewGuid();
ImGui.BeginTable(day.ToString(), 3,
ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoSavedSettings);
foreach (KeyValuePair<EitEventCoordinate, string> valuePair in keyValuePair.Value)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(valuePair.Key.StartTime.ToShortTimeString());
ImGui.TableSetColumnIndex(1);
string sName = ResolveServiceDisplayName(valuePair.Key.ServiceId);
SafeText(sName);
ImGui.TableSetColumnIndex(2);
SafeText(valuePair.Value);
}
ImGui.EndTable();
}
}
}
ImGui.End();
}
}
public void NotifyEvent(EitEvent eitEvent)
{
if (eitDisplay == null)
eitDisplay = new SortedList<EitDay, SortedList<EitEventCoordinate, string>>(new EitDayComparer());
TsType = 1;
HasEit = true;
EitDay date = new EitDay();
date.Date = eitEvent.StartTime.Date;
date.Visible = true;
lock (eitDisplay)
{
if (!eitDisplay.ContainsKey(date))
{
eitDisplay[date] = new SortedList<EitEventCoordinate, string>(new EitEventCoordinateComparer());
}
SortedList<EitEventCoordinate, string> sortedList = eitDisplay[date];
EitEventCoordinate coordinate = new EitEventCoordinate();
coordinate.StartTime = eitEvent.StartTime;
coordinate.NetworkId = eitEvent.OriginalNetworkId;
coordinate.ServiceId = eitEvent.ServiceId;
if (!sortedList.ContainsKey(coordinate))
{
sortedList.Add(coordinate, eitEvent.EventName);
}
}
}
#endregion EIT
#region SDT
private bool HasSdt;
private string ResolveServiceDisplayName(ushort serviceId)
{
if (sdtDisplay == null)
return String.Format("0x{0:X4}", serviceId);
lock (sdtDisplay)
{
if (sdtDisplay.ContainsKey(serviceId))
{
string v = sdtDisplay[serviceId].ServiceName;
if (string.IsNullOrEmpty(v))
return "???";
else
return v;
}
}
return String.Format("0x{0:X4}", serviceId);
}
private SdtCoordinate ResolveService(ushort serviceId)
{
if (sdtDisplay == null)
return new SdtCoordinate();
lock (sdtDisplay)
{
if (sdtDisplay.ContainsKey(serviceId))
{
return sdtDisplay[serviceId];
}
}
return new SdtCoordinate();
}
private struct SdtCoordinate
{
public string ProviderName;
public string ServiceName;
public bool FreeCaMode;
public ushort[] CaIdentifiers;
public ServiceDescriptor.ServiceTypeCoding? ServiceType;
}
private SortedList<ushort, SdtCoordinate> sdtDisplay;
private string sdtTableUuid;
private void RenderSdt()
{
if (sdtDisplay == null)
return;
if (string.IsNullOrEmpty(sdtTableUuid))
sdtTableUuid = Guid.NewGuid().ToString();
ImGui.Begin("Service Description Table");
if (ImGui.BeginTable(sdtTableUuid, 4, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("Service ID");
ImGui.TableSetupColumn("Name");
ImGui.TableSetupColumn("Provider");
ImGui.TableSetupColumn("CA");
ImGui.TableHeadersRow();
lock (sdtDisplay)
{
foreach (KeyValuePair<ushort, SdtCoordinate> keyValuePair in sdtDisplay)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(String.Format("{0:X4}", keyValuePair.Key));
ImGui.TableSetColumnIndex(1);
SafeText(keyValuePair.Value.ServiceName);
ImGui.TableSetColumnIndex(2);
SafeText(keyValuePair.Value.ProviderName);
ImGui.TableSetColumnIndex(3);
bool ca = keyValuePair.Value.FreeCaMode;
ImGui.BeginDisabled(true);
ImGui.Checkbox("", ref ca);
ImGui.EndDisabled();
}
}
ImGui.EndTable();
ImGui.End();
}
}
public void NotifySdtService(SdtService sdtService)
{
TsType = 1;
HasSdt = true;
if (sdtDisplay == null)
sdtDisplay = new SortedList<ushort, SdtCoordinate>();
if (sdtDisplay.ContainsKey(sdtService.ServiceId))
return;
SdtCoordinate child = new SdtCoordinate();
child.ProviderName = sdtService.ServiceProviderName;
child.ServiceName = sdtService.ServiceName;
child.FreeCaMode = sdtService.FreeCaMode;
child.CaIdentifiers = sdtService.CaIdentifiers;
child.ServiceType = sdtService.ServiceType;
lock (sdtDisplay)
{
sdtDisplay.Add(sdtService.ServiceId, child);
}
}
#endregion
#region PAT
private class PatEntry
{
public ushort programId;
public ProgramMapping pmt;
public string PmtViewUuid;
}
private bool HasPat;
private int TsType;
private SortedList<int, PatEntry> patDisplay;
public void NotifyPatProgram(int pmtPid, ushort programId)
{
HasPat = true;
TsType = 1;
if (patDisplay == null)
patDisplay = new SortedList<int, PatEntry>();
if (patDisplay.ContainsKey(pmtPid))
return;
PatEntry patEntry = new PatEntry();
patEntry.programId = programId;
lock (patDisplay)
{
patDisplay.Add(pmtPid, patEntry);
}
}
private string patTableUuid;
public void RenderPat()
{
if (patDisplay == null)
return;
if (string.IsNullOrEmpty(patTableUuid))
patTableUuid = Guid.NewGuid().ToString();
if (ImGui.Begin("Program Allocation Table"))
{
if (ImGui.BeginTable(patTableUuid, 2, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("PMT PID");
ImGui.TableSetupColumn("Service");
ImGui.TableHeadersRow();
lock (patDisplay)
{
foreach (KeyValuePair<int, PatEntry> keyValuePair in patDisplay)
{
string k = String.Format("0x{0:X4}", keyValuePair.Key);
string v = ResolveServiceDisplayName(keyValuePair.Value.programId);
if (v == null)
v = "???";
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(k);
ImGui.TableSetColumnIndex(1);
SafeText(v);
}
}
ImGui.EndTable();
}
ImGui.End();
}
}
#endregion
#region PMT
private bool HasPmt;
public void NotifyPmtProgram(ProgramMapping result, int pmtPid)
{
HasPmt = true;
TsType = 1;
if (!patDisplay.ContainsKey(pmtPid))
return;
PatEntry patEntry = patDisplay[pmtPid];
if (patEntry.pmt != null)
return;
patEntry.pmt = result;
}
private string pmtTabBarUuid;
public void RenderPmt()
{
if (!HasPmt)
return;
if (string.IsNullOrEmpty(pmtTabBarUuid))
pmtTabBarUuid = Guid.NewGuid().ToString();
if (ImGui.Begin("Program Map Table"))
{
if (ImGui.BeginTabBar(pmtTabBarUuid, ImGuiTabBarFlags.FittingPolicyScroll | ImGuiTabBarFlags.TabListPopupButton))
{
lock (patDisplay)
{
foreach (KeyValuePair<int, PatEntry> keyValuePair in patDisplay)
{
if (ImGui.BeginTabItem(ResolveServiceDisplayName(keyValuePair.Value.programId)))
{
if (string.IsNullOrEmpty(keyValuePair.Value.PmtViewUuid))
keyValuePair.Value.PmtViewUuid = Guid.NewGuid().ToString();
if (keyValuePair.Value.pmt == null)
continue;
ProgramMapping pmt = keyValuePair.Value.pmt;
SafeText(String.Format("Service ID: 0x{0:X4}", pmt.ProgramNumber));
ImGui.BeginTable(keyValuePair.Value.PmtViewUuid, 2, ImGuiTableFlags.NoSavedSettings);
ImGui.TableSetupColumn("PID");
ImGui.TableSetupColumn("Type");
ImGui.TableHeadersRow();
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(String.Format("0x{0:X4}", keyValuePair.Key));
ImGui.TableSetColumnIndex(1);
SafeText("PMT");
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(String.Format("0x{0:X4}", keyValuePair.Value.pmt.PcrPid));
ImGui.TableSetColumnIndex(1);
SafeText("PCR");
foreach (ProgramMappingStream programMappingStream in pmt.Streams)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(String.Format("0x{0:X4}", programMappingStream.ElementaryPid));
ImGui.TableSetColumnIndex(1);
SafeText(StreamTypeAsString(programMappingStream, pmt.RegistrationFormatIdentifier));
}
ImGui.EndTable();
ImGui.EndTabItem();
}
}
}
ImGui.EndTabBar();
}
ImGui.End();
}
}
private string StreamTypeAsString(ProgramMappingStream stream, uint? parentRegistrationFormatIdentifier)
{
if (streamTypes != null)
{
if (streamTypes.ContainsKey(stream.ElementaryPid))
{
return streamTypes[stream.ElementaryPid];
}
}
if (stream.StreamType == PmtStreamType.H262)
return "MPEG-2 Video";
if (stream.AvcStillPresent.HasValue)
return "MPEG-4 Video (still frame)";
if (stream.AudioType.HasValue)
{
switch (stream.AudioType)
{
case AudioType.CleanEffects: return "Audio (no effects)";
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.StreamType == PmtStreamType.Iso13818_1PesPackets && stream.Subtitlings != null && stream.Subtitlings.Length > 0)
return "Subtitle";
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);
}
#endregion
#region NIT
private class NitNetworkMeta
{
public ushort ONID;
public string DisplayUUID;
public override string ToString()
{
return String.Format("Network 0x{0:X4}", ONID);
}
public bool Equals(NitNetworkMeta other)
{
return ONID == other.ONID;
}
public override bool Equals(object? obj)
{
return obj is NitNetworkMeta other && Equals(other);
}
public override int GetHashCode()
{
return ONID.GetHashCode();
}
}
private class NitCoordinateComparer : IComparer<NitNetworkMeta>
{
public int Compare(NitNetworkMeta x, NitNetworkMeta y)
{
return x.ONID.CompareTo(y.ONID);
}
}
private SortedList<NitNetworkMeta, SortedList<ushort, NitTransportStream>> nitDisplay;
private string nitTableUuid;
private bool HasNit;
public void NotifyNit(NitTransportStream transportStream)
{
TsType = 1;
HasNit = true;
if (nitDisplay == null)
nitDisplay = new SortedList<NitNetworkMeta, SortedList<ushort, NitTransportStream>>(new NitCoordinateComparer());
NitNetworkMeta nnm = new NitNetworkMeta();
nnm.ONID = transportStream.OriginalNetworkId;
if (!nitDisplay.ContainsKey(nnm))
{
lock (nitDisplay)
{
nitDisplay.Add(nnm, new SortedList<ushort, NitTransportStream>());
}
}
SortedList<ushort, NitTransportStream> nitTransportStreams = nitDisplay[nnm];
if (nitTransportStreams.ContainsKey(transportStream.TransportStreamId))
return;
lock (nitTransportStreams)
{
nitTransportStreams.Add(transportStream.TransportStreamId, transportStream);
}
}
private string GetFrequencyString(NitTransportStream nts)
{
if (nts.Frequency.HasValue && nts.Polarization.HasValue)
return String.Format("{0} Mhz, {1}", nts.Frequency.Value / 100, nts.Polarization.ToString().Substring(0, 1));
return "???";
}
private void RenderNit()
{
if (nitDisplay == null)
return;
if (string.IsNullOrWhiteSpace(nitTableUuid))
nitTableUuid = Guid.NewGuid().ToString();
if (ImGui.Begin("Network Information Table"))
{
lock (nitDisplay)
{
foreach (KeyValuePair<NitNetworkMeta, SortedList<ushort, NitTransportStream>> keyValuePair in nitDisplay)
{
if (ImGui.CollapsingHeader(keyValuePair.Key.ToString()))
{
if (string.IsNullOrEmpty(keyValuePair.Key.DisplayUUID))
keyValuePair.Key.DisplayUUID = Guid.NewGuid().ToString();
if (ImGui.BeginTable(keyValuePair.Key.DisplayUUID, 4, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
lock (keyValuePair.Value)
{
foreach (KeyValuePair<ushort, NitTransportStream> nitTransportStream in keyValuePair
.Value)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(nitTransportStream.Value.DeliveryMethod.ToString().Replace('_', '_'));
ImGui.TableSetColumnIndex(1);
if (nitTransportStream.Value.OrbitalPosition.HasValue &&
nitTransportStream.Value.East.HasValue)
{
SafeText(String.Format("{0:F1} °{1}",
nitTransportStream.Value.OrbitalPosition.Value,
nitTransportStream.Value.East.Value ? "E" : "W"));
}
ImGui.TableSetColumnIndex(2);
SafeText(GetFrequencyString(nitTransportStream.Value));
ImGui.TableSetColumnIndex(3);
if (nitTransportStream.Value.SymbolRate.HasValue)
SafeText(String.Format("{0} ksym/s",
nitTransportStream.Value.SymbolRate / 10));
}
}
}
ImGui.EndTable();
}
}
}
ImGui.End();
}
}
#endregion
#region MPE
private IpTrafficInfoComparer trafficInfoComparer;
private string mpeTableUuid;
private List<KeyValuePair<IpTrafficInfo, IpPerformanceInfo>> mpeDisplays;
private bool HasMpe;
public void NotifyMpeTraffic(IpTrafficInfo iti, int ipv4PacketLength)
{
if (trafficInfoComparer == null)
trafficInfoComparer = new IpTrafficInfoComparer();
HasMpe = true;
if (mpeDisplays == null)
mpeDisplays = new List<KeyValuePair<IpTrafficInfo, IpPerformanceInfo>>();
lock (mpeDisplays)
{
foreach (KeyValuePair<IpTrafficInfo, IpPerformanceInfo> line in mpeDisplays)
{
if (line.Key.Equals(iti))
{
line.Value.CountPacket(ipv4PacketLength);
return;
}
}
KeyValuePair<IpTrafficInfo, IpPerformanceInfo> newChild = new KeyValuePair<IpTrafficInfo, IpPerformanceInfo>(iti, new IpPerformanceInfo());
newChild.Value.CountPacket(ipv4PacketLength);
mpeDisplays.Add(newChild);
}
}
private void RenderMpe()
{
if (mpeDisplays == null)
return;
if (secondTick)
{
lock (mpeDisplays)
{
foreach (KeyValuePair<IpTrafficInfo, IpPerformanceInfo> line in mpeDisplays)
{
line.Value.UpdatePerSeconds();
}
}
}
string windowName = String.Format("{0} Encapsulation", TsType == 1 ? "Multiprotocol" : "Generic Stream");
if (ImGui.Begin(windowName))
{
if (mpeDisplays != null)
{
if (mpeDisplays.Count > 0)
{
SafeText(String.Format("Communication parties: {0}", mpeDisplays.Count));
}
}
if (string.IsNullOrEmpty(mpeTableUuid))
mpeTableUuid = Guid.NewGuid().ToString();
if (ImGui.BeginTable(mpeTableUuid, 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoSavedSettings))
{
ImGui.TableSetupColumn("Protocol");
ImGui.TableSetupColumn("Source IP");
ImGui.TableSetupColumn("Destination IP");
ImGui.TableSetupColumn("Packets");
ImGui.TableSetupColumn("Traffic");
ImGui.TableHeadersRow();
lock (mpeDisplays)
{
mpeDisplays.Sort(trafficInfoComparer);
foreach (KeyValuePair<IpTrafficInfo, IpPerformanceInfo> ipPerformanceInfo in mpeDisplays)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(IpTrafficInfo.GetProtocolName(ipPerformanceInfo.Key.Protocol));
ImGui.TableSetColumnIndex(1);
SafeText(RenderIp(ipPerformanceInfo, false));
ImGui.TableSetColumnIndex(2);
SafeText(RenderIp(ipPerformanceInfo, true));
ImGui.TableSetColumnIndex(3);
SafeText(ipPerformanceInfo.Value.TotalPackets.ToString());
ImGui.TableSetColumnIndex(4);
SafeText(String.Format("{0:F1} kb/s",
(double)ipPerformanceInfo.Value.BytesPerSecond / 1000.0));
}
}
ImGui.EndTable();
}
ImGui.End();
}
}
private string RenderIp(KeyValuePair<IpTrafficInfo, IpPerformanceInfo> ipPerformanceInfo, bool destination)
{
if (!destination)
{
if (string.IsNullOrEmpty(ipPerformanceInfo.Key.SourceName))
return ipPerformanceInfo.Key.Source.ToString();
else
return ipPerformanceInfo.Key.SourceName;
}
else
{
if (string.IsNullOrEmpty(ipPerformanceInfo.Key.TargetName))
return ipPerformanceInfo.Key.Target.ToString();
else
return ipPerformanceInfo.Key.TargetName;
}
}
#endregion
#region AIT
private SortedList<ApplicationIdentifier, AitApplication> aitDisplay;
private string aitTableUuid;
private bool HasAit;
public void NotifyAit(AitApplication aitApplication)
{
TsType = 1;
HasAit = true;
if (aitDisplay == null)
aitDisplay = new SortedList<ApplicationIdentifier, AitApplication>(new ApplicationIdentifierComparer());
lock (aitDisplay)
{
if (!aitDisplay.ContainsKey(aitApplication.ApplicationIdentifier))
{
aitDisplay.Add(aitApplication.ApplicationIdentifier, aitApplication);
}
}
}
private void RenderAit()
{
if (aitDisplay == null)
return;
if (ImGui.Begin("Application Identification Table"))
{
if (string.IsNullOrEmpty(aitTableUuid))
aitTableUuid = Guid.NewGuid().ToString();
if (ImGui.BeginTable(aitTableUuid, 2, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("Application Name");
ImGui.TableSetupColumn("Transport");
ImGui.TableHeadersRow();
lock (aitDisplay)
{
foreach (KeyValuePair<ApplicationIdentifier, AitApplication> keyValuePair in aitDisplay)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(keyValuePair.Value.TryGetName());
ImGui.TableSetColumnIndex(1);
foreach (TransportProtocolDescriptor transportProtocolDescriptor in keyValuePair.Value.TransportProtocols)
{
SafeText(transportProtocolDescriptor.Selector.ToString());
}
}
}
ImGui.EndTable();
}
ImGui.End();
}
}
#endregion
#region DSM-CC Modules
private struct DsmCcModuleIdentifier
{
public int pid;
public ushort moduleId;
public byte moduleVersion;
}
private sealed class DsmCcModuleIdentifierComparer : IComparer<DsmCcModuleIdentifier>
{
public int Compare(DsmCcModuleIdentifier x, DsmCcModuleIdentifier y)
{
var pidComparison = x.pid.CompareTo(y.pid);
if (pidComparison != 0) return pidComparison;
var moduleIdComparison = x.moduleId.CompareTo(y.moduleId);
if (moduleIdComparison != 0) return moduleIdComparison;
return x.moduleVersion.CompareTo(y.moduleVersion);
}
}
private SortedList<DsmCcModuleIdentifier, double> dsmCcDisplay;
private string objectCarouselTableUuid;
public void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion)
{
TsType = 1;
HasDsmCc = true;
if (dsmCcDisplay == null)
dsmCcDisplay = new SortedList<DsmCcModuleIdentifier, double>(new DsmCcModuleIdentifierComparer());
DsmCcModuleIdentifier id = new DsmCcModuleIdentifier();
id.pid = elementaryPid;
id.moduleId = moduleInfoModuleId;
id.moduleVersion = moduleInfoModuleVersion;
lock (dsmCcDisplay)
{
dsmCcDisplay.Add(id, 0);
}
}
public void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion,
double moduleInfoDownloadProgress)
{
TsType = 1;
HasDsmCc = true;
if (dsmCcDisplay == null)
return;
DsmCcModuleIdentifier id = new DsmCcModuleIdentifier();
id.pid = elementaryPid;
id.moduleId = moduleInfoModuleId;
id.moduleVersion = moduleInfoModuleVersion;
if (!dsmCcDisplay.ContainsKey(id))
return;
lock (dsmCcDisplay)
{
dsmCcDisplay[id] = moduleInfoDownloadProgress;
}
}
public void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion)
{
DsmCcModuleIdentifier id = new DsmCcModuleIdentifier();
id.pid = elementaryPid;
id.moduleId = moduleModuleId;
id.moduleVersion = moduleModuleVersion;
lock (dsmCcDisplay)
{
dsmCcDisplay.Remove(id);
}
}
private void RenderDataCarousels()
{
if (dsmCcDisplay == null)
return;
if (dsmCcDisplay.Count == 0)
return;
if (ImGui.Begin("Digital Storage Media Command & Control, Data Carousels"))
{
if (string.IsNullOrEmpty(objectCarouselTableUuid))
{
objectCarouselTableUuid = Guid.NewGuid().ToString();
}
if (ImGui.BeginTable(objectCarouselTableUuid, 4, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("PID");
ImGui.TableSetupColumn("Module ID");
ImGui.TableSetupColumn("Version");
ImGui.TableSetupColumn("Progress");
ImGui.TableHeadersRow();
lock (dsmCcDisplay)
{
foreach (KeyValuePair<DsmCcModuleIdentifier, double> keyValuePair in dsmCcDisplay)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(String.Format("{0}", keyValuePair.Key.pid));
ImGui.TableSetColumnIndex(1);
SafeText(String.Format("{0}", keyValuePair.Key.moduleId));
ImGui.TableSetColumnIndex(2);
SafeText(String.Format("{0}", keyValuePair.Key.moduleVersion));
ImGui.TableSetColumnIndex(3);
ImGui.SetNextItemWidth(100);
ImGui.ProgressBar(Convert.ToSingle(keyValuePair.Value) / 100.0f, Vector2.Zero, String.Format("{0}%", keyValuePair.Value));
}
}
ImGui.EndTable();
}
ImGui.End();
}
}
#endregion
public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock)
{
}
#region Stream Type Autodetection
private Dictionary<int, string> streamTypes;
public void NotifyStreamTypeDetection(string contestantTag, int pid)
{
if (streamTypes == null)
streamTypes = new Dictionary<int, string>();
streamTypes[pid] = contestantTag;
}
#endregion
#region BAT
private struct DisplayableBat
{
public string Name;
public List<LinkageDescriptor> Linkages;
public string TableUuid;
public HashSet<BatTransportStream> TransportStreams;
}
private SortedList<ushort, DisplayableBat> batDisplay;
private bool HasBat;
public void NotifyBat(BatBouquet batBouquet)
{
TsType = 1;
HasBat = true;
if (batDisplay == null)
batDisplay = new SortedList<ushort, DisplayableBat>();
if (batDisplay.ContainsKey(batBouquet.BouquetId))
return;
DisplayableBat child = new DisplayableBat();
child.Name = batBouquet.TryGetName();
child.Linkages = batBouquet.Linkages;
child.TableUuid = Guid.NewGuid().ToString();
child.TransportStreams = new HashSet<BatTransportStream>();
lock (batDisplay)
{
batDisplay[batBouquet.BouquetId] = child;
}
}
public void NotifyBatTs(ushort batBouquetBouquetId, BatTransportStream child)
{
TsType = 1;
HasBat = true;
if (batDisplay == null)
return;
if (!batDisplay.ContainsKey(batBouquetBouquetId))
return;
batDisplay[batBouquetBouquetId].TransportStreams.Add(child);
}
private void RenderBat()
{
if (batDisplay == null)
return;
if (batDisplay.Count == 0)
return;
if (ImGui.Begin("Bouquet Association Table"))
{
lock (batDisplay)
{
foreach (KeyValuePair<ushort, DisplayableBat> keyValuePair in batDisplay)
{
if (ImGui.CollapsingHeader(String.Format("Bouquet #{0} - {1}", keyValuePair.Key, keyValuePair.Value.Name)))
{
if (ImGui.BeginTable(keyValuePair.Value.TableUuid, 5, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("L/TS");
ImGui.TableSetupColumn("ONID");
ImGui.TableSetupColumn("TSID");
ImGui.TableSetupColumn("Service");
ImGui.TableSetupColumn("");
ImGui.TableHeadersRow();
lock (keyValuePair.Value.Linkages)
{
foreach (LinkageDescriptor linkageDescriptor in keyValuePair.Value.Linkages)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText("Link");
ImGui.TableSetColumnIndex(1);
SafeText(String.Format("{0:X4}", linkageDescriptor.OriginalNetworkId));
ImGui.TableSetColumnIndex(2);
SafeText(String.Format("{0:X4}", linkageDescriptor.TransportStreamId));
ImGui.TableSetColumnIndex(3);
SafeText(ResolveServiceDisplayName(linkageDescriptor.ServiceId));
ImGui.TableSetColumnIndex(4);
SafeText(linkageDescriptor.LinkageType.ToString());
}
}
lock (keyValuePair.Value.TransportStreams)
{
foreach (BatTransportStream valueTransportStream in keyValuePair.Value.TransportStreams)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText("TS");
ImGui.TableSetColumnIndex(1);
SafeText(String.Format("{0:X4}", valueTransportStream.OriginalNetworkId));
ImGui.TableSetColumnIndex(2);
SafeText(String.Format("{0:X4}", valueTransportStream.TransportStreamId));
if (valueTransportStream.ServiceList != null)
{
foreach (ServiceListDescriptor.Service service in valueTransportStream.ServiceList)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText("Service");
ImGui.TableSetColumnIndex(3);
SafeText(ResolveServiceDisplayName(service.ServiceId));
ImGui.TableSetColumnIndex(4);
SafeText(service.ServiceType.ToString());
}
}
}
}
ImGui.EndTable();
}
}
}
}
ImGui.End();
}
}
#endregion
#region DSM-CC Object Carousel
private SortedList<int, VfsDirectory> displayObjectCarouselRoots;
private bool HasDsmCc;
private string GetServiceNameFromPid(int pid)
{
lock (patDisplay)
{
foreach (KeyValuePair<int, PatEntry> keyValuePair in patDisplay)
{
PatEntry patEntry = keyValuePair.Value;
if (patEntry.pmt == null)
continue;
foreach (ProgramMappingStream programMappingStream in patEntry.pmt.Streams)
{
if (programMappingStream.ElementaryPid == pid)
{
return ResolveServiceDisplayName(patEntry.programId);
}
}
}
}
return "???";
}
public void DsmCcVfs(VfsFile vfsFile)
{
TsType = 1;
HasDsmCc = true;
if (displayObjectCarouselRoots == null)
displayObjectCarouselRoots = new SortedList<int, VfsDirectory>();
if (displayObjectCarouselRoots.ContainsKey(vfsFile.SourcePid))
return;
VfsDirectory masterDirectory = vfsFile.ParentDirectory;
while (masterDirectory.ParentDirectory != null)
masterDirectory = masterDirectory.ParentDirectory;
lock (displayObjectCarouselRoots)
{
displayObjectCarouselRoots.Add(vfsFile.SourcePid, masterDirectory);
}
}
private void RenderObjectCarousels()
{
if (displayObjectCarouselRoots == null)
return;
if (ImGui.Begin("Digital Storage Media - Command & Control, Object Carousels"))
{
lock (displayObjectCarouselRoots)
{
foreach (KeyValuePair<int, VfsDirectory> displayObjectCarouselRoot in displayObjectCarouselRoots)
{
string name = String.Format("Object Carousel in PID 0x{1:X4} (Service: {0})", GetServiceNameFromPid(displayObjectCarouselRoot.Key), displayObjectCarouselRoot.Key);
if (ImGui.CollapsingHeader(name))
{
RenderDirectoryNode(displayObjectCarouselRoot.Value);
}
}
}
}
}
private void RenderDirectoryNode(VfsDirectory directory)
{
if (!directory.SkyscrpaerUiData.ContainsKey("UUID"))
directory.SkyscrpaerUiData.Add("UUID", Guid.NewGuid().ToString());
string dname = directory.Name;
if (string.IsNullOrEmpty(dname) && directory.ParentDirectory == null)
dname = "<root directory>";
if (ImGui.TreeNode(directory.SkyscrpaerUiData["UUID"].ToString(), dname))
{
foreach (VfsDirectory subdirectory in directory.subdirectories)
{
RenderDirectoryNode(subdirectory);
}
foreach (VfsFile directoryFile in directory.files)
{
SafeText(directoryFile.Name);
}
foreach (VfsEvent directoryEvent in directory.events)
{
SafeText(directoryEvent.Name);
}
ImGui.TreePop();
}
}
#endregion
#region TOT
private DateTime? totTime;
private LocalTimeOffsetDescriptor totDescriptor;
private string totDisplayUuid;
private bool HasTot;
public void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod)
{
TsType = 1;
HasTot = true;
totTime = utcTime;
totDescriptor = ltod;
}
private void RenderTot()
{
if (!totTime.HasValue)
return;
if (ImGui.Begin("Time Offset Table"))
{
SafeText(totTime.ToString());
if (totDescriptor != null)
{
if (totDescriptor.Valid)
{
if (string.IsNullOrEmpty(totDisplayUuid))
totDisplayUuid = Guid.NewGuid().ToString();
if (ImGui.BeginTable(totDisplayUuid, 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoSavedSettings))
{
ImGui.TableSetupColumn("Region");
ImGui.TableSetupColumn("Polarity");
ImGui.TableSetupColumn("Offset");
ImGui.TableHeadersRow();
foreach (LocalTimeOffsetDescriptor.LocalTime totDescriptorLocalTimeOffset in totDescriptor.LocalTimeOffsets)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(totDescriptorLocalTimeOffset.CountryCode);
ImGui.TableSetColumnIndex(1);
bool b = totDescriptorLocalTimeOffset.LocalTimeOffsetPolarity;
ImGui.BeginDisabled(true);
ImGui.Checkbox("", ref b);
ImGui.EndDisabled();
ImGui.TableSetColumnIndex(2);
SafeText(totDescriptorLocalTimeOffset.LocalTimeOffset.ToString());
}
ImGui.EndTable();
}
}
}
ImGui.End();
}
}
#endregion
#region TDT
private DateTime? tdtDisplay;
private bool HasTdt;
public void NotifyTdt(DateTime utcTime)
{
TsType = 1;
HasTdt = true;
tdtDisplay = utcTime;
}
private void RenderTdt()
{
if (tdtDisplay.HasValue)
{
if (ImGui.Begin("Time and Date Table"))
{
SafeText(tdtDisplay.Value.ToString());
ImGui.End();
}
}
}
#endregion
#region CAT
private string caTableUuid;
private HashSet<CaDescriptor> caDisplay;
private bool HasCat;
public void NotifyCat(CaDescriptor caDescriptor)
{
TsType = 1;
HasCat = true;
if (caDisplay == null)
caDisplay = new HashSet<CaDescriptor>();
lock (caDisplay)
{
caDisplay.Add(caDescriptor);
}
}
private void RenderCat()
{
if (caDisplay == null)
return;
if (ImGui.Begin("Conditional Access Table"))
{
if (string.IsNullOrEmpty(caTableUuid))
caTableUuid = Guid.NewGuid().ToString();
if (ImGui.BeginTable(caTableUuid, 3, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
{
ImGui.TableSetupColumn("CA System");
ImGui.TableSetupColumn("ECM/EMM PID");
ImGui.TableSetupColumn("Private Data");
ImGui.TableHeadersRow();
lock (caDisplay)
{
foreach (CaDescriptor caDescriptor in caDisplay)
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
SafeText(CaSystemNames.GetHumanReadableName(caDescriptor.CaSystemId));
ImGui.TableSetColumnIndex(1);
SafeText(String.Format("{0:X4}", caDescriptor.CaPid));
ImGui.TableSetColumnIndex(2);
if (caDescriptor.PrivateData != null)
{
if (caDescriptor.PrivateData.Length != 0)
SafeText(BitConverter.ToString(caDescriptor.PrivateData));
}
}
}
ImGui.EndTable();
}
ImGui.End();
}
}
#endregion
public void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert)
{
}
public void NotifyScte35(ushort programNumber, TimeSignal spliceInsert)
{
}
public void SetMemorySaverMode(bool saveMemory)
{
}
public void NotifyDocsisCarrier(DocsisEnvironment docsisEnvironment)
{
throw new NotImplementedException();
}
public void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm)
{
throw new NotImplementedException();
}
private bool gseMode;
public void SetGseMode()
{
gseMode = true;
}
#region Framegrabs
private Queue<PictureWindow> framegrabWindows;
private int windowSpawnX = 100;
public void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber,
int mappingStreamElementaryPid, byte[] imageData)
{
if (framegrabWindows == null)
framegrabWindows = new Queue<PictureWindow>();
Tasks.EnqueueTask(() =>
{
string resolveServiceDisplayName = ResolveServiceDisplayName(mappingProgramNumber);
if (string.IsNullOrEmpty(resolveServiceDisplayName))
resolveServiceDisplayName = String.Format("Framegrab of Service #{0:X4}");
else
resolveServiceDisplayName = String.Format("Framegrab of \"{0}\"", resolveServiceDisplayName);
if (PictureWindow.Renderer == null)
return;
Renderer renderer = PictureWindow.Renderer;
string displayName = resolveServiceDisplayName;
PictureWindow child = new PictureWindow(renderer, displayName, imageData);
child.SetPosition(windowSpawnX, windowSpawnX);
child.SetTaskQueue(Tasks, jobContext.Renderables);
jobContext.Renderables.Add(child);
framegrabWindows.Enqueue(child);
});
}
#endregion
public void NotifyBlockstreamCarrier()
{
throw new NotImplementedException();
}
#region Database Callbacks
public IEnumerable<HumanReadableService> GetServices()
{
if (HasPmt)
{
foreach (var (pmtPid, patValue) in patDisplay)
{
ushort serviceId = patValue.programId;
SdtCoordinate sdt = ResolveService(serviceId);
string providerName = sdt.ProviderName;
string serviceName = sdt.ServiceName;
ushort? caId = ResolveCaId(patValue.pmt, sdt);
ServiceDescriptor.ServiceTypeCoding? serviceType = sdt.ServiceType;
yield return new HumanReadableService(serviceId, providerName, serviceName, caId, serviceType.GetValueOrDefault());
}
}
}
private ushort? ResolveCaId(ProgramMapping patValuePmt, SdtCoordinate sdt)
{
if (patValuePmt != null)
{
if (patValuePmt.CaSystemId.HasValue)
return patValuePmt.CaSystemId.Value;
foreach (ProgramMappingStream stream in patValuePmt.Streams)
{
if (stream.CaSystemId.HasValue)
return stream.CaSystemId;
}
}
if (sdt.CaIdentifiers != null)
{
if (sdt.CaIdentifiers.Length > 0)
return sdt.CaIdentifiers[0];
}
return null;
}
#endregion
#endregion
#region During Blindscan
private FoundFrequenciesWindow2 foundFrequenciesWindow;
public void OnBlindscanOpenFoundFrquenciesWindow(List<BlindscanSearchResult> foundFrequencies, STD_TYPE tunerMetadataType)
{
foundFrequenciesWindow = new FoundFrequenciesWindow2(foundFrequencies);
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Add(foundFrequenciesWindow);
});
}
public void OnBlindscanJobDone(bool success)
{
jobContext.Puppets[0].AutoMoveToHome();
jobContext.Puppets[1].AutoMoveToHome();
jobContext.Puppets[2].AutoMoveTo(new Point(0, 720 / 2));
jobContext.Puppets[3].AutoMoveTo(new Point(1280 / 2, 0));
jobContext.ReadyForNextJob = true;
}
public void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed)
{
throw new NotImplementedException();
}
public void OnBlindscanBandComplete()
{
foreach (CharSet jobContextPuppet in jobContext.Puppets)
jobContextPuppet.AutoMoveToHome();
}
private BlindscanProgressWindow _blindscanProgressWindow;
public void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum)
{
_blindscanProgressWindow = new BlindscanProgressWindow();
_blindscanProgressWindow.Start = minimum;
_blindscanProgressWindow.Progress = minimum;
_blindscanProgressWindow.End = maximum;
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Add(_blindscanProgressWindow);
});
}
public void OnBlindscanAfterBLScan()
{
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Remove(_blindscanProgressWindow);
_blindscanProgressWindow = null;
});
}
public void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex,
int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency)
{
Blindscan.BlindscanResult blindscanResult = new Blindscan.BlindscanResult(searchResult.SearchResult, lnbTypeMinimumFrequency, lnbTypeMaximumFrequency);
jobContext.Puppets[blindscanResult.sr1.Pol].AutoMoveTo(blindscanResult.Position);
lock (jobContext.PressurePlates)
{
jobContext.PressurePlates.Add(blindscanResult);
}
_blindscanProgressWindow.Progress = searchResult.SearchResult.Freq;
SoundPlayer.PlaySoundFile("lock.wav");
}
private Point GetFrequencyPosition(SearchResult searchResult, int satPositionMinFreq, int satPositionMaxFreq)
{
int x = 0, y = 0;
if (searchResult.Pol == 0)
{
//Horizontal
int w = (searchResult.Freq / 1000) - satPositionMinFreq;
int hundert = 1280;
int g = (satPositionMaxFreq - satPositionMinFreq);
x = w * hundert / g;
y = 720 / 2;
}
else
{
//Vertical
int w = (searchResult.Freq / 1000) - satPositionMinFreq;
int hundert = 720;
int g = (satPositionMaxFreq - satPositionMinFreq);
x = 1280 / 2;
y = w * hundert / g;
}
Point position = new Point(x, y);
return position;
}
public void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult, LnbType lnb)
{
Point point = GetFrequencyPosition(blindscanResult.SearchResult, lnb.MinimumFrequency, lnb.MaximumFrequency);
jobContext.Puppets[2 + blindscanResult.SearchResult.Pol].AutoMoveTo(point);
}
public void OnScrapeBandComplete()
{
jobContext.Puppets[0].AutoMoveToHome();
jobContext.Puppets[1].AutoMoveToHome();
jobContext.Puppets[2].AutoMoveToHome();
jobContext.Puppets[3].AutoMoveToHome();
}
public void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult)
{
lock (jobContext.PressurePlates)
{
foreach (IPressurePlate pressurePlate in jobContext.PressurePlates)
{
Blindscan.BlindscanResult result = pressurePlate as Blindscan.BlindscanResult;
if (result.Satellite)
{
if (result.GetFrequency() == blindscanResult.GetFrequency())
{
jobContext.PressurePlates.Remove(result);
break;
}
}
else
{
throw new NotImplementedException("non satellite pressure plate.");
}
}
}
}
private SdlScottPlotWindowRfSpectrum rfSpectrumWindow;
public void OnBlindscanBeginRfSpectrum()
{
Tasks.EnqueueTask(() =>
{
rfSpectrumWindow = new SdlScottPlotWindowRfSpectrum(jobContext.ImgUiDevice);
jobContext.Renderables.Add(rfSpectrumWindow);
});
}
public void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf)
{
Tasks.EnqueueTask(() =>
{
rfSpectrumWindow.EnqueueSample(polarization, frequency, rf);
});
}
public void OnBlindscanEndRfSpectrum()
{
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Remove(rfSpectrumWindow);
rfSpectrumWindow.Dispose();
rfSpectrumWindow = null;
});
}
private IqWindow iqWindow;
public void OnBlindscanBeginIqSpectrum(IqChartData result)
{
Tasks.EnqueueTask(() =>
{
iqWindow = new IqWindow(jobContext.ImgUiDevice, result);
jobContext.Renderables.Add(iqWindow);
});
}
public void OnBlindscanEndIq()
{
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Remove(iqWindow);
iqWindow.Dispose();
iqWindow = null;
});
}
public void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState)
{
SoundPlayer.PlaySoundFile("fail.wav");
}
public void OnBlindscanFilterSetUp()
{
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Add(this);
});
foundFrequenciesWindow.allowZapNow = true;
foundFrequenciesWindow.statusPacketsInQueue = 0;
foundFrequenciesWindow.statusPacketsInTotal = 0;
}
public void OnBlindscanScrapeStopCondition()
{
foundFrequenciesWindow.allowZapNow = false;
}
public void OnBlindscanAfterPacketDrain()
{
Tasks.EnqueueTask(() =>
{
jobContext.Renderables.Remove(this);
ResetWindows();
});
}
public void OnBlindscanPacketError(int errorCount, int length)
{
throw new NotImplementedException();
}
public void OnBlindscanPacketOk(int numPackets, int packetsQueueCount)
{
foundFrequenciesWindow.statusPacketsInTotal += (uint)numPackets;
foundFrequenciesWindow.statusPacketsInQueue = packetsQueueCount;
}
public bool IsZapNowRequested()
{
if (foundFrequenciesWindow.zapNowRequested)
{
foundFrequenciesWindow.zapNowRequested = false;
return true;
}
return false;
}
public bool MayAutoZap()
{
return !foundFrequenciesWindow.doNotAutoZap;
}
public TaskQueue Tasks { get; set; }
internal JobContext jobContext;
#endregion
}
}