/** Synchronize this object's state with the internal state of the wrapped MediaCodec. */
  private void update() {
    // BEGIN_INCLUDE(update_codec_state)
    int index;

    // Get valid input buffers from the codec to fill later in the same order they were
    // made available by the codec.
    while ((index = mDecoder.dequeueInputBuffer(0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
      mAvailableInputBuffers.add(index);
    }

    // Likewise with output buffers. If the output buffers have changed, start using the
    // new set of output buffers. If the output format has changed, notify listeners.
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    while ((index = mDecoder.dequeueOutputBuffer(info, 0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
      switch (index) {
        case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
          mOutputBuffers = mDecoder.getOutputBuffers();
          mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
          mAvailableOutputBuffers.clear();
          break;
        case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
          if (mOutputFormatChangedListener != null) {
            mHandler.post(
                new Runnable() {
                  @Override
                  public void run() {
                    mOutputFormatChangedListener.outputFormatChanged(
                        MediaCodecWrapper.this, mDecoder.getOutputFormat());
                  }
                });
          }
          break;
        default:
          // Making sure the index is valid before adding to output buffers. We've already
          // handled INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED &
          // INFO_OUTPUT_BUFFERS_CHANGED i.e all the other possible return codes but
          // asserting index value anyways for future-proofing the code.
          if (index >= 0) {
            mOutputBufferInfo[index] = info;
            mAvailableOutputBuffers.add(index);
          } else {
            throw new IllegalStateException("Unknown status from dequeueOutputBuffer");
          }
          break;
      }
    }
    // END_INCLUDE(update_codec_state)

  }