feyris-tan ef86554f9a Import
2025-05-12 22:09:16 +02:00

217 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Descriptors.Extension;
using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Mpeg2;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Skyscraper.IO;
namespace skyscraper5.Dvb.Psi
{
class SdtParser : IPsiProcessor
{
public ISdtEventHandler EventHandler { get; }
public SdtParser(ISdtEventHandler eventHandler)
{
EventHandler = eventHandler;
}
public void GatherPsi(PsiSection section, int sourcePid)
{
MemoryStream ms = new MemoryStream(section.GetDataCopy(),false);
byte tableId = ms.ReadUInt8();
if (tableId != 0x42 && tableId != 0x46)
return;
ushort readUInt16Be = ms.ReadUInt16BE();
bool sectionSyntaxIndicator = (readUInt16Be & 0x8000) != 0;
if (!sectionSyntaxIndicator)
return;
int sectionLength = (readUInt16Be & 0x0fff);
ushort transportStreamId = ms.ReadUInt16BE();
byte readUInt8 = ms.ReadUInt8();
int versionNumber = (readUInt8 & 0x3e);
bool currentNextIndicator = (readUInt8 & 0x01) != 0;
byte sectionNumber = ms.ReadUInt8();
byte lastSectionNumber = ms.ReadUInt8();
ushort originalNetworkId = ms.ReadUInt16BE();
ms.ReadUInt8(); //reserved future use
if (tableId == 0x42)
{
//0x42 meaning current mux
EventHandler.SetNetworkId(originalNetworkId);
EventHandler.SetTransportStreamId(transportStreamId);
}
while (ms.GetAvailableBytes() > 4)
{
ReadService(ms, transportStreamId, originalNetworkId);
}
uint crc32 = ms.ReadUInt32BE();
}
private void ReadService(MemoryStream ms, ushort transportStreamId, ushort originalNetworkId)
{
ushort serviceId = ms.ReadUInt16BE();
byte readUInt8 = ms.ReadUInt8();
bool eitScheduleFlag = (readUInt8 & 0x02) != 0;
bool eitPresentFollowingFlag = (readUInt8 & 0x01) != 0;
ushort readUInt16Be = ms.ReadUInt16BE();
int rs = (readUInt16Be & 0xe000) >> 13;
RunningStatus runningStatus = (RunningStatus)rs;
bool freeCaMode = (readUInt16Be & 0x1000) != 0;
int descriptorsLoopLength = readUInt16Be & 0xfff;
SdtService child = new SdtService(serviceId, eitScheduleFlag, eitPresentFollowingFlag, runningStatus, freeCaMode);
byte[] descriptorsData = ms.ReadBytes(descriptorsLoopLength);
IEnumerable<TsDescriptor> unpackDescriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(descriptorsData, "SDT");
foreach (TsDescriptor dvbDescriptor in unpackDescriptors)
{
string name = dvbDescriptor.GetType().Name;
switch (name)
{
case nameof(ServiceDescriptor):
ServiceDescriptor serviceDescriptor = (ServiceDescriptor)dvbDescriptor;
child.ServiceName = serviceDescriptor.ServiceName;
child.ServiceProviderName = serviceDescriptor.ServiceProviderName;
child.ServiceType = serviceDescriptor.ServiceType;
break;
case nameof(UserDefinedDescriptor):
if (!child.PrivateDataSpecifier.HasValue)
break;
TsDescriptor tsDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)dvbDescriptor, child.PrivateDataSpecifier.Value, "SDT");
if (tsDescriptor == null)
break;
ParseUserDefinedDescriptor(tsDescriptor, child);
break;
case nameof(PrivateDataSpecifierDescriptor):
child.PrivateDataSpecifier = ((PrivateDataSpecifierDescriptor)dvbDescriptor).PrivateDataSpecifier;
break;
case nameof(CaIdentifierDescriptor):
child.CaIdentifiers = ((CaIdentifierDescriptor)dvbDescriptor).CaSystemIds;
if (child.CaIdentifiers.Length > 1)
Array.Sort(child.CaIdentifiers);
break;
case nameof(ComponentDescriptor):
ComponentDescriptor cd = (ComponentDescriptor)dvbDescriptor;
if (child.Components == null)
child.Components = new List<ComponentDescriptor>();
child.Components.Add(cd);
break;
case nameof(DataBroadcastDescriptor):
DataBroadcastDescriptor dbd = (DataBroadcastDescriptor)dvbDescriptor;
child.ComponentTag = dbd.ComponentTag;
child.DataBroadcastId = dbd.DataBroadcastId;
child.Selector = dbd.Selector;
child.Iso639LanguageCode = dbd.Iso639LanguageCode;
child.Text = dbd.Text;
break;
case nameof(CountryAvailabilityDescriptor):
CountryAvailabilityDescriptor cad = (CountryAvailabilityDescriptor)dvbDescriptor;
foreach (string cadCountryCode in cad.CountryCodes)
{
if (child.CountryAvailability == null)
child.CountryAvailability = new Dictionary<string, bool>();
child.CountryAvailability.Add(cadCountryCode, cad.CountryAvailabilityFlag);
}
break;
case nameof(LinkageDescriptor):
LinkageDescriptor ld = (LinkageDescriptor)dvbDescriptor;
if (child.Linkages == null)
child.Linkages = new HashSet<LinkageDescriptor>();
child.Linkages.Add(ld);
break;
case nameof(TimeShiftedServiceDescriptor):
child.ReferenceServiceId = ((TimeShiftedServiceDescriptor)dvbDescriptor).ReferenceServiceId;
break;
case nameof(NvodReferenceDescriptor):
child.NvodReferences = ((NvodReferenceDescriptor)dvbDescriptor).NvodReferences;
break;
case nameof(ExtensionUserDefinedDescriptor):
if (!child.PrivateDataSpecifier.HasValue)
break;
TsDescriptor extTsDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)dvbDescriptor, child.PrivateDataSpecifier.Value, "SDT");
if (extTsDescriptor == null)
break;
ParseUserDefinedDescriptor(extTsDescriptor, child);
break;
case nameof(DefaultAuthorityDescriptor):
DefaultAuthorityDescriptor defaultAuthorityDescriptor = (DefaultAuthorityDescriptor)dvbDescriptor;
child.DefaultAuthority = defaultAuthorityDescriptor.DefaultAuthority;
break;
case nameof(MultilingualServiceNameDescriptor):
MultilingualServiceNameDescriptor msnd = (MultilingualServiceNameDescriptor)dvbDescriptor;
child.MultilingualServiceName = msnd.ServiceNames;
break;
case nameof(FtaContentManagementDescriptor):
FtaContentManagementDescriptor fsnd = (FtaContentManagementDescriptor)dvbDescriptor;
child.ControlRemoteAccessOverInternet = fsnd.ControlRemoteAccessOverInternet;
child.DoNotApplyRevocation = fsnd.DoNotApplyRevocation;
child.DoNotScramble = fsnd.DoNotScramble;
break;
case nameof(ServiceRelocatedDescriptor):
ServiceRelocatedDescriptor serviceRelocatedDescriptor = (ServiceRelocatedDescriptor)dvbDescriptor;
child.OldOriginalNetworkId = serviceRelocatedDescriptor.OldOriginalNetworkId;
child.OldServiceId = serviceRelocatedDescriptor.OldServiceId;
child.OldTransportStreamId = serviceRelocatedDescriptor.OldTransportStreamId;
break;
case nameof(MessageDescriptor):
if (child.Messages == null)
child.Messages = new List<MessageDescriptor>();
MessageDescriptor message = (MessageDescriptor)dvbDescriptor;
child.Messages.Add(message);
break;
default:
throw new NotImplementedException(name);
}
}
EventHandler.OnSdtService(transportStreamId, originalNetworkId, child);
}
private void ParseUserDefinedDescriptor(TsDescriptor input, SdtService output)
{
if (input == null)
return;
string name = input.ToString();
switch (name)
{
default:
throw new NotImplementedException(name);
}
}
private void ParseUserDefinedExtensionDescriptor(TsDescriptor input, SdtService output)
{
if (input == null)
return;
string name = input.ToString();
switch (name)
{
default:
throw new NotImplementedException(name);
}
}
}
}