615 lines
37 KiB
C#
615 lines
37 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using skyscraper5.DsmCc.Descriptors;
|
|
using skyscraper5.Dvb;
|
|
using skyscraper5.Dvb.Descriptors;
|
|
using skyscraper5.Dvb.Descriptors.Extension;
|
|
using skyscraper5.Hdmv.Descriptors;
|
|
using skyscraper5.Mpeg2.Descriptors;
|
|
using skyscraper5.Mpeg2.ExtensionDescriptors;
|
|
using skyscraper5.Mpeg2.Psi.Model;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
|
using skyscraper5.src.Mpeg2.Descriptors;
|
|
using skyscraper8.Skyscraper;
|
|
|
|
namespace skyscraper5.Mpeg2.Psi
|
|
{
|
|
class PmtParser : IPsiProcessor, IMultistandardTable
|
|
{
|
|
public IPmtEventHandler EventHandler { get; }
|
|
|
|
public PmtParser(IPmtEventHandler eventHandler)
|
|
{
|
|
EventHandler = eventHandler;
|
|
}
|
|
|
|
public void GatherPsi(PsiSection section, int sourcePid)
|
|
{
|
|
MemoryStream buffer = new MemoryStream(section.GetDataCopy());
|
|
|
|
byte table_id = buffer.ReadUInt8();
|
|
if (table_id != 0x02)
|
|
return;
|
|
|
|
ushort readUInt16Be = buffer.ReadUInt16BE();
|
|
bool sectionSyntaxIndicator = (readUInt16Be & 0x8000) != 0;
|
|
if (!sectionSyntaxIndicator)
|
|
{
|
|
//According to T-REC-H.222.0-201808-S!!PDF-E.pdf, page 71 - this is supposed to be set to false.
|
|
return;
|
|
}
|
|
bool zero = (readUInt16Be & 0x4000) != 0;
|
|
int reserved = (readUInt16Be & 0x3000) >> 12;
|
|
int sectionLength = (readUInt16Be & 0x0fff);
|
|
|
|
ushort programNumber = buffer.ReadUInt16BE();
|
|
|
|
byte readUInt8 = buffer.ReadUInt8();
|
|
int reserved2 = (readUInt8 & 0xc0) >> 6;
|
|
int versionNumber = (readUInt8 & 0x3e);
|
|
bool currentNextIndicator = (readUInt8 & 0x01) != 0;
|
|
|
|
byte sectionNumber = buffer.ReadUInt8();
|
|
|
|
byte lastSectionNumber = buffer.ReadUInt8();
|
|
|
|
readUInt16Be = buffer.ReadUInt16BE();
|
|
int reserved3 = (readUInt16Be & 0xe000) >> 13;
|
|
int pcrPid = (readUInt16Be & 0x1fff);
|
|
|
|
readUInt16Be = buffer.ReadUInt16BE();
|
|
int reserved4 = (readUInt16Be & 0xf000) >> 12;
|
|
int programInfoLength = (readUInt16Be & 0x0fff) & 0x3ff;
|
|
|
|
ProgramMapping result = new ProgramMapping(programNumber, pcrPid);
|
|
if (programInfoLength > 0)
|
|
{
|
|
byte[] descriptorBuffer = new byte[programInfoLength];
|
|
int descriptorBufferFilling = buffer.Read(descriptorBuffer, 0, programInfoLength);
|
|
if (descriptorBufferFilling != programInfoLength)
|
|
return;
|
|
|
|
ParseOuterDescriptors(result, descriptorBuffer);
|
|
}
|
|
|
|
while ((buffer.Length - buffer.Position) > 4)
|
|
{
|
|
PmtStreamType streamType = (PmtStreamType)buffer.ReadUInt8();
|
|
|
|
readUInt16Be = buffer.ReadUInt16BE();
|
|
int reserved5 = (readUInt16Be & 0xe000) >> 13;
|
|
int elementaryPid = (readUInt16Be & 0x1fff);
|
|
|
|
readUInt16Be = buffer.ReadUInt16BE();
|
|
int reserved6 = (readUInt16Be & 0xf000) >> 12;
|
|
int esInfoLength = (readUInt16Be & 0xfff) & 0x3ff;
|
|
if (esInfoLength > buffer.GetAvailableBytes())
|
|
return;
|
|
|
|
byte[] descriptorBuffer2 = buffer.ReadBytes(esInfoLength);
|
|
ProgramMappingStream streamChild = new ProgramMappingStream(streamType, elementaryPid);
|
|
result.Streams.Add(streamChild);
|
|
ParseInnerDescriptors(streamChild, descriptorBuffer2);
|
|
}
|
|
|
|
EventHandler?.PmtEvent(result, sourcePid);
|
|
}
|
|
|
|
private void ParseInnerDescriptors(ProgramMappingStream output, byte[] inputBuffer)
|
|
{
|
|
IEnumerable<TsDescriptor> descriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(inputBuffer, GetTableType());
|
|
foreach (TsDescriptor dvbDescriptor in descriptors)
|
|
{
|
|
output.NumDescriptors++;
|
|
switch (dvbDescriptor.GetType().Name)
|
|
{
|
|
case nameof(StreamIdentifierDescriptor):
|
|
output.ComponentTag = ((StreamIdentifierDescriptor)dvbDescriptor).ComponentTag;
|
|
break;
|
|
case nameof(Iso639LanguageDescriptor):
|
|
Iso639LanguageDescriptor iso639Language = (Iso639LanguageDescriptor)dvbDescriptor;
|
|
output.Iso639LanguageCode = iso639Language.Iso639LanguageCode;
|
|
output.AudioType = iso639Language.AudioType;
|
|
break;
|
|
case nameof(TeletextDescriptor):
|
|
TeletextDescriptor teletextDescriptor = (TeletextDescriptor)dvbDescriptor;
|
|
output.Teletexts = teletextDescriptor.Teletexts;
|
|
break;
|
|
case nameof(ApplicationSignallingDescriptor):
|
|
ApplicationSignallingDescriptor alApplicationSignallingDescriptor = (ApplicationSignallingDescriptor)dvbDescriptor;
|
|
if (output.Applications == null)
|
|
output.Applications = new List<ApplicationSignallingDescriptor.ApplicationSignal>();
|
|
output.Applications.AddRange(alApplicationSignallingDescriptor.Applications);
|
|
break;
|
|
case nameof(CarouselIdentifierDescriptor):
|
|
CarouselIdentifierDescriptor carouselIdentifierDescriptor = (CarouselIdentifierDescriptor)dvbDescriptor;
|
|
output.CarouselFormatId = carouselIdentifierDescriptor.FormatId;
|
|
output.CarouselId = carouselIdentifierDescriptor.CarouselId;
|
|
break;
|
|
case nameof(DataBroadcastIdDescriptor):
|
|
DataBroadcastIdDescriptor dataBroadcastIdDescriptor = (DataBroadcastIdDescriptor)dvbDescriptor;
|
|
output.DataBroadcastId = dataBroadcastIdDescriptor.DataBroadcastId;
|
|
output.DataBroadcastSelector = dataBroadcastIdDescriptor.DataBroadcastSelector;
|
|
output.IpMacNotificationInfo = dataBroadcastIdDescriptor.IpMacNotificationInfo;
|
|
break;
|
|
case nameof(SupplemenatryAudioDescriptor):
|
|
SupplemenatryAudioDescriptor supplemenatryAudioDescriptor = (SupplemenatryAudioDescriptor)dvbDescriptor;
|
|
output.SupplementaryIndependantStream = supplemenatryAudioDescriptor.MixType;
|
|
output.EditorialClassification = supplemenatryAudioDescriptor.EditorialClassification;
|
|
output.SupplementaryLanguageCode = supplemenatryAudioDescriptor.Iso639LanguageCode;
|
|
break;
|
|
case nameof(Ac3Descriptor):
|
|
Ac3Descriptor ac3Descriptor = (Ac3Descriptor)dvbDescriptor;
|
|
output.Asvc = ac3Descriptor.Asvc;
|
|
output.BSID = ac3Descriptor.BSID;
|
|
output.ComponentType = ac3Descriptor.ComponentType;
|
|
output.MainId = ac3Descriptor.MainId;
|
|
output.Ac3DescriptorPresent = true;
|
|
break;
|
|
case nameof(VideoStreamDescriptor):
|
|
VideoStreamDescriptor videoStreamDescriptor = (VideoStreamDescriptor)dvbDescriptor;
|
|
output.FrameRate = videoStreamDescriptor.FrameRate;
|
|
output.Mpeg1OnlyFlag = videoStreamDescriptor.Mpeg1OnlyFlag;
|
|
output.ChromaFormat = videoStreamDescriptor.ChromaFormat;
|
|
output.ConstrainedParameterFlag = videoStreamDescriptor.ConstrainedParameterFlag;
|
|
output.FrameRateExtensionFlag = videoStreamDescriptor.FrameRateExtensionFlag;
|
|
output.MultipleFramerateFlag = videoStreamDescriptor.MultipleFramerateFlag;
|
|
output.ProfileAndLevelIndication = videoStreamDescriptor.ProfileAndLevelIndication;
|
|
output.StillPictureFlag = videoStreamDescriptor.StillPictureFlag;
|
|
break;
|
|
case nameof(DataStreamAlignmentDescriptor):
|
|
output.AlignmentType = ((DataStreamAlignmentDescriptor)dvbDescriptor).AlignmentType;
|
|
break;
|
|
case nameof(MaximumBitrateDescriptor):
|
|
MaximumBitrateDescriptor maximumBitrateDescriptor = ((MaximumBitrateDescriptor)dvbDescriptor);
|
|
output.MaximumBitrate = maximumBitrateDescriptor.MaximumBitrate;
|
|
break;
|
|
case nameof(AudioStreamDescriptor):
|
|
AudioStreamDescriptor audioStreamDescriptor = ((AudioStreamDescriptor)dvbDescriptor);
|
|
output.AudioStreamId = audioStreamDescriptor.ID;
|
|
output.FreeFormat = audioStreamDescriptor.FreeFormat;
|
|
output.Layer = audioStreamDescriptor.Layer;
|
|
output.VariableRateAudio = audioStreamDescriptor.VariableRateAudio;
|
|
break;
|
|
case nameof(AvcVideoDescriptor):
|
|
AvcVideoDescriptor avcVideoDescriptor = (AvcVideoDescriptor)dvbDescriptor;
|
|
output.Avc24HourPictureFlag = avcVideoDescriptor.Avc24HourPictureFlag;
|
|
output.AvcCompatibleFlags = avcVideoDescriptor.AvcCompatibleFlags;
|
|
output.AvcStillPresent = avcVideoDescriptor.AvcStillPresent;
|
|
output.ConstraintSet0Flag = avcVideoDescriptor.ConstraintSet0Flag;
|
|
output.ConstraintSet1Flag = avcVideoDescriptor.ConstraintSet1Flag;
|
|
output.ConstraintSet2Flag = avcVideoDescriptor.ConstraintSet2Flag;
|
|
output.ConstraintSet3Flag = avcVideoDescriptor.ConstraintSet3Flag;
|
|
output.ConstraintSet4Flag = avcVideoDescriptor.ConstraintSet4Flag;
|
|
output.ConstraintSet5Flag = avcVideoDescriptor.ConstraintSet5Flag;
|
|
output.FramePackingSeiNotPresent = avcVideoDescriptor.FramePackingSeiNotPresent;
|
|
output.LevelIdc = avcVideoDescriptor.LevelIdc;
|
|
output.ProfileRdc = avcVideoDescriptor.ProfileRdc;
|
|
break;
|
|
case nameof(CaDescriptor):
|
|
CaDescriptor caDescriptor = (CaDescriptor)dvbDescriptor;
|
|
output.CaPid = caDescriptor.CaPid;
|
|
output.CaSystemId = caDescriptor.CaSystemId;
|
|
output.CaPrivateData = caDescriptor.PrivateData;
|
|
break;
|
|
case nameof(UserDefinedDescriptor):
|
|
if (!output.PrivateDataSpecifier.HasValue)
|
|
{
|
|
if (output.UnknownUserDefines == null)
|
|
{
|
|
output.UnknownUserDefines = new List<UserDefinedDescriptor>();
|
|
}
|
|
output.UnknownUserDefines.Add((UserDefinedDescriptor)dvbDescriptor);
|
|
continue;
|
|
}
|
|
TsDescriptor userDefinedDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)dvbDescriptor, output.PrivateDataSpecifier.Value, "PMT");
|
|
if (userDefinedDescriptor == null)
|
|
{
|
|
if (output.UnknownUserDefines == null)
|
|
{
|
|
output.UnknownUserDefines = new List<UserDefinedDescriptor>();
|
|
}
|
|
output.UnknownUserDefines.Add((UserDefinedDescriptor)dvbDescriptor);
|
|
continue;
|
|
}
|
|
throw new NotImplementedException(nameof(UserDefinedDescriptor));
|
|
case nameof(PrivateDataSpecifierDescriptor):
|
|
output.PrivateDataSpecifier = ((PrivateDataSpecifierDescriptor)dvbDescriptor).PrivateDataSpecifier;
|
|
break;
|
|
case nameof(SubtitlingDescriptor):
|
|
output.Subtitlings = ((SubtitlingDescriptor)dvbDescriptor).Subtitlings;
|
|
break;
|
|
case nameof(RegistrationDescriptor):
|
|
RegistrationDescriptor rd = ((RegistrationDescriptor)dvbDescriptor);
|
|
output.FormatIdentifier = rd.FormatIdentifier;
|
|
output.AdditionalIdentificationInfo = rd.AdditionalIdentificationInfo;
|
|
break;
|
|
case nameof(AssociationTagDescriptor):
|
|
AssociationTagDescriptor atd = (AssociationTagDescriptor)dvbDescriptor;
|
|
output.AssociationTagSelector = atd.Selector;
|
|
output.AssociationTagTransactionId = atd.TransactionId;
|
|
output.AssociationTagUse = atd.Use;
|
|
output.AssociationTagPrivateData = atd.PrivateData;
|
|
output.AssociationTagTimeOut = atd.TimeOut;
|
|
break;
|
|
case nameof(VbiDataDescriptor):
|
|
output.VbiData = ((VbiDataDescriptor)dvbDescriptor).VbiData;
|
|
break;
|
|
case nameof(AacDescriptor):
|
|
AacDescriptor aacDescriptor = ((AacDescriptor)dvbDescriptor);
|
|
output.AacType = aacDescriptor.AacType;
|
|
output.AacAdditionalInfo = aacDescriptor.AdditionalInfo;
|
|
output.AacProfileAndLevel = aacDescriptor.ProfileAndLevel;
|
|
output.SaocDeFlag = aacDescriptor.SaocDeFlag;
|
|
break;
|
|
case nameof(AncillaryDataDescriptor):
|
|
AncillaryDataDescriptor acd = (AncillaryDataDescriptor)dvbDescriptor;
|
|
output.AncillaryDataDescriptor = ((AncillaryDataDescriptor)dvbDescriptor);
|
|
break;
|
|
case nameof(EnhancedAc3Descriptor):
|
|
EnhancedAc3Descriptor eac3d = ((EnhancedAc3Descriptor)dvbDescriptor);
|
|
output.MainId = eac3d.MainId;
|
|
output.BSID = eac3d.BSID;
|
|
if (eac3d.ComponentType != null)
|
|
output.ComponentType = (Ac3Descriptor.ComponentTypeEnum)eac3d.ComponentType;
|
|
output.Asvc = eac3d.ASVC;
|
|
output.MixInfoExists = eac3d.MixInfoExists;
|
|
output.Substream1 = eac3d.Substream1;
|
|
output.Substream2 = eac3d.Substream2;
|
|
output.Substream3 = eac3d.Substream3;
|
|
output.Ac3PlusDescriptorPresent = true;
|
|
break;
|
|
case nameof(HevcVideoDescriptor):
|
|
HevcVideoDescriptor hvd = (HevcVideoDescriptor)dvbDescriptor;
|
|
output.Copied44bits = hvd.Copied44bits;
|
|
output.LevelIdc = hvd.LevelIdc;
|
|
output.FrameOnlyConstraintFlag = hvd.FrameOnlyConstraintFlag;
|
|
output.HdrWcgIdc = hvd.HdrWcgIdc;
|
|
output.Hevc24hrPicturePresentFlag = hvd.Hevc24hrPicturePresentFlag;
|
|
output.HevcStillPresentFlag = hvd.HevcStillPresentFlag;
|
|
output.InterlacedSourceFlag = hvd.InterlacedSourceFlag;
|
|
output.NonPackedConstraintFlag = hvd.NonPackedConstraintFlag;
|
|
output.ProfileCompatibilityIndication = hvd.ProfileCompatibilityIndication;
|
|
output.ProfileIdc = hvd.ProfileIdc;
|
|
output.ProfileSpace = hvd.ProfileSpace;
|
|
output.ProgressiveSourceFlag = hvd.ProgressiveSourceFlag;
|
|
output.SubPicHrdParamsNotPresentFlag = hvd.SubPicHrdParamsNotPresentFlag;
|
|
output.TemporalIdMax = hvd.TemporalIdMax;
|
|
output.TierFlag = hvd.TierFlag;
|
|
output.TemporalIdMin = hvd.TemporalIdMin;
|
|
break;
|
|
case nameof(Ac4Descriptor):
|
|
Ac4Descriptor ac4d = (Ac4Descriptor)dvbDescriptor;
|
|
output.Ac4ChannelMode = ac4d.Ac4ChannelMode;
|
|
output.Ac4DialogEnhancement = ac4d.Ac4DialogEnhancementEnabled;
|
|
output.Ac4Dsi = ac4d.Ac4Dsi;
|
|
break;
|
|
case nameof(AudioPreselectionDescriptor):
|
|
output.AudioPreselection = ((AudioPreselectionDescriptor)dvbDescriptor).Preselections;
|
|
break;
|
|
case nameof(StdDescriptor):
|
|
output.LeakValidFlag = ((StdDescriptor)dvbDescriptor).LeakValidFlag;
|
|
break;
|
|
case nameof(VbiTeletextDescriptor):
|
|
VbiTeletextDescriptor vbiTeletext = ((VbiTeletextDescriptor)dvbDescriptor);
|
|
if (vbiTeletext.Teletexts == null)
|
|
break;
|
|
output.VbiTeletexts = vbiTeletext.Teletexts;
|
|
break;
|
|
case nameof(FmcDescriptor):
|
|
FmcDescriptor fd = ((FmcDescriptor)dvbDescriptor);
|
|
output.FlexMuxChannels = fd.FlexMuxChannels;
|
|
break;
|
|
case nameof(MvcExtensionDescriptor):
|
|
MvcExtensionDescriptor med = (MvcExtensionDescriptor)dvbDescriptor;
|
|
throw new NotImplementedException(nameof(MvcExtensionDescriptor));
|
|
case nameof(J2KVideoDescriptor):
|
|
J2KVideoDescriptor j2kvd = (J2KVideoDescriptor)dvbDescriptor;
|
|
throw new NotImplementedException(nameof(J2KVideoDescriptor));
|
|
case nameof(Mpeg4TextDescriptor):
|
|
Mpeg4TextDescriptor mtd = (Mpeg4TextDescriptor)dvbDescriptor;
|
|
if (mtd.FormatSpecificTextConfig == null)
|
|
break;
|
|
throw new NotImplementedException(nameof(Mpeg4TextDescriptor));
|
|
case nameof(SmoothingBufferDescriptor):
|
|
SmoothingBufferDescriptor sbd = (SmoothingBufferDescriptor)dvbDescriptor;
|
|
output.SbLeakRate = sbd.SbLeakRate;
|
|
output.SbSize = sbd.SbSize;
|
|
break;
|
|
case nameof(PrivateDataIndicatorDescriptor):
|
|
PrivateDataIndicatorDescriptor pdid = (PrivateDataIndicatorDescriptor)dvbDescriptor;
|
|
output.PrivateDataIndicator = pdid.PrivateDataIndicator;
|
|
break;
|
|
case nameof(HierarchyDescriptor):
|
|
HierarchyDescriptor hd = (HierarchyDescriptor)dvbDescriptor;
|
|
if (!hd.Valid)
|
|
break;
|
|
throw new NotImplementedException(nameof(HierarchyDescriptor));
|
|
case nameof(HevcTimingAndHrdDescriptor):
|
|
HevcTimingAndHrdDescriptor hahd = (HevcTimingAndHrdDescriptor)dvbDescriptor;
|
|
output._90khzFlag = hahd._90khzFlag;
|
|
output.PictureAndTimingInfoPresentFlag = hahd.PictureAndTimingInfoPresentFlag;
|
|
output.HdrManagementValidFlag = hahd.HrdManagementValidFlag;
|
|
output.K = hahd.K;
|
|
output.N = hahd.N;
|
|
output.NumUnitsInTick = hahd.NumUnitsInTick;
|
|
output.TargetScheduleIdx = hahd.TargetScheduleIdx;
|
|
output.TargetScheduleIdxNotPresentFlag = hahd.TargetScheduleIdxNotPresentFlag;
|
|
break;
|
|
case nameof(AdaptionFieldDataDescriptor):
|
|
output.AdaptionFieldDataIdentifier = ((AdaptionFieldDataDescriptor)dvbDescriptor).AdaptionFieldDataIdentifier;
|
|
break;
|
|
case nameof(AvcTimingAndHrdDescriptor):
|
|
AvcTimingAndHrdDescriptor atahd = (AvcTimingAndHrdDescriptor)dvbDescriptor;
|
|
output._90khzFlag = atahd._90khzFlag;
|
|
output.PictureAndTimingInfoPresentFlag = atahd.PictureAndTimingInfoPresentFlag;
|
|
output.NumUnitsInTick = atahd.NumUnitsInTick;
|
|
output.K = atahd.K;
|
|
output.N = atahd.N;
|
|
output.HdrManagementValidFlag = atahd.HrdManagementValidFlag;
|
|
output.FixedFrameRateFlag = atahd.FixedFrameRateFlag;
|
|
output.PictureToDisplayConversionFlag = atahd.PictureToDisplayConversionFlag;
|
|
output.TemporalPocFlag = atahd.TemporalPocFlag;
|
|
break;
|
|
case nameof(Mpeg4AudioDescriptor):
|
|
output.Mpeg4AudioProfileAndLevel = ((Mpeg4AudioDescriptor)dvbDescriptor).Mpeg4AudioProfileAndLevel;
|
|
break;
|
|
case nameof(Mpeg2AacAudioDescriptor):
|
|
Mpeg2AacAudioDescriptor mpeg2aacad = ((Mpeg2AacAudioDescriptor)dvbDescriptor);
|
|
output.AacChannelConfiguration = mpeg2aacad.AacChannelConfiguration;
|
|
output.AacAdditionalInformation = mpeg2aacad.AacAdditionalInformation;
|
|
output.AacProfile = mpeg2aacad.AacProfile;
|
|
break;
|
|
case nameof(ScramblingDescriptor):
|
|
ScramblingDescriptor sd = ((ScramblingDescriptor)dvbDescriptor);
|
|
output.ScramblingMode = sd.ScramblingMode;
|
|
break;
|
|
case nameof(RelatedContentDescriptor):
|
|
output.RelatedContentDescriptorPresent = true;
|
|
break;
|
|
case nameof(_0x11_T2MIDescriptor):
|
|
_0x11_T2MIDescriptor t2mid = (_0x11_T2MIDescriptor)dvbDescriptor;
|
|
output.NumT2MiStreams = t2mid.NumT2MiStreams;
|
|
output.T2MiStreamId = t2mid.T2MiStreamId;
|
|
output.PcrIscrCommonClockFlag = t2mid.PcrIscrCommonClockFlag;
|
|
break;
|
|
case nameof(ExternalEsIdDescriptor):
|
|
if (!dvbDescriptor.Valid)
|
|
break;
|
|
throw new NotImplementedException(nameof(ExternalEsIdDescriptor));
|
|
case nameof(_0x2E_Mpeg4AudioExtensionDescriptor):
|
|
_0x2E_Mpeg4AudioExtensionDescriptor mp4audioExtension = (_0x2E_Mpeg4AudioExtensionDescriptor)dvbDescriptor;
|
|
output.AudioSpecifConfig = mp4audioExtension.AudioSpecificConfig;
|
|
output.AudioProfileLevelIndication = mp4audioExtension.AudioProfileLevelIndication;
|
|
break;
|
|
case nameof(MetadataDescriptor):
|
|
MetadataDescriptor metadataDescriptor = (MetadataDescriptor)dvbDescriptor;
|
|
output.MetadataApplicationFormat = metadataDescriptor.MetadataApplicationFormat;
|
|
output.MetadataApplicationFormatIdentifier = metadataDescriptor.MetadataApplicationFormatIdentifier;
|
|
output.MetadataFormat = metadataDescriptor.MetadataFormat;
|
|
output.MetadataFormatIdentifier = metadataDescriptor.MetadataFormatIdentifier;
|
|
output.MetadataServiceId = metadataDescriptor.MetadataServiceId;
|
|
output.DecoderConfigFlag = metadataDescriptor.DecoderConfigFlag;
|
|
output.ServiceIdentificationRecord = metadataDescriptor.ServiceIdentificationRecord;
|
|
output.DecoderConfig = metadataDescriptor.DecoderConfig;
|
|
output.DecoderConfigIdentificationRecord = metadataDescriptor.DecoderConfigIdentificationRecord;
|
|
output.DecoderConfigMetadataServiceId = metadataDescriptor.DecoderConfigMetadataServiceId;
|
|
output.Reserved = metadataDescriptor.Reserved;
|
|
output.PrivateData = metadataDescriptor.PrivateData;
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(dvbDescriptor.GetType().Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ParseOuterDescriptors(ProgramMapping output, byte[] inputBuffer)
|
|
{
|
|
IEnumerable<TsDescriptor> descriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(inputBuffer, GetTableType());
|
|
foreach (TsDescriptor tsDescriptor in descriptors)
|
|
{
|
|
string name = tsDescriptor.GetType().Name;
|
|
switch (name)
|
|
{
|
|
case nameof(MaximumBitrateDescriptor):
|
|
output.MaximumBitrate = ((MaximumBitrateDescriptor)tsDescriptor).MaximumBitrate;
|
|
break;
|
|
case nameof(MultiplexBufferUtilizationDescriptor):
|
|
MultiplexBufferUtilizationDescriptor mbud = (MultiplexBufferUtilizationDescriptor)tsDescriptor;
|
|
output.MultiplexBufferUtilizationBoundValidFlag = mbud.BoundValidFlag;
|
|
output.MultiplexLtwOffsetLowerBound = mbud.LtwOffsetLowerBound;
|
|
output.MultiplexLtwOffsetUpperBound = mbud.LtwOffsetUpperBound;
|
|
break;
|
|
case nameof(SystemClockDescriptor):
|
|
SystemClockDescriptor scd = (SystemClockDescriptor)tsDescriptor;
|
|
output.ClockAccuracyExponent = scd.ClockAccuracyExponent;
|
|
output.ClockAccuracyInteger = scd.ClockAccuracyInteger;
|
|
output.ExternalClockReferenceIndicator = scd.ExternalClockReferenceIndicator;
|
|
break;
|
|
case nameof(SmoothingBufferDescriptor):
|
|
SmoothingBufferDescriptor sbd = (SmoothingBufferDescriptor)tsDescriptor;
|
|
output.SbLeakRate = sbd.SbLeakRate;
|
|
output.SbSize = sbd.SbSize;
|
|
break;
|
|
case nameof(CaDescriptor):
|
|
CaDescriptor caDescriptor = (CaDescriptor)tsDescriptor;
|
|
output.CaPid = caDescriptor.CaPid;
|
|
output.CaSystemId = caDescriptor.CaSystemId;
|
|
output.CaPrivateData = caDescriptor.PrivateData;
|
|
break;
|
|
case nameof(PrivateDataSpecifierDescriptor):
|
|
output.PrivateDataSpecifier = ((PrivateDataSpecifierDescriptor)tsDescriptor).PrivateDataSpecifier;
|
|
break;
|
|
case nameof(UserDefinedDescriptor):
|
|
uint registry;
|
|
if (output.PrivateDataSpecifier.HasValue)
|
|
registry = output.PrivateDataSpecifier.Value;
|
|
else if (output.RegistrationFormatIdentifier.HasValue)
|
|
registry = output.RegistrationFormatIdentifier.Value;
|
|
else
|
|
break;
|
|
|
|
TsDescriptor userDefinedDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)tsDescriptor, registry, "PMT");
|
|
if (userDefinedDescriptor == null)
|
|
continue;
|
|
name = userDefinedDescriptor.GetType().Name;
|
|
switch(name)
|
|
{
|
|
case nameof(CopyControlDescriptor):
|
|
CopyControlDescriptor ccd = (CopyControlDescriptor)userDefinedDescriptor;
|
|
output.CaSystemId = ccd.CaSystemId;
|
|
if (ccd.CaSystemId == 0x0fff)
|
|
output.CopyControlPrivateData = ((CopyControlDescriptor.AacsPrivateData)ccd.PrivateData).OriginalData;
|
|
else
|
|
output.CopyControlPrivateData = (byte[])ccd.PrivateData;
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(name);
|
|
}
|
|
break;
|
|
case nameof(RegistrationDescriptor):
|
|
RegistrationDescriptor registrationDescriptor = ((RegistrationDescriptor)tsDescriptor);
|
|
output.RegistrationFormatIdentifier = registrationDescriptor.FormatIdentifier;
|
|
output.RegistrationAdditionalIdentificationInfo = registrationDescriptor.AdditionalIdentificationInfo;
|
|
break;
|
|
case nameof(ServiceMoveDescriptor):
|
|
ServiceMoveDescriptor smd = (ServiceMoveDescriptor)tsDescriptor;
|
|
output.NewOriginalNetworkId = smd.NewOriginalNetworkId;
|
|
output.NewServiceId = smd.NewServiceId;
|
|
output.NewTransportStreamId = smd.NewTransportStreamId;
|
|
break;
|
|
case nameof(StreamIdentifierDescriptor):
|
|
StreamIdentifierDescriptor sid = (StreamIdentifierDescriptor)tsDescriptor;
|
|
output.ComponentTag = sid.ComponentTag;
|
|
break;
|
|
case nameof(MetadataStdDescriptor):
|
|
MetadataStdDescriptor mstdd = (MetadataStdDescriptor)tsDescriptor;
|
|
output.MetadataInputLeakRate = mstdd.MetadataInputLeakRate;
|
|
output.MetadataBufferSize = mstdd.MetadataBufferSize;
|
|
output.MetadataOutputLeakRate = mstdd.MetadataOutputLeakRate;
|
|
break;
|
|
case nameof(ScramblingDescriptor):
|
|
output.ScramblingMode = ((ScramblingDescriptor)tsDescriptor).ScramblingMode;
|
|
break;
|
|
case nameof(DeferredAssociationTagsDescriptor):
|
|
DeferredAssociationTagsDescriptor datd = (DeferredAssociationTagsDescriptor)tsDescriptor;
|
|
if (datd.AssociationTag == null)
|
|
break;
|
|
throw new NotImplementedException(nameof(DeferredAssociationTagsDescriptor));
|
|
case nameof(SLDescriptor):
|
|
output.EsId = ((SLDescriptor)tsDescriptor).EsId;
|
|
break;
|
|
case nameof(TeletextDescriptor):
|
|
//This should be in the inner loops.
|
|
break;
|
|
case nameof(Mpeg4TextDescriptor):
|
|
Mpeg4TextDescriptor mp4TextDescriptor = (Mpeg4TextDescriptor)tsDescriptor;
|
|
if (mp4TextDescriptor.FormatSpecificTextConfig == null)
|
|
break;
|
|
throw new NotImplementedException(nameof(Mpeg4TextDescriptor));
|
|
case nameof(PrivateDataIndicatorDescriptor):
|
|
PrivateDataIndicatorDescriptor pdid = (PrivateDataIndicatorDescriptor)tsDescriptor;
|
|
output.PrivateDataIndicator = pdid.PrivateDataIndicator;
|
|
break;
|
|
case nameof(VideoStreamDescriptor):
|
|
VideoStreamDescriptor vsd = (VideoStreamDescriptor)tsDescriptor;
|
|
output.FrameRate = vsd.FrameRate;
|
|
output.ChromaFormat = vsd.ChromaFormat;
|
|
output.ConstrainedParameterFlag = vsd.ConstrainedParameterFlag;
|
|
output.FrameRateExtensionFlag = vsd.FrameRateExtensionFlag;
|
|
output.Mpeg1OnlyFlag = vsd.Mpeg1OnlyFlag;
|
|
output.MultipleFramerateFlag = vsd.MultipleFramerateFlag;
|
|
output.ProfileAndLevelIndication = vsd.ProfileAndLevelIndication;
|
|
output.StillPictureFlag = vsd.StillPictureFlag;
|
|
break;
|
|
case nameof(TargetBackgroundGridDescriptor):
|
|
TargetBackgroundGridDescriptor tbgd = (TargetBackgroundGridDescriptor)tsDescriptor;
|
|
throw new NotImplementedException(nameof(TargetBackgroundGridDescriptor));
|
|
case nameof(MosaicDescriptor):
|
|
MosaicDescriptor md = (MosaicDescriptor)tsDescriptor;
|
|
throw new NotImplementedException(nameof(MosaicDescriptor));
|
|
case nameof(Iso639LanguageDescriptor):
|
|
Iso639LanguageDescriptor i639ld = (Iso639LanguageDescriptor)tsDescriptor;
|
|
output.AudioType = i639ld.AudioType;
|
|
output.Iso639LanguageCode = i639ld.Iso639LanguageCode;
|
|
break;
|
|
case nameof(IodDescriptor):
|
|
IodDescriptor iodD = (IodDescriptor)tsDescriptor;
|
|
output.InitialObjectDescriptor = iodD.InitialObjectDescriptor;
|
|
output.ScopeOfIodLabel = iodD.ScopeOfIodLabel;
|
|
output.IodLabel = iodD.IodLabel;
|
|
break;
|
|
case nameof(MetadataPointerDescriptor):
|
|
MetadataPointerDescriptor mpd = (MetadataPointerDescriptor)tsDescriptor;
|
|
output.MetadataProgramNumber = mpd.ProgramNumber;
|
|
output.MetadataApplicationFormat = mpd.MetadataApplicationFormat;
|
|
output.MetadataApplicationFormatIdentifier = mpd.MetadataApplicationFormatIdentifier;
|
|
output.MetadataFormat = mpd.MetadataFormat;
|
|
output.MetadataFormatIdentifier = mpd.MetadataFormatIdentifier;
|
|
output.MetadataLocatorRecord = mpd.MetadataLocatorRecord;
|
|
output.MetadataLocatorRecordFlag = mpd.MetadataLocatorRecordFlag;
|
|
output.MetadataServiceId = mpd.MetadataServiceId;
|
|
output.MpegCarriageFlag = mpd.MpegCarriageFlag;
|
|
output.MetadataPrivateData = mpd.PrivateData;
|
|
output.TransportStreamId = mpd.TransportStreamId;
|
|
output.TransportStreamLocation = mpd.TransportStreamLocation;
|
|
break;
|
|
case nameof(AudioStreamDescriptor):
|
|
AudioStreamDescriptor asd = (AudioStreamDescriptor)tsDescriptor;
|
|
output.FreeFormat = asd.FreeFormat;
|
|
output.AudioStreamId = asd.ID;
|
|
output.Layer = asd.Layer;
|
|
output.VariableRateAudio = asd.VariableRateAudio;
|
|
break;
|
|
case nameof(DataStreamAlignmentDescriptor):
|
|
DataStreamAlignmentDescriptor dsad = (DataStreamAlignmentDescriptor)tsDescriptor;
|
|
output.AlignmentType = dsad.AlignmentType;
|
|
break;
|
|
case nameof(HierarchyDescriptor):
|
|
HierarchyDescriptor hd = (HierarchyDescriptor)tsDescriptor;
|
|
output.HierarchyType = hd.HierarchyType;
|
|
output.HierarchyLayerType = hd.HierarchyLayerType;
|
|
output.TrefPresentFlag = hd.TrefPresentFlag;
|
|
output.HierarchyChannel = hd.HierarchyChannel;
|
|
output.NoViewScalabilityFlag = hd.NoViewScalabilityFlag;
|
|
output.HierarchyEmbeddedLayerIndex = hd.HierarchyEmbeddedLayerIndex;
|
|
output.NoQualityScalabilityFlag = hd.NoQualityScalabilityFlag;
|
|
output.NoSpatialScalabilityFlag = hd.NoSpatialScalabilityFlag;
|
|
output.NoTemporalScalabilityFlag = hd.NoTemporalScalabilityFlag;
|
|
break;
|
|
case nameof(ApplicationSignallingDescriptor):
|
|
ApplicationSignallingDescriptor asd2 = (ApplicationSignallingDescriptor)tsDescriptor;
|
|
if (!asd2.Valid)
|
|
break;
|
|
throw new NotImplementedException(nameof(ApplicationSignallingDescriptor));
|
|
default:
|
|
throw new NotImplementedException(name);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private STD_TYPE standard;
|
|
public void SetStandard(STD_TYPE standard)
|
|
{
|
|
this.standard = standard;
|
|
}
|
|
|
|
private string GetTableType()
|
|
{
|
|
if (IMultistandardTable.IsIsdb(standard))
|
|
{
|
|
return "ISDB PMT";
|
|
}
|
|
else
|
|
{
|
|
return "PMT";
|
|
}
|
|
}
|
|
}
|
|
}
|