Java 类com.google.android.exoplayer2.extractor.ChunkIndex 实例源码

项目:Exoplayer2Radio    文件:CachedRegionTracker.java   
public CachedRegionTracker(Cache cache, String cacheKey, ChunkIndex chunkIndex) {
  this.cache = cache;
  this.cacheKey = cacheKey;
  this.chunkIndex = chunkIndex;
  this.regions = new TreeSet<>();
  this.lookupRegion = new Region(0, 0);

  synchronized (this) {
    NavigableSet<CacheSpan> cacheSpans = cache.addListener(cacheKey, this);
    if (cacheSpans != null) {
      // Merge the spans into regions. mergeSpan is more efficient when merging from high to low,
      // which is why a descending iterator is used here.
      Iterator<CacheSpan> spanIterator = cacheSpans.descendingIterator();
      while (spanIterator.hasNext()) {
        CacheSpan span = spanIterator.next();
        mergeSpan(span);
      }
    }
  }
}
项目:K-Sonic    文件:DefaultDashChunkSource.java   
@Override
public void onChunkLoadCompleted(Chunk chunk) {
  if (chunk instanceof InitializationChunk) {
    InitializationChunk initializationChunk = (InitializationChunk) chunk;
    RepresentationHolder representationHolder =
        representationHolders[trackSelection.indexOf(initializationChunk.trackFormat)];
    // The null check avoids overwriting an index obtained from the manifest with one obtained
    // from the stream. If the manifest defines an index then the stream shouldn't, but in cases
    // where it does we should ignore it.
    if (representationHolder.segmentIndex == null) {
      SeekMap seekMap = representationHolder.extractorWrapper.getSeekMap();
      if (seekMap != null) {
        representationHolder.segmentIndex = new DashWrappingSegmentIndex((ChunkIndex) seekMap);
      }
    }
  }
}
项目:K-Sonic    文件:CachedRegionTracker.java   
public CachedRegionTracker(Cache cache, String cacheKey, ChunkIndex chunkIndex) {
  this.cache = cache;
  this.cacheKey = cacheKey;
  this.chunkIndex = chunkIndex;
  this.regions = new TreeSet<>();
  this.lookupRegion = new Region(0, 0);

  synchronized (this) {
    NavigableSet<CacheSpan> cacheSpans = cache.addListener(cacheKey, this);
    if (cacheSpans != null) {
      // Merge the spans into regions. mergeSpan is more efficient when merging from high to low,
      // which is why a descending iterator is used here.
      Iterator<CacheSpan> spanIterator = cacheSpans.descendingIterator();
      while (spanIterator.hasNext()) {
        CacheSpan span = spanIterator.next();
        mergeSpan(span);
      }
    }
  }
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
@Override
public void onChunkLoadCompleted(Chunk chunk) {
  if (chunk instanceof InitializationChunk) {
    InitializationChunk initializationChunk = (InitializationChunk) chunk;
    RepresentationHolder representationHolder =
        representationHolders[trackSelection.indexOf(initializationChunk.trackFormat)];
    Format sampleFormat = initializationChunk.getSampleFormat();
    if (sampleFormat != null) {
      representationHolder.setSampleFormat(sampleFormat);
    }
    // The null check avoids overwriting an index obtained from the manifest with one obtained
    // from the stream. If the manifest defines an index then the stream shouldn't, but in cases
    // where it does we should ignore it.
    if (representationHolder.segmentIndex == null) {
      SeekMap seekMap = initializationChunk.getSeekMap();
      if (seekMap != null) {
        representationHolder.segmentIndex = new DashWrappingSegmentIndex((ChunkIndex) seekMap,
            initializationChunk.dataSpec.uri.toString());
      }
    }
  }
}
项目:transistor    文件:DefaultDashChunkSource.java   
@Override
public void onChunkLoadCompleted(Chunk chunk) {
  if (chunk instanceof InitializationChunk) {
    InitializationChunk initializationChunk = (InitializationChunk) chunk;
    RepresentationHolder representationHolder =
        representationHolders[trackSelection.indexOf(initializationChunk.trackFormat)];
    // The null check avoids overwriting an index obtained from the manifest with one obtained
    // from the stream. If the manifest defines an index then the stream shouldn't, but in cases
    // where it does we should ignore it.
    if (representationHolder.segmentIndex == null) {
      SeekMap seekMap = representationHolder.extractorWrapper.getSeekMap();
      if (seekMap != null) {
        representationHolder.segmentIndex = new DashWrappingSegmentIndex((ChunkIndex) seekMap);
      }
    }
  }
}
项目:transistor    文件:CachedRegionTracker.java   
public CachedRegionTracker(Cache cache, String cacheKey, ChunkIndex chunkIndex) {
  this.cache = cache;
  this.cacheKey = cacheKey;
  this.chunkIndex = chunkIndex;
  this.regions = new TreeSet<>();
  this.lookupRegion = new Region(0, 0);

  synchronized (this) {
    NavigableSet<CacheSpan> cacheSpans = cache.addListener(cacheKey, this);
    if (cacheSpans != null) {
      // Merge the spans into regions. mergeSpan is more efficient when merging from high to low,
      // which is why a descending iterator is used here.
      Iterator<CacheSpan> spanIterator = cacheSpans.descendingIterator();
      while (spanIterator.hasNext()) {
        CacheSpan span = spanIterator.next();
        mergeSpan(span);
      }
    }
  }
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
  if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(leaf);
  } else if (leaf.type == Atom.TYPE_sidx) {
    Pair<Long, ChunkIndex> result = parseSidx(leaf.data, inputPosition);
    segmentIndexEarliestPresentationTimeUs = result.first;
    extractorOutput.seekMap(result.second);
    haveOutputSeekMap = true;
  } else if (leaf.type == Atom.TYPE_emsg) {
    onEmsgLeafAtomRead(leaf.data);
  }
}
项目:Exoplayer2Radio    文件:MatroskaExtractor.java   
/**
 * Builds a {@link SeekMap} from the recently gathered Cues information.
 *
 * @return The built {@link SeekMap}. The returned {@link SeekMap} may be unseekable if cues
 *     information was missing or incomplete.
 */
private SeekMap buildSeekMap() {
  if (segmentContentPosition == C.POSITION_UNSET || durationUs == C.TIME_UNSET
      || cueTimesUs == null || cueTimesUs.size() == 0
      || cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
    // Cues information is missing or incomplete.
    cueTimesUs = null;
    cueClusterPositions = null;
    return new SeekMap.Unseekable(durationUs);
  }
  int cuePointsSize = cueTimesUs.size();
  int[] sizes = new int[cuePointsSize];
  long[] offsets = new long[cuePointsSize];
  long[] durationsUs = new long[cuePointsSize];
  long[] timesUs = new long[cuePointsSize];
  for (int i = 0; i < cuePointsSize; i++) {
    timesUs[i] = cueTimesUs.get(i);
    offsets[i] = segmentContentPosition + cueClusterPositions.get(i);
  }
  for (int i = 0; i < cuePointsSize - 1; i++) {
    sizes[i] = (int) (offsets[i + 1] - offsets[i]);
    durationsUs[i] = timesUs[i + 1] - timesUs[i];
  }
  sizes[cuePointsSize - 1] =
      (int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
  durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
  cueTimesUs = null;
  cueClusterPositions = null;
  return new ChunkIndex(sizes, offsets, durationsUs, timesUs);
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
  if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(leaf);
  } else if (leaf.type == Atom.TYPE_sidx) {
    Pair<Long, ChunkIndex> result = parseSidx(leaf.data, inputPosition);
    segmentIndexEarliestPresentationTimeUs = result.first;
    extractorOutput.seekMap(result.second);
    haveOutputSeekMap = true;
  } else if (leaf.type == Atom.TYPE_emsg) {
    onEmsgLeafAtomRead(leaf.data);
  }
}
项目:K-Sonic    文件:MatroskaExtractor.java   
/**
 * Builds a {@link SeekMap} from the recently gathered Cues information.
 *
 * @return The built {@link SeekMap}. The returned {@link SeekMap} may be unseekable if cues
 *     information was missing or incomplete.
 */
private SeekMap buildSeekMap() {
  if (segmentContentPosition == C.POSITION_UNSET || durationUs == C.TIME_UNSET
      || cueTimesUs == null || cueTimesUs.size() == 0
      || cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
    // Cues information is missing or incomplete.
    cueTimesUs = null;
    cueClusterPositions = null;
    return new SeekMap.Unseekable(durationUs);
  }
  int cuePointsSize = cueTimesUs.size();
  int[] sizes = new int[cuePointsSize];
  long[] offsets = new long[cuePointsSize];
  long[] durationsUs = new long[cuePointsSize];
  long[] timesUs = new long[cuePointsSize];
  for (int i = 0; i < cuePointsSize; i++) {
    timesUs[i] = cueTimesUs.get(i);
    offsets[i] = segmentContentPosition + cueClusterPositions.get(i);
  }
  for (int i = 0; i < cuePointsSize - 1; i++) {
    sizes[i] = (int) (offsets[i + 1] - offsets[i]);
    durationsUs[i] = timesUs[i + 1] - timesUs[i];
  }
  sizes[cuePointsSize - 1] =
      (int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
  durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
  cueTimesUs = null;
  cueClusterPositions = null;
  return new ChunkIndex(sizes, offsets, durationsUs, timesUs);
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
  if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(leaf);
  } else if (leaf.type == Atom.TYPE_sidx) {
    ChunkIndex segmentIndex = parseSidx(leaf.data, inputPosition);
    extractorOutput.seekMap(segmentIndex);
    haveOutputSeekMap = true;
  }
}
项目:videoPickPlayer    文件:MatroskaExtractor.java   
/**
 * Builds a {@link SeekMap} from the recently gathered Cues information.
 *
 * @return The built {@link SeekMap}. The returned {@link SeekMap} may be unseekable if cues
 *     information was missing or incomplete.
 */
private SeekMap buildSeekMap() {
  if (segmentContentPosition == C.POSITION_UNSET || durationUs == C.TIME_UNSET
      || cueTimesUs == null || cueTimesUs.size() == 0
      || cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
    // Cues information is missing or incomplete.
    cueTimesUs = null;
    cueClusterPositions = null;
    return new SeekMap.Unseekable(durationUs);
  }
  int cuePointsSize = cueTimesUs.size();
  int[] sizes = new int[cuePointsSize];
  long[] offsets = new long[cuePointsSize];
  long[] durationsUs = new long[cuePointsSize];
  long[] timesUs = new long[cuePointsSize];
  for (int i = 0; i < cuePointsSize; i++) {
    timesUs[i] = cueTimesUs.get(i);
    offsets[i] = segmentContentPosition + cueClusterPositions.get(i);
  }
  for (int i = 0; i < cuePointsSize - 1; i++) {
    sizes[i] = (int) (offsets[i + 1] - offsets[i]);
    durationsUs[i] = timesUs[i + 1] - timesUs[i];
  }
  sizes[cuePointsSize - 1] =
      (int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
  durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
  cueTimesUs = null;
  cueClusterPositions = null;
  return new ChunkIndex(sizes, offsets, durationsUs, timesUs);
}
项目:transistor    文件:DashDownloader.java   
/**
 * Returns DashSegmentIndex for given representation.
 */
private DashSegmentIndex getSegmentIndex(DataSource dataSource, DashManifest manifest,
    RepresentationKey key) throws IOException, InterruptedException {
  AdaptationSet adaptationSet = manifest.getPeriod(key.periodIndex).adaptationSets.get(
      key.adaptationSetIndex);
  Representation representation = adaptationSet.representations.get(key.representationIndex);
  DashSegmentIndex index = representation.getIndex();
  if (index != null) {
    return index;
  }
  ChunkIndex seekMap = DashUtil.loadChunkIndex(dataSource, adaptationSet.type, representation);
  return seekMap == null ? null : new DashWrappingSegmentIndex(seekMap);
}
项目:transistor    文件:FragmentedMp4Extractor.java   
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
  if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(leaf);
  } else if (leaf.type == Atom.TYPE_sidx) {
    Pair<Long, ChunkIndex> result = parseSidx(leaf.data, inputPosition);
    segmentIndexEarliestPresentationTimeUs = result.first;
    extractorOutput.seekMap(result.second);
    haveOutputSeekMap = true;
  } else if (leaf.type == Atom.TYPE_emsg) {
    onEmsgLeafAtomRead(leaf.data);
  }
}
项目:transistor    文件:MatroskaExtractor.java   
/**
 * Builds a {@link SeekMap} from the recently gathered Cues information.
 *
 * @return The built {@link SeekMap}. The returned {@link SeekMap} may be unseekable if cues
 *     information was missing or incomplete.
 */
private SeekMap buildSeekMap() {
  if (segmentContentPosition == C.POSITION_UNSET || durationUs == C.TIME_UNSET
      || cueTimesUs == null || cueTimesUs.size() == 0
      || cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
    // Cues information is missing or incomplete.
    cueTimesUs = null;
    cueClusterPositions = null;
    return new SeekMap.Unseekable(durationUs);
  }
  int cuePointsSize = cueTimesUs.size();
  int[] sizes = new int[cuePointsSize];
  long[] offsets = new long[cuePointsSize];
  long[] durationsUs = new long[cuePointsSize];
  long[] timesUs = new long[cuePointsSize];
  for (int i = 0; i < cuePointsSize; i++) {
    timesUs[i] = cueTimesUs.get(i);
    offsets[i] = segmentContentPosition + cueClusterPositions.get(i);
  }
  for (int i = 0; i < cuePointsSize - 1; i++) {
    sizes[i] = (int) (offsets[i + 1] - offsets[i]);
    durationsUs[i] = timesUs[i + 1] - timesUs[i];
  }
  sizes[cuePointsSize - 1] =
      (int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
  durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
  cueTimesUs = null;
  cueClusterPositions = null;
  return new ChunkIndex(sizes, offsets, durationsUs, timesUs);
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
/**
 * Parses a sidx atom (defined in 14496-12).
 *
 * @param atom The atom data.
 * @param inputPosition The input position of the first byte after the atom.
 * @return A pair consisting of the earliest presentation time in microseconds, and the parsed
 *     {@link ChunkIndex}.
 */
private static Pair<Long, ChunkIndex> parseSidx(ParsableByteArray atom, long inputPosition)
    throws ParserException {
  atom.setPosition(Atom.HEADER_SIZE);
  int fullAtom = atom.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  atom.skipBytes(4);
  long timescale = atom.readUnsignedInt();
  long earliestPresentationTime;
  long offset = inputPosition;
  if (version == 0) {
    earliestPresentationTime = atom.readUnsignedInt();
    offset += atom.readUnsignedInt();
  } else {
    earliestPresentationTime = atom.readUnsignedLongToLong();
    offset += atom.readUnsignedLongToLong();
  }
  long earliestPresentationTimeUs = Util.scaleLargeTimestamp(earliestPresentationTime,
      C.MICROS_PER_SECOND, timescale);

  atom.skipBytes(2);

  int referenceCount = atom.readUnsignedShort();
  int[] sizes = new int[referenceCount];
  long[] offsets = new long[referenceCount];
  long[] durationsUs = new long[referenceCount];
  long[] timesUs = new long[referenceCount];

  long time = earliestPresentationTime;
  long timeUs = earliestPresentationTimeUs;
  for (int i = 0; i < referenceCount; i++) {
    int firstInt = atom.readInt();

    int type = 0x80000000 & firstInt;
    if (type != 0) {
      throw new ParserException("Unhandled indirect reference");
    }
    long referenceDuration = atom.readUnsignedInt();

    sizes[i] = 0x7FFFFFFF & firstInt;
    offsets[i] = offset;

    // Calculate time and duration values such that any rounding errors are consistent. i.e. That
    // timesUs[i] + durationsUs[i] == timesUs[i + 1].
    timesUs[i] = timeUs;
    time += referenceDuration;
    timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
    durationsUs[i] = timeUs - timesUs[i];

    atom.skipBytes(4);
    offset += sizes[i];
  }

  return Pair.create(earliestPresentationTimeUs,
      new ChunkIndex(sizes, offsets, durationsUs, timesUs));
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
/**
 * Parses a sidx atom (defined in 14496-12).
 *
 * @param atom The atom data.
 * @param inputPosition The input position of the first byte after the atom.
 * @return A pair consisting of the earliest presentation time in microseconds, and the parsed
 *     {@link ChunkIndex}.
 */
private static Pair<Long, ChunkIndex> parseSidx(ParsableByteArray atom, long inputPosition)
    throws ParserException {
  atom.setPosition(Atom.HEADER_SIZE);
  int fullAtom = atom.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  atom.skipBytes(4);
  long timescale = atom.readUnsignedInt();
  long earliestPresentationTime;
  long offset = inputPosition;
  if (version == 0) {
    earliestPresentationTime = atom.readUnsignedInt();
    offset += atom.readUnsignedInt();
  } else {
    earliestPresentationTime = atom.readUnsignedLongToLong();
    offset += atom.readUnsignedLongToLong();
  }
  long earliestPresentationTimeUs = Util.scaleLargeTimestamp(earliestPresentationTime,
      C.MICROS_PER_SECOND, timescale);

  atom.skipBytes(2);

  int referenceCount = atom.readUnsignedShort();
  int[] sizes = new int[referenceCount];
  long[] offsets = new long[referenceCount];
  long[] durationsUs = new long[referenceCount];
  long[] timesUs = new long[referenceCount];

  long time = earliestPresentationTime;
  long timeUs = earliestPresentationTimeUs;
  for (int i = 0; i < referenceCount; i++) {
    int firstInt = atom.readInt();

    int type = 0x80000000 & firstInt;
    if (type != 0) {
      throw new ParserException("Unhandled indirect reference");
    }
    long referenceDuration = atom.readUnsignedInt();

    sizes[i] = 0x7FFFFFFF & firstInt;
    offsets[i] = offset;

    // Calculate time and duration values such that any rounding errors are consistent. i.e. That
    // timesUs[i] + durationsUs[i] == timesUs[i + 1].
    timesUs[i] = timeUs;
    time += referenceDuration;
    timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
    durationsUs[i] = timeUs - timesUs[i];

    atom.skipBytes(4);
    offset += sizes[i];
  }

  return Pair.create(earliestPresentationTimeUs,
      new ChunkIndex(sizes, offsets, durationsUs, timesUs));
}
项目:K-Sonic    文件:DashWrappingSegmentIndex.java   
/**
 * @param chunkIndex The {@link ChunkIndex} to wrap.
 */
public DashWrappingSegmentIndex(ChunkIndex chunkIndex) {
  this.chunkIndex = chunkIndex;
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
/**
 * Parses a sidx atom (defined in 14496-12).
 */
private static ChunkIndex parseSidx(ParsableByteArray atom, long inputPosition)
    throws ParserException {
  atom.setPosition(Atom.HEADER_SIZE);
  int fullAtom = atom.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  atom.skipBytes(4);
  long timescale = atom.readUnsignedInt();
  long earliestPresentationTime;
  long offset = inputPosition;
  if (version == 0) {
    earliestPresentationTime = atom.readUnsignedInt();
    offset += atom.readUnsignedInt();
  } else {
    earliestPresentationTime = atom.readUnsignedLongToLong();
    offset += atom.readUnsignedLongToLong();
  }

  atom.skipBytes(2);

  int referenceCount = atom.readUnsignedShort();
  int[] sizes = new int[referenceCount];
  long[] offsets = new long[referenceCount];
  long[] durationsUs = new long[referenceCount];
  long[] timesUs = new long[referenceCount];

  long time = earliestPresentationTime;
  long timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
  for (int i = 0; i < referenceCount; i++) {
    int firstInt = atom.readInt();

    int type = 0x80000000 & firstInt;
    if (type != 0) {
      throw new ParserException("Unhandled indirect reference");
    }
    long referenceDuration = atom.readUnsignedInt();

    sizes[i] = 0x7FFFFFFF & firstInt;
    offsets[i] = offset;

    // Calculate time and duration values such that any rounding errors are consistent. i.e. That
    // timesUs[i] + durationsUs[i] == timesUs[i + 1].
    timesUs[i] = timeUs;
    time += referenceDuration;
    timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
    durationsUs[i] = timeUs - timesUs[i];

    atom.skipBytes(4);
    offset += sizes[i];
  }

  return new ChunkIndex(sizes, offsets, durationsUs, timesUs);
}
项目:videoPickPlayer    文件:DashWrappingSegmentIndex.java   
/**
 * @param chunkIndex The {@link ChunkIndex} to wrap.
 * @param uri The URI where the data is located.
 */
public DashWrappingSegmentIndex(ChunkIndex chunkIndex, String uri) {
  this.chunkIndex = chunkIndex;
  this.uri = uri;
}
项目:transistor    文件:DashWrappingSegmentIndex.java   
/**
 * @param chunkIndex The {@link ChunkIndex} to wrap.
 */
public DashWrappingSegmentIndex(ChunkIndex chunkIndex) {
  this.chunkIndex = chunkIndex;
}
项目:transistor    文件:FragmentedMp4Extractor.java   
/**
 * Parses a sidx atom (defined in 14496-12).
 *
 * @param atom The atom data.
 * @param inputPosition The input position of the first byte after the atom.
 * @return A pair consisting of the earliest presentation time in microseconds, and the parsed
 *     {@link ChunkIndex}.
 */
private static Pair<Long, ChunkIndex> parseSidx(ParsableByteArray atom, long inputPosition)
    throws ParserException {
  atom.setPosition(Atom.HEADER_SIZE);
  int fullAtom = atom.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  atom.skipBytes(4);
  long timescale = atom.readUnsignedInt();
  long earliestPresentationTime;
  long offset = inputPosition;
  if (version == 0) {
    earliestPresentationTime = atom.readUnsignedInt();
    offset += atom.readUnsignedInt();
  } else {
    earliestPresentationTime = atom.readUnsignedLongToLong();
    offset += atom.readUnsignedLongToLong();
  }
  long earliestPresentationTimeUs = Util.scaleLargeTimestamp(earliestPresentationTime,
      C.MICROS_PER_SECOND, timescale);

  atom.skipBytes(2);

  int referenceCount = atom.readUnsignedShort();
  int[] sizes = new int[referenceCount];
  long[] offsets = new long[referenceCount];
  long[] durationsUs = new long[referenceCount];
  long[] timesUs = new long[referenceCount];

  long time = earliestPresentationTime;
  long timeUs = earliestPresentationTimeUs;
  for (int i = 0; i < referenceCount; i++) {
    int firstInt = atom.readInt();

    int type = 0x80000000 & firstInt;
    if (type != 0) {
      throw new ParserException("Unhandled indirect reference");
    }
    long referenceDuration = atom.readUnsignedInt();

    sizes[i] = 0x7FFFFFFF & firstInt;
    offsets[i] = offset;

    // Calculate time and duration values such that any rounding errors are consistent. i.e. That
    // timesUs[i] + durationsUs[i] == timesUs[i + 1].
    timesUs[i] = timeUs;
    time += referenceDuration;
    timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
    durationsUs[i] = timeUs - timesUs[i];

    atom.skipBytes(4);
    offset += sizes[i];
  }

  return Pair.create(earliestPresentationTimeUs,
      new ChunkIndex(sizes, offsets, durationsUs, timesUs));
}
项目:K-Sonic    文件:DashUtil.java   
/**
 * Loads initialization and index data for the {@code representation} and returns the {@link
 * ChunkIndex}.
 *
 * @param dataSource The source from which the data should be loaded.
 * @param representation The representation which initialization chunk belongs to.
 * @return {@link ChunkIndex} of the given representation.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
public static ChunkIndex loadChunkIndex(DataSource dataSource, Representation representation)
    throws IOException, InterruptedException {
  ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, representation,
      true);
  return extractorWrapper == null ? null : (ChunkIndex) extractorWrapper.getSeekMap();
}
项目:transistor    文件:DashUtil.java   
/**
 * Loads initialization and index data for the {@code representation} and returns the {@link
 * ChunkIndex}.
 *
 * @param dataSource The source from which the data should be loaded.
 * @param trackType The type of the representation. Typically one of the
 *     {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
 * @param representation The representation which initialization chunk belongs to.
 * @return The {@link ChunkIndex} of the given representation, or null if no initialization or
 *     index data exists.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
public static ChunkIndex loadChunkIndex(DataSource dataSource, int trackType,
    Representation representation) throws IOException, InterruptedException {
  ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
      representation, true);
  return extractorWrapper == null ? null : (ChunkIndex) extractorWrapper.getSeekMap();
}