public final boolean queueSampleToCodec(boolean skip) {
        if(mInputEos || !shouldDecodeAnotherFrame()) return false;

        // If we are not at the EOS and the current extractor track is not the this track, we
        // return false because it is some other decoder's turn now.
        // If we are at the EOS, the following code will issue a BUFFER_FLAG_END_OF_STREAM.
        if(mExtractor.getSampleTrackIndex() != -1 && mExtractor.getSampleTrackIndex() != mTrackIndex) {
            if(skip) return mExtractor.advance();
            return false;
        }

        boolean sampleQueued = false;
        int inputBufIndex = mCodec.dequeueInputBuffer(TIMEOUT_US);
        if (inputBufIndex >= 0) {
            ByteBuffer inputBuffer = mCodecInputBuffers[inputBufIndex];

            if(mExtractor.hasTrackFormatChanged()) {
                /* The mRepresentationChanging flag and BUFFER_FLAG_END_OF_STREAM flag together
                 * notify the decoding loop that the representation changes and the codec
                 * needs to be reconfigured.
                 */
                mRepresentationChanging = true;
                mCodec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

                // Check buffering state before representation changes (and possibly a new segment needs to be downloaded)
                if(mExtractor.getCachedDuration() > -1) {
                    if(mOnDecoderEventListener != null) {
                        mOnDecoderEventListener.onBuffering(this);
                    }
                }
            } else {
                // Check buffering state before the blocking readSampleData call
                if(mExtractor.getCachedDuration() > -1) {
                    if(mOnDecoderEventListener != null) {
                        mOnDecoderEventListener.onBuffering(this);
                    }
                }
                int sampleSize = mExtractor.readSampleData(inputBuffer, 0);
                long presentationTimeUs = 0;

                if (sampleSize < 0) {
                    Log.d(TAG, "EOS input");
                    mInputEos = true;
                    sampleSize = 0;
                } else {
                    presentationTimeUs = mExtractor.getSampleTime();
                    sampleQueued = true;
                }

                mCodec.queueInputBuffer(
                        inputBufIndex,
                        0,
                        sampleSize,
                        presentationTimeUs,
                        mInputEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);

                mInputSamplePTS = presentationTimeUs;

                //Log.d(TAG, "queued PTS " + presentationTimeUs);

                if (!mInputEos) {
                    mExtractor.advance();
                }
            }
        }
        return sampleQueued;
    }
Queues a sample from the MediaExtractor to the input of the MediaCodec. The return value
signals if the operation was successful and can be tried another time (return true), or if
there are no more input buffers available, the next sample does not belong to this decoder
(if skip is false) or the input EOS is reached (return false).

@param skip if true, samples belonging to foreign tracks are skipped
@return true if the operation can be repeated for another sample, false if it's another
decoder's turn or the EOS
MediaPlayer/src/main/java/net/protyposis/android/mediaplayer/MediaCodecDecoder.java