Java Code Examples for com.google.android.exoplayer2.C#RESULT_FORMAT_READ

The following examples show how to use com.google.android.exoplayer2.C#RESULT_FORMAT_READ . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SilenceMediaSource.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
@Override
public int readData(
    FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) {
  if (!sentFormat || formatRequired) {
    formatHolder.format = FORMAT;
    sentFormat = true;
    return C.RESULT_FORMAT_READ;
  }

  long bytesRemaining = durationBytes - positionBytes;
  if (bytesRemaining == 0) {
    buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    return C.RESULT_BUFFER_READ;
  }

  int bytesToWrite = (int) Math.min(SILENCE_SAMPLE.length, bytesRemaining);
  buffer.ensureSpaceForWrite(bytesToWrite);
  buffer.data.put(SILENCE_SAMPLE, /* offset= */ 0, bytesToWrite);
  buffer.timeUs = getAudioPositionUs(positionBytes);
  buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
  positionBytes += bytesToWrite;
  return C.RESULT_BUFFER_READ;
}
 
Example 2
Source File: SilenceMediaSource.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Override
public int readData(
    FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) {
  if (!sentFormat || formatRequired) {
    formatHolder.format = FORMAT;
    sentFormat = true;
    return C.RESULT_FORMAT_READ;
  }

  long bytesRemaining = durationBytes - positionBytes;
  if (bytesRemaining == 0) {
    buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    return C.RESULT_BUFFER_READ;
  }

  int bytesToWrite = (int) Math.min(SILENCE_SAMPLE.length, bytesRemaining);
  buffer.ensureSpaceForWrite(bytesToWrite);
  buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
  buffer.data.put(SILENCE_SAMPLE, /* offset= */ 0, bytesToWrite);
  buffer.timeUs = getAudioPositionUs(positionBytes);
  positionBytes += bytesToWrite;
  return C.RESULT_BUFFER_READ;
}
 
Example 3
Source File: SingleSampleMediaPeriod.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean requireFormat) {
  if (streamState == STREAM_STATE_END_OF_STREAM) {
    buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    return C.RESULT_BUFFER_READ;
  } else if (requireFormat || streamState == STREAM_STATE_SEND_FORMAT) {
    formatHolder.format = format;
    streamState = STREAM_STATE_SEND_SAMPLE;
    return C.RESULT_FORMAT_READ;
  } else if (loadingFinished) {
    if (loadingSucceeded) {
      buffer.timeUs = 0;
      buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
      buffer.ensureSpaceForWrite(sampleSize);
      buffer.data.put(sampleData, 0, sampleSize);
      sendFormat();
    } else {
      buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    }
    streamState = STREAM_STATE_END_OF_STREAM;
    return C.RESULT_BUFFER_READ;
  }
  return C.RESULT_NOTHING_READ;
}
 
Example 4
Source File: SampleQueue.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempts to read from the queue.
 *
 * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
 * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
 *     end of the stream. If the end of the stream has been reached, the {@link
 *     C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. If a {@link
 *     DecoderInputBuffer#isFlagsOnly() flags-only} buffer is passed, only the buffer flags may be
 *     populated by this method and the read position of the queue will not change.
 * @param formatRequired Whether the caller requires that the format of the stream be read even if
 *     it's not changing. A sample will never be read if set to true, however it is still possible
 *     for the end of stream or nothing to be read.
 * @param loadingFinished True if an empty queue should be considered the end of the stream.
 * @param decodeOnlyUntilUs If a buffer is read, the {@link C#BUFFER_FLAG_DECODE_ONLY} flag will
 *     be set if the buffer's timestamp is less than this value.
 * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
 *     {@link C#RESULT_BUFFER_READ}.
 */
public int read(
    FormatHolder formatHolder,
    DecoderInputBuffer buffer,
    boolean formatRequired,
    boolean loadingFinished,
    long decodeOnlyUntilUs) {
  int result = metadataQueue.read(formatHolder, buffer, formatRequired, loadingFinished,
      downstreamFormat, extrasHolder);
  switch (result) {
    case C.RESULT_FORMAT_READ:
      downstreamFormat = formatHolder.format;
      return C.RESULT_FORMAT_READ;
    case C.RESULT_BUFFER_READ:
      if (!buffer.isEndOfStream()) {
        if (buffer.timeUs < decodeOnlyUntilUs) {
          buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
        }
        if (!buffer.isFlagsOnly()) {
          // Read encryption data if the sample is encrypted.
          if (buffer.isEncrypted()) {
            readEncryptionData(buffer, extrasHolder);
          }
          // Write the sample data into the holder.
          buffer.ensureSpaceForWrite(extrasHolder.size);
          readData(extrasHolder.offset, buffer.data, extrasHolder.size);
        }
      }
      return C.RESULT_BUFFER_READ;
    case C.RESULT_NOTHING_READ:
      return C.RESULT_NOTHING_READ;
    default:
      throw new IllegalStateException();
  }
}
 
Example 5
Source File: SoftVideoRenderer.java    From DanDanPlayForAndroid with MIT License 5 votes vote down vote up
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  if (outputStreamEnded) {
    return;
  }

  if (format == null) {
    // We don't have a format yet, so try and read one.
    flagsOnlyBuffer.clear();
    int result = readSource(formatHolder, flagsOnlyBuffer, true);
    if (result == C.RESULT_FORMAT_READ) {
      onInputFormatChanged(formatHolder.format);
    } else if (result == C.RESULT_BUFFER_READ) {
      // End of stream read having not read a format.
      Assertions.checkState(flagsOnlyBuffer.isEndOfStream());
      inputStreamEnded = true;
      outputStreamEnded = true;
      return;
    } else {
      // We still don't have a format and can't make progress without one.
      return;
    }
  }

  // If we don't have a videoDecoder yet, we need to instantiate one.
  maybeInitDecoder();

  if (videoDecoder != null) {
    try {
      // Rendering loop.
      TraceUtil.beginSection("drainAndFeed");
      while (drainOutputBuffer(positionUs)) {}
      while (feedInputBuffer()) {}
      TraceUtil.endSection();
    } catch (VideoSoftDecoderException e) {
      throw ExoPlaybackException.createForRenderer(e, getIndex());
    }
    decoderCounters.ensureUpdated();
  }
}
 
Example 6
Source File: EventSampleStream.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean formatRequired) {
  if (formatRequired || !isFormatSentDownstream) {
    formatHolder.format = upstreamFormat;
    isFormatSentDownstream = true;
    return C.RESULT_FORMAT_READ;
  }
  if (currentIndex == eventTimesUs.length) {
    if (!eventStreamUpdatable) {
      buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
      return C.RESULT_BUFFER_READ;
    } else {
      return C.RESULT_NOTHING_READ;
    }
  }
  int sampleIndex = currentIndex++;
  byte[] serializedEvent = eventMessageEncoder.encode(eventStream.events[sampleIndex],
      eventStream.timescale);
  if (serializedEvent != null) {
    buffer.ensureSpaceForWrite(serializedEvent.length);
    buffer.setFlags(C.BUFFER_FLAG_KEY_FRAME);
    buffer.data.put(serializedEvent);
    buffer.timeUs = eventTimesUs[sampleIndex];
    return C.RESULT_BUFFER_READ;
  } else {
    return C.RESULT_NOTHING_READ;
  }
}
 
Example 7
Source File: SampleMetadataQueue.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempts to read from the queue.
 *
 * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
 * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
 *     end of the stream. If a sample is read then the buffer is populated with information
 *     about the sample, but not its data. The size and absolute position of the data in the
 *     rolling buffer is stored in {@code extrasHolder}, along with an encryption id if present
 *     and the absolute position of the first byte that may still be required after the current
 *     sample has been read. May be null if the caller requires that the format of the stream be
 *     read even if it's not changing.
 * @param formatRequired Whether the caller requires that the format of the stream be read even
 *     if it's not changing. A sample will never be read if set to true, however it is still
 *     possible for the end of stream or nothing to be read.
 * @param loadingFinished True if an empty queue should be considered the end of the stream.
 * @param downstreamFormat The current downstream {@link Format}. If the format of the next
 *     sample is different to the current downstream format then a format will be read.
 * @param extrasHolder The holder into which extra sample information should be written.
 * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ}
 *     or {@link C#RESULT_BUFFER_READ}.
 */
@SuppressWarnings("ReferenceEquality")
public synchronized int read(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean formatRequired, boolean loadingFinished, Format downstreamFormat,
    SampleExtrasHolder extrasHolder) {
  if (!hasNextSample()) {
    if (loadingFinished) {
      buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
      return C.RESULT_BUFFER_READ;
    } else if (upstreamFormat != null
        && (formatRequired || upstreamFormat != downstreamFormat)) {
      formatHolder.format = upstreamFormat;
      return C.RESULT_FORMAT_READ;
    } else {
      return C.RESULT_NOTHING_READ;
    }
  }

  int relativeReadIndex = getRelativeIndex(readPosition);
  if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
    formatHolder.format = formats[relativeReadIndex];
    return C.RESULT_FORMAT_READ;
  }

  if (buffer.isFlagsOnly()) {
    return C.RESULT_NOTHING_READ;
  }

  buffer.timeUs = timesUs[relativeReadIndex];
  buffer.setFlags(flags[relativeReadIndex]);
  extrasHolder.size = sizes[relativeReadIndex];
  extrasHolder.offset = offsets[relativeReadIndex];
  extrasHolder.cryptoData = cryptoDatas[relativeReadIndex];

  readPosition++;
  return C.RESULT_BUFFER_READ;
}
 
Example 8
Source File: SampleQueue.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempts to read from the queue.
 *
 * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
 * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
 *     end of the stream. If the end of the stream has been reached, the
 *     {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
 * @param formatRequired Whether the caller requires that the format of the stream be read even if
 *     it's not changing. A sample will never be read if set to true, however it is still possible
 *     for the end of stream or nothing to be read.
 * @param loadingFinished True if an empty queue should be considered the end of the stream.
 * @param decodeOnlyUntilUs If a buffer is read, the {@link C#BUFFER_FLAG_DECODE_ONLY} flag will
 *     be set if the buffer's timestamp is less than this value.
 * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
 *     {@link C#RESULT_BUFFER_READ}.
 */
public int read(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired,
    boolean loadingFinished, long decodeOnlyUntilUs) {
  int result = metadataQueue.read(formatHolder, buffer, formatRequired, loadingFinished,
      downstreamFormat, extrasHolder);
  switch (result) {
    case C.RESULT_FORMAT_READ:
      downstreamFormat = formatHolder.format;
      return C.RESULT_FORMAT_READ;
    case C.RESULT_BUFFER_READ:
      if (!buffer.isEndOfStream()) {
        if (buffer.timeUs < decodeOnlyUntilUs) {
          buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
        }
        // Read encryption data if the sample is encrypted.
        if (buffer.isEncrypted()) {
          readEncryptionData(buffer, extrasHolder);
        }
        // Write the sample data into the holder.
        buffer.ensureSpaceForWrite(extrasHolder.size);
        readData(extrasHolder.offset, buffer.data, extrasHolder.size);
      }
      return C.RESULT_BUFFER_READ;
    case C.RESULT_NOTHING_READ:
      return C.RESULT_NOTHING_READ;
    default:
      throw new IllegalStateException();
  }
}
 
Example 9
Source File: SingleSampleMediaPeriod.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean requireFormat) {
  maybeNotifyDownstreamFormat();
  if (streamState == STREAM_STATE_END_OF_STREAM) {
    buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    return C.RESULT_BUFFER_READ;
  } else if (requireFormat || streamState == STREAM_STATE_SEND_FORMAT) {
    formatHolder.format = format;
    streamState = STREAM_STATE_SEND_SAMPLE;
    return C.RESULT_FORMAT_READ;
  } else if (loadingFinished) {
    if (loadingSucceeded) {
      buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
      buffer.timeUs = 0;
      if (buffer.isFlagsOnly()) {
        return C.RESULT_BUFFER_READ;
      }
      buffer.ensureSpaceForWrite(sampleSize);
      buffer.data.put(sampleData, 0, sampleSize);
    } else {
      buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    }
    streamState = STREAM_STATE_END_OF_STREAM;
    return C.RESULT_BUFFER_READ;
  }
  return C.RESULT_NOTHING_READ;
}
 
Example 10
Source File: MediaCodecRenderer.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/** Reads into {@link #flagsOnlyBuffer} and returns whether a {@link Format} was read. */
private boolean readToFlagsOnlyBuffer(boolean requireFormat) throws ExoPlaybackException {
  FormatHolder formatHolder = getFormatHolder();
  flagsOnlyBuffer.clear();
  int result = readSource(formatHolder, flagsOnlyBuffer, requireFormat);
  if (result == C.RESULT_FORMAT_READ) {
    onInputFormatChanged(formatHolder);
    return true;
  } else if (result == C.RESULT_BUFFER_READ && flagsOnlyBuffer.isEndOfStream()) {
    inputStreamEnded = true;
    processEndOfStream();
  }
  return false;
}
 
Example 11
Source File: SingleSampleMediaPeriod.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean requireFormat) {
  maybeNotifyDownstreamFormat();
  if (streamState == STREAM_STATE_END_OF_STREAM) {
    buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    return C.RESULT_BUFFER_READ;
  } else if (requireFormat || streamState == STREAM_STATE_SEND_FORMAT) {
    formatHolder.format = format;
    streamState = STREAM_STATE_SEND_SAMPLE;
    return C.RESULT_FORMAT_READ;
  } else if (loadingFinished) {
    if (sampleData != null) {
      buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
      buffer.timeUs = 0;
      if (buffer.isFlagsOnly()) {
        return C.RESULT_BUFFER_READ;
      }
      buffer.ensureSpaceForWrite(sampleSize);
      buffer.data.put(sampleData, 0, sampleSize);
    } else {
      buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
    }
    streamState = STREAM_STATE_END_OF_STREAM;
    return C.RESULT_BUFFER_READ;
  }
  return C.RESULT_NOTHING_READ;
}
 
Example 12
Source File: MetadataRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) {
    buffer.clear();
    int result = readSource(formatHolder, buffer, false);
    if (result == C.RESULT_BUFFER_READ) {
      if (buffer.isEndOfStream()) {
        inputStreamEnded = true;
      } else if (buffer.isDecodeOnly()) {
        // Do nothing. Note this assumes that all metadata buffers can be decoded independently.
        // If we ever need to support a metadata format where this is not the case, we'll need to
        // pass the buffer to the decoder and discard the output.
      } else {
        buffer.subsampleOffsetUs = subsampleOffsetUs;
        buffer.flip();
        Metadata metadata = decoder.decode(buffer);
        if (metadata != null) {
          List<Metadata.Entry> entries = new ArrayList<>(metadata.length());
          decodeWrappedMetadata(metadata, entries);
          if (!entries.isEmpty()) {
            Metadata expandedMetadata = new Metadata(entries);
            int index =
                (pendingMetadataIndex + pendingMetadataCount) % MAX_PENDING_METADATA_COUNT;
            pendingMetadata[index] = expandedMetadata;
            pendingMetadataTimestamps[index] = buffer.timeUs;
            pendingMetadataCount++;
          }
        }
      }
    } else if (result == C.RESULT_FORMAT_READ) {
      subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
    }
  }

  if (pendingMetadataCount > 0 && pendingMetadataTimestamps[pendingMetadataIndex] <= positionUs) {
    invokeRenderer(pendingMetadata[pendingMetadataIndex]);
    pendingMetadata[pendingMetadataIndex] = null;
    pendingMetadataIndex = (pendingMetadataIndex + 1) % MAX_PENDING_METADATA_COUNT;
    pendingMetadataCount--;
  }
}
 
Example 13
Source File: SimpleDecoderVideoRenderer.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
private boolean feedInputBuffer() throws VideoDecoderException, ExoPlaybackException {
  if (decoder == null
      || decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM
      || inputStreamEnded) {
    // We need to reinitialize the decoder or the input stream has ended.
    return false;
  }

  if (inputBuffer == null) {
    inputBuffer = decoder.dequeueInputBuffer();
    if (inputBuffer == null) {
      return false;
    }
  }

  if (decoderReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
    inputBuffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    decoderReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
    return false;
  }

  int result;
  FormatHolder formatHolder = getFormatHolder();
  if (waitingForKeys) {
    // We've already read an encrypted sample into buffer, and are waiting for keys.
    result = C.RESULT_BUFFER_READ;
  } else {
    result = readSource(formatHolder, inputBuffer, false);
  }

  if (result == C.RESULT_NOTHING_READ) {
    return false;
  }
  if (result == C.RESULT_FORMAT_READ) {
    onInputFormatChanged(formatHolder);
    return true;
  }
  if (inputBuffer.isEndOfStream()) {
    inputStreamEnded = true;
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    return false;
  }
  boolean bufferEncrypted = inputBuffer.isEncrypted();
  waitingForKeys = shouldWaitForKeys(bufferEncrypted);
  if (waitingForKeys) {
    return false;
  }
  if (waitingForFirstSampleInFormat) {
    formatQueue.add(inputBuffer.timeUs, inputFormat);
    waitingForFirstSampleInFormat = false;
  }
  inputBuffer.flip();
  inputBuffer.colorInfo = inputFormat.colorInfo;
  onQueueInputBuffer(inputBuffer);
  decoder.queueInputBuffer(inputBuffer);
  buffersInCodecCount++;
  decoderReceivedBuffers = true;
  decoderCounters.inputBufferCount++;
  inputBuffer = null;
  return true;
}
 
Example 14
Source File: MetadataRenderer.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) {
    buffer.clear();
    int result = readSource(formatHolder, buffer, false);
    if (result == C.RESULT_BUFFER_READ) {
      if (buffer.isEndOfStream()) {
        inputStreamEnded = true;
      } else if (buffer.isDecodeOnly()) {
        // Do nothing. Note this assumes that all metadata buffers can be decoded independently.
        // If we ever need to support a metadata format where this is not the case, we'll need to
        // pass the buffer to the decoder and discard the output.
      } else {
        buffer.subsampleOffsetUs = subsampleOffsetUs;
        buffer.flip();
        Metadata metadata = decoder.decode(buffer);
        if (metadata != null) {
          List<Metadata.Entry> entries = new ArrayList<>(metadata.length());
          decodeWrappedMetadata(metadata, entries);
          if (!entries.isEmpty()) {
            Metadata expandedMetadata = new Metadata(entries);
            int index =
                (pendingMetadataIndex + pendingMetadataCount) % MAX_PENDING_METADATA_COUNT;
            pendingMetadata[index] = expandedMetadata;
            pendingMetadataTimestamps[index] = buffer.timeUs;
            pendingMetadataCount++;
          }
        }
      }
    } else if (result == C.RESULT_FORMAT_READ) {
      subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
    }
  }

  if (pendingMetadataCount > 0 && pendingMetadataTimestamps[pendingMetadataIndex] <= positionUs) {
    invokeRenderer(pendingMetadata[pendingMetadataIndex]);
    pendingMetadata[pendingMetadataIndex] = null;
    pendingMetadataIndex = (pendingMetadataIndex + 1) % MAX_PENDING_METADATA_COUNT;
    pendingMetadataCount--;
  }
}
 
Example 15
Source File: SimpleDecoderAudioRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
private boolean feedInputBuffer() throws AudioDecoderException, ExoPlaybackException {
  if (decoder == null || decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM
      || inputStreamEnded) {
    // We need to reinitialize the decoder or the input stream has ended.
    return false;
  }

  if (inputBuffer == null) {
    inputBuffer = decoder.dequeueInputBuffer();
    if (inputBuffer == null) {
      return false;
    }
  }

  if (decoderReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
    inputBuffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    decoderReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
    return false;
  }

  int result;
  if (waitingForKeys) {
    // We've already read an encrypted sample into buffer, and are waiting for keys.
    result = C.RESULT_BUFFER_READ;
  } else {
    result = readSource(formatHolder, inputBuffer, false);
  }

  if (result == C.RESULT_NOTHING_READ) {
    return false;
  }
  if (result == C.RESULT_FORMAT_READ) {
    onInputFormatChanged(formatHolder.format);
    return true;
  }
  if (inputBuffer.isEndOfStream()) {
    inputStreamEnded = true;
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    return false;
  }
  boolean bufferEncrypted = inputBuffer.isEncrypted();
  waitingForKeys = shouldWaitForKeys(bufferEncrypted);
  if (waitingForKeys) {
    return false;
  }
  inputBuffer.flip();
  onQueueInputBuffer(inputBuffer);
  decoder.queueInputBuffer(inputBuffer);
  decoderReceivedBuffers = true;
  decoderCounters.inputBufferCount++;
  inputBuffer = null;
  return true;
}
 
Example 16
Source File: SimpleDecoderVideoRenderer.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  if (outputStreamEnded) {
    return;
  }

  if (inputFormat == null) {
    // We don't have a format yet, so try and read one.
    FormatHolder formatHolder = getFormatHolder();
    flagsOnlyBuffer.clear();
    int result = readSource(formatHolder, flagsOnlyBuffer, true);
    if (result == C.RESULT_FORMAT_READ) {
      onInputFormatChanged(formatHolder);
    } else if (result == C.RESULT_BUFFER_READ) {
      // End of stream read having not read a format.
      Assertions.checkState(flagsOnlyBuffer.isEndOfStream());
      inputStreamEnded = true;
      outputStreamEnded = true;
      return;
    } else {
      // We still don't have a format and can't make progress without one.
      return;
    }
  }

  // If we don't have a decoder yet, we need to instantiate one.
  maybeInitDecoder();

  if (decoder != null) {
    try {
      // Rendering loop.
      TraceUtil.beginSection("drainAndFeed");
      while (drainOutputBuffer(positionUs, elapsedRealtimeUs)) {}
      while (feedInputBuffer()) {}
      TraceUtil.endSection();
    } catch (VideoDecoderException e) {
      throw createRendererException(e, inputFormat);
    }
    decoderCounters.ensureUpdated();
  }
}
 
Example 17
Source File: SimpleDecoderAudioRenderer.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
private boolean feedInputBuffer() throws AudioDecoderException, ExoPlaybackException {
  if (decoder == null || decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM
      || inputStreamEnded) {
    // We need to reinitialize the decoder or the input stream has ended.
    return false;
  }

  if (inputBuffer == null) {
    inputBuffer = decoder.dequeueInputBuffer();
    if (inputBuffer == null) {
      return false;
    }
  }

  if (decoderReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
    inputBuffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    decoderReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
    return false;
  }

  int result;
  FormatHolder formatHolder = getFormatHolder();
  if (waitingForKeys) {
    // We've already read an encrypted sample into buffer, and are waiting for keys.
    result = C.RESULT_BUFFER_READ;
  } else {
    result = readSource(formatHolder, inputBuffer, false);
  }

  if (result == C.RESULT_NOTHING_READ) {
    return false;
  }
  if (result == C.RESULT_FORMAT_READ) {
    onInputFormatChanged(formatHolder);
    return true;
  }
  if (inputBuffer.isEndOfStream()) {
    inputStreamEnded = true;
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    return false;
  }
  boolean bufferEncrypted = inputBuffer.isEncrypted();
  waitingForKeys = shouldWaitForKeys(bufferEncrypted);
  if (waitingForKeys) {
    return false;
  }
  inputBuffer.flip();
  onQueueInputBuffer(inputBuffer);
  decoder.queueInputBuffer(inputBuffer);
  decoderReceivedBuffers = true;
  decoderCounters.inputBufferCount++;
  inputBuffer = null;
  return true;
}
 
Example 18
Source File: SimpleDecoderAudioRenderer.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
private boolean feedInputBuffer() throws AudioDecoderException, ExoPlaybackException {
  if (decoder == null || decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM
      || inputStreamEnded) {
    // We need to reinitialize the decoder or the input stream has ended.
    return false;
  }

  if (inputBuffer == null) {
    inputBuffer = decoder.dequeueInputBuffer();
    if (inputBuffer == null) {
      return false;
    }
  }

  if (decoderReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
    inputBuffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    decoderReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
    return false;
  }

  int result;
  if (waitingForKeys) {
    // We've already read an encrypted sample into buffer, and are waiting for keys.
    result = C.RESULT_BUFFER_READ;
  } else {
    result = readSource(formatHolder, inputBuffer, false);
  }

  if (result == C.RESULT_NOTHING_READ) {
    return false;
  }
  if (result == C.RESULT_FORMAT_READ) {
    onInputFormatChanged(formatHolder.format);
    return true;
  }
  if (inputBuffer.isEndOfStream()) {
    inputStreamEnded = true;
    decoder.queueInputBuffer(inputBuffer);
    inputBuffer = null;
    return false;
  }
  boolean bufferEncrypted = inputBuffer.isEncrypted();
  waitingForKeys = shouldWaitForKeys(bufferEncrypted);
  if (waitingForKeys) {
    return false;
  }
  inputBuffer.flip();
  onQueueInputBuffer(inputBuffer);
  decoder.queueInputBuffer(inputBuffer);
  decoderReceivedBuffers = true;
  decoderCounters.inputBufferCount++;
  inputBuffer = null;
  return true;
}
 
Example 19
Source File: DefaultTrackOutput.java    From K-Sonic with MIT License 4 votes vote down vote up
/**
 * Attempts to read from the queue.
 *
 * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
 * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
 *     end of the stream. If a sample is read then the buffer is populated with information
 *     about the sample, but not its data. The size and absolute position of the data in the
 *     rolling buffer is stored in {@code extrasHolder}, along with an encryption id if present
 *     and the absolute position of the first byte that may still be required after the current
 *     sample has been read. May be null if the caller requires that the format of the stream be
 *     read even if it's not changing.
 * @param formatRequired Whether the caller requires that the format of the stream be read even
 *     if it's not changing. A sample will never be read if set to true, however it is still
 *     possible for the end of stream or nothing to be read.
 * @param loadingFinished True if an empty queue should be considered the end of the stream.
 * @param downstreamFormat The current downstream {@link Format}. If the format of the next
 *     sample is different to the current downstream format then a format will be read.
 * @param extrasHolder The holder into which extra sample information should be written.
 * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ}
 *     or {@link C#RESULT_BUFFER_READ}.
 */
@SuppressWarnings("ReferenceEquality")
public synchronized int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
    boolean formatRequired, boolean loadingFinished, Format downstreamFormat,
    BufferExtrasHolder extrasHolder) {
  if (queueSize == 0) {
    if (loadingFinished) {
      buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
      return C.RESULT_BUFFER_READ;
    } else if (upstreamFormat != null
        && (formatRequired || upstreamFormat != downstreamFormat)) {
      formatHolder.format = upstreamFormat;
      return C.RESULT_FORMAT_READ;
    } else {
      return C.RESULT_NOTHING_READ;
    }
  }

  if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
    formatHolder.format = formats[relativeReadIndex];
    return C.RESULT_FORMAT_READ;
  }

  buffer.timeUs = timesUs[relativeReadIndex];
  buffer.setFlags(flags[relativeReadIndex]);
  extrasHolder.size = sizes[relativeReadIndex];
  extrasHolder.offset = offsets[relativeReadIndex];
  extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex];

  largestDequeuedTimestampUs = Math.max(largestDequeuedTimestampUs, buffer.timeUs);
  queueSize--;
  relativeReadIndex++;
  absoluteReadIndex++;
  if (relativeReadIndex == capacity) {
    // Wrap around.
    relativeReadIndex = 0;
  }

  extrasHolder.nextOffset = queueSize > 0 ? offsets[relativeReadIndex]
      : extrasHolder.offset + extrasHolder.size;
  return C.RESULT_BUFFER_READ;
}
 
Example 20
Source File: SampleMetadataQueue.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Attempts to read from the queue.
 *
 * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
 * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
 *     end of the stream. If a sample is read then the buffer is populated with information about
 *     the sample, but not its data. The size and absolute position of the data in the rolling
 *     buffer is stored in {@code extrasHolder}, along with an encryption id if present and the
 *     absolute position of the first byte that may still be required after the current sample has
 *     been read. If a {@link DecoderInputBuffer#isFlagsOnly() flags-only} buffer is passed, only
 *     the buffer flags may be populated by this method and the read position of the queue will
 *     not change. May be null if the caller requires that the format of the stream be read even
 *     if it's not changing.
 * @param formatRequired Whether the caller requires that the format of the stream be read even if
 *     it's not changing. A sample will never be read if set to true, however it is still possible
 *     for the end of stream or nothing to be read.
 * @param loadingFinished True if an empty queue should be considered the end of the stream.
 * @param downstreamFormat The current downstream {@link Format}. If the format of the next sample
 *     is different to the current downstream format then a format will be read.
 * @param extrasHolder The holder into which extra sample information should be written.
 * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
 *     {@link C#RESULT_BUFFER_READ}.
 */
@SuppressWarnings("ReferenceEquality")
public synchronized int read(
    FormatHolder formatHolder,
    DecoderInputBuffer buffer,
    boolean formatRequired,
    boolean loadingFinished,
    Format downstreamFormat,
    SampleExtrasHolder extrasHolder) {
  if (!hasNextSample()) {
    if (loadingFinished || isLastSampleQueued) {
      buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
      return C.RESULT_BUFFER_READ;
    } else if (upstreamFormat != null
        && (formatRequired || upstreamFormat != downstreamFormat)) {
      formatHolder.format = upstreamFormat;
      return C.RESULT_FORMAT_READ;
    } else {
      return C.RESULT_NOTHING_READ;
    }
  }

  int relativeReadIndex = getRelativeIndex(readPosition);
  if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
    formatHolder.format = formats[relativeReadIndex];
    return C.RESULT_FORMAT_READ;
  }

  buffer.setFlags(flags[relativeReadIndex]);
  buffer.timeUs = timesUs[relativeReadIndex];
  if (buffer.isFlagsOnly()) {
    return C.RESULT_BUFFER_READ;
  }

  extrasHolder.size = sizes[relativeReadIndex];
  extrasHolder.offset = offsets[relativeReadIndex];
  extrasHolder.cryptoData = cryptoDatas[relativeReadIndex];

  readPosition++;
  return C.RESULT_BUFFER_READ;
}