public void ReadProperties(object variable) { foreach (PropertyInfo info in variable.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { if (info.PropertyType == typeof(ulong)) { info.SetValue(variable, this.ReadUInt64(), null); } else if (info.PropertyType == typeof(uint)) { info.SetValue(variable, this.ReadUInt32(), null); } else if (info.PropertyType == typeof(ushort)) { info.SetValue(variable, this.ReadUInt16(), null); } else if (info.PropertyType == typeof(byte)) { info.SetValue(variable, this.ReadByte(), null); } else { if (info.PropertyType != typeof(BoxType)) { throw new InvalidOperationException("Type not yet supported for auto reading"); } BoxType type2 = new BoxType(this.ReadBytes(4)); info.SetValue(variable, type2, null); } } }
public virtual void Read(BoxReader reader) { this.Offset = (ulong)reader.BaseStream.Position; this.size = reader.ReadUInt32(); if (size == 0) { this.type = BoxTypes.Error; return; } this.type = reader.ReadBoxType(); if (this.size == 1) { this.largeSize = reader.ReadUInt64(); } if (this.expectedType == BoxTypes.Any) { reader.BaseStream.Seek((long) (this.size - 8), SeekOrigin.Current); } else if (this.expectedType == BoxTypes.AnyDescription) { return; } else if (this.type != this.expectedType) { throw new UnexpectedBoxException(this.expectedType, this.type); } }
public override void Read(BoxReader reader) { using (SizeChecker checker = new SizeChecker(this, reader)) { base.Read(reader); this.TrackFragmentHeaderBox.Read(reader); this.TrackFragmentRunBox.Read(reader); while (checker.DataLeft() > 8) { // it appears that Independent and Disposable Sample Box is optional BoxType nextbox = reader.PeekNextBoxType(); if (nextbox == BoxTypes.IndependentAndDisposableSamplesBox) { this.IndependentAndDisposableSamplesBox = new IndependentAndDisposableSamplesBox(this.TrackFragmentRunBox.Samples.Count); this.IndependentAndDisposableSamplesBox.Read(reader); continue; } if (nextbox == BoxTypes.UUID) { UserUniqueIDBox = new UserUniqueIDBox(); UserUniqueIDBox.Read(reader); continue; } break; // this shouldn't happen, and it should force the SizeChecker to throw an exception as it means we didn't read everything... } } }
public void WriteProperties(object variable) { foreach (PropertyInfo info in variable.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { if (info.PropertyType == typeof(ulong)) { this.WriteUInt64((UInt64)info.GetValue(variable, null)); // info.SetValue(variable, this.ReadUInt64(), null); } else if (info.PropertyType == typeof(uint)) { this.WriteUInt32((UInt32)info.GetValue(variable, null)); // info.SetValue(variable, this.ReadUInt32(), null); } else if (info.PropertyType == typeof(ushort)) { this.WriteUInt16((UInt16)info.GetValue(variable, null)); // info.SetValue(variable, this.ReadUInt16(), null); } else if (info.PropertyType == typeof(byte)) { this.Write((byte)info.GetValue(variable, null)); // info.SetValue(variable, this.ReadByte(), null); } else { BoxType btype = (BoxType)info.GetValue(variable, null); this.Write(btype.GetBytes()); } } }
public override void Read(BoxReader reader) { using (new SizeChecker(this, reader)) { base.Read(reader); TrackHeaderBox.Read(reader); while (this.Size > (ulong)(reader.BaseStream.Position - (long)this.Offset)) { long pos = reader.BaseStream.Position; BoxType next = reader.PeekNextBoxType(); if (next == BoxTypes.Edts) { EdtsBox = new EdtsBox(); EdtsBox.movieTimeScale = movieTimeScale; EdtsBox.Read(reader); } else if (next == BoxTypes.TrackReference) { TrackReferenceBox = new TrackReferenceBox(); TrackReferenceBox.Read(reader); } else if (next == BoxTypes.Media) { MediaBox = new MediaBox(this); MediaBox.Read(reader); } else { Box unknown = new Box(BoxTypes.Any); unknown.Read(reader); Debug.WriteLine(string.Format("Unknow box type {0} in Trak box, skipped", next.ToString())); } } } }
public virtual void Read(BoxReader reader) { this.Offset = (ulong)reader.BaseStream.Position; this.size = reader.ReadUInt32(); if (size == 0) { this.type = BoxTypes.Error; return; } this.type = reader.ReadBoxType(); if (this.size == 1) { this.largeSize = reader.ReadUInt64(); } if (this.expectedType == BoxTypes.Any) { reader.BaseStream.Seek((long)(this.size - 8), SeekOrigin.Current); } else if (this.expectedType == BoxTypes.AnyDescription) { return; } else if (this.type != this.expectedType) { throw new UnexpectedBoxException(this.expectedType, this.type); } }
public AnyPrivBox(BoxType btype, string privData) : base(btype) { int n = 0; if (privData.StartsWith("00000001")) n = 8; if (btype == BoxTypes.Dvc1) // ISMV video, which doesn't work in MP4 format n += 14; // ignore first seven bytes codecPrivateData = H264Utilities.HexStringToBytes(privData.Substring(n)); this.Size += (ulong)codecPrivateData.Length; }
public override void Read(BoxReader reader) { using (new SizeChecker(this, reader)) { base.Read(reader); // Apple either omits the header, or puts it after the TrackExtendBoxes BoxType boxType = reader.PeekNextBoxType(); if (boxType == BoxTypes.MovieExtendsHeader) { MovieExtendsHeaderBox = new MovieExtendsHeaderBox(); MovieExtendsHeaderBox.Read(reader); } // Apple puts the MovieExtendsBoxes BEFORE TrackBoxes, so TrackBoxes may be NULL below. if (parent.TrackBoxes != null) { TrackExtendBoxes = new TrackExtendsBox[parent.TrackBoxes.Length]; for (int i = 0; i < parent.TrackBoxes.Length; i++) { TrackExtendBoxes[i] = new TrackExtendsBox(); TrackExtendBoxes[i].Read(reader); } } else { // get the size of a TrackExtendsBox, then use that to determine the size of the array Box test = new Box(BoxTypes.Any); test.Read(reader); reader.BaseStream.Position = (long)test.Offset; if (MovieExtendsHeaderBox == null) { TrackExtendBoxes = new TrackExtendsBox[(this.Size - 8) / test.Size]; } else { TrackExtendBoxes = new TrackExtendsBox[(this.Size - 8 - MovieExtendsHeaderBox.Size) / test.Size]; } for (int i = 0; i < TrackExtendBoxes.Length; i++) { TrackExtendBoxes[i] = new TrackExtendsBox(); TrackExtendBoxes[i].Read(reader); } } } }
public UnknownEntry(BoxType inType) : base(inType) { // this should never be used when constructing boxes }
public FullBox(BoxType type) : base(type) { this.Size += 4UL; }
public FullBox(BoxType type, Type enumFlags) : base(type) { this.m_enumFlags = enumFlags; }
public void WriteBoxType(BoxType inType) { this.Write(inType.GetBytes(), 0, 4); }
/// <summary> /// InitSampleStreamFromSampleTableBox /// The idea is to collect information on slices starting from startindex to endIndex. /// This is a fairly complex method that traverses all boxes read from this SampleTableBox. /// </summary> /// <param name="sampleTimeScale">uint - sample time scale</param> /// <param name="startIndex">int - start index</param> /// <param name="endIndex">int - end index</param> /// <param name="lastEnd">ref ulong</param> /// <returns></returns> public List <StreamDataBlockInfo> InitSampleStreamFromSampleTableBox(uint sampleTimeScale, int startIndex, int endIndex, ref ulong lastEnd) { List <StreamDataBlockInfo> SampleStreamLocations = new List <StreamDataBlockInfo>(); // local vars DecodingTimeToSampleBox stts = this.DecodingTimeToSampleBox; if (stts == null) { throw new Exception("SampleTableBox.DecodingTimeToSampleBox missing for track"); } uint sampleCount = 0; ulong timeT = 0; ulong currScaledT = 0; ulong prevScaledT = 0; ulong endT = 0; uint[] counts = stts.SampleCount; uint[] deltaTimes = stts.SampleDelta; ulong currOffset = 0UL; SampleSizeBox stsz = this.SampleSizeBox; uint sampleSize = stsz.SampleSize; uint totalSamples = stsz.SampleCount; uint[] sizeArray = stsz.SampleSizeArray; int sampleCountInList = 0; if ((this.SampleDescriptionsBox == null) || (this.SampleDescriptionsBox.EntryCount != 1)) { throw new Exception("SampleTableBox.SampleDescriptionsBox error"); } BoxType sampleDescriptionBoxType = this.SampleDescriptionsBox.Entries[0].Type; // initialize (set) cttsIndex to the value that corresponds to startIndex int k = 0; int cttsIndex = 0; if (CompositionTimeToSample != null && CompositionTimeToSample.EntryCount > 0) { int sliceIndex = 1; while (cttsIndex < CompositionTimeToSample.SampleOffset.Length) { if (sliceIndex == startIndex) { break; } k++; if (k == CompositionTimeToSample.SampleCount[cttsIndex]) { k = 0; // begin counting from zero again cttsIndex++; } sliceIndex++; } } for (int i = 0; i < stts.EntryCount; i++) { for (int j = 0; j < counts[i]; j++) { currScaledT = (ulong)((timeT * (ulong)TimeSpan.FromSeconds(1.0).Ticks) / sampleTimeScale); if ((sampleCount + 1 >= startIndex) && (sampleCount + 1 <= endIndex)) { StreamDataBlockInfo data = new StreamDataBlockInfo(); data.index = (int)sampleCount; data.TimeStampNew = currScaledT; data.SliceDuration = (uint)((deltaTimes[i] * TimeSpan.TicksPerSecond) / sampleTimeScale) + 1; data.SliceSize = (int)sampleSize; if (sampleSize == 0) { data.SliceSize = (int)sizeArray[sampleCount]; } data.StreamOffset = (ulong)this.SampleToChunkBox.GetFileOffset((uint)(sampleCount + 1)); data.SliceType = sampleDescriptionBoxType == BoxTypes.Mp4a ? SliceType.MP4A : ((this.SyncSampleMapBox == null) || this.SyncSampleMapBox.IsIFrame(sampleCount + 1) ? SliceType.IFrame : SliceType.DFrame); // if necessary, increment cttsIndex if (CompositionTimeToSample != null && CompositionTimeToSample.EntryCount > 0) { k++; data.NonQuickTimeCTTS = CompositionTimeToSample.SampleOffset[cttsIndex]; if (k == CompositionTimeToSample.SampleCount[cttsIndex]) { k = 0; // begin counting from zero again cttsIndex++; } } SampleStreamLocations.Add(data); sampleCountInList++; } if (sampleCount + 1 > endIndex) { endT = prevScaledT; break; } // close of if (currScaledT > endTimeJustBeforeIFrame) // keep track of offset if (sampleSize > 0) { currOffset += sampleSize; } else { if (sampleCount > totalSamples) { throw new Exception("SampleTableBox error: sample count inconsistency bet. stts and stsz"); } currOffset += sizeArray[sampleCount]; } prevScaledT = currScaledT; timeT += deltaTimes[i]; sampleCount++; } // end of for j if (endT > 0UL) // end sample found { break; } } // end of for i if (endT == 0UL) // if we did not find end, endTime would not be set { lastEnd = currScaledT; } else { lastEnd = endT; } return(SampleStreamLocations); }
protected int nextIndex = 0; // internal use only #endregion Fields #region Constructors public MetaDataSampleEntry(BoxType inType) : base(inType) { //this.Size += (uint)allStrings.Length; // do this in derived class }
public SampleEntry(BoxType inType) : base(inType) { DataReferenceIndex = 1; // FIXME: assumes that there's only one DataReferenceBox this.Size += 8UL; }
public VisualSampleEntry(BoxType inType, RawVideoTrackInfo trackInfo) : base(inType) { Width = (ushort)trackInfo.Width; Height = (ushort)trackInfo.Height; HorizResolution = (uint)0x00480000; // 72 dpi VertResolution = (uint)0x00480000; FrameCount = (ushort)1; this.Size += 34UL; CompressorName = ""; // "Orions Digital MP4 Recoding"; Depth = (ushort)0x18; // images in color with no alpha this.Size += 36UL; // compressor name is 30 bytes plus 2 for length, 2 for depth, 2 for reserved if (trackInfo.PayloadType == VideoPayloadType.avc1) { AvcCBox = new AvcCBox(); AvcCBox.CodecPrivateData = trackInfo.CodecPrivateData; this.Size += AvcCBox.Size; } else if (trackInfo.PayloadType == VideoPayloadType.vc1) { PrivDataBox = new AnyPrivBox(BoxTypes.Dvc1, trackInfo.CodecPrivateData); // MS ISMV this.Size += PrivDataBox.Size; } else if (trackInfo.PayloadType == VideoPayloadType.mp4v) { //CleanApertureBox = new CleanApertureBox(); // We won't be putting a CleanApertureBox for now PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Esds, trackInfo.CodecPrivateData); // 3gp mp4v --> esds this.Size += PrivDataFullBox.Size; } if (trackInfo.AspectRatioX != trackInfo.AspectRatioY) { PixelAspectRatioBox = new PixelAspectRatioBox(); PixelAspectRatioBox.hSpacing = (uint)trackInfo.AspectRatioX; PixelAspectRatioBox.vSpacing = (uint)trackInfo.AspectRatioY; this.Size += PixelAspectRatioBox.Size; } }
public AudioSampleEntry(BoxType inType) : base(inType) { }
public AudioSampleEntry(BoxType inType, RawAudioTrackInfo audioInfo) : base(inType) { ChannelCount = (ushort)audioInfo.ChannelCount; SampleSize = (ushort)audioInfo.SampleSize; SampleRate = (uint)audioInfo.SampleRate; this.Size += 20UL; switch (audioInfo.PayloadType) { case AudioPayloadType.aac: case AudioPayloadType.mp4a: PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Esds, audioInfo.CodecPrivateData); // AAC encoding this.Size += PrivDataFullBox.Size; break; case AudioPayloadType.wma: PrivDataBox = new AnyPrivBox(BoxTypes.Wfex, audioInfo.CodecPrivateData); this.Size += PrivDataBox.Size; break; case AudioPayloadType.samr: // 3gp audio PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Damr, audioInfo.CodecPrivateData); this.Size += PrivDataFullBox.Size; break; default: throw new Exception(string.Format("Unknown audio track payload type: {0}", audioInfo.PayloadType)); } }
public Box(BoxType expectedType) { this.expectedType = expectedType; this.type = expectedType; this.size = 8; // base class size }
public VisualSampleEntry(BoxType inType) : base(inType) { }
public HintSampleEntry(BoxType inType) : base(inType) { this.Size += (ulong)data.Length; }
public AnyPrivFullBox(BoxType btype, string privData) : base(btype) { int n = 0; if (privData.StartsWith("00000001")) n = 8; codecPrivateData = H264Utilities.HexStringToBytes(privData.Substring(n)); if (codecPrivateData != null) this.Size += (ulong)codecPrivateData.Length; }