public void CollectAllPayload() { MovieMetadataBox movieMetadata = this.mmb; TrackBox[] tracks = movieMetadata.TrackBoxes; done = new bool[tracks.Length]; SampleCountsInChunk = new List <uint> [tracks.Length]; int[] NextChunkOffsetIndex = new int[tracks.Length]; OffsetValues = new uint[tracks.Length]; ChunkOffSetBox[] stco = new ChunkOffSetBox[tracks.Length]; uint[] sample = new uint[tracks.Length]; for (int i = 0; i < tracks.Length; i++) { InitializeSampleCountsInChunk(i); NextChunkOffsetIndex[i] = 0; stco[i] = tracks[i].MediaBox.MediaInformationBox.SampleTableBox.ChunkOffSetBox; sample[i] = 0; } for (int i = 0; i < tracks.Length; i++) { OffsetValues[i] = stco[i].ChunkOffsets[NextChunkOffsetIndex[i]]; } int track; uint currOffset = GetNextOffset(tracks.Length, out track); Stream.Position = (long)currOffset; while (done.Any(d => d == false)) { uint offset = GetNextOffset(tracks.Length, out track); if (offset != currOffset) { throw new Exception("Input MP4 file has a problem with chunk offsets"); } NextChunkOffsetIndex[track]++; if (NextChunkOffsetIndex[track] == stco[track].ChunkOffsets.Length) { done[track] = true; OffsetValues[track] = uint.MaxValue; } else { OffsetValues[track] = stco[track].ChunkOffsets[NextChunkOffsetIndex[track]]; } int chunk = SampleToChunkIndex(track, sample[track]); uint count = SampleCountsInChunk[track][chunk]; SampleSizeBox stsz = tracks[track].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox; for (int k = 0; k < count; k++, sample[track]++) { ProcessSample(currOffset, stsz.SampleSizeArray[sample[track]]); currOffset += stsz.SampleSizeArray[sample[track]]; } } }
public void CollectAllPayload() { MovieMetadataBox movieMetadata = this.mmb; TrackBox[] tracks = movieMetadata.TrackBoxes; done = new bool[tracks.Length]; SampleCountsInChunk = new List<uint>[tracks.Length]; int[] NextChunkOffsetIndex = new int[tracks.Length]; OffsetValues = new uint[tracks.Length]; ChunkOffSetBox[] stco = new ChunkOffSetBox[tracks.Length]; uint[] sample = new uint[tracks.Length]; for (int i = 0; i < tracks.Length; i++) { InitializeSampleCountsInChunk(i); NextChunkOffsetIndex[i] = 0; stco[i] = tracks[i].MediaBox.MediaInformationBox.SampleTableBox.ChunkOffSetBox; sample[i] = 0; } for (int i = 0; i < tracks.Length; i++) { OffsetValues[i] = stco[i].ChunkOffsets[NextChunkOffsetIndex[i]]; } int track; uint currOffset = GetNextOffset(tracks.Length, out track); Stream.Position = (long)currOffset; while (done.Any(d => d == false)) { uint offset = GetNextOffset(tracks.Length, out track); if (offset != currOffset) throw new Exception("Input MP4 file has a problem with chunk offsets"); NextChunkOffsetIndex[track]++; if (NextChunkOffsetIndex[track] == stco[track].ChunkOffsets.Length) { done[track] = true; OffsetValues[track] = uint.MaxValue; } else { OffsetValues[track] = stco[track].ChunkOffsets[NextChunkOffsetIndex[track]]; } int chunk = SampleToChunkIndex(track, sample[track]); uint count = SampleCountsInChunk[track][chunk]; SampleSizeBox stsz = tracks[track].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox; for (int k = 0; k < count; k++, sample[track]++) { ProcessSample(currOffset, stsz.SampleSizeArray[sample[track]]); currOffset += stsz.SampleSizeArray[sample[track]]; } } }
/// <summary> /// Constructor to use when building the box from scratch. /// NOTE: We don't compute the Size of this box in this constructor. /// The Size of this box is computed during FinalizeBox. /// NOTE: The ordering of the sub-boxes is not determined in the constructor. /// Writing out the sub-boxes (see the Write method below) determines the order of sub-boxes. /// </summary> /// <param name="inParent">MediaInformationBox</param> /// <param name="trackInfo">IsochronousTrackInfo</param> public SampleTableBox(MediaInformationBox inParent, IsochronousTrackInfo trackInfo) : this(inParent) { CTTSOut = trackInfo.CTTSOut; fragmented = trackInfo.IsFragment; SampleDescriptionsBox = new SampleDescriptionsBox(this, trackInfo); DecodingTimeToSampleBox = new DecodingTimeToSampleBox(this); SampleToChunkBox = new SampleToChunkBox(this); SampleSizeBox = new SampleSizeBox(this); ChunkOffSetBox = new ChunkOffSetBox(this); if ((trackInfo is RawVideoTrackInfo) && !fragmented) { SyncSampleMapBox = new SyncSampleMapBox(); //CompositionTimeToSample = new CompositionTimeToSample(this); } }
/// <summary> /// Read - read in the SampleTableBox from the input MP4 file. /// Sub-boxes can come in in any order. /// </summary> /// <param name="reader">BoxReader</param> public override void Read(BoxReader reader) { using (new SizeChecker(this, reader)) { base.Read(reader); while (reader.BaseStream.Position < (long)(this.Size + this.Offset)) { long pos = reader.BaseStream.Position; Box test = new Box(BoxTypes.Any); test.Read(reader); reader.BaseStream.Position = pos; if (test.Type == BoxTypes.TimeToSample) { this.DecodingTimeToSampleBox = new DecodingTimeToSampleBox(this); DecodingTimeToSampleBox.Read(reader); } else if (test.Type == BoxTypes.CompositionOffset) { this.CompositionTimeToSample = new CompositionTimeToSample(this); CompositionTimeToSample.Read(reader); } else if (test.Type == BoxTypes.SampleDescription) { this.SampleDescriptionsBox = new SampleDescriptionsBox(this); SampleDescriptionsBox.Read(reader); } else if (test.Type == BoxTypes.SampleToChunk) { this.SampleToChunkBox = new SampleToChunkBox(this); SampleToChunkBox.Read(reader); } else if (test.Type == BoxTypes.SampleSize) { this.SampleSizeBox = new SampleSizeBox(this); SampleSizeBox.Read(reader); } else if (test.Type == BoxTypes.ChunkOffset) // FIXME: this can be a "co64" box { this.ChunkOffSetBox = new ChunkOffSetBox(this); ChunkOffSetBox.Read(reader); } else if (test.Type == BoxTypes.SyncSampleMap) { this.SyncSampleMapBox = new SyncSampleMapBox(); SyncSampleMapBox.Read(reader); } else { reader.BaseStream.Position = (long)(test.Size + test.Offset); // skip unknown box Debug.WriteLine(string.Format("Unknown box type {0} in SampleTableBox (stbl), skipped", test.Type.ToString())); } } // end of while if (SampleToChunkBox != null) { SampleToChunkBox.CheckIntegrityOfChunkData(); } } }
/// <summary> /// Constructor to use when building the box from scratch. /// NOTE: We don't compute the Size of this box in this constructor. /// The Size of this box is computed during FinalizeBox. /// NOTE: The ordering of the sub-boxes is not determined in the constructor. /// Writing out the sub-boxes (see the Write method below) determines the order of sub-boxes. /// </summary> /// <param name="inParent">MediaInformationBox</param> /// <param name="trackInfo">IsochronousTrackInfo</param> public SampleTableBox(MediaInformationBox inParent, IsochronousTrackInfo trackInfo) : this(inParent) { CTTSOut = trackInfo.CTTSOut; fragmented = trackInfo.IsFragment; SampleDescriptionsBox = new SampleDescriptionsBox(this, trackInfo); DecodingTimeToSampleBox = new DecodingTimeToSampleBox(this); SampleToChunkBox = new SampleToChunkBox(this); SampleSizeBox = new SampleSizeBox(this); ChunkOffSetBox = new ChunkOffSetBox(this); if ((trackInfo is RawVideoTrackInfo) && !fragmented) { SyncSampleMapBox = new SyncSampleMapBox(); //CompositionTimeToSample = new CompositionTimeToSample(this); } }
/// <summary> /// Read - read in the SampleTableBox from the input MP4 file. /// Sub-boxes can come in in any order. /// </summary> /// <param name="reader">BoxReader</param> public override void Read(BoxReader reader) { using (new SizeChecker(this, reader)) { base.Read(reader); while (reader.BaseStream.Position < (long)(this.Size + this.Offset)) { long pos = reader.BaseStream.Position; Box test = new Box(BoxTypes.Any); test.Read(reader); reader.BaseStream.Position = pos; if (test.Type == BoxTypes.TimeToSample) { this.DecodingTimeToSampleBox = new DecodingTimeToSampleBox(this); DecodingTimeToSampleBox.Read(reader); } else if (test.Type == BoxTypes.CompositionOffset) { this.CompositionTimeToSample = new CompositionTimeToSample(this); CompositionTimeToSample.Read(reader); } else if (test.Type == BoxTypes.SampleDescription) { this.SampleDescriptionsBox = new SampleDescriptionsBox(this); SampleDescriptionsBox.Read(reader); } else if (test.Type == BoxTypes.SampleToChunk) { this.SampleToChunkBox = new SampleToChunkBox(this); SampleToChunkBox.Read(reader); } else if (test.Type == BoxTypes.SampleSize) { this.SampleSizeBox = new SampleSizeBox(this); SampleSizeBox.Read(reader); } else if (test.Type == BoxTypes.ChunkOffset) { // FIXME: this can be a "co64" box this.ChunkOffSetBox = new ChunkOffSetBox(this); ChunkOffSetBox.Read(reader); } else if (test.Type == BoxTypes.SyncSampleMap) { this.SyncSampleMapBox = new SyncSampleMapBox(); SyncSampleMapBox.Read(reader); } else { reader.BaseStream.Position = (long)(test.Size + test.Offset); // skip unknown box Debug.WriteLine(string.Format("Unknown box type {0} in SampleTableBox (stbl), skipped", test.Type.ToString())); } } // end of while if (SampleToChunkBox != null) SampleToChunkBox.CheckIntegrityOfChunkData(); } }