149 lines
4.0 KiB
C#
149 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using skyscraper5.Mpeg2;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.Skyscraper.Plugins;
|
|
using skyscraper5.Skyscraper.Scraper;
|
|
using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
|
|
using skyscraper8.Mpeg2.Psi;
|
|
|
|
namespace skyscraper8.Experimentals.OtvSsu
|
|
{
|
|
[SkyscraperPlugin]
|
|
internal class OtvSsuDetector : Contestant, OtvSsuHandler
|
|
{
|
|
private const int MAXIMUM_FILE_SIZE = 33554432; //32MB.
|
|
//Let's use a limit here to avoid detecting too many large files and false positives.
|
|
|
|
private OtvSsuDetectorParser parser;
|
|
public OtvSsuDetector(int pid) : base("OpenTV SSU", pid)
|
|
{
|
|
parser = new OtvSsuDetectorParser(this, pid);
|
|
PacketProcessor = new PsiDecoder(pid, parser);
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
parser = null;
|
|
PacketProcessor = null;
|
|
}
|
|
|
|
public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext)
|
|
{
|
|
skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid,new OtvSsuParser(skyscraperContext)));
|
|
}
|
|
|
|
public override void Introduce(ProgramContext programContext)
|
|
{
|
|
}
|
|
|
|
class OtvSsuDetectorParser : PrivateSectionParser
|
|
{
|
|
private readonly OtvSsuHandler _handler;
|
|
private readonly int _pid;
|
|
private List<Coordinate> _coordinates;
|
|
|
|
public OtvSsuDetectorParser(OtvSsuHandler handler, int pid)
|
|
{
|
|
_handler = handler;
|
|
_pid = pid;
|
|
_coordinates = new List<Coordinate>();
|
|
}
|
|
|
|
class Coordinate
|
|
{
|
|
public ushort tableIdExtension;
|
|
public uint fileId;
|
|
public uint unknown1;
|
|
public uint length;
|
|
|
|
public Coordinate(ushort tableIdExtension1, uint u, uint unknown2, uint length1)
|
|
{
|
|
this.tableIdExtension = tableIdExtension1;
|
|
this.fileId = u;
|
|
this.unknown1 = unknown2;
|
|
this.length = length1;
|
|
}
|
|
|
|
public long hits;
|
|
}
|
|
|
|
protected override void HandleTable(byte tableId, int sourcePid, byte sectionNumber, byte lastSectionNumber, ushort tableIdExtension,
|
|
byte[] payload)
|
|
{
|
|
MemoryStream ms = new MemoryStream(payload, false);
|
|
uint fileId = ms.ReadUInt32BE();
|
|
uint unknown1 = ms.ReadUInt32BE();
|
|
uint offset = ms.ReadUInt32BE();
|
|
uint length = ms.ReadUInt32BE();
|
|
if (length > MAXIMUM_FILE_SIZE)
|
|
{
|
|
_handler.OnOtvSsuError(_pid, OtvSsuError.FileTooLarge);
|
|
return;
|
|
}
|
|
if (offset > length)
|
|
{
|
|
_handler.OnOtvSsuError(_pid,OtvSsuError.OffsetOutOfRange);
|
|
return;
|
|
}
|
|
|
|
if (tableIdExtension == 1 && (fileId & 0x00ff0000) == 0x00ff0000)
|
|
{
|
|
_handler.OnOtvSsuError(_pid, OtvSsuError.NdsOverlap);
|
|
return;
|
|
}
|
|
|
|
Coordinate coordinate = _coordinates.Find(x =>
|
|
x.tableIdExtension == tableIdExtension && x.fileId == fileId && x.unknown1 == unknown1 &&
|
|
x.length == length);
|
|
if (coordinate == null)
|
|
{
|
|
coordinate = new Coordinate(tableIdExtension, fileId, unknown1, length);
|
|
_handler.OnOtvSsuFileAnnouncement(_pid,tableIdExtension, fileId, unknown1, length);
|
|
_coordinates.Add(coordinate);
|
|
}
|
|
else
|
|
{
|
|
coordinate.hits++;
|
|
_handler.OnOtvSsuBlock(_pid, tableIdExtension, fileId, unknown1, length);
|
|
}
|
|
}
|
|
|
|
protected override void HandleTable(byte tableId, int sourcePid, byte[] payload)
|
|
{
|
|
_handler.OnOtvSsuError(_pid, OtvSsuError.SectionSyntaxIndicatorMissing);
|
|
}
|
|
}
|
|
|
|
public void OnOtvSsuError(int pid, OtvSsuError offsetOutOfRange)
|
|
{
|
|
Score--;
|
|
}
|
|
|
|
|
|
public void OnOtvSsuFileAnnouncement(int pid, ushort tableIdExtension, uint fileId, uint unknown1, uint length)
|
|
{
|
|
Score--;
|
|
}
|
|
|
|
public void OnOtvSsuBlock(int pid, ushort tableIdExtension, uint fileId, uint unknown1, uint length)
|
|
{
|
|
Score++;
|
|
}
|
|
|
|
public void OnOtvSsuComplete(int sourcePid, Stream getStream, ushort tableIdExtension, uint fileId, uint unknown1,
|
|
uint length)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public bool OnOtvCheckFileAlreadyKnown(int sourcePid, ushort tableIdExtension, uint fileId, uint unknown1, uint length)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|