protected final void reinitCodec() throws IOException {
        try {
            long t1 = SystemClock.elapsedRealtime();
            /* On some versions of Android it does not work to reconfigure an existing codec
             * instance. The codec just won't return any input buffer afterwards, stalling
             * decoding and thus playback. Instead, we need to create a completely new instance.
             *
             * https://github.com/protyposis/MediaPlayer-Extended/issues/67
             *
             * Issue observed on:
             * - Android 4.1.2 (LG Lucid 2 [VS870 4G])
             * - CM 10.1.3 / Android 4.2.2 (Samsung Galaxy S2 [GT-I9100])
             * - CM 10.1.3 / Android 4.2.2 (Samsung Galaxy S3 [SGH-I747])
             *
             * Non-issue on:
             * - Android 4.1.2 (Samsung Galaxy S2 / GT-I9100)
             * - Android 4.4.4 (Samsung Galaxy S3 [SGH-I747])
             * - Android 5.x (Nexus 5)
             * - Android 5.1 (Blu Energy X2)
             * - Android 6.x (Nexus 5X)
             * - Android 7.x (Nexus 5X)
             * - Android 7.1 (Nexus 5X)
             * - Android 7.1.1 (OnePlus 3 [A3000])
             *
             * Since this issue has only been observed on Android below 4.4, we limit this fix to
             * these versions.
              */
            boolean createNewDecoder = Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT;

            // Get new format and restart codec with this format
            mFormat = mExtractor.getTrackFormat(mTrackIndex);

            mCodec.stop();

            if (createNewDecoder) {
                mCodec.release();
                mCodec = MediaCodec.createDecoderByType(mFormat.getString(MediaFormat.KEY_MIME));
            }

            configureCodec(mCodec, mFormat);
            mCodec.start(); // TODO speedup, but how? this takes a long time and introduces lags when switching DASH representations (AVC codec)
            mCodecInputBuffers = mCodec.getInputBuffers();
            mCodecOutputBuffers = mCodec.getOutputBuffers();
            mBufferInfo = new MediaCodec.BufferInfo();
            mInputEos = false;
            mOutputEos = false;

            // Create FrameInfo objects for later reuse
            mEmptyFrameInfos = new ArrayList<>();
            for (int i = 0; i < mCodecOutputBuffers.length; i++) {
                mEmptyFrameInfos.add(new FrameInfo());
            }

            Log.d(TAG, "reinitCodec " + (SystemClock.elapsedRealtime() - t1) + "ms");
        } catch (IllegalArgumentException e) {
            mCodec.release(); // Release failed codec to not leak a codec thread (MediaCodec_looper)
            Log.e(TAG, "reinitCodec: invalid surface or format");
            throw e;
        } catch (IllegalStateException e) {
            mCodec.release(); // Release failed codec to not leak a codec thread (MediaCodec_looper)
            Log.e(TAG, "reinitCodec: illegal state");
            throw e;
        }
    }
Starts or restarts the codec with a new format, e.g. after a representation change.
MediaPlayer/src/main/java/net/protyposis/android/mediaplayer/MediaCodecDecoder.java