Java 类com.google.android.exoplayer.C 实例源码

项目:android_packages_apps_tv    文件:MpegTsSampleSource.java   
@Override
public int readData(int track, long positionUs, MediaFormatHolder formatHolder,
  SampleHolder sampleHolder) {
    Assertions.checkState(mPrepared);
    Assertions.checkState(mTrackStates.get(track) != TRACK_STATE_DISABLED);
    if (mPendingDiscontinuities.get(track)) {
        return NOTHING_READ;
    }
    if (mTrackStates.get(track) != TRACK_STATE_FORMAT_SENT) {
        mSampleExtractor.getTrackMediaFormat(track, formatHolder);
        mTrackStates.set(track, TRACK_STATE_FORMAT_SENT);
        return FORMAT_READ;
    }

    mPendingSeekPositionUs = C.UNKNOWN_TIME_US;
    return mSampleExtractor.readSample(track, sampleHolder);
}
项目:ExoPlayer-Demo    文件:Mp4ExtractorTest.java   
public void testParsesValidMp4File() throws Exception {
  TestUtil.consumeTestData(extractor,
      getTestInputData(true /* includeStss */, false /* mp4vFormat */));

  // The seek map is correct.
  assertSeekMap(extractorOutput.seekMap, true);

  // The video and audio formats are set correctly.
  assertEquals(2, extractorOutput.trackOutputs.size());
  MediaFormat videoFormat = extractorOutput.trackOutputs.get(0).format;
  MediaFormat audioFormat = extractorOutput.trackOutputs.get(1).format;
  assertEquals(MimeTypes.VIDEO_H264, videoFormat.mimeType);
  assertEquals(VIDEO_WIDTH, videoFormat.width);
  assertEquals(VIDEO_HEIGHT, videoFormat.height);
  assertEquals(MimeTypes.AUDIO_AAC, audioFormat.mimeType);

  // The timestamps and sizes are set correctly.
  FakeTrackOutput videoTrackOutput = extractorOutput.trackOutputs.get(0);
  videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
  for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
    byte[] sampleData = getOutputSampleData(i, true);
    int sampleFlags = SAMPLE_IS_SYNC[i] ? C.SAMPLE_FLAG_SYNC : 0;
    long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
    videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
  }
}
项目:ExoPlayer-Demo    文件:DefaultHttpDataSource.java   
/**
 * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at
 * index {@code offset}.
 * <p>
 * This method blocks until at least one byte of data can be read, the end of the opened range is
 * detected, or an exception is thrown.
 *
 * @param buffer The buffer into which the read data should be stored.
 * @param offset The start offset into {@code buffer} at which data should be written.
 * @param readLength The maximum number of bytes to read.
 * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the end of the opened
 *     range is reached.
 * @throws IOException If an error occurs reading from the source.
 */
private int readInternal(byte[] buffer, int offset, int readLength) throws IOException {
  readLength = bytesToRead == C.LENGTH_UNBOUNDED ? readLength
      : (int) Math.min(readLength, bytesToRead - bytesRead);
  if (readLength == 0) {
    // We've read all of the requested data.
    return C.RESULT_END_OF_INPUT;
  }

  int read = inputStream.read(buffer, offset, readLength);
  if (read == -1) {
    if (bytesToRead != C.LENGTH_UNBOUNDED && bytesToRead != bytesRead) {
      // The server closed the connection having not sent sufficient data.
      throw new EOFException();
    }
    return C.RESULT_END_OF_INPUT;
  }

  bytesRead += read;
  if (listener != null) {
    listener.onBytesTransferred(read);
  }
  return read;
}
项目:miku    文件:RollingSampleBuffer.java   
/**
 * Appends data to the rolling buffer.
 *
 * @param dataSource The source from which to read.
 * @param length The maximum length of the read.
 * @param allowEndOfInput True if encountering the end of the input having appended no data is
 *     allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
 *     should be considered an error, causing an {@link EOFException} to be thrown.
 * @return The number of bytes appended, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
 * @throws IOException If an error occurs reading from the source.
 */
public int appendData(DataSource dataSource, int length, boolean allowEndOfInput)
    throws IOException {
  length = prepareForAppend(length);
  int bytesAppended = dataSource.read(lastAllocation.data,
      lastAllocation.translateOffset(lastAllocationOffset), length);
  if (bytesAppended == C.RESULT_END_OF_INPUT) {
    if (allowEndOfInput) {
      return C.RESULT_END_OF_INPUT;
    }
    throw new EOFException();
  }
  lastAllocationOffset += bytesAppended;
  totalBytesWritten += bytesAppended;
  return bytesAppended;
}
项目:miku    文件:RollingSampleBuffer.java   
/**
 * Appends data to the rolling buffer.
 *
 * @param input The source from which to read.
 * @param length The maximum length of the read.
 * @param allowEndOfInput True if encountering the end of the input having appended no data is
 *     allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
 *     should be considered an error, causing an {@link EOFException} to be thrown.
 * @return The number of bytes appended, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
 * @throws IOException If an error occurs reading from the source.
 * @throws InterruptedException If the thread has been interrupted.
 */
public int appendData(ExtractorInput input, int length, boolean allowEndOfInput)
    throws IOException, InterruptedException {
  length = prepareForAppend(length);
  int bytesAppended = input.read(lastAllocation.data,
      lastAllocation.translateOffset(lastAllocationOffset), length);
  if (bytesAppended == C.RESULT_END_OF_INPUT) {
    if (allowEndOfInput) {
      return C.RESULT_END_OF_INPUT;
    }
    throw new EOFException();
  }
  lastAllocationOffset += bytesAppended;
  totalBytesWritten += bytesAppended;
  return bytesAppended;
}
项目:ExoPlayer-Demo    文件:SmoothStreamingManifest.java   
public StreamElement(String baseUri, String chunkTemplate, int type, String subType,
    long timescale, String name, int qualityLevels, int maxWidth, int maxHeight,
    int displayWidth, int displayHeight, String language, TrackElement[] tracks,
    List<Long> chunkStartTimes, long lastChunkDuration) {
  this.baseUri = baseUri;
  this.chunkTemplate = chunkTemplate;
  this.type = type;
  this.subType = subType;
  this.timescale = timescale;
  this.name = name;
  this.qualityLevels = qualityLevels;
  this.maxWidth = maxWidth;
  this.maxHeight = maxHeight;
  this.displayWidth = displayWidth;
  this.displayHeight = displayHeight;
  this.language = language;
  this.tracks = tracks;
  this.chunkCount = chunkStartTimes.size();
  this.chunkStartTimes = chunkStartTimes;
  lastChunkDurationUs =
      Util.scaleLargeTimestamp(lastChunkDuration, C.MICROS_PER_SECOND, timescale);
  chunkStartTimesUs =
      Util.scaleLargeTimestamps(chunkStartTimes, C.MICROS_PER_SECOND, timescale);
}
项目:miku    文件:SeiReader.java   
@Override
public void consume(ParsableByteArray seiBuffer, long pesTimeUs, boolean startOfPacket) {
  int b;
  while (seiBuffer.bytesLeft() > 1 /* last byte will be rbsp_trailing_bits */) {
    // Parse payload type.
    int payloadType = 0;
    do {
      b = seiBuffer.readUnsignedByte();
      payloadType += b;
    } while (b == 0xFF);
    // Parse payload size.
    int payloadSize = 0;
    do {
      b = seiBuffer.readUnsignedByte();
      payloadSize += b;
    } while (b == 0xFF);
    // Process the payload. We only support EIA-608 payloads currently.
    if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) {
      output.sampleData(seiBuffer, payloadSize);
      output.sampleMetadata(pesTimeUs, C.SAMPLE_FLAG_SYNC, payloadSize, 0, null);
    } else {
      seiBuffer.skipBytes(payloadSize);
    }
  }
}
项目:miku    文件:DefaultExtractorInput.java   
@Override
public int read(byte[] target, int offset, int length) throws IOException, InterruptedException {
  if (Thread.interrupted()) {
    throw new InterruptedException();
  }
  int peekBytes = Math.min(peekBufferLength, length);
  System.arraycopy(peekBuffer, 0, target, offset, peekBytes);
  offset += peekBytes;
  length -= peekBytes;
  int bytesRead = length != 0 ? dataSource.read(target, offset, length) : 0;
  if (bytesRead == C.RESULT_END_OF_INPUT) {
    return C.RESULT_END_OF_INPUT;
  }
  updatePeekBuffer(peekBytes);
  bytesRead += peekBytes;
  position += bytesRead;
  return bytesRead;
}
项目:miku    文件:DefaultExtractorInput.java   
@Override
public boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput)
    throws IOException, InterruptedException {
  int peekBytes = Math.min(peekBufferLength, length);
  System.arraycopy(peekBuffer, 0, target, offset, peekBytes);
  offset += peekBytes;
  int remaining = length - peekBytes;
  while (remaining > 0) {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    int bytesRead = dataSource.read(target, offset, remaining);
    if (bytesRead == C.RESULT_END_OF_INPUT) {
      if (allowEndOfInput && remaining == length) {
        return false;
      }
      throw new EOFException();
    }
    offset += bytesRead;
    remaining -= bytesRead;
  }
  updatePeekBuffer(peekBytes);
  position += length;
  return true;
}
项目:miku    文件:DefaultExtractorInput.java   
@Override
public void skipFully(int length) throws IOException, InterruptedException {
  int peekBytes = Math.min(peekBufferLength, length);
  int remaining = length - peekBytes;
  while (remaining > 0) {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    int bytesRead = dataSource.read(SCRATCH_SPACE, 0, Math.min(SCRATCH_SPACE.length, remaining));
    if (bytesRead == C.RESULT_END_OF_INPUT) {
      throw new EOFException();
    }
    remaining -= bytesRead;
  }
  updatePeekBuffer(peekBytes);
  position += length;
}
项目:ExoPlayer-Demo    文件:FileDataSource.java   
@Override
public long open(DataSpec dataSpec) throws FileDataSourceException {
  try {
    uriString = dataSpec.uri.toString();
    file = new RandomAccessFile(dataSpec.uri.getPath(), "r");
    file.seek(dataSpec.position);
    bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? file.length() - dataSpec.position
        : dataSpec.length;
    if (bytesRemaining < 0) {
      throw new EOFException();
    }
  } catch (IOException e) {
    throw new FileDataSourceException(e);
  }

  opened = true;
  if (listener != null) {
    listener.onTransferStart();
  }

  return bytesRemaining;
}
项目:ExoPlayer-Demo    文件:DashChunkSource.java   
@Override
public void fixedTrack(MediaPresentationDescription manifest, int periodIndex,
    int adaptationSetIndex, int representationIndex) {
  List<AdaptationSet> adaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
  AdaptationSet adaptationSet = adaptationSets.get(adaptationSetIndex);
  Format representationFormat = adaptationSet.representations.get(representationIndex).format;
  String mediaMimeType = getMediaMimeType(representationFormat);
  if (mediaMimeType == null) {
    Log.w(TAG, "Skipped track " + representationFormat.id + " (unknown media mime type)");
    return;
  }
  MediaFormat trackFormat = getTrackFormat(adaptationSet.type, representationFormat,
      mediaMimeType, manifest.dynamic ? C.UNKNOWN_TIME_US : manifest.duration * 1000);
  if (trackFormat == null) {
    Log.w(TAG, "Skipped track " + representationFormat.id + " (unknown media format)");
    return;
  }
  tracks.add(new ExposedTrack(trackFormat, adaptationSetIndex, representationFormat));
}
项目:ExoPlayer-Demo    文件:SeiReader.java   
public void consume(long pesTimeUs, ParsableByteArray seiBuffer) {
  int b;
  while (seiBuffer.bytesLeft() > 1 /* last byte will be rbsp_trailing_bits */) {
    // Parse payload type.
    int payloadType = 0;
    do {
      b = seiBuffer.readUnsignedByte();
      payloadType += b;
    } while (b == 0xFF);
    // Parse payload size.
    int payloadSize = 0;
    do {
      b = seiBuffer.readUnsignedByte();
      payloadSize += b;
    } while (b == 0xFF);
    // Process the payload.
    if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) {
      output.sampleData(seiBuffer, payloadSize);
      output.sampleMetadata(pesTimeUs, C.SAMPLE_FLAG_SYNC, payloadSize, 0, null);
    } else {
      seiBuffer.skipBytes(payloadSize);
    }
  }
}
项目:miku    文件:CacheDataSource.java   
@Override
public int read(byte[] buffer, int offset, int max) throws IOException {
  try {
    int bytesRead = currentDataSource.read(buffer, offset, max);
    if (bytesRead >= 0) {
      if (currentDataSource == cacheReadDataSource) {
        totalCachedBytesRead += bytesRead;
      }
      readPosition += bytesRead;
      if (bytesRemaining != C.LENGTH_UNBOUNDED) {
        bytesRemaining -= bytesRead;
      }
    } else {
      closeCurrentSource();
      if (bytesRemaining > 0 && bytesRemaining != C.LENGTH_UNBOUNDED) {
        openNextSource();
        return read(buffer, offset, max);
      }
    }
    return bytesRead;
  } catch (IOException e) {
    handleBeforeThrow(e);
    throw e;
  }
}
项目:ExoPlayer-Demo    文件:OkHttpDataSource.java   
/**
 * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at
 * index {@code offset}.
 * <p>
 * This method blocks until at least one byte of data can be read, the end of the opened range is
 * detected, or an exception is thrown.
 *
 * @param buffer The buffer into which the read data should be stored.
 * @param offset The start offset into {@code buffer} at which data should be written.
 * @param readLength The maximum number of bytes to read.
 * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the end of the opened
 *     range is reached.
 * @throws IOException If an error occurs reading from the source.
 */
private int readInternal(byte[] buffer, int offset, int readLength) throws IOException {
  readLength = bytesToRead == C.LENGTH_UNBOUNDED ? readLength
      : (int) Math.min(readLength, bytesToRead - bytesRead);
  if (readLength == 0) {
    // We've read all of the requested data.
    return C.RESULT_END_OF_INPUT;
  }

  int read = responseByteStream.read(buffer, offset, readLength);
  if (read == -1) {
    if (bytesToRead != C.LENGTH_UNBOUNDED && bytesToRead != bytesRead) {
      // The server closed the connection having not sent sufficient data.
      throw new EOFException();
    }
    return C.RESULT_END_OF_INPUT;
  }

  bytesRead += read;
  if (listener != null) {
    listener.onBytesTransferred(read);
  }
  return read;
}
项目:danish-media-license    文件:OkHttpDataSource.java   
/**
 * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at index
 * {@code offset}.
 *
 * <p>This method blocks until at least one byte of data can be read, the end of the opened range
 * is detected, or an exception is thrown.
 *
 * @param buffer     The buffer into which the read data should be stored.
 * @param offset     The start offset into {@code buffer} at which data should be written.
 * @param readLength The maximum number of bytes to read.
 * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the end of the opened
 *     range is reached.
 * @throws IOException If an error occurs reading from the source.
 */
private int readInternal(byte[] buffer, int offset, int readLength) throws IOException {
  readLength = bytesToRead == C.LENGTH_UNBOUNDED ? readLength
      : (int) Math.min(readLength, bytesToRead - bytesRead);
  if (readLength == 0) {
    // We've read all of the requested data.
    return C.RESULT_END_OF_INPUT;
  }

  int read = responseByteStream.read(buffer, offset, readLength);
  if (read == -1) {
    if (bytesToRead != C.LENGTH_UNBOUNDED && bytesToRead != bytesRead) {
      // The server closed the connection having not sent sufficient data.
      throw new EOFException();
    }
    return C.RESULT_END_OF_INPUT;
  }

  bytesRead += read;
  if (listener != null) {
    listener.onBytesTransferred(read);
  }
  return read;
}
项目:ExoPlayer-Demo    文件:WebvttExtractor.java   
@Override
public int read(ExtractorInput input, PositionHolder seekPosition)
    throws IOException, InterruptedException {
  int currentFileSize = (int) input.getLength();

  // Increase the size of sampleData if necessary.
  if (sampleSize == sampleData.length) {
    sampleData = Arrays.copyOf(sampleData,
        (currentFileSize != C.LENGTH_UNBOUNDED ? currentFileSize : sampleData.length) * 3 / 2);
  }

  // Consume to the input.
  int bytesRead = input.read(sampleData, sampleSize, sampleData.length - sampleSize);
  if (bytesRead != C.RESULT_END_OF_INPUT) {
    sampleSize += bytesRead;
    if (currentFileSize == C.LENGTH_UNBOUNDED || sampleSize != currentFileSize) {
      return Extractor.RESULT_CONTINUE;
    }
  }

  // We've reached the end of the input, which corresponds to the end of the current file.
  processSample();
  return Extractor.RESULT_END_OF_INPUT;
}
项目:ExoPlayer-Demo    文件:RollingSampleBuffer.java   
/**
 * Appends data to the rolling buffer.
 *
 * @param dataSource The source from which to read.
 * @param length The maximum length of the read.
 * @param allowEndOfInput True if encountering the end of the input having appended no data is
 *     allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
 *     should be considered an error, causing an {@link EOFException} to be thrown.
 * @return The number of bytes appended, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
 * @throws IOException If an error occurs reading from the source.
 */
public int appendData(DataSource dataSource, int length, boolean allowEndOfInput)
    throws IOException {
  length = prepareForAppend(length);
  int bytesAppended = dataSource.read(lastAllocation.data,
      lastAllocation.translateOffset(lastAllocationOffset), length);
  if (bytesAppended == C.RESULT_END_OF_INPUT) {
    if (allowEndOfInput) {
      return C.RESULT_END_OF_INPUT;
    }
    throw new EOFException();
  }
  lastAllocationOffset += bytesAppended;
  totalBytesWritten += bytesAppended;
  return bytesAppended;
}
项目:luxunPro    文件:OkHttpDataSource.java   
/**
 * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at
 * index {@code offset}.
 * <p>
 * This method blocks until at least one byte of data can be read, the end of the opened range is
 * detected, or an exception is thrown.
 *
 * @param buffer The buffer into which the read data should be stored.
 * @param offset The start offset into {@code buffer} at which data should be written.
 * @param readLength The maximum number of bytes to read.
 * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the end of the opened
 *     range is reached.
 * @throws IOException If an error occurs reading from the source.
 */
private int readInternal(byte[] buffer, int offset, int readLength) throws IOException {
    readLength = bytesToRead == C.LENGTH_UNBOUNDED ? readLength
            : (int) Math.min(readLength, bytesToRead - bytesRead);
    if (readLength == 0) {
        // We've read all of the requested data.
        return C.RESULT_END_OF_INPUT;
    }

    int read = responseByteStream.read(buffer, offset, readLength);
    if (read == -1) {
        if (bytesToRead != C.LENGTH_UNBOUNDED && bytesToRead != bytesRead) {
            // The server closed the connection having not sent sufficient data.
            throw new EOFException();
        }
        return C.RESULT_END_OF_INPUT;
    }

    bytesRead += read;
    if (listener != null) {
        listener.onBytesTransferred(read);
    }
    return read;
}
项目:ExoCacheDataSource    文件:OkHttpDataSource.java   
/**
 * Establishes a connection.
 */
private Request makeRequest(DataSpec dataSpec) {
    long position = dataSpec.position;
    long length = dataSpec.length;
    boolean allowGzip = (dataSpec.flags & DataSpec.FLAG_ALLOW_GZIP) != 0;

    HttpUrl url = HttpUrl.parse(dataSpec.uri.toString());
    Request.Builder builder = new Request.Builder().url(url);
    if (cacheControl != null) {
        builder.cacheControl(cacheControl);
    }
    synchronized (requestProperties) {
        for (Map.Entry<String, String> property : requestProperties.entrySet()) {
            builder.addHeader(property.getKey(), property.getValue());
        }
    }
    if (!(position == 0 && length == C.LENGTH_UNBOUNDED)) {
        String rangeRequest = "bytes=" + position + "-";
        if (length != C.LENGTH_UNBOUNDED) {
            rangeRequest += (position + length - 1);
        }
        builder.addHeader("Range", rangeRequest);
    }
    builder.addHeader("User-Agent", userAgent);
    if (!allowGzip) {
        builder.addHeader("Accept-Encoding", "identity");
    }
    if (dataSpec.postBody != null) {
        builder.post(RequestBody.create(null, dataSpec.postBody));
    }
    return builder.build();
}
项目:ExoPlayer-Demo    文件:WebmExtractorTest.java   
private void assertSample(int index, byte[] expectedMedia, long timeUs, boolean keyframe,
    boolean invisible, byte[] encryptionKey, FakeTrackOutput output) {
  if (encryptionKey != null) {
    expectedMedia = TestUtil.joinByteArrays(
        new byte[] {(byte) StreamBuilder.TEST_INITIALIZATION_VECTOR.length},
        StreamBuilder.TEST_INITIALIZATION_VECTOR, expectedMedia);
  }
  int flags = 0;
  flags |= keyframe ? C.SAMPLE_FLAG_SYNC : 0;
  flags |= invisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
  flags |= encryptionKey != null ? C.SAMPLE_FLAG_ENCRYPTED : 0;
  output.assertSample(index, expectedMedia, timeUs, flags, encryptionKey);
}
项目:miku    文件:HlsChunkSource.java   
private MediaPlaylistChunk newMediaPlaylistChunk(int variantIndex) {
  Uri mediaPlaylistUri = UriUtil.resolveToUri(baseUri, variants[variantIndex].url);
  DataSpec dataSpec = new DataSpec(mediaPlaylistUri, 0, C.LENGTH_UNBOUNDED, null,
      DataSpec.FLAG_ALLOW_GZIP);
  return new MediaPlaylistChunk(dataSource, dataSpec, scratchSpace, playlistParser, variantIndex,
      mediaPlaylistUri.toString());
}
项目:miku    文件:RollingSampleBuffer.java   
/**
 * Attempts to locate the keyframe before the specified time, if it's present in the buffer.
 *
 * @param timeUs The seek time.
 * @return The offset of the keyframe's data if the keyframe was present. -1 otherwise.
 */
public synchronized long skipToKeyframeBefore(long timeUs) {
  if (queueSize == 0 || timeUs < timesUs[relativeReadIndex]) {
    return -1;
  }

  int lastWriteIndex = (relativeWriteIndex == 0 ? capacity : relativeWriteIndex) - 1;
  long lastTimeUs = timesUs[lastWriteIndex];
  if (timeUs > lastTimeUs) {
    return -1;
  }

  // TODO: This can be optimized further using binary search, although the fact that the array
  // is cyclic means we'd need to implement the binary search ourselves.
  int sampleCount = 0;
  int sampleCountToKeyframe = -1;
  int searchIndex = relativeReadIndex;
  while (searchIndex != relativeWriteIndex) {
    if (timesUs[searchIndex] > timeUs) {
      // We've gone too far.
      break;
    } else if ((flags[searchIndex] & C.SAMPLE_FLAG_SYNC) != 0) {
      // We've found a keyframe, and we're still before the seek position.
      sampleCountToKeyframe = sampleCount;
    }
    searchIndex = (searchIndex + 1) % capacity;
    sampleCount++;
  }

  if (sampleCountToKeyframe == -1) {
    return -1;
  }

  queueSize -= sampleCountToKeyframe;
  relativeReadIndex = (relativeReadIndex + sampleCountToKeyframe) % capacity;
  absoluteReadIndex += sampleCountToKeyframe;
  return offsets[relativeReadIndex];
}
项目:ExoPlayer-Demo    文件:Util.java   
/**
 * Converts a sample bit depth to a corresponding PCM encoding constant.
 *
 * @param bitDepth The bit depth. Supported values are 8, 16, 24 and 32.
 * @return The corresponding encoding. One of {@link C#ENCODING_PCM_8BIT},
 *     {@link C#ENCODING_PCM_16BIT}, {@link C#ENCODING_PCM_24BIT} and
 *     {@link C#ENCODING_PCM_32BIT}. If the bit depth is unsupported then
 *     {@link C#ENCODING_INVALID} is returned.
 */
public static int getPcmEncoding(int bitDepth) {
  switch (bitDepth) {
    case 8:
      return C.ENCODING_PCM_8BIT;
    case 16:
      return C.ENCODING_PCM_16BIT;
    case 24:
      return C.ENCODING_PCM_24BIT;
    case 32:
      return C.ENCODING_PCM_32BIT;
    default:
      return C.ENCODING_INVALID;
  }
}
项目:miku    文件:ExtractorSampleSource.java   
@Override
public void load() throws IOException, InterruptedException {
  int result = Extractor.RESULT_CONTINUE;
  while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
    ExtractorInput input = null;
    try {
      long position = positionHolder.position;
      long length = dataSource.open(new DataSpec(uri, position, C.LENGTH_UNBOUNDED, null));
      if (length != C.LENGTH_UNBOUNDED) {
        length += position;
      }
      input = new DefaultExtractorInput(dataSource, position, length);
      Extractor extractor = extractorHolder.selectExtractor(input);
      if (pendingExtractorSeek) {
        extractor.seek();
        pendingExtractorSeek = false;
      }
      while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
        allocator.blockWhileTotalBytesAllocatedExceeds(requestedBufferSize);
        result = extractor.read(input, positionHolder);
        // TODO: Implement throttling to stop us from buffering data too often.
      }
    } finally {
      if (result == Extractor.RESULT_SEEK) {
        result = Extractor.RESULT_CONTINUE;
      } else if (input != null) {
        positionHolder.position = input.getPosition();
      }
      dataSource.close();
    }
  }
}
项目:ExoPlayer-Demo    文件:DefaultExtractorInputTest.java   
public void testSkipFullyWithFailingDataSource() throws IOException, InterruptedException {
  FakeDataSource testDataSource = buildFailingDataSource();
  DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
  try {
    input.skipFully(TEST_DATA.length);
    fail();
  } catch (IOException e) {
    // Expected.
  }
  // The position should not have advanced.
  assertEquals(0, input.getPosition());
}
项目:miku    文件:MpegAudioReader.java   
/**
 * Attempts to read the remainder of the frame.
 * <p>
 * If a frame is read in full then true is returned. The frame will have been output, and the
 * position of the source will have been advanced to the byte that immediately follows the end of
 * the frame.
 * <p>
 * If a frame is not read in full then the position of the source will have been advanced to the
 * limit, and the method should be called again with the next source to continue the read.
 *
 * @param source The source from which to read.
 */
private void readFrameRemainder(ParsableByteArray source) {
  int bytesToRead = Math.min(source.bytesLeft(), frameSize - frameBytesRead);
  output.sampleData(source, bytesToRead);
  frameBytesRead += bytesToRead;
  if (frameBytesRead < frameSize) {
    // We haven't read the whole of the frame yet.
    return;
  }

  output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, frameSize, 0, null);
  timeUs += frameDurationUs;
  frameBytesRead = 0;
  state = STATE_FINDING_HEADER;
}
项目:ExoPlayer-Demo    文件:DtsReader.java   
@Override
public void consume(ParsableByteArray data) {
  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_SYNC:
        if (skipToNextSync(data)) {
          bytesRead = SYNC_VALUE_SIZE;
          state = STATE_READING_HEADER;
        }
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, headerScratchBytes.data, HEADER_SIZE)) {
          parseHeader();
          headerScratchBytes.setPosition(0);
          output.sampleData(headerScratchBytes, HEADER_SIZE);
          state = STATE_READING_SAMPLE;
        }
        break;
      case STATE_READING_SAMPLE:
        int bytesToRead = Math.min(data.bytesLeft(), sampleSize - bytesRead);
        output.sampleData(data, bytesToRead);
        bytesRead += bytesToRead;
        if (bytesRead == sampleSize) {
          output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
          timeUs += sampleDurationUs;
          state = STATE_FINDING_SYNC;
        }
        break;
    }
  }
}
项目:ExoPlayer-Demo    文件:FakeDataSource.java   
@Override
public long open(DataSpec dataSpec) throws IOException {
  Assertions.checkState(!opened);
  // DataSpec requires a matching close call even if open fails.
  opened = true;
  // If the source knows that the request is unsatisfiable then fail.
  if (dataSpec.position >= totalLength) {
    throw new IOException("Unsatisfiable position");
  } else if (dataSpec.length != C.LENGTH_UNBOUNDED
      && dataSpec.position + dataSpec.length >= totalLength) {
    throw new IOException("Unsatisfiable range");
  }
  // Scan through the segments, configuring them for the current read.
  boolean findingCurrentSegmentIndex = true;
  currentSegmentIndex = 0;
  int scannedLength = 0;
  for (Segment segment : segments) {
    segment.bytesRead =
        (int) Math.min(Math.max(0, dataSpec.position - scannedLength), segment.length);
    scannedLength += segment.length;
    findingCurrentSegmentIndex &= segment.isErrorSegment() ? segment.exceptionCleared
        : segment.bytesRead == segment.length;
    if (findingCurrentSegmentIndex) {
      currentSegmentIndex++;
    }
  }
  // Configure bytesRemaining, and return.
  if (dataSpec.length == C.LENGTH_UNBOUNDED) {
    bytesRemaining = totalLength - dataSpec.position;
    return simulateUnknownLength ? C.LENGTH_UNBOUNDED : bytesRemaining;
  } else {
    bytesRemaining = dataSpec.length;
    return bytesRemaining;
  }
}
项目:ExoPlayer-Demo    文件:VarintReader.java   
/**
 * Reads an EBML variable-length integer (varint) from an {@link ExtractorInput} such that
 * reading can be resumed later if an error occurs having read only some of it.
 * <p>
 * If an value is successfully read, then the reader will automatically reset itself ready to
 * read another value.
 * <p>
 * If an {@link IOException} or {@link InterruptedException} is throw, the read can be resumed
 * later by calling this method again, passing an {@link ExtractorInput} providing data starting
 * where the previous one left off.
 *
 * @param input The {@link ExtractorInput} from which the integer should be read.
 * @param allowEndOfInput True if encountering the end of the input having read no data is
 *     allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
 *     should be considered an error, causing an {@link EOFException} to be thrown.
 * @param removeLengthMask Removes the variable-length integer length mask from the value.
 * @param maximumAllowedLength Maximum allowed length of the variable integer to be read.
 * @return The read value, or {@link C#RESULT_END_OF_INPUT} if {@code allowEndOfStream} is true
 *     and the end of the input was encountered, or {@link C#RESULT_MAX_LENGTH_EXCEEDED} if the
 *     length of the varint exceeded maximumAllowedLength.
 * @throws IOException If an error occurs reading from the input.
 * @throws InterruptedException If the thread is interrupted.
 */
public long readUnsignedVarint(ExtractorInput input, boolean allowEndOfInput,
    boolean removeLengthMask, int maximumAllowedLength) throws IOException, InterruptedException {
  if (state == STATE_BEGIN_READING) {
    // Read the first byte to establish the length.
    if (!input.readFully(scratch, 0, 1, allowEndOfInput)) {
      return C.RESULT_END_OF_INPUT;
    }
    int firstByte = scratch[0] & 0xFF;
    length = parseUnsignedVarintLength(firstByte);
    if (length == -1) {
      throw new IllegalStateException("No valid varint length mask found");
    }
    state = STATE_READ_CONTENTS;
  }

  if (length > maximumAllowedLength) {
    state = STATE_BEGIN_READING;
    return C.RESULT_MAX_LENGTH_EXCEEDED;
  }

  if (length != 1) {
    // Read the remaining bytes.
    input.readFully(scratch, 1, length - 1);
  }

  state = STATE_BEGIN_READING;
  return assembleVarint(scratch, length, removeLengthMask);
}
项目:ExoPlayer-Demo    文件:ContentDataSource.java   
@Override
public long open(DataSpec dataSpec) throws ContentDataSourceException {
  try {
    uriString = dataSpec.uri.toString();
    AssetFileDescriptor assetFd = resolver.openAssetFileDescriptor(dataSpec.uri, "r");
    inputStream = new FileInputStream(assetFd.getFileDescriptor());
    long skipped = inputStream.skip(dataSpec.position);
    if (skipped < dataSpec.position) {
      // We expect the skip to be satisfied in full. If it isn't then we're probably trying to
      // skip beyond the end of the data.
      throw new EOFException();
    }
    if (dataSpec.length != C.LENGTH_UNBOUNDED) {
      bytesRemaining = dataSpec.length;
    } else {
      bytesRemaining = inputStream.available();
      if (bytesRemaining == 0) {
        // FileInputStream.available() returns 0 if the remaining length cannot be determined, or
        // if it's greater than Integer.MAX_VALUE. We don't know the true length in either case,
        // so treat as unbounded.
        bytesRemaining = C.LENGTH_UNBOUNDED;
      }
    }
  } catch (IOException e) {
    throw new ContentDataSourceException(e);
  }

  opened = true;
  if (listener != null) {
    listener.onTransferStart();
  }

  return bytesRemaining;
}
项目:miku    文件:TrackSampleTable.java   
/**
 * Returns the sample index of the closest synchronization sample at or before the given
 * timestamp, if one is available.
 *
 * @param timeUs Timestamp adjacent to which to find a synchronization sample.
 * @return Index of the synchronization sample, or {@link #NO_SAMPLE} if none.
 */
public int getIndexOfEarlierOrEqualSynchronizationSample(long timeUs) {
  int startIndex = Util.binarySearchFloor(timestampsUs, timeUs, true, false);
  for (int i = startIndex; i >= 0; i--) {
    if (timestampsUs[i] <= timeUs && (flags[i] & C.SAMPLE_FLAG_SYNC) != 0) {
      return i;
    }
  }
  return NO_SAMPLE;
}
项目:miku    文件:AtomParsers.java   
/**
 * Parses a trak atom (defined in 14496-12).
 *
 * @param trak Atom to parse.
 * @param mvhd Movie header atom, used to get the timescale.
 * @return A {@link Track} instance, or {@code null} if the track's type isn't supported.
 */
public static Track parseTrak(Atom.ContainerAtom trak, Atom.LeafAtom mvhd) {
  Atom.ContainerAtom mdia = trak.getContainerAtomOfType(Atom.TYPE_mdia);
  int trackType = parseHdlr(mdia.getLeafAtomOfType(Atom.TYPE_hdlr).data);
  if (trackType != Track.TYPE_AUDIO && trackType != Track.TYPE_VIDEO
      && trackType != Track.TYPE_TEXT && trackType != Track.TYPE_SUBTITLE) {
    return null;
  }

  Pair<Integer, Long> header = parseTkhd(trak.getLeafAtomOfType(Atom.TYPE_tkhd).data);
  int id = header.first;
  long duration = header.second;
  long movieTimescale = parseMvhd(mvhd.data);
  long durationUs;
  if (duration == -1) {
    durationUs = C.UNKNOWN_TIME_US;
  } else {
    durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
  }
  Atom.ContainerAtom stbl = mdia.getContainerAtomOfType(Atom.TYPE_minf)
      .getContainerAtomOfType(Atom.TYPE_stbl);

  long mediaTimescale = parseMdhd(mdia.getLeafAtomOfType(Atom.TYPE_mdhd).data);
  StsdDataHolder stsdData = parseStsd(stbl.getLeafAtomOfType(Atom.TYPE_stsd).data, durationUs);
  return stsdData.mediaFormat == null ? null
      : new Track(id, trackType, mediaTimescale, durationUs, stsdData.mediaFormat,
          stsdData.trackEncryptionBoxes, stsdData.nalUnitLengthFieldLength);
}
项目:ExoPlayer-Demo    文件:SegmentBase.java   
/**
 * @see DashSegmentIndex#getTimeUs(int)
 */
public final long getSegmentTimeUs(int sequenceNumber) {
  long unscaledSegmentTime;
  if (segmentTimeline != null) {
    unscaledSegmentTime = segmentTimeline.get(sequenceNumber - startNumber).startTime
        - presentationTimeOffset;
  } else {
    unscaledSegmentTime = (sequenceNumber - startNumber) * duration;
  }
  return Util.scaleLargeTimestamp(unscaledSegmentTime, C.MICROS_PER_SECOND, timescale);
}
项目:ExoPlayer-Demo    文件:Mp3Extractor.java   
private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
  if (sampleBytesRemaining == 0) {
    if (!maybeResynchronize(extractorInput)) {
      return RESULT_END_OF_INPUT;
    }
    if (basisTimeUs == -1) {
      basisTimeUs = seeker.getTimeUs(extractorInput.getPosition());
      if (forcedFirstSampleTimestampUs != -1) {
        long embeddedFirstSampleTimestampUs = seeker.getTimeUs(0);
        basisTimeUs += forcedFirstSampleTimestampUs - embeddedFirstSampleTimestampUs;
      }
    }
    sampleBytesRemaining = synchronizedHeader.frameSize;
  }
  int bytesAppended = trackOutput.sampleData(extractorInput, sampleBytesRemaining, true);
  if (bytesAppended == C.RESULT_END_OF_INPUT) {
    return RESULT_END_OF_INPUT;
  }
  sampleBytesRemaining -= bytesAppended;
  if (sampleBytesRemaining > 0) {
    return RESULT_CONTINUE;
  }
  long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate);
  trackOutput.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, synchronizedHeader.frameSize, 0, null);
  samplesRead += synchronizedHeader.samplesPerFrame;
  sampleBytesRemaining = 0;
  return RESULT_CONTINUE;
}
项目:ExoPlayer-Demo    文件:VarintReaderTest.java   
public void testReadVarintExceedsMaximumAllowedLength() throws IOException, InterruptedException {
  VarintReader reader = new VarintReader();
  ExtractorInput input = new FakeExtractorInput.Builder()
      .setData(DATA_8_BYTE_0)
      .setSimulateUnknownLength(true)
      .build();
  long result = reader.readUnsignedVarint(input, false, true, 4);
  assertEquals(C.RESULT_MAX_LENGTH_EXCEEDED, result);
}
项目:miku    文件:XingSeeker.java   
@Override
public long getPosition(long timeUs) {
  float percent = timeUs * 100f / durationUs;
  float fx;
  if (percent <= 0f) {
    fx = 0f;
  } else if (percent >= 100f) {
    fx = 256f;
  } else {
    int a = (int) percent;
    float fa, fb;
    if (a == 0) {
      fa = 0f;
    } else {
      fa = tableOfContents[a - 1];
    }
    if (a < 99) {
      fb = tableOfContents[a];
    } else {
      fb = 256f;
    }
    fx = fa + (fb - fa) * (percent - a);
  }

  long position = (long) ((1f / 256) * fx * sizeBytes) + firstFramePosition;
  return inputLength != C.LENGTH_UNBOUNDED ? Math.min(position, inputLength - 1) : position;
}
项目:luxunPro    文件:OkHttpDataSource.java   
/**
 * Establishes a connection.
 */
private Request makeRequest(DataSpec dataSpec) {
    long position = dataSpec.position;
    long length = dataSpec.length;
    boolean allowGzip = (dataSpec.flags & DataSpec.FLAG_ALLOW_GZIP) != 0;

    HttpUrl url = HttpUrl.parse(dataSpec.uri.toString());
    Request.Builder builder = new Request.Builder().url(url);
    if (cacheControl != null) {
        builder.cacheControl(cacheControl);
    }
    synchronized (requestProperties) {
        for (Map.Entry<String, String> property : requestProperties.entrySet()) {
            builder.addHeader(property.getKey(), property.getValue());
        }
    }
    if (!(position == 0 && length == C.LENGTH_UNBOUNDED)) {
        String rangeRequest = "bytes=" + position + "-";
        if (length != C.LENGTH_UNBOUNDED) {
            rangeRequest += (position + length - 1);
        }
        builder.addHeader("Range", rangeRequest);
    }
    builder.addHeader("User-Agent", userAgent);
    if (!allowGzip) {
        builder.addHeader("Accept-Encoding", "identity");
    }
    if (dataSpec.postBody != null) {
        builder.post(RequestBody.create(null, dataSpec.postBody));
    }
    return builder.build();
}
项目:ExoPlayer-Demo    文件:XingSeeker.java   
@Override
public long getPosition(long timeUs) {
  if (!isSeekable()) {
    return firstFramePosition;
  }
  float percent = timeUs * 100f / durationUs;
  float fx;
  if (percent <= 0f) {
    fx = 0f;
  } else if (percent >= 100f) {
    fx = 256f;
  } else {
    int a = (int) percent;
    float fa, fb;
    if (a == 0) {
      fa = 0f;
    } else {
      fa = tableOfContents[a - 1];
    }
    if (a < 99) {
      fb = tableOfContents[a];
    } else {
      fb = 256f;
    }
    fx = fa + (fb - fa) * (percent - a);
  }

  long position = Math.round((1.0 / 256) * fx * sizeBytes) + firstFramePosition;
  long maximumPosition = inputLength != C.LENGTH_UNBOUNDED ? inputLength - 1
      : firstFramePosition - headerSize + sizeBytes - 1;
  return Math.min(position, maximumPosition);
}
项目:ExoPlayer-Demo    文件:Util.java   
/**
 * Given a {@link DataSpec} and a number of bytes already loaded, returns a {@link DataSpec}
 * that represents the remainder of the data.
 *
 * @param dataSpec The original {@link DataSpec}.
 * @param bytesLoaded The number of bytes already loaded.
 * @return A {@link DataSpec} that represents the remainder of the data.
 */
public static DataSpec getRemainderDataSpec(DataSpec dataSpec, int bytesLoaded) {
  if (bytesLoaded == 0) {
    return dataSpec;
  } else {
    long remainingLength = dataSpec.length == C.LENGTH_UNBOUNDED ? C.LENGTH_UNBOUNDED
        : dataSpec.length - bytesLoaded;
    return new DataSpec(dataSpec.uri, dataSpec.position + bytesLoaded, remainingLength,
        dataSpec.key, dataSpec.flags);
  }
}