@SuppressLint("Assert")
  @Override
  public boolean stepPipeline() {
    if (mIsEOS) return false;
    int trackIndex = mExtractor.getSampleTrackIndex();
    if (trackIndex < 0) {
      mBuffer.clear();
      mBufferInfo.set(0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
      mMuxer.writeSampleData(mSampleType, mBuffer, mBufferInfo);
      mIsEOS = true;
      return true;
    }
    if (trackIndex != mTrackIndex) return false;

    mBuffer.clear();
    int sampleSize = mExtractor.readSampleData(mBuffer, 0);
    assert sampleSize <= mBufferSize;
    boolean isKeyFrame = (mExtractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) != 0;
    int flags = isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0;
    mBufferInfo.set(0, sampleSize, mExtractor.getSampleTime(), flags);
    mMuxer.writeSampleData(mSampleType, mBuffer, mBufferInfo);
    mWrittenPresentationTimeUs = mBufferInfo.presentationTimeUs;

    mExtractor.advance();
    return true;
  }
  public PassThroughTrackTranscoder(
      MediaExtractor extractor,
      int trackIndex,
      QueuedMuxer muxer,
      QueuedMuxer.SampleType sampleType) {
    mExtractor = extractor;
    mTrackIndex = trackIndex;
    mMuxer = muxer;
    mSampleType = sampleType;

    mActualOutputFormat = mExtractor.getTrackFormat(mTrackIndex);
    mMuxer.setOutputFormat(mSampleType, mActualOutputFormat);
    mBufferSize = mActualOutputFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
    mBuffer = ByteBuffer.allocateDirect(mBufferSize).order(ByteOrder.nativeOrder());
  }