synchronized void put(ByteBuffer data, long presentationTimeUs) {
            //Log.d(TAG, "put");
            if(data.remaining() > bufferSize) {
                /* Buffer size has increased, invalidate all empty buffers since they can not be
                 * reused any more. */
                emptyBuffers.clear();
                bufferSize = data.remaining();
            }

            Item item;
            if(!emptyBuffers.isEmpty()) {
                item = emptyBuffers.remove(0);
            } else {
                item = new Item(data.remaining());
            }

            item.buffer.limit(data.remaining());
            item.buffer.mark();
            item.buffer.put(data);
            item.buffer.reset();
            item.presentationTimeUs = presentationTimeUs;

            bufferQueue.add(item);
            mQueuedDataSize += item.buffer.remaining();
        }
Intermediate buffer queue for audio chunks. When an audio chunk is decoded, it is put into
this queue until the audio track periodic notification event gets fired, telling that a certain
amount of the audio playback buffer has been consumed, which then enqueues another chunk to
the playback output buffer.
MediaPlayer/src/main/java/net/protyposis/android/mediaplayer/AudioPlayback.java