Java 类com.google.android.exoplayer2.source.dash.manifest.Representation 实例源码

项目:K-Sonic    文件:DefaultDashChunkSource.java   
/**
 * @param manifestLoaderErrorThrower Throws errors affecting loading of manifests.
 * @param manifest The initial manifest.
 * @param periodIndex The index of the period in the manifest.
 * @param adaptationSetIndex The index of the adaptation set in the period.
 * @param trackSelection The track selection.
 * @param dataSource A {@link DataSource} suitable for loading the media data.
 * @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between
 *     server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified
 *     as the server's unix time minus the local elapsed time. If unknown, set to 0.
 * @param maxSegmentsPerLoad The maximum number of segments to combine into a single request.
 *     Note that segments will only be combined if their {@link Uri}s are the same and if their
 *     data ranges are adjacent.
 * @param enableEventMessageTrack Whether the chunks generated by the source may output an event
 *     message track.
 * @param enableEventMessageTrack Whether the chunks generated by the source may output a CEA-608
 *     track.
 */
public DefaultDashChunkSource(LoaderErrorThrower manifestLoaderErrorThrower,
    DashManifest manifest, int periodIndex, int adaptationSetIndex, TrackSelection trackSelection,
    DataSource dataSource, long elapsedRealtimeOffsetMs, int maxSegmentsPerLoad,
    boolean enableEventMessageTrack, boolean enableCea608Track) {
  this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
  this.manifest = manifest;
  this.adaptationSetIndex = adaptationSetIndex;
  this.trackSelection = trackSelection;
  this.dataSource = dataSource;
  this.periodIndex = periodIndex;
  this.elapsedRealtimeOffsetMs = elapsedRealtimeOffsetMs;
  this.maxSegmentsPerLoad = maxSegmentsPerLoad;

  long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
  AdaptationSet adaptationSet = getAdaptationSet();
  List<Representation> representations = adaptationSet.representations;
  representationHolders = new RepresentationHolder[trackSelection.length()];
  for (int i = 0; i < representationHolders.length; i++) {
    Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
    representationHolders[i] = new RepresentationHolder(periodDurationUs, representation,
        enableEventMessageTrack, enableCea608Track, adaptationSet.type);
  }
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
/**
 * @param manifestLoaderErrorThrower Throws errors affecting loading of manifests.
 * @param manifest The initial manifest.
 * @param periodIndex The index of the period in the manifest.
 * @param adaptationSetIndex The index of the adaptation set in the period.
 * @param trackSelection The track selection.
 * @param dataSource A {@link DataSource} suitable for loading the media data.
 * @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between
 *     server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified
 *     as the server's unix time minus the local elapsed time. If unknown, set to 0.
 */
public DefaultDashChunkSource(LoaderErrorThrower manifestLoaderErrorThrower,
    DashManifest manifest, int periodIndex, int adaptationSetIndex, TrackSelection trackSelection,
    DataSource dataSource, long elapsedRealtimeOffsetMs) {
  this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
  this.manifest = manifest;
  this.adaptationSetIndex = adaptationSetIndex;
  this.trackSelection = trackSelection;
  this.dataSource = dataSource;
  this.periodIndex = periodIndex;
  this.elapsedRealtimeOffsetMs = elapsedRealtimeOffsetMs;

  long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
  List<Representation> representations = getRepresentations();
  representationHolders = new RepresentationHolder[trackSelection.length()];
  for (int i = 0; i < representationHolders.length; i++) {
    Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
    representationHolders[i] = new RepresentationHolder(periodDurationUs, representation);
  }
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
private Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource,
    Format trackFormat, int trackSelectionReason,
    Object trackSelectionData, Format sampleFormat, int segmentNum) {
  Representation representation = representationHolder.representation;
  long startTimeUs = representationHolder.getSegmentStartTimeUs(segmentNum);
  long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum);
  RangedUri segmentUri = representationHolder.getSegmentUrl(segmentNum);
  DataSpec dataSpec = new DataSpec(segmentUri.getUri(), segmentUri.start, segmentUri.length,
      representation.getCacheKey());

  if (representationHolder.extractorWrapper == null) {
    return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason,
        trackSelectionData, startTimeUs, endTimeUs, segmentNum, trackFormat);
  } else {
    long sampleOffsetUs = -representation.presentationTimeOffsetUs;
    return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason,
        trackSelectionData, startTimeUs, endTimeUs, segmentNum, sampleOffsetUs,
        representationHolder.extractorWrapper, sampleFormat);
  }
}
项目:transistor    文件:DefaultDashChunkSource.java   
/**
 * @param manifestLoaderErrorThrower Throws errors affecting loading of manifests.
 * @param manifest The initial manifest.
 * @param periodIndex The index of the period in the manifest.
 * @param adaptationSetIndices The indices of the adaptation sets in the period.
 * @param trackSelection The track selection.
 * @param trackType The type of the tracks in the selection.
 * @param dataSource A {@link DataSource} suitable for loading the media data.
 * @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between
 *     server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified
 *     as the server's unix time minus the local elapsed time. If unknown, set to 0.
 * @param maxSegmentsPerLoad The maximum number of segments to combine into a single request.
 *     Note that segments will only be combined if their {@link Uri}s are the same and if their
 *     data ranges are adjacent.
 * @param enableEventMessageTrack Whether the chunks generated by the source may output an event
 *     message track.
 * @param enableCea608Track Whether the chunks generated by the source may output a CEA-608 track.
 */
public DefaultDashChunkSource(LoaderErrorThrower manifestLoaderErrorThrower,
    DashManifest manifest, int periodIndex, int[] adaptationSetIndices,
    TrackSelection trackSelection, int trackType, DataSource dataSource,
    long elapsedRealtimeOffsetMs, int maxSegmentsPerLoad, boolean enableEventMessageTrack,
    boolean enableCea608Track) {
  this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
  this.manifest = manifest;
  this.adaptationSetIndices = adaptationSetIndices;
  this.trackSelection = trackSelection;
  this.trackType = trackType;
  this.dataSource = dataSource;
  this.periodIndex = periodIndex;
  this.elapsedRealtimeOffsetMs = elapsedRealtimeOffsetMs;
  this.maxSegmentsPerLoad = maxSegmentsPerLoad;

  long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
  liveEdgeTimeUs = C.TIME_UNSET;
  List<Representation> representations = getRepresentations();
  representationHolders = new RepresentationHolder[trackSelection.length()];
  for (int i = 0; i < representationHolders.length; i++) {
    Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
    representationHolders[i] = new RepresentationHolder(periodDurationUs, trackType,
        representation, enableEventMessageTrack, enableCea608Track);
  }
}
项目:transistor    文件:DashUtil.java   
/**
 * Loads {@link DrmInitData} for a given period in a DASH manifest.
 *
 * @param dataSource The {@link HttpDataSource} from which data should be loaded.
 * @param period The {@link Period}.
 * @return The loaded {@link DrmInitData}, or null if none is defined.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
    throws IOException, InterruptedException {
  int primaryTrackType = C.TRACK_TYPE_VIDEO;
  Representation representation = getFirstRepresentation(period, primaryTrackType);
  if (representation == null) {
    primaryTrackType = C.TRACK_TYPE_AUDIO;
    representation = getFirstRepresentation(period, primaryTrackType);
    if (representation == null) {
      return null;
    }
  }
  DrmInitData drmInitData = representation.format.drmInitData;
  if (drmInitData != null) {
    // Prefer drmInitData obtained from the manifest over drmInitData obtained from the stream,
    // as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
    return drmInitData;
  }
  Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
  return sampleFormat == null ? null : sampleFormat.drmInitData;
}
项目:K-Sonic    文件:OfflineLicenseHelper.java   
/**
 * Downloads an offline license.
 *
 * @param dataSource The {@link HttpDataSource} to be used for download.
 * @param dashManifest The {@link DashManifest} of the DASH content.
 * @return The downloaded offline license key set id.
 * @throws IOException If an error occurs reading data from the stream.
 * @throws InterruptedException If the thread has been interrupted.
 * @throws DrmSessionException Thrown when there is an error during DRM session.
 */
public byte[] download(HttpDataSource dataSource, DashManifest dashManifest)
    throws IOException, InterruptedException, DrmSessionException {
  // Get DrmInitData
  // Prefer drmInitData obtained from the manifest over drmInitData obtained from the stream,
  // as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
  if (dashManifest.getPeriodCount() < 1) {
    return null;
  }
  Period period = dashManifest.getPeriod(0);
  int adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
  if (adaptationSetIndex == C.INDEX_UNSET) {
    adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_AUDIO);
    if (adaptationSetIndex == C.INDEX_UNSET) {
      return null;
    }
  }
  AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
  if (adaptationSet.representations.isEmpty()) {
    return null;
  }
  Representation representation = adaptationSet.representations.get(0);
  DrmInitData drmInitData = representation.format.drmInitData;
  if (drmInitData == null) {
    Format sampleFormat = DashUtil.loadSampleFormat(dataSource, representation);
    if (sampleFormat != null) {
      drmInitData = sampleFormat.drmInitData;
    }
    if (drmInitData == null) {
      return null;
    }
  }
  blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData);
  return drmSessionManager.getOfflineLicenseKeySetId();
}
项目:K-Sonic    文件:DefaultDashChunkSource.java   
@Override
public void updateManifest(DashManifest newManifest, int newPeriodIndex) {
  try {
    manifest = newManifest;
    periodIndex = newPeriodIndex;
    long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
    List<Representation> representations = getAdaptationSet().representations;
    for (int i = 0; i < representationHolders.length; i++) {
      Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
      representationHolders[i].updateRepresentation(periodDurationUs, representation);
    }
  } catch (BehindLiveWindowException e) {
    fatalError = e;
  }
}
项目:K-Sonic    文件:DashUtil.java   
/**
 * Loads initialization data for the {@code representation} and optionally index data then
 * returns a {@link ChunkExtractorWrapper} which contains the output.
 *
 * @param dataSource The source from which the data should be loaded.
 * @param representation The representation which initialization chunk belongs to.
 * @param loadIndex Whether to load index data too.
 * @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no
 *     initialization or (if requested) index data exists.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource,
    Representation representation, boolean loadIndex)
    throws IOException, InterruptedException {
  RangedUri initializationUri = representation.getInitializationUri();
  if (initializationUri == null) {
    return null;
  }
  ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(representation.format);
  RangedUri requestUri;
  if (loadIndex) {
    RangedUri indexUri = representation.getIndexUri();
    if (indexUri == null) {
      return null;
    }
    // It's common for initialization and index data to be stored adjacently. Attempt to merge
    // the two requests together to request both at once.
    requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrl);
    if (requestUri == null) {
      loadInitializationData(dataSource, representation, extractorWrapper, initializationUri);
      requestUri = indexUri;
    }
  } else {
    requestUri = initializationUri;
  }
  loadInitializationData(dataSource, representation, extractorWrapper, requestUri);
  return extractorWrapper;
}
项目:K-Sonic    文件:DashUtil.java   
private static void loadInitializationData(DataSource dataSource,
    Representation representation, ChunkExtractorWrapper extractorWrapper, RangedUri requestUri)
    throws IOException, InterruptedException {
  DataSpec dataSpec = new DataSpec(requestUri.resolveUri(representation.baseUrl),
      requestUri.start, requestUri.length, representation.getCacheKey());
  InitializationChunk initializationChunk = new InitializationChunk(dataSource, dataSpec,
      representation.format, C.SELECTION_REASON_UNKNOWN, null /* trackSelectionData */,
      extractorWrapper);
  initializationChunk.load();
}
项目:K-Sonic    文件:DashMediaPeriod.java   
private static boolean hasEventMessageTrack(AdaptationSet adaptationSet) {
  List<Representation> representations = adaptationSet.representations;
  for (int i = 0; i < representations.size(); i++) {
    Representation representation = representations.get(i);
    if (!representation.inbandEventStreams.isEmpty()) {
      return true;
    }
  }
  return false;
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
@Override
public void updateManifest(DashManifest newManifest, int newPeriodIndex) {
  try {
    manifest = newManifest;
    periodIndex = newPeriodIndex;
    long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
    List<Representation> representations = getRepresentations();
    for (int i = 0; i < representationHolders.length; i++) {
      Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
      representationHolders[i].updateRepresentation(periodDurationUs, representation);
    }
  } catch (BehindLiveWindowException e) {
    fatalError = e;
  }
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
public void updateRepresentation(long newPeriodDurationUs, Representation newRepresentation)
    throws BehindLiveWindowException{
  DashSegmentIndex oldIndex = representation.getIndex();
  DashSegmentIndex newIndex = newRepresentation.getIndex();

  periodDurationUs = newPeriodDurationUs;
  representation = newRepresentation;
  if (oldIndex == null) {
    // Segment numbers cannot shift if the index isn't defined by the manifest.
    return;
  }

  segmentIndex = newIndex;
  if (!oldIndex.isExplicit()) {
    // Segment numbers cannot shift if the index isn't explicit.
    return;
  }

  int oldIndexLastSegmentNum = oldIndex.getLastSegmentNum(periodDurationUs);
  long oldIndexEndTimeUs = oldIndex.getTimeUs(oldIndexLastSegmentNum)
      + oldIndex.getDurationUs(oldIndexLastSegmentNum, periodDurationUs);
  int newIndexFirstSegmentNum = newIndex.getFirstSegmentNum();
  long newIndexStartTimeUs = newIndex.getTimeUs(newIndexFirstSegmentNum);
  if (oldIndexEndTimeUs == newIndexStartTimeUs) {
    // The new index continues where the old one ended, with no overlap.
    segmentNumShift += oldIndex.getLastSegmentNum(periodDurationUs) + 1
        - newIndexFirstSegmentNum;
  } else if (oldIndexEndTimeUs < newIndexStartTimeUs) {
    // There's a gap between the old index and the new one which means we've slipped behind the
    // live window and can't proceed.
    throw new BehindLiveWindowException();
  } else {
    // The new index overlaps with the old one.
    segmentNumShift += oldIndex.getSegmentNum(newIndexStartTimeUs, periodDurationUs)
        - newIndexFirstSegmentNum;
  }
}
项目:videoPickPlayer    文件:DashMediaPeriod.java   
private static TrackGroupArray buildTrackGroups(Period period) {
  TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()];
  for (int i = 0; i < period.adaptationSets.size(); i++) {
    AdaptationSet adaptationSet = period.adaptationSets.get(i);
    List<Representation> representations = adaptationSet.representations;
    Format[] formats = new Format[representations.size()];
    for (int j = 0; j < formats.length; j++) {
      formats[j] = representations.get(j).format;
    }
    trackGroupArray[i] = new TrackGroup(formats);
  }
  return new TrackGroupArray(trackGroupArray);
}
项目:transistor    文件:DefaultDashChunkSource.java   
@Override
public void updateManifest(DashManifest newManifest, int newPeriodIndex) {
  try {
    manifest = newManifest;
    periodIndex = newPeriodIndex;
    long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
    List<Representation> representations = getRepresentations();
    for (int i = 0; i < representationHolders.length; i++) {
      Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
      representationHolders[i].updateRepresentation(periodDurationUs, representation);
    }
  } catch (BehindLiveWindowException e) {
    fatalError = e;
  }
}
项目:transistor    文件:DefaultDashChunkSource.java   
private ArrayList<Representation> getRepresentations() {
  List<AdaptationSet> manifestAdapationSets = manifest.getPeriod(periodIndex).adaptationSets;
  ArrayList<Representation> representations = new ArrayList<>();
  for (int adaptationSetIndex : adaptationSetIndices) {
    representations.addAll(manifestAdapationSets.get(adaptationSetIndex).representations);
  }
  return representations;
}
项目:transistor    文件:DashUtil.java   
/**
 * Loads initialization data for the {@code representation} and optionally index data then
 * returns a {@link ChunkExtractorWrapper} which contains the output.
 *
 * @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.
 * @param loadIndex Whether to load index data too.
 * @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no
 *     initialization or (if requested) index data exists.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource, int trackType,
    Representation representation, boolean loadIndex) throws IOException, InterruptedException {
  RangedUri initializationUri = representation.getInitializationUri();
  if (initializationUri == null) {
    return null;
  }
  ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(trackType, representation.format);
  RangedUri requestUri;
  if (loadIndex) {
    RangedUri indexUri = representation.getIndexUri();
    if (indexUri == null) {
      return null;
    }
    // It's common for initialization and index data to be stored adjacently. Attempt to merge
    // the two requests together to request both at once.
    requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrl);
    if (requestUri == null) {
      loadInitializationData(dataSource, representation, extractorWrapper, initializationUri);
      requestUri = indexUri;
    }
  } else {
    requestUri = initializationUri;
  }
  loadInitializationData(dataSource, representation, extractorWrapper, requestUri);
  return extractorWrapper;
}
项目:transistor    文件:DashUtil.java   
private static void loadInitializationData(DataSource dataSource,
    Representation representation, ChunkExtractorWrapper extractorWrapper, RangedUri requestUri)
    throws IOException, InterruptedException {
  DataSpec dataSpec = new DataSpec(requestUri.resolveUri(representation.baseUrl),
      requestUri.start, requestUri.length, representation.getCacheKey());
  InitializationChunk initializationChunk = new InitializationChunk(dataSource, dataSpec,
      representation.format, C.SELECTION_REASON_UNKNOWN, null /* trackSelectionData */,
      extractorWrapper);
  initializationChunk.load();
}
项目:transistor    文件:DashUtil.java   
private static Representation getFirstRepresentation(Period period, int type) {
  int index = period.getAdaptationSetIndex(type);
  if (index == C.INDEX_UNSET) {
    return null;
  }
  List<Representation> representations = period.adaptationSets.get(index).representations;
  return representations.isEmpty() ? null : representations.get(0);
}
项目: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    文件:DashMediaPeriod.java   
private static boolean hasEventMessageTrack(List<AdaptationSet> adaptationSets,
    int[] adaptationSetIndices) {
  for (int i : adaptationSetIndices) {
    List<Representation> representations = adaptationSets.get(i).representations;
    for (int j = 0; j < representations.size(); j++) {
      Representation representation = representations.get(j);
      if (!representation.inbandEventStreams.isEmpty()) {
        return true;
      }
    }
  }
  return false;
}
项目:transistor    文件:DashUtilTest.java   
private static Representation newRepresentations(DrmInitData drmInitData) {
  Format format = Format.createVideoContainerFormat("id", MimeTypes.VIDEO_MP4,
      MimeTypes.VIDEO_H264, "", Format.NO_VALUE, 1024, 768, Format.NO_VALUE, null, 0);
  if (drmInitData != null) {
    format = format.copyWithDrmInitData(drmInitData);
  }
  return Representation.newInstance("", 0, format, "", new SingleSegmentBase());
}
项目:K-Sonic    文件:DefaultDashChunkSource.java   
public void updateRepresentation(long newPeriodDurationUs, Representation newRepresentation)
    throws BehindLiveWindowException{
  DashSegmentIndex oldIndex = representation.getIndex();
  DashSegmentIndex newIndex = newRepresentation.getIndex();

  periodDurationUs = newPeriodDurationUs;
  representation = newRepresentation;
  if (oldIndex == null) {
    // Segment numbers cannot shift if the index isn't defined by the manifest.
    return;
  }

  segmentIndex = newIndex;
  if (!oldIndex.isExplicit()) {
    // Segment numbers cannot shift if the index isn't explicit.
    return;
  }

  int oldIndexSegmentCount = oldIndex.getSegmentCount(periodDurationUs);
  if (oldIndexSegmentCount == 0) {
    // Segment numbers cannot shift if the old index was empty.
    return;
  }

  int oldIndexLastSegmentNum = oldIndex.getFirstSegmentNum() + oldIndexSegmentCount - 1;
  long oldIndexEndTimeUs = oldIndex.getTimeUs(oldIndexLastSegmentNum)
      + oldIndex.getDurationUs(oldIndexLastSegmentNum, periodDurationUs);
  int newIndexFirstSegmentNum = newIndex.getFirstSegmentNum();
  long newIndexStartTimeUs = newIndex.getTimeUs(newIndexFirstSegmentNum);
  if (oldIndexEndTimeUs == newIndexStartTimeUs) {
    // The new index continues where the old one ended, with no overlap.
    segmentNumShift += oldIndexLastSegmentNum + 1 - newIndexFirstSegmentNum;
  } else if (oldIndexEndTimeUs < newIndexStartTimeUs) {
    // There's a gap between the old index and the new one which means we've slipped behind the
    // live window and can't proceed.
    throw new BehindLiveWindowException();
  } else {
    // The new index overlaps with the old one.
    segmentNumShift += oldIndex.getSegmentNum(newIndexStartTimeUs, periodDurationUs)
        - newIndexFirstSegmentNum;
  }
}
项目:videoPickPlayer    文件:DefaultDashChunkSource.java   
private List<Representation> getRepresentations() {
  return manifest.getPeriod(periodIndex).adaptationSets.get(adaptationSetIndex).representations;
}
项目:transistor    文件:DefaultDashChunkSource.java   
void updateRepresentation(long newPeriodDurationUs,
    Representation newRepresentation) throws BehindLiveWindowException {
  DashSegmentIndex oldIndex = representation.getIndex();
  DashSegmentIndex newIndex = newRepresentation.getIndex();

  periodDurationUs = newPeriodDurationUs;
  representation = newRepresentation;
  if (oldIndex == null) {
    // Segment numbers cannot shift if the index isn't defined by the manifest.
    return;
  }

  segmentIndex = newIndex;
  if (!oldIndex.isExplicit()) {
    // Segment numbers cannot shift if the index isn't explicit.
    return;
  }

  int oldIndexSegmentCount = oldIndex.getSegmentCount(periodDurationUs);
  if (oldIndexSegmentCount == 0) {
    // Segment numbers cannot shift if the old index was empty.
    return;
  }

  int oldIndexLastSegmentNum = oldIndex.getFirstSegmentNum() + oldIndexSegmentCount - 1;
  long oldIndexEndTimeUs = oldIndex.getTimeUs(oldIndexLastSegmentNum)
      + oldIndex.getDurationUs(oldIndexLastSegmentNum, periodDurationUs);
  int newIndexFirstSegmentNum = newIndex.getFirstSegmentNum();
  long newIndexStartTimeUs = newIndex.getTimeUs(newIndexFirstSegmentNum);
  if (oldIndexEndTimeUs == newIndexStartTimeUs) {
    // The new index continues where the old one ended, with no overlap.
    segmentNumShift += oldIndexLastSegmentNum + 1 - newIndexFirstSegmentNum;
  } else if (oldIndexEndTimeUs < newIndexStartTimeUs) {
    // There's a gap between the old index and the new one which means we've slipped behind the
    // live window and can't proceed.
    throw new BehindLiveWindowException();
  } else {
    // The new index overlaps with the old one.
    segmentNumShift += oldIndex.getSegmentNum(newIndexStartTimeUs, periodDurationUs)
        - newIndexFirstSegmentNum;
  }
}
项目:transistor    文件:DashDownloader.java   
@Override
protected List<Segment> getSegments(DataSource dataSource, DashManifest manifest,
    RepresentationKey[] keys, boolean allowIndexLoadErrors)
    throws InterruptedException, IOException {
  ArrayList<Segment> segments = new ArrayList<>();
  for (RepresentationKey key : keys) {
    DashSegmentIndex index;
    try {
      index = getSegmentIndex(dataSource, manifest, key);
      if (index == null) {
        // Loading succeeded but there was no index. This is always a failure.
        throw new DownloadException("No index for representation: " + key);
      }
    } catch (IOException e) {
      if (allowIndexLoadErrors) {
        // Loading failed, but load errors are allowed. Advance to the next key.
        continue;
      } else {
        throw e;
      }
    }

    int segmentCount = index.getSegmentCount(C.TIME_UNSET);
    if (segmentCount == DashSegmentIndex.INDEX_UNBOUNDED) {
      throw new DownloadException("Unbounded index for representation: " + key);
    }

    Period period = manifest.getPeriod(key.periodIndex);
    Representation representation = period.adaptationSets.get(key.adaptationSetIndex)
        .representations.get(key.representationIndex);
    long startUs = C.msToUs(period.startMs);
    String baseUrl = representation.baseUrl;
    RangedUri initializationUri = representation.getInitializationUri();
    if (initializationUri != null) {
      addSegment(segments, startUs, baseUrl, initializationUri);
    }
    RangedUri indexUri = representation.getIndexUri();
    if (indexUri != null) {
      addSegment(segments, startUs, baseUrl, indexUri);
    }

    int firstSegmentNum = index.getFirstSegmentNum();
    int lastSegmentNum = firstSegmentNum + segmentCount - 1;
    for (int j = firstSegmentNum; j <= lastSegmentNum; j++) {
      addSegment(segments, startUs + index.getTimeUs(j), baseUrl, index.getSegmentUrl(j));
    }
  }
  return segments;
}
项目:transistor    文件:DashUtilTest.java   
private static AdaptationSet newAdaptationSets(Representation... representations) {
  return new AdaptationSet(0, C.TRACK_TYPE_VIDEO, Arrays.asList(representations), null, null);
}
项目:K-Sonic    文件:DashUtil.java   
/**
 * Loads initialization data for the {@code representation} and returns the sample {@link
 * Format}.
 *
 * @param dataSource The source from which the data should be loaded.
 * @param representation The representation which initialization chunk belongs to.
 * @return the sample {@link Format} of the given representation.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
public static Format loadSampleFormat(DataSource dataSource, Representation representation)
    throws IOException, InterruptedException {
  ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, representation,
      false);
  return extractorWrapper == null ? null : extractorWrapper.getSampleFormats()[0];
}
项目: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 data for the {@code representation} and returns the sample {@link Format}.
 *
 * @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 sample {@link Format} of the given representation.
 * @throws IOException Thrown when there is an error while loading.
 * @throws InterruptedException Thrown if the thread was interrupted.
 */
public static Format loadSampleFormat(DataSource dataSource, int trackType,
    Representation representation) throws IOException, InterruptedException {
  ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
      representation, false);
  return extractorWrapper == null ? null : extractorWrapper.getSampleFormats()[0];
}
项目: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();
}