public bool GetSampleStream(List <StreamDataBlockInfo> sampleStream, int inStartSampleIndex, int inEndSampleIndex, ref ulong lastEnd) { if (inStartSampleIndex >= (_startIndex + Length)) { return(false); // requested index is beyond this fragment } _currentFrame = _startIndex; _currentTime = (long)_startTime; foreach (StreamDataBlockInfo sliceData in _listOfSampleInfo) { if (sliceData.index >= inStartSampleIndex) { if ((sliceData.index > inEndSampleIndex) && (sliceData.SliceType != SliceType.DFrame) && (sliceData.SliceType != SliceType.BFrame)) { break; } _currentTime += (long)sliceData.SliceDuration; lastEnd = (ulong)_currentTime; StreamDataBlockInfo sliceCopy = new StreamDataBlockInfo(); sliceCopy.Copy(sliceData); sampleStream.Add(sliceCopy); } _currentFrame++; } return(true); }
// IEnumerable<Slice> accessor, assumes that this fragment has been read-in. // index starts at _startIndex (it is the index of the slice in the track, not index in this fragment) public override Slice this[int index] { get { if (index < _startIndex) { return(null); } if (_listOfSampleInfo == null) { return(null); } StreamDataBlockInfo sampleInfo = _listOfSampleInfo[index - _startIndex]; Slice slice = new Slice(); StreamDataBlockInfo sliceInfo = slice as StreamDataBlockInfo; sliceInfo.Copy(sampleInfo); _reader.BaseStream.Position = (long)sampleInfo.StreamOffset; slice.SliceBytes = _reader.ReadBytes(sampleInfo.SliceSize); // return the actual bits from MDAT slice.SliceSize = slice.SliceBytes.Length; return(slice); } set // this can work only with ODT fragments because each fragment is its own file { // if original frag has not been read-in yet, do nothing if (_listOfSampleInfo == null) { return; } FixupBoxesAndMDAT(index, value); } }
/// <summary> /// GetSampleStream /// Assemble the "sampleStream" which is the list of sample records that point to the sample bits in mdat, and also contain duration data, etc. /// Traverse the TrackFragmentRunBox in this fragment to collect the samples. /// The Iteration time span delimited by startTime and endTime may encompass several fragments, in which case this method /// will only put all samples in this one fragment. This method will not fetch the next fragment because that would mean another Fragment class instance. /// It is up to the caller whether to create another Fragment instance and collect samples from the next fragment. /// FIXME: Need to optimize this so that sampleStream is assembled from listOfSampleInfo, instead of reading boxes again. /// </summary> /// <param name="sampleStream">List of sample records to be assembled.</param> /// <param name="timeScale">Sampling rate (samples per second).</param> /// <param name="trackType">Which track does this fragment belong?</param> /// <param name="startTime">Start of Iteration time.</param> /// <param name="endTime">End of Iteration time.</param> /// <param name="lastEnd">Previous endTime.</param> /// <returns></returns> public bool GetSampleStream(List <StreamDataBlockInfo> sampleStream, uint timeScale, string trackType, ulong startTime, ulong endTime, ref ulong lastEnd) { if (startTime > (_startTime + Duration)) { return(false); // requested start time is ahead of this whole fragment } if (_timeScale != timeScale) { return(false); } _currentFrame = _startIndex; _currentTime = (long)_startTime; foreach (StreamDataBlockInfo sliceData in _listOfSampleInfo) { if (sliceData.TimeStampNew >= startTime) { if ((sliceData.TimeStampNew > endTime) && (sliceData.SliceType != SliceType.DFrame) && (sliceData.SliceType != SliceType.BFrame)) { break; } _currentTime += (long)sliceData.SliceDuration; lastEnd = (ulong)_currentTime; StreamDataBlockInfo sliceCopy = new StreamDataBlockInfo(); sliceCopy.Copy(sliceData); sampleStream.Add(sliceCopy); } _currentFrame++; } return(true); }
public bool GetSampleStream(List<StreamDataBlockInfo> sampleStream, int inStartSampleIndex, int inEndSampleIndex, ref ulong lastEnd) { if (inStartSampleIndex >= (_startIndex + Length)) return false; // requested index is beyond this fragment _currentFrame = _startIndex; _currentTime = (long)_startTime; foreach (StreamDataBlockInfo sliceData in _listOfSampleInfo) { if (sliceData.index >= inStartSampleIndex) { if ((sliceData.index > inEndSampleIndex) && (sliceData.SliceType != SliceType.DFrame) && (sliceData.SliceType != SliceType.BFrame)) { break; } _currentTime += (long)sliceData.SliceDuration; lastEnd = (ulong)_currentTime; StreamDataBlockInfo sliceCopy = new StreamDataBlockInfo(); sliceCopy.Copy(sliceData); sampleStream.Add(sliceCopy); } _currentFrame++; } return (true); }
/// <summary> /// GetSampleStream /// Assemble the "sampleStream" which is the list of sample records that point to the sample bits in mdat, and also contain duration data, etc. /// Traverse the TrackFragmentRunBox in this fragment to collect the samples. /// The Iteration time span delimited by startTime and endTime may encompass several fragments, in which case this method /// will only put all samples in this one fragment. This method will not fetch the next fragment because that would mean another Fragment class instance. /// It is up to the caller whether to create another Fragment instance and collect samples from the next fragment. /// FIXME: Need to optimize this so that sampleStream is assembled from listOfSampleInfo, instead of reading boxes again. /// </summary> /// <param name="sampleStream">List of sample records to be assembled.</param> /// <param name="timeScale">Sampling rate (samples per second).</param> /// <param name="trackType">Which track does this fragment belong?</param> /// <param name="startTime">Start of Iteration time.</param> /// <param name="endTime">End of Iteration time.</param> /// <param name="lastEnd">Previous endTime.</param> /// <returns></returns> public bool GetSampleStream(List<StreamDataBlockInfo> sampleStream, uint timeScale, string trackType, ulong startTime, ulong endTime, ref ulong lastEnd) { if (startTime > (_startTime + Duration)) return false; // requested start time is ahead of this whole fragment if (_timeScale != timeScale) return false; _currentFrame = _startIndex; _currentTime = (long)_startTime; foreach (StreamDataBlockInfo sliceData in _listOfSampleInfo) { if (sliceData.TimeStampNew >= startTime) { if ((sliceData.TimeStampNew > endTime) && (sliceData.SliceType != SliceType.DFrame) && (sliceData.SliceType != SliceType.BFrame)) { break; } _currentTime += (long)sliceData.SliceDuration; lastEnd = (ulong)_currentTime; StreamDataBlockInfo sliceCopy = new StreamDataBlockInfo(); sliceCopy.Copy(sliceData); sampleStream.Add(sliceCopy); } _currentFrame++; } return (true); }