99 lines
2.3 KiB
C#
99 lines
2.3 KiB
C#
using skyscraper5.Mpeg2;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.Skyscraper.Scraper.Utils;
|
|
using skyscraper5.src.Id3.Frames;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace skyscraper5.src.Id3
|
|
{
|
|
internal class Id3PesProcessor : IPesProcessor
|
|
{
|
|
public Id3PesProcessor(Id3Handler handler)
|
|
{
|
|
this.handler = handler;
|
|
}
|
|
|
|
private Id3Handler handler;
|
|
|
|
public void ProcessPesPacket(PesPacket packet)
|
|
{
|
|
if (packet.Payload == null)
|
|
{
|
|
handler.OnId3Error(Id3ErrorState.NullPacket);
|
|
return;
|
|
}
|
|
|
|
MemoryStream ms = new MemoryStream(packet.Payload, false);
|
|
if (ms.ReadUInt8() != 'I')
|
|
{
|
|
handler.OnId3Error(Id3ErrorState.InvalidMagic);
|
|
return;
|
|
}
|
|
if (ms.ReadUInt8() != 'D')
|
|
{
|
|
handler.OnId3Error(Id3ErrorState.InvalidMagic);
|
|
return;
|
|
}
|
|
if (ms.ReadUInt8() != '3')
|
|
{
|
|
handler.OnId3Error(Id3ErrorState.InvalidMagic);
|
|
return;
|
|
}
|
|
|
|
byte major = ms.ReadUInt8();
|
|
byte minor = ms.ReadUInt8();
|
|
Version version = new Version(2, major, minor);
|
|
Id3Tag frame = new Id3Tag(version);
|
|
|
|
byte flags = ms.ReadUInt8();
|
|
frame.Unsynchronisation = ((flags & 0x80) != 0);
|
|
bool extendedHeaderPresent = ((flags & 0x40) != 0);
|
|
frame.ExperimentalIndicator = ((flags & 0x20) != 0);
|
|
bool footerPresent = ((flags & 0x10) != 0);
|
|
|
|
uint size = ms.ReadUInt32BE();
|
|
if (ms.GetAvailableBytes() < size)
|
|
{
|
|
handler.OnId3Error(Id3ErrorState.PacketTooShort);
|
|
return;
|
|
}
|
|
|
|
if (extendedHeaderPresent)
|
|
{
|
|
throw new NotImplementedException("ID3 extended header");
|
|
}
|
|
|
|
long dataLeft = size;
|
|
while (dataLeft > 0)
|
|
{
|
|
uint entryFourcc = ms.ReadUInt32BE();
|
|
dataLeft -= 4;
|
|
uint entrySize = ms.ReadUInt32BE();
|
|
dataLeft -= 4;
|
|
ushort entryFlags = ms.ReadUInt16BE();
|
|
dataLeft -= 2;
|
|
byte[] entryData = ms.ReadBytes(entrySize);
|
|
dataLeft -= entrySize;
|
|
|
|
Id3Frame child = null;
|
|
switch(entryFourcc)
|
|
{
|
|
case 1347570006: //PRIV
|
|
child = new PrivateFrame(entryData, entryFlags);
|
|
break;
|
|
default:
|
|
string v = Encoding.ASCII.GetString(BitConverter.GetBytes(entryFourcc));
|
|
throw new NotImplementedException(String.Format("ID3 Frame {0}", v));
|
|
}
|
|
frame.Frames.Add(child);
|
|
}
|
|
handler.OnId3Tag(frame);
|
|
}
|
|
}
|
|
}
|