internal CodecStream(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, QtAtom root) { if (dataReader == null) { throw new ArgumentNullException("dataReader"); } if (dataBlockBuilder == null) { throw new ArgumentNullException("dataBlockBuilder"); } if (root == null) { throw new ArgumentNullException("root"); } _dataReader = dataReader; _dataBlockBuilder = dataBlockBuilder; _root = root; _moov = _root.FindChild(AtomName.Movie); _mdat = _root.FindChild(AtomName.MediaData); _fileOffset = _root.FirstChild.Offset; if (_mdat == null) { _mdatChunk = new Chunk(((QtAtom)_root.GetLastDescendant()).Offset - _fileOffset, 0); } else { _mdatChunk = new Chunk(_mdat.Offset - _fileOffset + 8, (_mdat.Length - 8)); } _mdatMaxUnparsedBytes = (uint)QtDetector.Configurable[QtDetector.ConfigurationKey.MediaDateMaxUnparsedBytes]; }
private static string GetExtraDataCodecStreamName(IResultNode headerDataAtom) { QtAtom track = FindParentAtom(headerDataAtom, AtomName.Track); QtAtom sampleDescription = FindParentAtom(headerDataAtom, AtomName.SampleDescription); return(GetCodecStreamName(track, sampleDescription, true)); }
private T GetRequiredAtom <T>(QtAtom parent, AtomName atomName, bool recursive) where T : QtAtom { T atom = (parent == null) ? null : parent.FindChild(atomName, recursive) as T; if (atom == null) { _requiredAtomsMissing = true; } return(atom); }
/// <summary> /// Locates the handler reference and verifies that the given /// <paramref name="componentSubType"/> is correct for this /// sample description. /// </summary> /// <param name="componentSubType">the component sub-type</param> /// <returns>true if the component sub-type is valid, false otherwise</returns> protected bool CheckComponentSubType(ComponentSubType componentSubType) { QtAtom media = FindParent(AtomName.Media); if (media != null) { HandlerReference handlerReference = media.FindChild(AtomName.HandlerReference) as HandlerReference; if (handlerReference != null && handlerReference.ComponentSubType != componentSubType) { return(false); } } return(true); }
private static string GetCodecStreamName(QtAtom track, QtAtom sampleDescription, bool isPartial) { var sb = new StringBuilder(); if (track != null) { // Report the track ID var trackHeader = track.FindChild(AtomName.TrackHeader) as TrackHeader; if (trackHeader != null) { sb.AppendFormat(CultureInfo.CurrentCulture, "Track {0}", trackHeader.TrackID); } if (isPartial) { sb.Append(" [Partial]"); } // Report the handler type (audio/video) and the handler component name var handlerReference = track.FindChild(AtomName.HandlerReference, true) as HandlerReference; if (handlerReference != null) { sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", handlerReference.ComponentSubType); if (!string.IsNullOrEmpty(handlerReference.ComponentName)) { sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", handlerReference.ComponentName); } } } else if (isPartial) { sb.Append("[Partial]"); } // Report the codec name + description if ((sampleDescription != null) && sampleDescription.HasChildren()) { string typeName = Enum.GetName(typeof(QtAtom.Attribute), QtAtom.Attribute.Type); string dataFormat = sampleDescription.Children[0].FindAttributeByName(typeName).ValueAsString; if (!string.IsNullOrEmpty(dataFormat)) { sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", dataFormat); sb.AppendDescriptiveCodecName(dataFormat); } } return(sb.ToString()); }
internal TrackData(QtAtom track, Chunk mdatChunk, long fileOffset) { _track = track; _mdatChunk = mdatChunk; _fileOffset = fileOffset; _buffer = new byte[8]; _sampleTable = GetRequiredAtom <QtAtom>(track, AtomName.SampleTable, true); _handlerReference = GetRequiredAtom <HandlerReference>(track, AtomName.HandlerReference, true); _sampleDescription = GetRequiredAtom <SampleDescription>(_sampleTable, AtomName.SampleDescription); _chunkOffset = GetRequiredAtom <ChunkOffset>(_sampleTable, AtomName.ChunkOffset); _sampleSize = GetRequiredAtom <SampleSize>(_sampleTable, AtomName.SampleSize); _sampleToChunk = GetRequiredAtom <SampleToChunk>(_sampleTable, AtomName.SampleToChunk); _chunks = new List <Chunk>(); _validators = new List <VideoSampleValidator> { IsValidH264Sample, IsValidMpeg4Sample, IsValidH263Sample }; _validatorsToRemove = new List <VideoSampleValidator>(); FirstSampleOffset = long.MaxValue; LastSampleEndOffset = long.MinValue; }
public ElementaryStreamDescriptor(QtAtom previousHeader) : base(previousHeader, AtomName.ElementaryStreamDescriptor) { }
public ClippingRegion(QtAtom previousHeader) : base(previousHeader, AtomName.ClippingRegion) { }
public override bool IsSuitableParent(QtAtom parent) { // File type should always be the first atom return(parent.IsRoot && !parent.HasChildren()); }
public FileType(QtAtom previousHeader) : base(previousHeader, AtomName.FileType) { }
public DataReferenceEntry(QtAtom previousHeader) : base(previousHeader, AtomName.DataReferenceEntry) { }
public MetaData(QtAtom previousHeader) : base(previousHeader, AtomName.MetaData) { }
protected SampleEntry(QtAtom previousHeader, AtomName atomName) : base(previousHeader, atomName) { }
public QtSampleDescriptionAtom(QtAtom previousHeader, AtomName atomName) : base(previousHeader, atomName) { Debug.Assert(atomName.IsFlagSet(AtomFlags.SizeAndType) && !atomName.IsFlagSet(AtomFlags.VersionAndFlags)); }
public TimeCodeSampleDescription(QtAtom previousHeader) : base(previousHeader, AtomName.TimeCodeSampleDescription) { }
public ColorParameter(QtAtom previousHeader) : base(previousHeader, AtomName.ColorParameter) { }
public AvcConfigurationBox(QtAtom previousHeader) : base(previousHeader, AtomName.AvcConfigurationBox) { }
public override bool IsSuitableParent(QtAtom parent) { return(!parent.HasChildren() || parent.LastChild.HeaderName != AtomName.Wide); }
/// <summary> /// Creates a new wide atom. /// </summary> /// <param name="previousHeader">the header that directly precedes the wide atom</param> public Wide(QtAtom previousHeader) : base(previousHeader, AtomName.Wide) { }
public Profile(QtAtom previousHeader) : base(previousHeader, AtomName.Profile) { }
public AvcLayerEntry(QtAtom previousHeader) : base(previousHeader, AtomName.AvcLayerEntry) { }
public TimeToSample(QtAtom previousHeader) : base(previousHeader, AtomName.TimeToSample) { }
protected SampleGroupDescriptionEntry(QtAtom previousHeader, AtomName atomName) : base(previousHeader, atomName) { }
public SampleSize(QtAtom previousHeader) : base(previousHeader, AtomName.SampleSize) { }
public SyncSample(QtAtom previousHeader) : base(previousHeader, AtomName.SyncSample) { }
public ChunkOffset(QtAtom previousHeader, AtomType atomType) : base(previousHeader, AtomName.ChunkOffset) { _atomType = atomType; }
public EditList(QtAtom previousHeader) : base(previousHeader, AtomName.EditList) { }
public SampleToGroupBox(QtAtom previousHeader) : base(previousHeader, AtomName.SampleToGroupBox) { }
public AvcSubSequenceEntry(QtAtom previousHeader) : base(previousHeader, AtomName.AvcSubSequenceEntry) { }
public TrackHeader(QtAtom previousHeader) : base(previousHeader, AtomName.TrackHeader) { }