// Copyright 2013 The Cobalt Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Modifications Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cobalt.media;

import static dev.cobalt.media.Log.TAG;

import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaCodec.CryptoInfo;
import android.media.MediaCodec.CryptoInfo.Pattern;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.VideoCapabilities;
import android.media.MediaCrypto;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
import androidx.annotation.Nullable;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Locale;
import java.util.Optional;

/** A wrapper of the MediaCodec class. */
@SuppressWarnings("unused")
@UsedByNative
class MediaCodecBridge {
  // Error code for MediaCodecBridge. Keep this value in sync with
  // MEDIA_CODEC_* values in media_codec_bridge.h.
  private static final int MEDIA_CODEC_OK = 0;
  private static final int MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER = 1;
  private static final int MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER = 2;
  private static final int MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED = 3;
  private static final int MEDIA_CODEC_OUTPUT_FORMAT_CHANGED = 4;
  private static final int MEDIA_CODEC_INPUT_END_OF_STREAM = 5;
  private static final int MEDIA_CODEC_OUTPUT_END_OF_STREAM = 6;
  private static final int MEDIA_CODEC_NO_KEY = 7;
  private static final int MEDIA_CODEC_INSUFFICIENT_OUTPUT_PROTECTION = 8;
  private static final int MEDIA_CODEC_ABORT = 9;
  private static final int MEDIA_CODEC_ERROR = 10;

  // After a flush(), dequeueOutputBuffer() can often produce empty presentation timestamps
  // for several frames. As a result, the player may find that the time does not increase
  // after decoding a frame. To detect this, we check whether the presentation timestamp from
  // dequeueOutputBuffer() is larger than input_timestamp - MAX_PRESENTATION_TIMESTAMP_SHIFT_US
  // after a flush. And we set the presentation timestamp from dequeueOutputBuffer() to be
  // non-decreasing for the remaining frames.
  private static final long MAX_PRESENTATION_TIMESTAMP_SHIFT_US = 100000;

  // We use only one output audio format (PCM16) that has 2 bytes per sample
  private static final int PCM16_BYTES_PER_SAMPLE = 2;

  // TODO: Use MediaFormat constants when part of the public API.
  private static final String KEY_CROP_LEFT = "crop-left";
  private static final String KEY_CROP_RIGHT = "crop-right";
  private static final String KEY_CROP_BOTTOM = "crop-bottom";
  private static final String KEY_CROP_TOP = "crop-top";

  private static final int BITRATE_ADJUSTMENT_FPS = 30;

  private long mNativeMediaCodecBridge;
  private MediaCodec mMediaCodec;
  private MediaCodec.Callback mCallback;
  private boolean mFlushed;
  private long mLastPresentationTimeUs;
  private final String mMime;
  private double mPlaybackRate = 1.0;
  private int mFps = 30;

  private MediaCodec.OnFrameRenderedListener mFrameRendererListener;

  // Functions that require this will be called frequently in a tight loop.
  // Only create one of these and reuse it to avoid excessive allocations,
  // which would cause GC cycles long enough to impact playback.
  private final MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

  // Type of bitrate adjustment for video encoder.
  public enum BitrateAdjustmentTypes {
    // No adjustment - video encoder has no known bitrate problem.
    NO_ADJUSTMENT,
    // Framerate based bitrate adjustment is required - HW encoder does not use frame
    // timestamps to calculate frame bitrate budget and instead is relying on initial
    // fps configuration assuming that all frames are coming at fixed initial frame rate.
    FRAMERATE_ADJUSTMENT,
  }

  public static final class MimeTypes {
    public static final String VIDEO_MP4 = "video/mp4";
    public static final String VIDEO_WEBM = "video/webm";
    public static final String VIDEO_H264 = "video/avc";
    public static final String VIDEO_H265 = "video/hevc";
    public static final String VIDEO_VP8 = "video/x-vnd.on2.vp8";
    public static final String VIDEO_VP9 = "video/x-vnd.on2.vp9";
    public static final String VIDEO_AV1 = "video/av01";
  }

  private class FrameRateEstimator {
    private static final int INVALID_FRAME_RATE = -1;
    private static final long INVALID_FRAME_TIMESTAMP = -1;
    private static final int MINIMUM_REQUIRED_FRAMES = 4;
    private long mLastFrameTimestampUs = INVALID_FRAME_TIMESTAMP;
    private long mNumberOfFrames = 0;
    private long mTotalDurationUs = 0;

    public int getEstimatedFrameRate() {
      if (mTotalDurationUs <= 0 || mNumberOfFrames < MINIMUM_REQUIRED_FRAMES) {
        return INVALID_FRAME_RATE;
      }
      return Math.round((mNumberOfFrames - 1) * 1000000.0f / mTotalDurationUs);
    }

    public void reset() {
      mLastFrameTimestampUs = INVALID_FRAME_TIMESTAMP;
      mNumberOfFrames = 0;
      mTotalDurationUs = 0;
    }

    public void onNewFrame(long presentationTimeUs) {
      mNumberOfFrames++;

      if (mLastFrameTimestampUs == INVALID_FRAME_TIMESTAMP) {
        mLastFrameTimestampUs = presentationTimeUs;
        return;
      }
      if (presentationTimeUs <= mLastFrameTimestampUs) {
        Log.v(TAG, "Invalid output presentation timestamp.");
        return;
      }

      mTotalDurationUs += presentationTimeUs - mLastFrameTimestampUs;
      mLastFrameTimestampUs = presentationTimeUs;
    }
  }

  private FrameRateEstimator mFrameRateEstimator = null;
  private BitrateAdjustmentTypes mBitrateAdjustmentType = BitrateAdjustmentTypes.NO_ADJUSTMENT;

  @SuppressWarnings("unused")
  @UsedByNative
  public static class DequeueInputResult {
    private int mStatus;
    private int mIndex;

    @SuppressWarnings("unused")
    @UsedByNative
    private DequeueInputResult() {
      mStatus = MEDIA_CODEC_ERROR;
      mIndex = -1;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private DequeueInputResult(int status, int index) {
      mStatus = status;
      mIndex = index;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int status() {
      return mStatus;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int index() {
      return mIndex;
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private static class DequeueOutputResult {
    private int mStatus;
    private int mIndex;
    private int mFlags;
    private int mOffset;
    private long mPresentationTimeMicroseconds;
    private int mNumBytes;

    @SuppressWarnings("unused")
    @UsedByNative
    private DequeueOutputResult() {
      mStatus = MEDIA_CODEC_ERROR;
      mIndex = -1;
      mFlags = 0;
      mOffset = 0;
      mPresentationTimeMicroseconds = 0;
      mNumBytes = 0;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private DequeueOutputResult(
        int status,
        int index,
        int flags,
        int offset,
        long presentationTimeMicroseconds,
        int numBytes) {
      mStatus = status;
      mIndex = index;
      mFlags = flags;
      mOffset = offset;
      mPresentationTimeMicroseconds = presentationTimeMicroseconds;
      mNumBytes = numBytes;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int status() {
      return mStatus;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int index() {
      return mIndex;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int flags() {
      return mFlags;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int offset() {
      return mOffset;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private long presentationTimeMicroseconds() {
      return mPresentationTimeMicroseconds;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int numBytes() {
      return mNumBytes;
    }
  }

  /** A wrapper around a MediaFormat. */
  @SuppressWarnings("unused")
  @UsedByNative
  private static class GetOutputFormatResult {
    private int mStatus;
    // May be null if mStatus is not MEDIA_CODEC_OK.
    private MediaFormat mFormat;
    private Optional<Boolean> mFormatHasCropValues = Optional.empty();

    @SuppressWarnings("unused")
    @UsedByNative
    private GetOutputFormatResult() {
      mStatus = MEDIA_CODEC_ERROR;
      mFormat = null;
    }

    private boolean formatHasCropValues() {
      if (!mFormatHasCropValues.isPresent() && mFormat != null) {
        boolean hasCropValues =
            mFormat.containsKey(KEY_CROP_RIGHT)
                && mFormat.containsKey(KEY_CROP_LEFT)
                && mFormat.containsKey(KEY_CROP_BOTTOM)
                && mFormat.containsKey(KEY_CROP_TOP);
        mFormatHasCropValues = Optional.ofNullable(hasCropValues);
      }
      return mFormatHasCropValues.orElse(false);
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int status() {
      return mStatus;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int textureWidth() {
      return (mFormat != null && mFormat.containsKey(MediaFormat.KEY_WIDTH))
          ? mFormat.getInteger(MediaFormat.KEY_WIDTH)
          : 0;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int textureHeight() {
      return (mFormat != null && mFormat.containsKey(MediaFormat.KEY_HEIGHT))
          ? mFormat.getInteger(MediaFormat.KEY_HEIGHT)
          : 0;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int cropLeft() {
      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_LEFT) : -1;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int cropTop() {
      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_TOP) : -1;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int cropRight() {
      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_RIGHT) : -1;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int cropBottom() {
      return formatHasCropValues() ? mFormat.getInteger(KEY_CROP_BOTTOM) : -1;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int sampleRate() {
      return mFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private int channelCount() {
      return mFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private static class ColorInfo {
    private static final int MAX_CHROMATICITY = 50000; // Defined in CTA-861.3.
    private static final int DEFAULT_MAX_CLL = 1000;
    private static final int DEFAULT_MAX_FALL = 200;

    public int colorRange;
    public int colorStandard;
    public int colorTransfer;
    public ByteBuffer hdrStaticInfo;

    @SuppressWarnings("unused")
    @UsedByNative
    ColorInfo(
        int colorRange,
        int colorStandard,
        int colorTransfer,
        float primaryRChromaticityX,
        float primaryRChromaticityY,
        float primaryGChromaticityX,
        float primaryGChromaticityY,
        float primaryBChromaticityX,
        float primaryBChromaticityY,
        float whitePointChromaticityX,
        float whitePointChromaticityY,
        float maxMasteringLuminance,
        float minMasteringLuminance,
        int maxCll,
        int maxFall,
        boolean forceBigEndianHdrMetadata) {
      this.colorRange = colorRange;
      this.colorStandard = colorStandard;
      this.colorTransfer = colorTransfer;

      if (maxCll <= 0) {
        maxCll = DEFAULT_MAX_CLL;
      }
      if (maxFall <= 0) {
        maxFall = DEFAULT_MAX_FALL;
      }

      // This logic is inspired by
      // https://cs.android.com/android/_/android/platform/external/exoplayer/+/3423b4bbfffbb62b5f2d8f16cfdc984dc107cd02:tree/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java;l=2200-2215;drc=9af07bc62f8115cbaa6f1178ce8aa3533d2b9e29.
      ByteBuffer hdrStaticInfo = ByteBuffer.allocateDirect(25);
      // Force big endian in case the HDR metadata causes problems in production.
      if (forceBigEndianHdrMetadata) {
        hdrStaticInfo.order(ByteOrder.BIG_ENDIAN);
      } else {
        hdrStaticInfo.order(ByteOrder.LITTLE_ENDIAN);
      }

      hdrStaticInfo.put((byte) 0);
      hdrStaticInfo.putShort((short) ((primaryRChromaticityX * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((primaryRChromaticityY * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((primaryGChromaticityX * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((primaryGChromaticityY * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((primaryBChromaticityX * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((primaryBChromaticityY * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((whitePointChromaticityX * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) ((whitePointChromaticityY * MAX_CHROMATICITY) + 0.5f));
      hdrStaticInfo.putShort((short) (maxMasteringLuminance + 0.5f));
      hdrStaticInfo.putShort((short) (minMasteringLuminance + 0.5f));
      hdrStaticInfo.putShort((short) maxCll);
      hdrStaticInfo.putShort((short) maxFall);
      hdrStaticInfo.rewind();
      this.hdrStaticInfo = hdrStaticInfo;
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private static class CreateMediaCodecBridgeResult {
    private MediaCodecBridge mMediaCodecBridge;
    // Contains the error message when mMediaCodecBridge is null.
    private String mErrorMessage;

    @SuppressWarnings("unused")
    @UsedByNative
    private CreateMediaCodecBridgeResult() {
      mMediaCodecBridge = null;
      mErrorMessage = "";
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private MediaCodecBridge mediaCodecBridge() {
      return mMediaCodecBridge;
    }

    @SuppressWarnings("unused")
    @UsedByNative
    private String errorMessage() {
      return mErrorMessage;
    }
  }

  private MediaCodecBridge(
      long nativeMediaCodecBridge,
      MediaCodec mediaCodec,
      String mime,
      BitrateAdjustmentTypes bitrateAdjustmentType,
      int tunnelModeAudioSessionId) {
    if (mediaCodec == null) {
      throw new IllegalArgumentException();
    }
    mNativeMediaCodecBridge = nativeMediaCodecBridge;
    mMediaCodec = mediaCodec;
    mMime = mime; // TODO: Delete the unused mMime field
    mLastPresentationTimeUs = 0;
    mFlushed = true;
    mBitrateAdjustmentType = bitrateAdjustmentType;
    mCallback =
        new MediaCodec.Callback() {
          @Override
          public void onError(MediaCodec codec, MediaCodec.CodecException e) {
            synchronized (this) {
              if (mNativeMediaCodecBridge == 0) {
                return;
              }
              nativeOnMediaCodecError(
                  mNativeMediaCodecBridge,
                  e.isRecoverable(),
                  e.isTransient(),
                  e.getDiagnosticInfo());
            }
          }

          @Override
          public void onInputBufferAvailable(MediaCodec codec, int index) {
            synchronized (this) {
              if (mNativeMediaCodecBridge == 0) {
                return;
              }
              nativeOnMediaCodecInputBufferAvailable(mNativeMediaCodecBridge, index);
            }
          }

          @Override
          public void onOutputBufferAvailable(
              MediaCodec codec, int index, MediaCodec.BufferInfo info) {
            synchronized (this) {
              if (mNativeMediaCodecBridge == 0) {
                return;
              }
              nativeOnMediaCodecOutputBufferAvailable(
                  mNativeMediaCodecBridge,
                  index,
                  info.flags,
                  info.offset,
                  info.presentationTimeUs,
                  info.size);
              if (mFrameRateEstimator != null) {
                mFrameRateEstimator.onNewFrame(info.presentationTimeUs);
                int fps = mFrameRateEstimator.getEstimatedFrameRate();
                if (fps != FrameRateEstimator.INVALID_FRAME_RATE && mFps != fps) {
                  mFps = fps;
                  updateOperatingRate();
                }
              }
            }
          }

          @Override
          public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
            synchronized (this) {
              if (mNativeMediaCodecBridge == 0) {
                return;
              }
              nativeOnMediaCodecOutputFormatChanged(mNativeMediaCodecBridge);
              if (mFrameRateEstimator != null) {
                mFrameRateEstimator.reset();
              }
            }
          }
        };
    mMediaCodec.setCallback(mCallback);

    if (isFrameRenderedCallbackEnabled() || tunnelModeAudioSessionId != -1) {
      mFrameRendererListener =
          new MediaCodec.OnFrameRenderedListener() {
            @Override
            public void onFrameRendered(MediaCodec codec, long presentationTimeUs, long nanoTime) {
              synchronized (this) {
                if (mNativeMediaCodecBridge == 0) {
                  return;
                }
                nativeOnMediaCodecFrameRendered(
                    mNativeMediaCodecBridge, presentationTimeUs, nanoTime);
              }
            }
          };
      mMediaCodec.setOnFrameRenderedListener(mFrameRendererListener, null);
    }
  }

  @UsedByNative
  public static boolean isFrameRenderedCallbackEnabled() {
    // Starting with Android 14, onFrameRendered should be called accurately for each rendered
    // frame.
    return Build.VERSION.SDK_INT >= 34;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  public static MediaCodecBridge createAudioMediaCodecBridge(
      long nativeMediaCodecBridge,
      String mime,
      String decoderName,
      int sampleRate,
      int channelCount,
      MediaCrypto crypto,
      @Nullable byte[] configurationData) {
    if (decoderName.equals("")) {
      Log.e(TAG, "Invalid decoder name.");
      return null;
    }
    MediaCodec mediaCodec = null;
    try {
      Log.i(TAG, "Creating \"%s\" decoder.", decoderName);
      mediaCodec = MediaCodec.createByCodecName(decoderName);
    } catch (Exception e) {
      Log.e(TAG, "Failed to create MediaCodec: %s, DecoderName: %s", mime, decoderName, e);
      return null;
    }
    if (mediaCodec == null) {
      return null;
    }
    MediaCodecBridge bridge =
        new MediaCodecBridge(
            nativeMediaCodecBridge, mediaCodec, mime, BitrateAdjustmentTypes.NO_ADJUSTMENT, -1);

    MediaFormat mediaFormat = createAudioFormat(mime, sampleRate, channelCount);

    if (mime.contains("opus")) {
      if (!setOpusConfigurationData(mediaFormat, sampleRate, configurationData)) {
        bridge.release();
        return null;
      }
    } else {
      // TODO: Determine if we should explicitly check the mime for AAC audio before calling
      // setFrameHasADTSHeader(), as more codecs may be supported here in the future.
      setFrameHasADTSHeader(mediaFormat);
    }
    if (!bridge.configureAudio(mediaFormat, crypto, 0)) {
      Log.e(TAG, "Failed to configure audio codec.");
      bridge.release();
      return null;
    }
    if (!bridge.start()) {
      Log.e(TAG, "Failed to start audio codec.");
      bridge.release();
      return null;
    }

    return bridge;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  public static void createVideoMediaCodecBridge(
      long nativeMediaCodecBridge,
      String mime,
      String decoderName,
      // `widthHint` and `heightHint` are used to create the Android video format, which don't have
      // to be directly related to the resolution of the video.
      int widthHint,
      int heightHint,
      int fps,
      int maxWidth,
      int maxHeight,
      Surface surface,
      MediaCrypto crypto,
      ColorInfo colorInfo,
      int tunnelModeAudioSessionId,
      int maxVideoInputSize,
      CreateMediaCodecBridgeResult outCreateMediaCodecBridgeResult) {
    MediaCodec mediaCodec = null;
    outCreateMediaCodecBridgeResult.mMediaCodecBridge = null;

    if (decoderName.equals("")) {
      String message = "Invalid decoder name.";
      Log.e(TAG, message);
      outCreateMediaCodecBridgeResult.mErrorMessage = message;
      return;
    }

    try {
      Log.i(TAG, "Creating \"%s\" decoder.", decoderName);
      mediaCodec = MediaCodec.createByCodecName(decoderName);
    } catch (Exception e) {
      String message =
          String.format(
              Locale.US,
              "Failed to create MediaCodec: %s, mustSupportSecure: %s," + " DecoderName: %s",
              mime,
              crypto != null,
              decoderName);
      Log.e(TAG, message, e);
      outCreateMediaCodecBridgeResult.mErrorMessage = message;
      return;
    }
    if (mediaCodec == null) {
      outCreateMediaCodecBridgeResult.mErrorMessage = "mediaCodec is null";
      return;
    }

    MediaCodecInfo codecInfo = mediaCodec.getCodecInfo();
    if (codecInfo == null) {
      outCreateMediaCodecBridgeResult.mErrorMessage = "codecInfo is null";
      return;
    }
    CodecCapabilities codecCapabilities = codecInfo.getCapabilitiesForType(mime);
    if (codecCapabilities == null) {
      outCreateMediaCodecBridgeResult.mErrorMessage = "codecCapabilities is null";
      return;
    }
    VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabilities();
    if (videoCapabilities == null) {
      outCreateMediaCodecBridgeResult.mErrorMessage = "videoCapabilities is null";
      return;
    }

    MediaCodecBridge bridge =
        new MediaCodecBridge(
            nativeMediaCodecBridge,
            mediaCodec,
            mime,
            BitrateAdjustmentTypes.NO_ADJUSTMENT,
            tunnelModeAudioSessionId);
    MediaFormat mediaFormat =
        createVideoDecoderFormat(mime, widthHint, heightHint, videoCapabilities);

    boolean shouldConfigureHdr =
        colorInfo != null && MediaCodecUtil.isHdrCapableVideoDecoder(mime, codecCapabilities);
    if (shouldConfigureHdr) {
      Log.d(TAG, "Setting HDR info.");
      mediaFormat.setInteger(MediaFormat.KEY_COLOR_TRANSFER, colorInfo.colorTransfer);
      mediaFormat.setInteger(MediaFormat.KEY_COLOR_STANDARD, colorInfo.colorStandard);
      // If color range is unspecified, don't set it.
      if (colorInfo.colorRange != 0) {
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_RANGE, colorInfo.colorRange);
      }
      mediaFormat.setByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, colorInfo.hdrStaticInfo);
    }

    if (tunnelModeAudioSessionId != -1) {
      mediaFormat.setFeatureEnabled(CodecCapabilities.FEATURE_TunneledPlayback, true);
      mediaFormat.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, tunnelModeAudioSessionId);
      Log.d(TAG, "Enabled tunnel mode playback on audio session " + tunnelModeAudioSessionId);
    }

    if (maxWidth > 0 && maxHeight > 0) {
      Log.i(TAG, "Evaluate maxWidth and maxHeight (%d, %d) passed in", maxWidth, maxHeight);
    } else {
      maxWidth = videoCapabilities.getSupportedWidths().getUpper();
      maxHeight = videoCapabilities.getSupportedHeights().getUpper();
      Log.i(
          TAG,
          "maxWidth and maxHeight not passed in, using result of getSupportedWidths()/Heights()"
              + " (%d, %d)",
          maxWidth,
          maxHeight);
    }

    if (fps > 0) {
      if (videoCapabilities.areSizeAndRateSupported(maxWidth, maxHeight, fps)) {
        Log.i(
            TAG,
            "Set maxWidth and maxHeight to (%d, %d)@%d per `areSizeAndRateSupported()`",
            maxWidth,
            maxHeight,
            fps);
      } else {
        Log.w(
            TAG,
            "maxWidth and maxHeight (%d, %d)@%d not supported per `areSizeAndRateSupported()`,"
                + " continue searching",
            maxWidth,
            maxHeight,
            fps);
        if (maxHeight >= 4320 && videoCapabilities.areSizeAndRateSupported(7680, 4320, fps)) {
          maxWidth = 7680;
          maxHeight = 4320;
        } else if (maxHeight >= 2160
            && videoCapabilities.areSizeAndRateSupported(3840, 2160, fps)) {
          maxWidth = 3840;
          maxHeight = 2160;
        } else if (maxHeight >= 1080
            && videoCapabilities.areSizeAndRateSupported(1920, 1080, fps)) {
          maxWidth = 1920;
          maxHeight = 1080;
        } else {
          Log.e(TAG, "Failed to find a compatible resolution");
          maxWidth = 1920;
          maxHeight = 1080;
        }
        Log.i(
            TAG,
            "Set maxWidth and maxHeight to (%d, %d)@%d per `areSizeAndRateSupported()`",
            maxWidth,
            maxHeight,
            fps);
      }
    } else {
      if (maxHeight >= 480 && videoCapabilities.isSizeSupported(maxWidth, maxHeight)) {
        // Technically we can do this check for all resolutions, but only check for resolution with
        // height more than 480p to minimize production impact.  To use a lower resolution is more
        // to reduce memory footprint, and optimize for lower resolution isn't as helpful anyway.
        Log.i(
            TAG,
            "Set maxWidth and maxHeight to (%d, %d) per `isSizeSupported()`",
            maxWidth,
            maxHeight);
      } else {
        if (maxHeight >= 2160 && videoCapabilities.isSizeSupported(3840, 2160)) {
          maxWidth = 3840;
          maxHeight = 2160;
        } else if (maxHeight >= 1080 && videoCapabilities.isSizeSupported(1920, 1080)) {
          maxWidth = 1920;
          maxHeight = 1080;
        } else {
          Log.e(TAG, "Failed to find a compatible resolution");
          maxWidth = 1920;
          maxHeight = 1080;
        }
        Log.i(
            TAG,
            "Set maxWidth and maxHeight to (%d, %d) per `isSizeSupported()`",
            maxWidth,
            maxHeight);
      }
    }

    if (maxVideoInputSize > 0) {
      mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, maxVideoInputSize);
      try {
        Log.i(
            TAG,
            "Set KEY_MAX_INPUT_SIZE to "
                + maxVideoInputSize
                + " (actual: "
                + mediaFormat.getInteger(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)
                + ").");
      } catch (Exception e) {
        Log.e(TAG, "MediaFormat.getInteger(KEY_MAX_INPUT_SIZE) failed with exception: ", e);
      }
    }
    if (!bridge.configureVideo(
        mediaFormat, surface, crypto, 0, maxWidth, maxHeight, outCreateMediaCodecBridgeResult)) {
      Log.e(TAG, "Failed to configure video codec.");
      bridge.release();
      // outCreateMediaCodecBridgeResult.mErrorMessage is set inside configureVideo() on error.
      return;
    }
    if (!bridge.start()) {
      Log.e(TAG, "Failed to start video codec.");
      bridge.release();
      outCreateMediaCodecBridgeResult.mErrorMessage = "Failed to start video codec";
      return;
    }

    outCreateMediaCodecBridgeResult.mMediaCodecBridge = bridge;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  public void release() {
    try {
      String codecName = mMediaCodec.getName();
      Log.w(TAG, "calling MediaCodec.release() on " + codecName);
      mMediaCodec.release();
    } catch (Exception e) {
      // The MediaCodec is stuck in a wrong state, possibly due to losing
      // the surface.
      Log.e(TAG, "Cannot release media codec", e);
    }
    mMediaCodec = null;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private boolean start() {
    try {
      mMediaCodec.start();
    } catch (IllegalStateException | IllegalArgumentException e) {
      Log.e(TAG, "Cannot start the media codec", e);
      return false;
    }
    return true;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void setPlaybackRate(double playbackRate) {
    if (mPlaybackRate == playbackRate) {
      return;
    }
    mPlaybackRate = playbackRate;
    if (mFrameRateEstimator != null) {
      updateOperatingRate();
    }
  }

  private void updateOperatingRate() {
    // We needn't set operation rate if playback rate is 0 or less.
    if (Double.compare(mPlaybackRate, 0.0) <= 0) {
      return;
    }
    if (mFps == FrameRateEstimator.INVALID_FRAME_RATE) {
      return;
    }
    if (mFps <= 0) {
      Log.e(TAG, "Failed to set operating rate with invalid fps " + mFps);
      return;
    }
    if (mMediaCodec == null) {
      Log.e(TAG, "Failed to set operating rate when media codec is null.");
      return;
    }
    double operatingRate = mPlaybackRate * mFps;
    Bundle b = new Bundle();
    b.putFloat(MediaFormat.KEY_OPERATING_RATE, (float) operatingRate);
    try {
      mMediaCodec.setParameters(b);
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to set MediaCodec operating rate", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private int flush() {
    try {
      mFlushed = true;
      mMediaCodec.flush();
    } catch (Exception e) {
      Log.e(TAG, "Failed to flush MediaCodec", e);
      return MEDIA_CODEC_ERROR;
    }
    return MEDIA_CODEC_OK;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void stop() {
    synchronized (this) {
      mNativeMediaCodecBridge = 0;
    }
    try {
      mMediaCodec.stop();
    } catch (Exception e) {
      Log.e(TAG, "Failed to stop MediaCodec", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private String getName() {
    String codecName = "unknown";
    try {
      codecName = mMediaCodec.getName();
    } catch (IllegalStateException e) {
      Log.e(TAG, "Cannot get codec name", e);
    }
    return codecName;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void getOutputFormat(GetOutputFormatResult outGetOutputFormatResult) {
    MediaFormat format = null;
    int status = MEDIA_CODEC_OK;
    try {
      format = mMediaCodec.getOutputFormat();
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to get output format", e);
      status = MEDIA_CODEC_ERROR;
    }
    outGetOutputFormatResult.mStatus = status;
    outGetOutputFormatResult.mFormat = format;
  }

  /** Returns null if MediaCodec throws IllegalStateException. */
  @SuppressWarnings("unused")
  @UsedByNative
  private ByteBuffer getInputBuffer(int index) {
    try {
      return mMediaCodec.getInputBuffer(index);
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to get input buffer", e);
      return null;
    }
  }

  /** Returns null if MediaCodec throws IllegalStateException. */
  @SuppressWarnings("unused")
  @UsedByNative
  private ByteBuffer getOutputBuffer(int index) {
    try {
      return mMediaCodec.getOutputBuffer(index);
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to get output buffer", e);
      return null;
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private int queueInputBuffer(
      int index, int offset, int size, long presentationTimeUs, int flags) {
    resetLastPresentationTimeIfNeeded(presentationTimeUs);
    try {
      mMediaCodec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
    } catch (Exception e) {
      Log.e(TAG, "Failed to queue input buffer", e);
      return MEDIA_CODEC_ERROR;
    }
    return MEDIA_CODEC_OK;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void setVideoBitrate(int bps, int frameRate) {
    int targetBps = bps;
    if (mBitrateAdjustmentType == BitrateAdjustmentTypes.FRAMERATE_ADJUSTMENT && frameRate > 0) {
      targetBps = BITRATE_ADJUSTMENT_FPS * bps / frameRate;
    }

    Bundle b = new Bundle();
    b.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, targetBps);
    try {
      mMediaCodec.setParameters(b);
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to set MediaCodec parameters", e);
    }
    Log.v(TAG, "setVideoBitrate: input " + bps + "bps@" + frameRate + ", targetBps " + targetBps);
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void requestKeyFrameSoon() {
    Bundle b = new Bundle();
    b.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
    try {
      mMediaCodec.setParameters(b);
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to set MediaCodec parameters", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private int queueSecureInputBuffer(
      int index,
      int offset,
      byte[] iv,
      byte[] keyId,
      int[] numBytesOfClearData,
      int[] numBytesOfEncryptedData,
      int numSubSamples,
      int cipherMode,
      int blocksToEncrypt,
      int blocksToSkip,
      long presentationTimeUs) {
    resetLastPresentationTimeIfNeeded(presentationTimeUs);
    try {
      CryptoInfo cryptoInfo = new CryptoInfo();
      cryptoInfo.set(
          numSubSamples, numBytesOfClearData, numBytesOfEncryptedData, keyId, iv, cipherMode);

      if (cipherMode == MediaCodec.CRYPTO_MODE_AES_CBC) {
        cryptoInfo.setPattern(new Pattern(blocksToEncrypt, blocksToSkip));
      } else if (blocksToEncrypt != 0 || blocksToSkip != 0) {
        Log.e(TAG, "Pattern encryption only supported for 'cbcs' scheme (CBC mode).");
        return MEDIA_CODEC_ERROR;
      }

      mMediaCodec.queueSecureInputBuffer(index, offset, cryptoInfo, presentationTimeUs, 0);
    } catch (MediaCodec.CryptoException e) {
      int errorCode = e.getErrorCode();
      if (errorCode == MediaCodec.CryptoException.ERROR_NO_KEY) {
        Log.d(TAG, "Failed to queue secure input buffer: CryptoException.ERROR_NO_KEY");
        return MEDIA_CODEC_NO_KEY;
      } else if (errorCode == MediaCodec.CryptoException.ERROR_INSUFFICIENT_OUTPUT_PROTECTION) {
        Log.d(
            TAG,
            "Failed to queue secure input buffer: "
                + "CryptoException.ERROR_INSUFFICIENT_OUTPUT_PROTECTION");
        return MEDIA_CODEC_INSUFFICIENT_OUTPUT_PROTECTION;
      }
      Log.e(
          TAG,
          "Failed to queue secure input buffer, CryptoException with error code "
              + e.getErrorCode());
      return MEDIA_CODEC_ERROR;
    } catch (IllegalArgumentException e) {
      Log.e(TAG, "Failed to queue secure input buffer, IllegalArgumentException " + e);
      return MEDIA_CODEC_ERROR;
    } catch (IllegalStateException e) {
      Log.e(TAG, "Failed to queue secure input buffer, IllegalStateException " + e);
      return MEDIA_CODEC_ERROR;
    }
    return MEDIA_CODEC_OK;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void releaseOutputBuffer(int index, boolean render) {
    try {
      mMediaCodec.releaseOutputBuffer(index, render);
    } catch (IllegalStateException e) {
      // TODO: May need to report the error to the caller. crbug.com/356498.
      Log.e(TAG, "Failed to release output buffer", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private void releaseOutputBuffer(int index, long renderTimestampNs) {
    try {
      mMediaCodec.releaseOutputBuffer(index, renderTimestampNs);
    } catch (IllegalStateException e) {
      // TODO: May need to report the error to the caller. crbug.com/356498.
      Log.e(TAG, "Failed to release output buffer", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private boolean configureVideo(
      MediaFormat format,
      Surface surface,
      MediaCrypto crypto,
      int flags,
      int maxSupportedWidth,
      int maxSupportedHeight,
      CreateMediaCodecBridgeResult outCreateMediaCodecBridgeResult) {
    try {
      // Since we haven't passed the properties of the stream we're playing down to this level, from
      // our perspective, we could potentially adapt up to 8k at any point. We thus request 8k
      // buffers up front, unless the decoder claims to not be able to do 8k, in which case we're
      // ok, since we would've rejected a 8k stream when canPlayType was called, and then use those
      // decoder values instead. We only support 8k for API level 29 and above.
      if (Build.VERSION.SDK_INT > 28) {
        format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(7680, maxSupportedWidth));
        format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(4320, maxSupportedHeight));
      } else {
        // Android 5.0/5.1 seems not support 8K. Fallback to 4K until we get a
        // better way to get maximum supported resolution.
        format.setInteger(MediaFormat.KEY_MAX_WIDTH, Math.min(3840, maxSupportedWidth));
        format.setInteger(MediaFormat.KEY_MAX_HEIGHT, Math.min(2160, maxSupportedHeight));
      }

      maybeSetMaxVideoInputSize(format);
      mMediaCodec.configure(format, surface, crypto, flags);
      mFrameRateEstimator = new FrameRateEstimator();
      return true;
    } catch (IllegalArgumentException e) {
      Log.e(TAG, "Cannot configure the video codec with IllegalArgumentException: ", e);
      outCreateMediaCodecBridgeResult.mErrorMessage =
          "Cannot configure the video codec with IllegalArgumentException: " + e.toString();
    } catch (IllegalStateException e) {
      Log.e(TAG, "Cannot configure the video codec with IllegalStateException: ", e);
      outCreateMediaCodecBridgeResult.mErrorMessage =
          "Cannot configure the video codec with IllegalStateException: " + e.toString();
    } catch (MediaCodec.CryptoException e) {
      Log.e(TAG, "Cannot configure the video codec with CryptoException: ", e);
      outCreateMediaCodecBridgeResult.mErrorMessage =
          "Cannot configure the video codec with CryptoException: " + e.toString();
    } catch (Exception e) {
      Log.e(TAG, "Cannot configure the video codec with Exception: ", e);
      outCreateMediaCodecBridgeResult.mErrorMessage =
          "Cannot configure the video codec with Exception: " + e.toString();
    }
    return false;
  }

  public static MediaFormat createAudioFormat(String mime, int sampleRate, int channelCount) {
    return MediaFormat.createAudioFormat(mime, sampleRate, channelCount);
  }

  private static MediaFormat createVideoDecoderFormat(
      String mime, int widthHint, int heightHint, VideoCapabilities videoCapabilities) {
    return MediaFormat.createVideoFormat(
        mime,
        alignDimension(widthHint, videoCapabilities.getWidthAlignment()),
        alignDimension(heightHint, videoCapabilities.getHeightAlignment()));
  }

  private static int alignDimension(int size, int alignment) {
    int ceilDivide = (size + alignment - 1) / alignment;
    return ceilDivide * alignment;
  }

  // Use some heuristics to set KEY_MAX_INPUT_SIZE (the size of the input buffers).
  // Taken from ExoPlayer:
  // https://github.com/google/ExoPlayer/blob/8595c65678a181296cdf673eacb93d8135479340/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
  private void maybeSetMaxVideoInputSize(MediaFormat format) {
    if (format.containsKey(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)) {
      try {
        Log.i(
            TAG,
            "Use default value for KEY_MAX_INPUT_SIZE: "
                + format.getInteger(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)
                + '.');
      } catch (Exception e) {
        Log.e(TAG, "MediaFormat.getInteger(KEY_MAX_INPUT_SIZE) failed with exception: ", e);
      }
      // Already set. The source of the format may know better, so do nothing.
      return;
    }
    int maxHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
    if (format.containsKey(MediaFormat.KEY_MAX_HEIGHT)) {
      maxHeight = Math.max(maxHeight, format.getInteger(MediaFormat.KEY_MAX_HEIGHT));
    }
    int maxWidth = format.getInteger(MediaFormat.KEY_WIDTH);
    if (format.containsKey(MediaFormat.KEY_MAX_WIDTH)) {
      maxWidth = Math.max(maxHeight, format.getInteger(MediaFormat.KEY_MAX_WIDTH));
    }
    int maxPixels;
    int minCompressionRatio;
    switch (format.getString(MediaFormat.KEY_MIME)) {
      case MimeTypes.VIDEO_H264:
        if ("BRAVIA 4K 2015".equals(Build.MODEL)) {
          // The Sony BRAVIA 4k TV has input buffers that are too small for the calculated
          // 4k video maximum input size, so use the default value.
          return;
        }
        // Round up width/height to an integer number of macroblocks.
        maxPixels = ((maxWidth + 15) / 16) * ((maxHeight + 15) / 16) * 16 * 16;
        minCompressionRatio = 2;
        break;
      case MimeTypes.VIDEO_VP8:
        // VPX does not specify a ratio so use the values from the platform's SoftVPX.cpp.
        maxPixels = maxWidth * maxHeight;
        minCompressionRatio = 2;
        break;
      case MimeTypes.VIDEO_H265:
      case MimeTypes.VIDEO_VP9:
      case MimeTypes.VIDEO_AV1:
        maxPixels = maxWidth * maxHeight;
        minCompressionRatio = 4;
        break;
      default:
        // Leave the default max input size.
        return;
    }
    // Estimate the maximum input size assuming three channel 4:2:0 subsampled input frames.
    int maxVideoInputSize = (maxPixels * 3) / (2 * minCompressionRatio);
    format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, maxVideoInputSize);
    try {
      Log.i(
          TAG,
          "Set KEY_MAX_INPUT_SIZE to "
              + maxVideoInputSize
              + " (actual: "
              + format.getInteger(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)
              + ").");
    } catch (Exception e) {
      Log.e(TAG, "MediaFormat.getInteger(KEY_MAX_INPUT_SIZE) failed with exception: ", e);
    }
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private static void setCodecSpecificData(MediaFormat format, int index, byte[] bytes) {
    // Codec Specific Data is set in the MediaFormat as ByteBuffer entries with keys csd-0,
    // csd-1, and so on. See: http://developer.android.com/reference/android/media/MediaCodec.html
    // for details.
    String name;
    switch (index) {
      case 0:
        name = "csd-0";
        break;
      case 1:
        name = "csd-1";
        break;
      case 2:
        name = "csd-2";
        break;
      default:
        name = null;
        break;
    }
    if (name != null) {
      format.setByteBuffer(name, ByteBuffer.wrap(bytes));
    }
  }

  @SuppressWarnings("unused")
  private static boolean setOpusConfigurationData(
      MediaFormat format, int sampleRate, @Nullable byte[] configurationData) {
    final int MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE = 19;
    final long NANOSECONDS_IN_ONE_SECOND = 1000000000L;
    // 3840 is the default seek pre-roll samples used by ExoPlayer:
    // https://github.com/google/ExoPlayer/blob/0ba317b1337eaa789f05dd6c5241246478a3d1e5/library/common/src/main/java/com/google/android/exoplayer2/audio/OpusUtil.java#L30.
    final int DEFAULT_SEEK_PRE_ROLL_SAMPLES = 3840;
    if (configurationData == null
        || configurationData.length < MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE) {
      Log.e(
          TAG,
          "Failed to configure Opus audio codec. "
              + (configurationData == null
                  ? "|configurationData| is null."
                  : String.format(
                      Locale.US,
                      "Configuration data size (%d) is less than the required size (%d).",
                      configurationData.length,
                      MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE)));
      return false;
    }
    // Both the number of samples to skip from the beginning of the stream and the amount of time
    // to pre-roll when seeking must be specified when configuring the Opus decoder. Logic adapted
    // from ExoPlayer:
    // https://github.com/google/ExoPlayer/blob/0ba317b1337eaa789f05dd6c5241246478a3d1e5/library/common/src/main/java/com/google/android/exoplayer2/audio/OpusUtil.java#L52.
    int preSkipSamples = ((configurationData[11] & 0xFF) << 8) | (configurationData[10] & 0xFF);
    long preSkipNanos = (preSkipSamples * NANOSECONDS_IN_ONE_SECOND) / sampleRate;
    long seekPreRollNanos =
        (DEFAULT_SEEK_PRE_ROLL_SAMPLES * NANOSECONDS_IN_ONE_SECOND) / sampleRate;
    setCodecSpecificData(format, 0, configurationData);
    setCodecSpecificData(
        format,
        1,
        ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()).putLong(preSkipNanos).array());
    setCodecSpecificData(
        format,
        2,
        ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()).putLong(seekPreRollNanos).array());
    return true;
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private static void setFrameHasADTSHeader(MediaFormat format) {
    format.setInteger(MediaFormat.KEY_IS_ADTS, 1);
  }

  @SuppressWarnings("unused")
  @UsedByNative
  private boolean configureAudio(MediaFormat format, MediaCrypto crypto, int flags) {
    try {
      mMediaCodec.configure(format, null, crypto, flags);
      return true;
    } catch (IllegalArgumentException | IllegalStateException e) {
      Log.e(TAG, "Cannot configure the audio codec", e);
    } catch (MediaCodec.CryptoException e) {
      Log.e(TAG, "Cannot configure the audio codec: DRM error", e);
    } catch (Exception e) {
      Log.e(TAG, "Cannot configure the audio codec", e);
    }
    return false;
  }

  private void resetLastPresentationTimeIfNeeded(long presentationTimeUs) {
    if (mFlushed) {
      mLastPresentationTimeUs =
          Math.max(presentationTimeUs - MAX_PRESENTATION_TIMESTAMP_SHIFT_US, 0);
      mFlushed = false;
    }
  }

  @SuppressWarnings("deprecation")
  private int getAudioFormat(int channelCount) {
    switch (channelCount) {
      case 1:
        return AudioFormat.CHANNEL_OUT_MONO;
      case 2:
        return AudioFormat.CHANNEL_OUT_STEREO;
      case 4:
        return AudioFormat.CHANNEL_OUT_QUAD;
      case 6:
        return AudioFormat.CHANNEL_OUT_5POINT1;
      case 8:
        return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
      default:
        return AudioFormat.CHANNEL_OUT_DEFAULT;
    }
  }

  private native void nativeOnMediaCodecError(
      long nativeMediaCodecBridge,
      boolean isRecoverable,
      boolean isTransient,
      String diagnosticInfo);

  private native void nativeOnMediaCodecInputBufferAvailable(
      long nativeMediaCodecBridge, int bufferIndex);

  private native void nativeOnMediaCodecOutputBufferAvailable(
      long nativeMediaCodecBridge,
      int bufferIndex,
      int flags,
      int offset,
      long presentationTimeUs,
      int size);

  private native void nativeOnMediaCodecOutputFormatChanged(long nativeMediaCodecBridge);

  private native void nativeOnMediaCodecFrameRendered(
      long nativeMediaCodecBridge, long presentationTimeUs, long renderAtSystemTimeNs);
}
