Java 类com.google.android.exoplayer.parser.Extractor 实例源码

项目:android-exoplayer    文件:Mp4MediaChunk.java   
@Override
public boolean prepare() throws ParserException {
  if (!prepared) {
    if (maybeSelfContained) {
      // Read up to the first sample. Once we're there, we know that the extractor must have
      // parsed a moov atom if the chunk contains one.
      NonBlockingInputStream inputStream = getNonBlockingInputStream();
      Assertions.checkState(inputStream != null);
      int result = extractor.read(inputStream, null);
      prepared = (result & Extractor.RESULT_NEED_SAMPLE_HOLDER) != 0;
    } else {
      // We know there isn't a moov atom. The extractor must have parsed one from a separate
      // initialization chunk.
      prepared = true;
    }
    if (prepared) {
      mediaFormat = extractor.getFormat();
      Map<UUID, byte[]> extractorPsshInfo = extractor.getPsshInfo();
      if (extractorPsshInfo != null) {
        psshInfo = extractorPsshInfo;
      }
    }
  }
  return prepared;
}
项目:edx-app-android    文件:Mp4MediaChunk.java   
@Override
public boolean prepare() throws ParserException {
  if (!prepared) {
    if (maybeSelfContained) {
      // Read up to the first sample. Once we're there, we know that the extractor must have
      // parsed a moov atom if the chunk contains one.
      NonBlockingInputStream inputStream = getNonBlockingInputStream();
      Assertions.checkState(inputStream != null);
      int result = extractor.read(inputStream, null);
      prepared = (result & Extractor.RESULT_NEED_SAMPLE_HOLDER) != 0;
    } else {
      // We know there isn't a moov atom. The extractor must have parsed one from a separate
      // initialization chunk.
      prepared = true;
    }
    if (prepared) {
      mediaFormat = Assertions.checkNotNull(extractor.getFormat());
      psshInfo = extractor.getPsshInfo();
    }
  }
  return prepared;
}
项目:android-exoplayer    文件:Mp4MediaChunk.java   
/**
 * @deprecated Use the other constructor, passing null as {@code psshInfo}.
 */
@Deprecated
public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format,
    int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex,
    Extractor extractor, boolean maybeSelfContained, long sampleOffsetUs) {
  this(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex,
      extractor, null, maybeSelfContained, sampleOffsetUs);
}
项目:android-exoplayer    文件:Mp4MediaChunk.java   
@Override
public boolean read(SampleHolder holder) throws ParserException {
  NonBlockingInputStream inputStream = getNonBlockingInputStream();
  Assertions.checkState(inputStream != null);
  int result = extractor.read(inputStream, holder);
  boolean sampleRead = (result & Extractor.RESULT_READ_SAMPLE) != 0;
  if (sampleRead) {
    holder.timeUs -= sampleOffsetUs;
  }
  return sampleRead;
}
项目:android-exoplayer    文件:DashChunkSource.java   
private DashChunkSource(ManifestFetcher<MediaPresentationDescription> manifestFetcher,
    MediaPresentationDescription initialManifest, int adaptationSetIndex,
    int[] representationIndices, DataSource dataSource, FormatEvaluator formatEvaluator,
    long liveEdgeLatencyUs) {
  this.manifestFetcher = manifestFetcher;
  this.currentManifest = initialManifest;
  this.adaptationSetIndex = adaptationSetIndex;
  this.representationIndices = representationIndices;
  this.dataSource = dataSource;
  this.evaluator = formatEvaluator;
  this.liveEdgeLatencyUs = liveEdgeLatencyUs;
  this.evaluation = new Evaluation();
  this.headerBuilder = new StringBuilder();

  psshInfo = getPsshInfo(currentManifest, adaptationSetIndex);
  Representation[] representations = getFilteredRepresentations(currentManifest,
      adaptationSetIndex, representationIndices);
  long periodDurationUs = (representations[0].periodDurationMs == TrackRenderer.UNKNOWN_TIME_US)
      ? TrackRenderer.UNKNOWN_TIME_US : representations[0].periodDurationMs * 1000;
  this.trackInfo = new TrackInfo(representations[0].format.mimeType, periodDurationUs);

  this.formats = new Format[representations.length];
  this.representationHolders = new HashMap<String, RepresentationHolder>();
  int maxWidth = 0;
  int maxHeight = 0;
  for (int i = 0; i < representations.length; i++) {
    formats[i] = representations[i].format;
    maxWidth = Math.max(formats[i].width, maxWidth);
    maxHeight = Math.max(formats[i].height, maxHeight);
    Extractor extractor = mimeTypeIsWebm(formats[i].mimeType) ? new WebmExtractor()
        : new FragmentedMp4Extractor();
    representationHolders.put(formats[i].id,
        new RepresentationHolder(representations[i], extractor));
  }
  this.maxWidth = maxWidth;
  this.maxHeight = maxHeight;
  Arrays.sort(formats, new DecreasingBandwidthComparator());
}
项目:android-exoplayer    文件:DashChunkSource.java   
private Chunk newInitializationChunk(RangedUri initializationUri, RangedUri indexUri,
    Representation representation, Extractor extractor, DataSource dataSource,
    int trigger) {
  int expectedExtractorResult = Extractor.RESULT_END_OF_STREAM;
  long indexAnchor = 0;
  RangedUri requestUri;
  if (initializationUri != 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.
    expectedExtractorResult |= Extractor.RESULT_READ_INIT;
    requestUri = initializationUri.attemptMerge(indexUri);
    if (requestUri != null) {
      expectedExtractorResult |= Extractor.RESULT_READ_INDEX;
      if (extractor.hasRelativeIndexOffsets()) {
        indexAnchor = indexUri.start + indexUri.length;
      }
    } else {
      requestUri = initializationUri;
    }
  } else {
    requestUri = indexUri;
    if (extractor.hasRelativeIndexOffsets()) {
      indexAnchor = indexUri.start + indexUri.length;
    }
    expectedExtractorResult |= Extractor.RESULT_READ_INDEX;
  }
  DataSpec dataSpec = new DataSpec(requestUri.getUri(), requestUri.start, requestUri.length,
      representation.getCacheKey());

  return new InitializationLoadable(dataSource, dataSpec, trigger, representation.format,
      extractor, expectedExtractorResult, indexAnchor);
}
项目:android-exoplayer    文件:DashChunkSource.java   
public InitializationLoadable(DataSource dataSource, DataSpec dataSpec, int trigger,
    Format format, Extractor extractor, int expectedExtractorResult,
    long indexAnchor) {
  super(dataSource, dataSpec, format, trigger);
  this.extractor = extractor;
  this.expectedExtractorResult = expectedExtractorResult;
  this.indexAnchor = indexAnchor;
  this.uri = dataSpec.uri;
}
项目:android-exoplayer    文件:DashChunkSource.java   
@Override
protected void consumeStream(NonBlockingInputStream stream) throws IOException {
  int result = extractor.read(stream, null);
  if (result != expectedExtractorResult) {
    throw new ParserException("Invalid extractor result. Expected "
        + expectedExtractorResult + ", got " + result);
  }
  if ((result & Extractor.RESULT_READ_INDEX) != 0) {
    representationHolders.get(format.id).segmentIndex =
        new DashWrappingSegmentIndex(extractor.getIndex(), uri, indexAnchor);
  }
}
项目:android-exoplayer    文件:SmoothStreamingChunkSource.java   
private static MediaChunk newMediaChunk(Format formatInfo, Uri uri, String cacheKey,
    Extractor extractor, Map<UUID, byte[]> psshInfo, DataSource dataSource, int chunkIndex,
    boolean isLast, long chunkStartTimeUs, long nextChunkStartTimeUs, int trigger) {
  int nextChunkIndex = isLast ? -1 : chunkIndex + 1;
  long nextStartTimeUs = isLast ? -1 : nextChunkStartTimeUs;
  long offset = 0;
  DataSpec dataSpec = new DataSpec(uri, offset, -1, cacheKey);
  // In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
  // To convert them the absolute timestamps, we need to set sampleOffsetUs to -chunkStartTimeUs.
  return new Mp4MediaChunk(dataSource, dataSpec, formatInfo, trigger, chunkStartTimeUs,
      nextStartTimeUs, nextChunkIndex, extractor, psshInfo, false, -chunkStartTimeUs);
}
项目:edx-app-android    文件:Mp4MediaChunk.java   
@Override
public boolean read(SampleHolder holder) throws ParserException {
  NonBlockingInputStream inputStream = getNonBlockingInputStream();
  Assertions.checkState(inputStream != null);
  int result = extractor.read(inputStream, holder);
  boolean sampleRead = (result & Extractor.RESULT_READ_SAMPLE) != 0;
  if (sampleRead) {
    holder.timeUs -= sampleOffsetUs;
  }
  return sampleRead;
}
项目:edx-app-android    文件:DashChunkSource.java   
/**
 * @param dataSource A {@link DataSource} suitable for loading the media data.
 * @param evaluator Selects from the available formats.
 * @param representations The representations to be considered by the source.
 */
public DashChunkSource(DataSource dataSource, FormatEvaluator evaluator,
    Representation... representations) {
  this.dataSource = dataSource;
  this.evaluator = evaluator;
  this.formats = new Format[representations.length];
  this.extractors = new HashMap<String, Extractor>();
  this.segmentIndexes = new HashMap<String, DashSegmentIndex>();
  this.representations = new HashMap<String, Representation>();
  this.trackInfo = new TrackInfo(representations[0].format.mimeType,
      representations[0].periodDurationMs * 1000);
  this.evaluation = new Evaluation();
  int maxWidth = 0;
  int maxHeight = 0;
  for (int i = 0; i < representations.length; i++) {
    formats[i] = representations[i].format;
    maxWidth = Math.max(formats[i].width, maxWidth);
    maxHeight = Math.max(formats[i].height, maxHeight);
    Extractor extractor = formats[i].mimeType.startsWith(MimeTypes.VIDEO_WEBM)
        ? new WebmExtractor() : new FragmentedMp4Extractor();
    extractors.put(formats[i].id, extractor);
    this.representations.put(formats[i].id, representations[i]);
    DashSegmentIndex segmentIndex = representations[i].getIndex();
    if (segmentIndex != null) {
      segmentIndexes.put(formats[i].id, segmentIndex);
    }
  }
  this.maxWidth = maxWidth;
  this.maxHeight = maxHeight;
  Arrays.sort(formats, new DecreasingBandwidthComparator());
}
项目:edx-app-android    文件:DashChunkSource.java   
private Chunk newInitializationChunk(RangedUri initializationUri, RangedUri indexUri,
    Representation representation, Extractor extractor, DataSource dataSource,
    int trigger) {
  int expectedExtractorResult = Extractor.RESULT_END_OF_STREAM;
  long indexAnchor = 0;
  RangedUri requestUri;
  if (initializationUri != 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.
    expectedExtractorResult |= Extractor.RESULT_READ_INIT;
    requestUri = initializationUri.attemptMerge(indexUri);
    if (requestUri != null) {
      expectedExtractorResult |= Extractor.RESULT_READ_INDEX;
      if (extractor.hasRelativeIndexOffsets()) {
        indexAnchor = indexUri.start + indexUri.length;
      }
    } else {
      requestUri = initializationUri;
    }
  } else {
    requestUri = indexUri;
    if (extractor.hasRelativeIndexOffsets()) {
      indexAnchor = indexUri.start + indexUri.length;
    }
    expectedExtractorResult |= Extractor.RESULT_READ_INDEX;
  }
  DataSpec dataSpec = new DataSpec(requestUri.getUri(), requestUri.start, requestUri.length,
      representation.getCacheKey());
  return new InitializationLoadable(dataSource, dataSpec, trigger, representation.format,
      extractor, expectedExtractorResult, indexAnchor);
}
项目:edx-app-android    文件:DashChunkSource.java   
private Chunk newMediaChunk(Representation representation, DashSegmentIndex segmentIndex,
    Extractor extractor, DataSource dataSource, int segmentNum, int trigger) {
  int lastSegmentNum = segmentIndex.getLastSegmentNum();
  int nextSegmentNum = segmentNum == lastSegmentNum ? -1 : segmentNum + 1;
  long startTimeUs = segmentIndex.getTimeUs(segmentNum);
  long endTimeUs = segmentNum < lastSegmentNum ? segmentIndex.getTimeUs(segmentNum + 1)
      : startTimeUs + segmentIndex.getDurationUs(segmentNum);
  RangedUri segmentUri = segmentIndex.getSegmentUrl(segmentNum);
  DataSpec dataSpec = new DataSpec(segmentUri.getUri(), segmentUri.start, segmentUri.length,
      representation.getCacheKey());
  return new Mp4MediaChunk(dataSource, dataSpec, representation.format, trigger, startTimeUs,
      endTimeUs, nextSegmentNum, extractor, false, 0);
}
项目:edx-app-android    文件:DashChunkSource.java   
public InitializationLoadable(DataSource dataSource, DataSpec dataSpec, int trigger,
    Format format, Extractor extractor, int expectedExtractorResult,
    long indexAnchor) {
  super(dataSource, dataSpec, format, trigger);
  this.extractor = extractor;
  this.expectedExtractorResult = expectedExtractorResult;
  this.indexAnchor = indexAnchor;
  this.uri = dataSpec.uri;
}
项目:edx-app-android    文件:DashChunkSource.java   
@Override
protected void consumeStream(NonBlockingInputStream stream) throws IOException {
  int result = extractor.read(stream, null);
  if (result != expectedExtractorResult) {
    throw new ParserException("Invalid extractor result. Expected "
        + expectedExtractorResult + ", got " + result);
  }
  if ((result & Extractor.RESULT_READ_INDEX) != 0) {
    segmentIndexes.put(format.id,
        new DashWrappingSegmentIndex(extractor.getIndex(), uri, indexAnchor));
  }
}
项目:edx-app-android    文件:SmoothStreamingChunkSource.java   
private static MediaChunk newMediaChunk(Format formatInfo, Uri uri, String cacheKey,
    Extractor extractor, DataSource dataSource, int chunkIndex,
    boolean isLast, long chunkStartTimeUs, long nextChunkStartTimeUs, int trigger) {
  int nextChunkIndex = isLast ? -1 : chunkIndex + 1;
  long nextStartTimeUs = isLast ? -1 : nextChunkStartTimeUs;
  long offset = 0;
  DataSpec dataSpec = new DataSpec(uri, offset, -1, cacheKey);
  // In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
  // To convert them the absolute timestamps, we need to set sampleOffsetUs to -chunkStartTimeUs.
  return new Mp4MediaChunk(dataSource, dataSpec, formatInfo, trigger, chunkStartTimeUs,
      nextStartTimeUs, nextChunkIndex, extractor, false, -chunkStartTimeUs);
}
项目:android-exoplayer    文件:Mp4MediaChunk.java   
@Override
public boolean sampleAvailable() throws ParserException {
  NonBlockingInputStream inputStream = getNonBlockingInputStream();
  int result = extractor.read(inputStream, null);
  return (result & Extractor.RESULT_NEED_SAMPLE_HOLDER) != 0;
}
项目:android-exoplayer    文件:DashChunkSource.java   
public RepresentationHolder(Representation representation, Extractor extractor) {
  this.representation = representation;
  this.extractor = extractor;
  this.segmentIndex = representation.getIndex();
}
项目:edx-app-android    文件:Mp4MediaChunk.java   
@Override
public boolean sampleAvailable() throws ParserException {
  NonBlockingInputStream inputStream = getNonBlockingInputStream();
  int result = extractor.read(inputStream, null);
  return (result & Extractor.RESULT_NEED_SAMPLE_HOLDER) != 0;
}
项目:edx-app-android    文件:DashChunkSource.java   
@Override
public final void getChunkOperation(List<? extends MediaChunk> queue, long seekPositionUs,
    long playbackPositionUs, ChunkOperationHolder out) {
  evaluation.queueSize = queue.size();
  if (evaluation.format == null || !lastChunkWasInitialization) {
    evaluator.evaluate(queue, playbackPositionUs, formats, evaluation);
  }
  Format selectedFormat = evaluation.format;
  out.queueSize = evaluation.queueSize;

  if (selectedFormat == null) {
    out.chunk = null;
    return;
  } else if (out.queueSize == queue.size() && out.chunk != null
      && out.chunk.format.id.equals(selectedFormat.id)) {
    // We already have a chunk, and the evaluation hasn't changed either the format or the size
    // of the queue. Leave unchanged.
    return;
  }

  Representation selectedRepresentation = representations.get(selectedFormat.id);
  Extractor extractor = extractors.get(selectedRepresentation.format.id);

  RangedUri pendingInitializationUri = null;
  RangedUri pendingIndexUri = null;
  if (extractor.getFormat() == null) {
    pendingInitializationUri = selectedRepresentation.getInitializationUri();
  }
  if (!segmentIndexes.containsKey(selectedRepresentation.format.id)) {
    pendingIndexUri = selectedRepresentation.getIndexUri();
  }
  if (pendingInitializationUri != null || pendingIndexUri != null) {
    // We have initialization and/or index requests to make.
    Chunk initializationChunk = newInitializationChunk(pendingInitializationUri, pendingIndexUri,
        selectedRepresentation, extractor, dataSource, evaluation.trigger);
    lastChunkWasInitialization = true;
    out.chunk = initializationChunk;
    return;
  }

  int nextSegmentNum;
  DashSegmentIndex segmentIndex = segmentIndexes.get(selectedRepresentation.format.id);
  if (queue.isEmpty()) {
    nextSegmentNum = segmentIndex.getSegmentNum(seekPositionUs);
  } else {
    nextSegmentNum = queue.get(out.queueSize - 1).nextChunkIndex;
  }

  if (nextSegmentNum == -1) {
    out.chunk = null;
    return;
  }

  Chunk nextMediaChunk = newMediaChunk(selectedRepresentation, segmentIndex, extractor,
      dataSource, nextSegmentNum, evaluation.trigger);
  lastChunkWasInitialization = false;
  out.chunk = nextMediaChunk;
}
项目:android-exoplayer    文件:Mp4MediaChunk.java   
/**
 * @param dataSource A {@link DataSource} for loading the data.
 * @param dataSpec Defines the data to be loaded.
 * @param format The format of the stream to which this chunk belongs.
 * @param trigger The reason for this chunk being selected.
 * @param startTimeUs The start time of the media contained by the chunk, in microseconds.
 * @param endTimeUs The end time of the media contained by the chunk, in microseconds.
 * @param nextChunkIndex The index of the next chunk, or -1 if this is the last chunk.
 * @param extractor The extractor that will be used to extract the samples.
 * @param psshInfo Pssh data. May be null if pssh data is present within the stream, meaning it
 *     can be obtained directly from {@code extractor}, or if no pssh data is required.
 * @param maybeSelfContained Set to true if this chunk might be self contained, meaning it might
 *     contain a moov atom defining the media format of the chunk. This parameter can always be
 *     safely set to true. Setting to false where the chunk is known to not be self contained may
 *     improve startup latency.
 * @param sampleOffsetUs An offset to subtract from the sample timestamps parsed by the extractor.
 */
public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format,
    int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex, Extractor extractor,
    Map<UUID, byte[]> psshInfo, boolean maybeSelfContained, long sampleOffsetUs) {
  super(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex);
  this.extractor = extractor;
  this.maybeSelfContained = maybeSelfContained;
  this.sampleOffsetUs = sampleOffsetUs;
  this.psshInfo = psshInfo;
}
项目:edx-app-android    文件:Mp4MediaChunk.java   
/**
 * @param dataSource A {@link DataSource} for loading the data.
 * @param dataSpec Defines the data to be loaded.
 * @param format The format of the stream to which this chunk belongs.
 * @param trigger The reason for this chunk being selected.
 * @param startTimeUs The start time of the media contained by the chunk, in microseconds.
 * @param endTimeUs The end time of the media contained by the chunk, in microseconds.
 * @param nextChunkIndex The index of the next chunk, or -1 if this is the last chunk.
 * @param extractor The extractor that will be used to extract the samples.
 * @param maybeSelfContained Set to true if this chunk might be self contained, meaning it might
 *     contain a moov atom defining the media format of the chunk. This parameter can always be
 *     safely set to true. Setting to false where the chunk is known to not be self contained may
 *     improve startup latency.
 * @param sampleOffsetUs An offset to subtract from the sample timestamps parsed by the extractor.
 */
public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format,
    int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex,
    Extractor extractor, boolean maybeSelfContained, long sampleOffsetUs) {
  super(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex);
  this.extractor = extractor;
  this.maybeSelfContained = maybeSelfContained;
  this.sampleOffsetUs = sampleOffsetUs;
}