mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-15 20:02:04 +01:00
- rewrote LG data file cleanup. Now it complete rewrites the DVB-S channel information
- fixed opening editor when typing on keyboard - persisting more user settings
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#define SYMBOL_RATE_ROUNDING
|
||||
//#define SYMBOL_RATE_ROUNDING
|
||||
//#define STORE_DVBS_CHANNELS_IN_DATABASE
|
||||
//#define TESTING_LM640T_HACK
|
||||
|
||||
@@ -73,6 +73,7 @@ namespace ChanSort.Loader.LG
|
||||
this.Features.EraseChannelData = true;
|
||||
this.Features.FileInformation = true;
|
||||
this.Features.DeviceSettings = true;
|
||||
this.Features.CleanUpChannelData = true;
|
||||
this.SupportedTvCountryCodes = new List<string>
|
||||
{
|
||||
"___ (None)", "AUT (Austria)", "BEL (Belgium)", "CHE (Switzerland)",
|
||||
@@ -138,6 +139,9 @@ namespace ChanSort.Loader.LG
|
||||
this.ReadDvbSBlock(ref off);
|
||||
this.ReadSettingsBlock(ref off);
|
||||
|
||||
if (this.EraseDuplicateChannels)
|
||||
this.CleanUpChannelData();
|
||||
|
||||
#if STORE_DVBS_CHANNELS_IN_DATABASE
|
||||
this.StoreToDatabase();
|
||||
#endif
|
||||
@@ -331,7 +335,7 @@ namespace ChanSort.Loader.LG
|
||||
this.dvbsChannelCount = header.ChannelCount;
|
||||
off += header.Size;
|
||||
off += satConfig.dvbsMaxChannelCount/8; // skip allocation bitmap
|
||||
this.ReadDvbsChannelLinkedList(ref off);
|
||||
this.ReadDvbsChannelLinkedList(header, ref off);
|
||||
|
||||
this.ReadDvbsChannels(ref off, header.LinkedListStartIndex);
|
||||
|
||||
@@ -379,24 +383,13 @@ namespace ChanSort.Loader.LG
|
||||
for (int i=0; i<satConfig.transponderCount; i++)
|
||||
{
|
||||
mapping.SetDataPtr(this.fileContent, off + i*satConfig.transponderLength);
|
||||
var data = new SatTransponder(mapping);
|
||||
if (data.SatIndex == 0xFF)
|
||||
SatTransponder transponder = new SatTransponder(i, mapping, this.DataRoot);
|
||||
if (transponder.Satellite == null)
|
||||
continue;
|
||||
#if SYMBOL_RATE_ROUNDING
|
||||
ushort sr = (ushort)(data.SymbolRate & 0x7FFF);
|
||||
if (sr % 100 >= 95)
|
||||
data.SymbolRate = (ushort)((data.SymbolRate & 0x8000) | ((sr / 100 + 1) * 100));
|
||||
#endif
|
||||
|
||||
Transponder transponder = new Transponder(i);
|
||||
transponder.FrequencyInMhz = data.Frequency;
|
||||
transponder.OriginalNetworkId = data.OriginalNetworkId;
|
||||
transponder.TransportStreamId = data.TransportStreamId;
|
||||
transponder.SymbolRate = data.SymbolRate & 0x7FFF;
|
||||
if (data.SymbolRate == 11000)
|
||||
if (transponder.SymbolRate == 11000)
|
||||
this.isDvbsSymbolRateDiv2 = true;
|
||||
|
||||
var sat = this.DataRoot.Satellites.TryGet(data.SatIndex/2);
|
||||
var sat = transponder.Satellite;
|
||||
this.DataRoot.AddTransponder(sat, transponder);
|
||||
}
|
||||
|
||||
@@ -411,16 +404,16 @@ namespace ChanSort.Loader.LG
|
||||
#endregion
|
||||
|
||||
#region ReadDvbsChannelLinkedList()
|
||||
private void ReadDvbsChannelLinkedList(ref int off)
|
||||
private void ReadDvbsChannelLinkedList(SatChannelListHeader header, ref int off)
|
||||
{
|
||||
this.nextChannelIndex = new Dictionary<int, int>();
|
||||
for (int i = 0; i < satConfig.dvbsMaxChannelCount; i++)
|
||||
int index = header.LinkedListStartIndex;
|
||||
while (index != 0xFFFF)
|
||||
{
|
||||
int offEntry = off + i*satConfig.sizeOfChannelLinkedListEntry;
|
||||
int cur = BitConverter.ToUInt16(fileContent, offEntry + 4);
|
||||
if (cur != i)
|
||||
break;
|
||||
this.nextChannelIndex.Add(cur, BitConverter.ToUInt16(fileContent, offEntry + 2));
|
||||
int offEntry = off + index*satConfig.sizeOfChannelLinkedListEntry;
|
||||
int nextIndex = BitConverter.ToUInt16(fileContent, offEntry + 2);
|
||||
this.nextChannelIndex.Add(index, nextIndex);
|
||||
index = nextIndex;
|
||||
}
|
||||
off += satConfig.dvbsMaxChannelCount*satConfig.sizeOfChannelLinkedListEntry;
|
||||
}
|
||||
@@ -438,28 +431,29 @@ namespace ChanSort.Loader.LG
|
||||
SatChannel ci = new SatChannel(i, index, mapping, this.DataRoot);
|
||||
if (!ci.InUse)
|
||||
++this.deletedChannelsHard;
|
||||
else if (ci.IsDeleted)
|
||||
++this.deletedChannelsSoft;
|
||||
else
|
||||
{
|
||||
if (ci.IsDeleted)
|
||||
{
|
||||
ci.OldProgramNr = -1;
|
||||
ci.NewProgramNr = -1;
|
||||
++this.deletedChannelsSoft;
|
||||
}
|
||||
|
||||
var list = this.DataRoot.GetChannelList(ci.SignalSource);
|
||||
var dupes = list.GetChannelByUid(ci.Uid);
|
||||
if (dupes.Count == 0)
|
||||
{
|
||||
if (ci.OldProgramNr == 0)
|
||||
if (ci.OldProgramNr == 0 && !ci.IsDeleted)
|
||||
++this.dvbsChannelsAtPr0;
|
||||
this.DataRoot.AddChannel(list, ci);
|
||||
}
|
||||
else
|
||||
{
|
||||
// duplicate channels (ONID,TSID,SSID) cause the TV to randomly reorder channels and show wrong ones in the
|
||||
// program list, so we erase all dupes here
|
||||
this.DataRoot.Warnings.AppendFormat(ERR_dupeChannel, ci.RecordIndex, ci.OldProgramNr, dupes[0].RecordIndex,
|
||||
dupes[0].OldProgramNr, dupes[0].Name).AppendLine();
|
||||
if (this.EraseDuplicateChannels)
|
||||
this.EraseDuplicateDvbsChannel(index, recordOffset, satConfig);
|
||||
++this.duplicateChannels;
|
||||
}
|
||||
this.DataRoot.AddChannel(list, ci);
|
||||
}
|
||||
|
||||
if (!this.nextChannelIndex.TryGetValue(index, out index) || index == -1)
|
||||
@@ -469,39 +463,6 @@ namespace ChanSort.Loader.LG
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region EraseDuplicateDvbsChannel()
|
||||
private void EraseDuplicateDvbsChannel(int index, int off, DvbsDataLayout c)
|
||||
{
|
||||
// erase channel data
|
||||
for (int i = 0; i < c.dvbsChannelLength; i++)
|
||||
fileContent[off++] = 0xFF;
|
||||
|
||||
// remove channel record from linked list
|
||||
int listBaseOff = this.dvbsBlockOffset + c.SequenceTableOffset;
|
||||
int listEntryOff = listBaseOff + index*c.sizeOfChannelLinkedListEntry;
|
||||
int prevRecordIndex = BitConverter.ToInt16(fileContent, listEntryOff + 0);
|
||||
int nextRecordIndex = BitConverter.ToInt16(fileContent, listEntryOff + 2);
|
||||
Tools.SetInt16(fileContent, listEntryOff + 0, 0);
|
||||
Tools.SetInt16(fileContent, listEntryOff + 2, 0);
|
||||
Tools.SetInt16(fileContent, listEntryOff + 4, 0);
|
||||
Tools.SetInt16(fileContent, listBaseOff + prevRecordIndex * c.sizeOfChannelLinkedListEntry + 2, nextRecordIndex);
|
||||
Tools.SetInt16(fileContent, listBaseOff + nextRecordIndex*c.sizeOfChannelLinkedListEntry + 0, prevRecordIndex);
|
||||
var header = new SatChannelListHeader(this.fileContent, this.dvbsBlockOffset + c.ChannelListHeaderOffset);
|
||||
if (header.LinkedListStartIndex == index)
|
||||
header.LinkedListStartIndex = nextRecordIndex;
|
||||
if (header.LinkedListEndIndex1 == index)
|
||||
header.LinkedListEndIndex1 = prevRecordIndex;
|
||||
if (header.LinkedListEndIndex2 == index)
|
||||
header.LinkedListEndIndex2 = prevRecordIndex;
|
||||
--header.ChannelCount;
|
||||
|
||||
// remove channel from allocation bitmap
|
||||
int allocBitmapOffset = dvbsBlockOffset + c.AllocationBitmapOffset + (index/8);
|
||||
int mask = 1 << (index & 7);
|
||||
this.fileContent[allocBitmapOffset] &= (byte)~mask;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetSatLocation()
|
||||
private string GetSatLocation(byte degree, byte fractionAndOrientation)
|
||||
{
|
||||
@@ -509,6 +470,7 @@ namespace ChanSort.Loader.LG
|
||||
}
|
||||
#endregion
|
||||
|
||||
// Test code for fixing broken DVB-S block of xxLM640T ==========
|
||||
|
||||
#region EraseDvbsBlock()
|
||||
|
||||
@@ -593,6 +555,163 @@ namespace ChanSort.Loader.LG
|
||||
}
|
||||
#endregion
|
||||
|
||||
// Sat channel list cleanup ==================
|
||||
|
||||
#region CleanUpChannelData()
|
||||
public override string CleanUpChannelData()
|
||||
{
|
||||
this.ResetChannelInformationInTransponderData();
|
||||
|
||||
byte[] sortedChannels = new byte[this.satConfig.dvbsMaxChannelCount*this.satConfig.dvbsChannelLength];
|
||||
|
||||
var channelsByTransponder =
|
||||
this.satTvChannels.Channels.Union(this.satRadioChannels.Channels).OrderBy(PhysicalChannelOrder).ToList();
|
||||
int prevChannelOrderId = -1;
|
||||
int prevTransponderIndex = -1;
|
||||
int channelCounter = 0;
|
||||
int removedCounter = 0;
|
||||
SatTransponder currentTransponder = null;
|
||||
foreach (var channel in channelsByTransponder)
|
||||
{
|
||||
SatChannel satChannel = channel as SatChannel;
|
||||
if (satChannel == null) // ignore proxy channels created by a reference list
|
||||
continue;
|
||||
RelocateChannelData(satChannel, ref prevChannelOrderId, sortedChannels, ref removedCounter,
|
||||
ref prevTransponderIndex, ref channelCounter, ref currentTransponder);
|
||||
}
|
||||
if (currentTransponder != null)
|
||||
{
|
||||
currentTransponder.LastChannelIndex = channelCounter - 1;
|
||||
currentTransponder.ChannelCount = channelCounter - currentTransponder.FirstChannelIndex;
|
||||
}
|
||||
|
||||
// copy temp data back to fileContent and clear remainder
|
||||
Tools.MemCopy(sortedChannels, 0,
|
||||
this.fileContent, this.dvbsBlockOffset + satConfig.ChannelListOffset,
|
||||
channelCounter*satConfig.dvbsChannelLength);
|
||||
Tools.MemSet(this.fileContent,
|
||||
this.dvbsBlockOffset + satConfig.ChannelListOffset + channelCounter*satConfig.dvbsChannelLength, 0xFF,
|
||||
(satConfig.dvbsMaxChannelCount - channelCounter)*satConfig.dvbsChannelLength);
|
||||
|
||||
UpdateChannelAllocationBitmap(channelCounter);
|
||||
UpdateChannelLinkedList(channelCounter);
|
||||
|
||||
return string.Format("{0} duplicate channels were detected and removed", removedCounter);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ResetChannelInformationInTransponderData()
|
||||
private void ResetChannelInformationInTransponderData()
|
||||
{
|
||||
foreach (SatTransponder transponder in this.DataRoot.Transponder.Values)
|
||||
{
|
||||
transponder.FirstChannelIndex = 0xFFFF;
|
||||
transponder.LastChannelIndex = 0xFFFF;
|
||||
transponder.ChannelCount = 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PhysicalChannelOrder()
|
||||
private int PhysicalChannelOrder(ChannelInfo channel)
|
||||
{
|
||||
return (channel.Transponder.Id << 16) + channel.ServiceId;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RelocateChannelData()
|
||||
private void RelocateChannelData(SatChannel channel, ref int prevChannelOrderId,
|
||||
byte[] sortedChannels, ref int removed, ref int prevTransponderIndex, ref int counter,
|
||||
ref SatTransponder currentTransponder)
|
||||
{
|
||||
if (RemoveChannelIfDupe(channel, ref prevChannelOrderId, ref removed))
|
||||
return;
|
||||
|
||||
UpdateChannelIndexInTransponderData(channel, ref prevTransponderIndex, counter, ref currentTransponder);
|
||||
|
||||
Tools.MemCopy(this.fileContent,
|
||||
this.dvbsBlockOffset + satConfig.ChannelListOffset + channel.RecordIndex*satConfig.dvbsChannelLength,
|
||||
sortedChannels,
|
||||
counter*satConfig.dvbsChannelLength,
|
||||
satConfig.dvbsChannelLength);
|
||||
|
||||
channel.RecordIndex = counter++;
|
||||
channel.baseOffset = this.dvbsBlockOffset + satConfig.ChannelListOffset + channel.RecordIndex*satConfig.dvbsChannelLength;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RemoveChannelIfDupe()
|
||||
private bool RemoveChannelIfDupe(SatChannel channel, ref int prevOrder, ref int removed)
|
||||
{
|
||||
int order = this.PhysicalChannelOrder(channel);
|
||||
if (order == prevOrder)
|
||||
{
|
||||
var list = this.DataRoot.GetChannelList(channel.SignalSource);
|
||||
list.RemoveChannel(channel);
|
||||
++removed;
|
||||
channel.NewProgramNr = -1;
|
||||
channel.OldProgramNr = -1;
|
||||
return true;
|
||||
}
|
||||
prevOrder = order;
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateChannelIndexInTransponderData()
|
||||
private void UpdateChannelIndexInTransponderData(SatChannel channel, ref int prevTransponderIndex, int counter,
|
||||
ref SatTransponder transponder)
|
||||
{
|
||||
if (channel.Transponder.Id == prevTransponderIndex)
|
||||
return;
|
||||
|
||||
if (transponder != null)
|
||||
{
|
||||
transponder.LastChannelIndex = counter - 1;
|
||||
transponder.ChannelCount = counter - transponder.FirstChannelIndex;
|
||||
}
|
||||
|
||||
transponder = (SatTransponder)channel.Transponder;
|
||||
transponder.FirstChannelIndex = counter;
|
||||
prevTransponderIndex = channel.Transponder.Id;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateChannelAllocationBitmap()
|
||||
private void UpdateChannelAllocationBitmap(int counter)
|
||||
{
|
||||
Tools.MemSet(fileContent, this.dvbsBlockOffset + satConfig.AllocationBitmapOffset, 0, satConfig.dvbsMaxChannelCount / 8);
|
||||
Tools.MemSet(fileContent, this.dvbsBlockOffset + satConfig.AllocationBitmapOffset, 0xFF, counter / 8);
|
||||
if (counter % 8 != 0)
|
||||
fileContent[this.dvbsBlockOffset + satConfig.AllocationBitmapOffset + counter / 8] = (byte)(0xFF >> (8 - counter % 8));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateChannelLinkedList()
|
||||
private void UpdateChannelLinkedList(int counter)
|
||||
{
|
||||
var header = new SatChannelListHeader(this.fileContent, this.dvbsBlockOffset + satConfig.ChannelListHeaderOffset);
|
||||
header.LinkedListStartIndex = 0;
|
||||
header.LinkedListEndIndex1 = counter - 1;
|
||||
header.LinkedListEndIndex2 = counter - 1;
|
||||
header.ChannelCount = counter;
|
||||
|
||||
// update linked list
|
||||
var off = this.dvbsBlockOffset + satConfig.SequenceTableOffset;
|
||||
for (int i = 0; i < counter; i++)
|
||||
{
|
||||
Tools.SetInt16(this.fileContent, off + 0, i - 1);
|
||||
Tools.SetInt16(this.fileContent, off + 2, i + 1);
|
||||
Tools.SetInt16(this.fileContent, off + 4, i);
|
||||
off += satConfig.sizeOfChannelLinkedListEntry;
|
||||
}
|
||||
Tools.SetInt16(this.fileContent, off - satConfig.sizeOfChannelLinkedListEntry + 2, 0xFFFF);
|
||||
Tools.MemSet(fileContent, off, 0, (satConfig.dvbsMaxChannelCount - counter) * satConfig.sizeOfChannelLinkedListEntry);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
// Saving ====================================
|
||||
|
||||
#region Save()
|
||||
public override void Save(string tvOutputFile)
|
||||
|
||||
Reference in New Issue
Block a user