Added support for LG's 2013 LA-Series (Sat list only)

Improved LG duplicate channel cleanup (including linked list and allocation bitmap)
This commit is contained in:
hbeham
2013-04-28 12:44:40 +02:00
parent d6570d18f3
commit a2ae5583ff
15 changed files with 3079 additions and 2126 deletions

View File

@@ -196,6 +196,35 @@
lnbCount = 40
lnbLength = 44
[DvbsBlock:907336]
; LA series
satCount = 64
satLength = 48
transponderCount = 2400
transponderLength = 56
dvbsChannelCount = 7520
dvbsChannelLength = 92
lnbCount = 40
lnbLength = 52
[TransponderDataMapping:40]
offTransponderIndex = 10
offFrequency = 12
offOriginalNetworkId = 18
offTransportStreamId = 20
offSymbolRate = 25
offSatIndex = 36
symbolRateFactor = 1
[TransponderDataMapping:56]
offTransponderIndex = 10
offFrequency = 12
offOriginalNetworkId = 22
offTransportStreamId = 24
offSymbolRate = 29
offSatIndex = 40
symbolRateFactor = 0.5
[SatChannelDataMapping:68]
lenName = 40
offSatelliteNr = 0
@@ -250,6 +279,34 @@
offVideoPid = 60
offAudioPid = 62
[SatChannelDataMapping:92]
; LA series
lenName = 40
offSatelliteNr = 0
offSourceType = 4
offTransponderIndex = 6, 12
offProgramNr = 8
offProgramNrPreset = 10
offFavorites2 = 14
offDeleted = 14
maskDeleted = 0x42
offEncrypted = 14
maskEncrypted = 0x80
offLock = 15
maskLock = 0x01
offSkip = 15
maskSkip = 0x02
offHide = 15
maskHide = 0x04
offProgNrCustomized = 15
maskProgNrCustomized = 0x40
offServiceId = 16
offServiceType = 18
offNameLength = 19
offName = 20
offVideoPid = 72
offAudioPid = 74
[FirmwareData:6944]
; LH series
offSize = 0
@@ -307,9 +364,6 @@
[FirmwareData:35504]
; LV,LW,LK950S
offSize = 0
offSystemLock =
offTvPassword =
offHbbTvEnabled =
offHotelModeEnabled=34643
offHotelModeDtvUpdate=34653
offHotelMenuAccessCode = 34668
@@ -338,3 +392,10 @@
offHotelMenuAccessCode = 35660
offHotelMenuPin = 35706
offSettingsChannelUpdate=36544
[FirmwareData:39592]
; LA7408
offSize = 0
offHotelModeEnabled=38255
offHotelModeDtvUpdate=38266
offHotelMenuAccessCode = 38282

View File

@@ -47,16 +47,18 @@
/// </summary>
public int ChannelListHeaderOffset
{
get { return 4 + this.dvbsSubblockLength[0] + this.dvbsSubblockLength[1] + this.dvbsSubblockLength[2]; }
get { return 4 + 4 + this.dvbsSubblockLength[0] + 4 + this.dvbsSubblockLength[1] + 4 + this.dvbsSubblockLength[2]; }
}
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
/// </summary>
public int SequenceTableOffset
{
get { return ChannelListHeaderOffset + 12 + dvbsMaxChannelCount/8; }
}
public int AllocationBitmapOffset { get { return ChannelListHeaderOffset + 16; } }
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
/// </summary>
public int SequenceTableOffset { get { return this.AllocationBitmapOffset + dvbsMaxChannelCount/8; } }
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
@@ -65,5 +67,6 @@
{
get { return SequenceTableOffset + dvbsMaxChannelCount*sizeOfChannelLinkedListEntry; }
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using ChanSort.Api;
namespace ChanSort.Loader.LG
{
@@ -6,13 +7,34 @@ namespace ChanSort.Loader.LG
{
private readonly byte[] data;
private readonly int baseOffset;
public SatChannelListHeader(byte[] data, int offset) { this.data = data; this.baseOffset = offset; }
public uint Checksum { get { return BitConverter.ToUInt32(data, baseOffset + 0); } }
public int LinkedListStartIndex { get { return BitConverter.ToInt16(data, baseOffset + 8); }}
public int LinkedListEndIndex1 { get { return BitConverter.ToInt16(data, baseOffset + 10); } }
public int LinkedListEndIndex2 { get { return BitConverter.ToInt16(data, baseOffset + 12); } }
public int ChannelCount { get { return BitConverter.ToInt16(data, baseOffset + 14); } }
public SatChannelListHeader(byte[] data, int offset)
{
this.data = data; this.baseOffset = offset;
}
public uint Checksum { get { return BitConverter.ToUInt32(data, baseOffset + 0); } }
public int LinkedListStartIndex
{
get { return BitConverter.ToInt16(data, baseOffset + 8); }
set { Tools.SetInt16(data, baseOffset + 8, value); }
}
public int LinkedListEndIndex1
{
get { return BitConverter.ToInt16(data, baseOffset + 10); }
set { Tools.SetInt16(data, baseOffset + 10, value); }
}
public int LinkedListEndIndex2
{
get { return BitConverter.ToInt16(data, baseOffset + 12); }
set { Tools.SetInt16(data, baseOffset + 12, value); }
}
public int ChannelCount
{
get { return BitConverter.ToInt16(data, baseOffset + 14); }
set { Tools.SetInt16(data, baseOffset + 14, value); }
}
public int Size { get { return 16; } }
}

View File

@@ -1,31 +1,52 @@
using System;
using System.Globalization;
using ChanSort.Api;
namespace ChanSort.Loader.LG
{
internal class SatTransponder
{
private readonly byte[] data;
public int BaseOffset { get; set; }
private const string _Frequency = "offFrequency";
private const string _OriginalNetworkId = "offOriginalNetworkId";
private const string _TransportStreamId = "offTransportStreamId";
private const string _SymbolRate = "offSymbolRate";
private const string _SatIndex = "offSatIndex";
public SatTransponder(byte[] data)
private readonly DataMapping mapping;
private readonly byte[] data;
private readonly int offset;
private int symbolRate;
public SatTransponder(DataMapping mapping)
{
this.data = data;
this.mapping = mapping;
this.data = mapping.Data;
this.offset = mapping.BaseOffset;
this.Frequency = mapping.GetWord(_Frequency);
this.OriginalNetworkId = mapping.GetWord(_OriginalNetworkId);
this.TransportStreamId = mapping.GetWord(_TransportStreamId);
this.symbolRate = mapping.GetWord(_SymbolRate);
string strFactor = mapping.Settings.GetString("symbolRateFactor");
decimal factor;
if (!string.IsNullOrEmpty(strFactor) && decimal.TryParse(strFactor, NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo, out factor))
this.symbolRate = (int)(this.symbolRate * factor);
this.SatIndex = mapping.GetByte(_SatIndex);
}
public int Frequency { get { return BitConverter.ToInt16(data, BaseOffset + 12); } }
public int OriginalNetworkId { get { return BitConverter.ToInt16(data, BaseOffset + 18); } }
public int TransportStreamId { get { return BitConverter.ToInt16(data, BaseOffset + 20); } }
public int Frequency { get; private set; }
public int OriginalNetworkId { get; private set; }
public int TransportStreamId { get; private set; }
public int SatIndex { get; private set; }
public int SymbolRate
{
get { return BitConverter.ToInt16(data, BaseOffset + 25); }
get { return symbolRate; }
set
{
data[BaseOffset + 25] = (byte)value;
data[BaseOffset + 26] = (byte)(value >> 8);
mapping.SetDataPtr(this.data, this.offset);
mapping.SetWord(_SymbolRate, value);
this.symbolRate = value;
}
}
public int SatIndex { get { return data[BaseOffset + 36]; } }
}
}

View File

@@ -24,7 +24,8 @@ namespace ChanSort.Loader.LG
private readonly Dictionary<int, DvbsDataLayout> satConfigs = new Dictionary<int, DvbsDataLayout>();
private readonly MappingPool<DataMapping> actMappings = new MappingPool<DataMapping>("Analog and DVB-C/T");
private readonly MappingPool<DataMapping> dvbsMappings = new MappingPool<DataMapping>("DVB-S");
private readonly MappingPool<DataMapping> dvbsMappings = new MappingPool<DataMapping>("DVB-S Channel");
private readonly MappingPool<DataMapping> dvbsTransponderMappings = new MappingPool<DataMapping>("DVB-S Transponder");
private readonly MappingPool<FirmwareData> firmwareMappings = new MappingPool<FirmwareData>("Firmware");
private readonly ChannelList atvChannels = new ChannelList(SignalSource.AnalogCT | SignalSource.Tv, "Analog TV");
@@ -106,6 +107,8 @@ namespace ChanSort.Loader.LG
actMappings.AddMapping(recordLength, new DataMapping(section));
else if (section.Name.StartsWith("SatChannelDataMapping"))
dvbsMappings.AddMapping(recordLength, new DataMapping(section));
else if (section.Name.StartsWith("TransponderDataMapping"))
dvbsTransponderMappings.AddMapping(recordLength, new DataMapping(section));
else if (section.Name.StartsWith("FirmwareData"))
firmwareMappings.AddMapping(recordLength, new FirmwareData(section));
}
@@ -372,10 +375,11 @@ namespace ChanSort.Loader.LG
#region ReadTransponderData()
private void ReadTransponderData(ref int off)
{
var data = new SatTransponder(fileContent);
data.BaseOffset = off;
var mapping = this.dvbsTransponderMappings.GetMapping(this.satConfig.transponderLength);
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)
continue;
#if SYMBOL_RATE_ROUNDING
@@ -394,8 +398,6 @@ namespace ChanSort.Loader.LG
var sat = this.DataRoot.Satellites.TryGet(data.SatIndex/2);
this.DataRoot.AddTransponder(sat, transponder);
data.BaseOffset += satConfig.transponderLength;
}
if (this.isDvbsSymbolRateDiv2)
@@ -454,7 +456,8 @@ namespace ChanSort.Loader.LG
// 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();
this.EraseDuplicateDvbsChannel(recordOffset, satConfig);
if (this.EraseDuplicateChannels)
this.EraseDuplicateDvbsChannel(index, recordOffset, satConfig);
++this.duplicateChannels;
}
}
@@ -467,10 +470,35 @@ namespace ChanSort.Loader.LG
#endregion
#region EraseDuplicateDvbsChannel()
private void EraseDuplicateDvbsChannel(int off, DvbsDataLayout c)
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
@@ -579,7 +607,7 @@ namespace ChanSort.Loader.LG
newDvbctChannelCount = this.dvbctChannelCount;
}
if (this.reorderPhysically || this.removeDeletedActChannels)
if (this.reorderPhysically || removeDeletedActChannels)
this.ReorderActChannelsPhysically();
if (satConfig != null)
@@ -658,7 +686,7 @@ namespace ChanSort.Loader.LG
int slot = 0;
foreach (ChannelInfo appChannel in sortedList)
{
if (appChannel.NewProgramNr <= 0 && this.removeDeletedActChannels)
if (appChannel.NewProgramNr <= 0 && removeDeletedActChannels)
continue;
if (appChannel.RecordIndex != slot)
{