using System.Collections.Generic; namespace hdsdump.f4f { public class AdobeSegmentRunTable: FullBox { public List<string> qualitySegmentURLModifiers = new List<string>(); public List<SegmentFragmentPair> segmentFragmentPairs = new List<SegmentFragmentPair>(); public override void Parse(BoxInfo bi, HDSBinaryReader br) { base.Parse(bi, br); qualitySegmentURLModifiers.Clear(); uint qualityEntryCount = br.ReadByte(); for (uint i = 0; i < qualityEntryCount; i++) { qualitySegmentURLModifiers.Add(br.ReadString()); } uint entryCount = br.ReadUInt32(); for (uint i = 0; i < entryCount; i++) { addSegmentFragmentPair(new SegmentFragmentPair(br.ReadUInt32(), br.ReadUInt32())); } } /// <summary> /// Adds the given SegmentFragmentPair to this run table. /// </summary> private void addSegmentFragmentPair(SegmentFragmentPair sfp) { SegmentFragmentPair prevSfp = segmentFragmentPairs.Count <= 0 ? null : segmentFragmentPairs[segmentFragmentPairs.Count - 1]; uint fragmentsAccrued = 0; if (prevSfp != null) { fragmentsAccrued = prevSfp.fragmentsAccrued + (sfp.firstSegment - prevSfp.firstSegment) * prevSfp.fragmentsPerSegment; } sfp.fragmentsAccrued = fragmentsAccrued; segmentFragmentPairs.Add(sfp); } public uint findSegmentIdByFragmentId(uint fragmentId) { SegmentFragmentPair curSfp; if (fragmentId < 1) { // fragmentId should never be smaller than 1, same for segmentId. So // return 0 to signal an error condition. return 0; } for (int i = 1; i < segmentFragmentPairs.Count; i++) { curSfp = segmentFragmentPairs[i]; if (curSfp.fragmentsAccrued >= fragmentId) { return calculateSegmentId(segmentFragmentPairs[i - 1], fragmentId); } } return calculateSegmentId(segmentFragmentPairs[segmentFragmentPairs.Count - 1], fragmentId); } public uint totalFragments() { if (segmentFragmentPairs.Count < 1) return 0; SegmentFragmentPair sfp = segmentFragmentPairs[segmentFragmentPairs.Count - 1]; return sfp.fragmentsPerSegment + sfp.fragmentsAccrued; } private uint calculateSegmentId(SegmentFragmentPair sfp, uint fragmentId) { return sfp.firstSegment + ((fragmentId - sfp.fragmentsAccrued - 1) / sfp.fragmentsPerSegment); } } }