mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-13 02:42:03 +01:00
- added config for 4532KB dtv_cmdb_2.bin - fixed some cmdb config issues (videoPid, channelTypeOld)
226 lines
8.4 KiB
C#
226 lines
8.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using ChanSort.Api;
|
|
|
|
namespace ChanSort.Loader.CmdbBin
|
|
{
|
|
public class CmdbFileSerializer : SerializerBase
|
|
{
|
|
private IniFile ini;
|
|
private readonly MappingPool<DataMapping> satMappings = new MappingPool<DataMapping>("dtv_cmdb_2.bin");
|
|
private readonly ChannelList dvbsTv = new ChannelList(SignalSource.DvbS | SignalSource.Tv, "Sat TV");
|
|
private readonly ChannelList dvbsRadio = new ChannelList(SignalSource.DvbS | SignalSource.Radio, "Sat Radio");
|
|
private readonly ChannelList dvbsData = new ChannelList(SignalSource.DvbS | SignalSource.Radio, "Sat Data");
|
|
private DvbStringDecoder dvbStringDecoder;
|
|
private bool loaded = false;
|
|
|
|
public CmdbFileSerializer(string inputFile) : base(inputFile)
|
|
{
|
|
this.Features.FavoritesMode = FavoritesMode.Flags;
|
|
this.Features.MaxFavoriteLists = 1;
|
|
|
|
this.DataRoot.AddChannelList(dvbsTv);
|
|
this.DataRoot.AddChannelList(dvbsRadio);
|
|
// this.DataRoot.AddChannelList(dvbsData); // there seem to be multiple data lists with Toshiba TVs which all have their own numbering starting at 1. Better don't show data channels at all than dupes
|
|
this.ReadConfigurationFromIniFile();
|
|
|
|
foreach (var list in this.DataRoot.ChannelLists)
|
|
{
|
|
//list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Favorites));
|
|
//list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Skip));
|
|
//list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Lock));
|
|
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Hidden));
|
|
//list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Encrypted));
|
|
}
|
|
}
|
|
|
|
#region ReadConfigurationFromIniFile()
|
|
|
|
private void ReadConfigurationFromIniFile()
|
|
{
|
|
string iniFile = this.GetType().Assembly.Location.ToLowerInvariant().Replace(".dll", ".ini");
|
|
this.ini = new IniFile(iniFile);
|
|
|
|
foreach (var section in ini.Sections)
|
|
{
|
|
int idx = section.Name.IndexOf(":");
|
|
if (idx < 0)
|
|
continue;
|
|
string recordLength = idx < 0 ? "" : section.Name.Substring(idx + 1);
|
|
if (section.Name.StartsWith("dtv_cmdb_2"))
|
|
satMappings.AddMapping(recordLength, new DataMapping(section));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Load()
|
|
public override void Load()
|
|
{
|
|
this.dvbStringDecoder = new DvbStringDecoder(this.DefaultEncoding);
|
|
|
|
foreach (var file in Directory.GetFiles(Path.GetDirectoryName(this.FileName)))
|
|
{
|
|
var lower = Path.GetFileName(file).ToLowerInvariant();
|
|
var size = (int)new FileInfo(file).Length;
|
|
switch (lower)
|
|
{
|
|
case "dtv_cmdb_2.bin":
|
|
LoadFile(file, this.dvbsTv, this.dvbsRadio, this.dvbsData, this.satMappings.GetMapping(size));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!this.loaded)
|
|
throw new FileLoadException("\"" + this.FileName + "\" does not belong to a dtv_cmdb_* file system");
|
|
}
|
|
#endregion
|
|
|
|
#region LoadFile()
|
|
private void LoadFile(string file, ChannelList tvList, ChannelList radioList, ChannelList dataList, DataMapping fileMapping)
|
|
{
|
|
var data = File.ReadAllBytes(file);
|
|
var sec = fileMapping.Settings;
|
|
|
|
LoadBitmappedRecords(data, sec, "Satellite", ReadSatellite);
|
|
LoadBitmappedRecords(data, sec, "Transponder", ReadTransponder);
|
|
LoadBitmappedRecords(data, sec, "Channel", (map, index) => ReadChannel(map, tvList, radioList, dvbsData, index));
|
|
|
|
this.loaded = true;
|
|
}
|
|
#endregion
|
|
|
|
#region LoadBitmappedRecords()
|
|
private void LoadBitmappedRecords(byte[] data, IniFile.Section sec, string recordType, Action<DataMapping, int> readRecord)
|
|
{
|
|
var lenRecord = sec.GetInt($"len{recordType}Record");
|
|
var map = new DataMapping(this.ini.GetSection($"dvbs{recordType}:{lenRecord}"));
|
|
map.DefaultEncoding = this.DefaultEncoding;
|
|
map.SetDataPtr(data, sec.GetInt($"off{recordType}Record"));
|
|
|
|
var off = sec.GetInt($"off{recordType}Bitmap");
|
|
var len = sec.GetInt($"len{recordType}Bitmap");
|
|
var count = sec.GetInt($"num{recordType}Record");
|
|
int index = 0;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
var b = data[off + i];
|
|
for (byte mask = 1; mask != 0; mask <<= 1)
|
|
{
|
|
if ((b & mask) != 0)
|
|
readRecord(map, index);
|
|
map.BaseOffset += lenRecord;
|
|
if (++index >= count)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region ReadSatellite()
|
|
private void ReadSatellite(DataMapping map, int index)
|
|
{
|
|
var sat = new Satellite(index);
|
|
sat.Name = map.GetString("offName", map.Settings.GetInt("lenName"));
|
|
this.DataRoot.AddSatellite(sat);
|
|
}
|
|
#endregion
|
|
|
|
#region ReadTransponder()
|
|
private void ReadTransponder(DataMapping map, int index)
|
|
{
|
|
//var idx = map.GetWord("offTransponderIndex"); // seems to be some logical number, skipping a new numbers here and there
|
|
|
|
var tp = new Transponder(index);
|
|
var satIndex = map.GetWord("offSatelliteIndex");
|
|
tp.Satellite = this.DataRoot.Satellites.TryGet(satIndex);
|
|
tp.OriginalNetworkId = map.GetWord("offOriginalNetworkId");
|
|
tp.TransportStreamId = map.GetWord("offTransportStreamId");
|
|
tp.FrequencyInMhz = map.GetDword("offFreqInMhz");
|
|
tp.SymbolRate = map.GetWord("offSymbolRate");
|
|
this.DataRoot.AddTransponder(tp.Satellite, tp);
|
|
}
|
|
#endregion
|
|
|
|
#region ReadChannel()
|
|
private void ReadChannel(DataMapping chanMap, ChannelList tvList, ChannelList radioList, ChannelList dataList, int recordIndex)
|
|
{
|
|
var channelType = (int)chanMap.GetByte("offChannelType");
|
|
if (channelType == 0) // some file format versions store the channel type in the upper nibble of a byte
|
|
channelType = chanMap.GetByte("offChannelTypeOld") >> 4;
|
|
var serviceType = chanMap.GetByte("offServiceType");
|
|
|
|
if (chanMap.Settings.GetInt("offFav", -1) < 0)
|
|
this.Features.FavoritesMode = FavoritesMode.None;
|
|
|
|
ChannelList list;
|
|
if (channelType != 0)
|
|
list = channelType == 1 ? tvList : channelType == 2 ? radioList : dataList;
|
|
else if (serviceType != 0)
|
|
{
|
|
var type = LookupData.Instance.IsRadioTvOrData(serviceType);
|
|
list = type == SignalSource.Radio ? radioList : type == SignalSource.Tv ? tvList : dataList;
|
|
}
|
|
else
|
|
list = tvList;
|
|
|
|
var progNr = (int)chanMap.GetWord("offProgramNr");
|
|
if (progNr == 0xFFFE)
|
|
progNr = -2;
|
|
|
|
var ch = new ChannelInfo(list.SignalSource, recordIndex, progNr, "");
|
|
ch.ServiceType = serviceType;
|
|
ch.ServiceTypeName = Api.LookupData.Instance.GetServiceTypeDescription(ch.ServiceType);
|
|
ch.PcrPid = chanMap.GetWord("offPcrPid") & 0x1FFF;
|
|
ch.ServiceId = chanMap.GetWord("offServiceId");
|
|
ch.AudioPid = chanMap.GetWord("offAudioPid");
|
|
ch.Encrypted = chanMap.GetFlag("Encrypted");
|
|
ch.VideoPid = chanMap.GetWord("offVideoPid") & 0x1FFF;
|
|
ch.Skip = chanMap.GetFlag("Skip");
|
|
ch.Lock = chanMap.GetFlag("Locked");
|
|
ch.Favorites = chanMap.GetFlag("Fav") ? Favorites.A : 0;
|
|
|
|
var off = chanMap.BaseOffset + chanMap.GetOffsets("offName")[0];
|
|
this.dvbStringDecoder.GetChannelNames(chanMap.Data, off, chanMap.Settings.GetInt("lenName"), out var longName, out var shortName);
|
|
ch.Name = longName;
|
|
ch.ShortName = shortName;
|
|
|
|
var offProv = chanMap.GetOffsets("offProvider");
|
|
if (offProv.Length > 0)
|
|
{
|
|
off = chanMap.BaseOffset + offProv[0];
|
|
this.dvbStringDecoder.GetChannelNames(chanMap.Data, off, chanMap.Settings.GetInt("lenName"), out longName, out _);
|
|
ch.Provider = longName;
|
|
}
|
|
|
|
var offDebug = chanMap.Settings.GetInt("offDebug");
|
|
var lenDebug = chanMap.Settings.GetInt("lenDebug");
|
|
ch.AddDebug(chanMap.Data, chanMap.BaseOffset + offDebug, lenDebug);
|
|
|
|
var transponderIndex = chanMap.GetWord("offTransponderIndex");
|
|
var tp = this.DataRoot.Transponder.TryGet(transponderIndex);
|
|
if (tp != null)
|
|
{
|
|
ch.Transponder = tp;
|
|
ch.OriginalNetworkId = tp.OriginalNetworkId;
|
|
ch.TransportStreamId = tp.TransportStreamId;
|
|
ch.FreqInMhz = tp.FrequencyInMhz;
|
|
ch.SymbolRate = tp.SymbolRate;
|
|
ch.Satellite = tp.Satellite?.Name;
|
|
}
|
|
|
|
this.DataRoot.AddChannel(list, ch);
|
|
}
|
|
#endregion
|
|
|
|
public override void Save(string tvOutputFile)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|