/**
   * Write a media sample to the decoder.
   *
   * <p>A "sample" here refers to a single atomic access unit in the media stream. The definition of
   * "access unit" is dependent on the type of encoding used, but it typically refers to a single
   * frame of video or a few seconds of audio. {@link android.media.MediaExtractor} extracts data
   * from a stream one sample at a time.
   *
   * @param extractor Instance of {@link android.media.MediaExtractor} wrapping the media.
   * @param presentationTimeUs The time, relative to the beginning of the media stream, at which
   *     this buffer should be rendered.
   * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int, int,
   *     int, long, int)}
   * @throws MediaCodec.CryptoException
   */
  public boolean writeSample(
      final MediaExtractor extractor,
      final boolean isSecure,
      final long presentationTimeUs,
      int flags) {
    boolean result = false;
    boolean isEos = false;

    if (!mAvailableInputBuffers.isEmpty()) {
      int index = mAvailableInputBuffers.remove();
      ByteBuffer buffer = mInputBuffers[index];

      // reads the sample from the file using extractor into the buffer
      int size = extractor.readSampleData(buffer, 0);
      if (size <= 0) {
        flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
      }

      // Submit the buffer to the codec for decoding. The presentationTimeUs
      // indicates the position (play time) for the current sample.
      if (!isSecure) {
        mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
      } else {
        extractor.getSampleCryptoInfo(cryptoInfo);
        mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
      }

      result = true;
    }
    return result;
  }
  /**
   * Write a media sample to the decoder.
   *
   * <p>A "sample" here refers to a single atomic access unit in the media stream. The definition of
   * "access unit" is dependent on the type of encoding used, but it typically refers to a single
   * frame of video or a few seconds of audio. {@link android.media.MediaExtractor} extracts data
   * from a stream one sample at a time.
   *
   * @param input A ByteBuffer containing the input data for one sample. The buffer must be set up
   *     for reading, with its position set to the beginning of the sample data and its limit set to
   *     the end of the sample data.
   * @param presentationTimeUs The time, relative to the beginning of the media stream, at which
   *     this buffer should be rendered.
   * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int, int,
   *     int, long, int)}
   * @throws MediaCodec.CryptoException
   */
  public boolean writeSample(
      final ByteBuffer input,
      final MediaCodec.CryptoInfo crypto,
      final long presentationTimeUs,
      final int flags)
      throws MediaCodec.CryptoException, WriteException {
    boolean result = false;
    int size = input.remaining();

    // check if we have dequed input buffers available from the codec
    if (size > 0 && !mAvailableInputBuffers.isEmpty()) {
      int index = mAvailableInputBuffers.remove();
      ByteBuffer buffer = mInputBuffers[index];

      // we can't write our sample to a lesser capacity input buffer.
      if (size > buffer.capacity()) {
        throw new MediaCodecWrapper.WriteException(
            String.format(
                "Insufficient capacity in MediaCodec buffer: "
                    + "tried to write %d, buffer capacity is %d.",
                input.remaining(), buffer.capacity()));
      }

      buffer.clear();
      buffer.put(input);

      // Submit the buffer to the codec for decoding. The presentationTimeUs
      // indicates the position (play time) for the current sample.
      if (crypto == null) {
        mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
      } else {
        mDecoder.queueSecureInputBuffer(index, 0, crypto, presentationTimeUs, flags);
      }
      result = true;
    }
    return result;
  }