/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package tee3.webrtc;

import android.annotation.TargetApi;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import tee3.webrtc.voiceengine.BuildInfo;

/** Container class for static constants and helpers used with MediaCodec. */
@TargetApi(18)
// We are forced to use the old API because we want to support API level < 21.
@SuppressWarnings("deprecation")
class MediaCodecUtils {
  private static final String TAG = "MediaCodecUtils";

  // Prefixes for supported hardware encoder/decoder component names.
  static final String EXYNOS_PREFIX = "OMX.Exynos.";
  static final String INTEL_PREFIX = "OMX.Intel.";
  static final String NVIDIA_PREFIX = "OMX.Nvidia.";
  static final String QCOM_PREFIX = "OMX.qcom.";
  static final String AVD_PREFIXS[] = new String[]{}; //"OMX.amlogic.","OMX.Intel.","OMX.Exynos.","OMX.qcom.","OMX.Nvidia.","OMX.rk.","OMX.MTK."


  // NV12 color format supported by QCOM codec, but not declared in MediaCodec -
  // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h
  static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar32m4ka = 0x7FA30C01;
  static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar16m4ka = 0x7FA30C02;
  static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
  static final int COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04;

  // Color formats supported by hardware decoder - in order of preference.
  static final int[] DECODER_COLOR_FORMATS = new int[] {
          CodecCapabilities.COLOR_FormatYUV420Planar,
          CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
          CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
      MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar32m4ka,
      MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar16m4ka,
      MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar64x32Tile2m8ka,
      MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m};

  // Color formats supported by hardware encoder - in order of preference.
  static final int[] ENCODER_COLOR_FORMATS = {
          CodecCapabilities.COLOR_FormatYUV420Planar,
          CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
          CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
      MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m};

  // Color formats supported by texture mode encoding - in order of preference.
  static final int[] TEXTURE_COLOR_FORMATS = {CodecCapabilities.COLOR_FormatSurface};

  /* HUAWEI not support CodecCapabilities.COLOR_FormatYUV420Planar£¬Sumsung not support CodecCapabilities.COLOR_FormatYUV420SemiPlanar */
  static @Nullable Integer selectColorFormat(
      int[] supportedColorFormats, CodecCapabilities capabilities) {
    for (int supportedColorFormat : supportedColorFormats) {
      for (int codecColorFormat : capabilities.colorFormats) {
        if (codecColorFormat == supportedColorFormat) {
          if ("HUAWEI".equals(BuildInfo.getDeviceManufacturer()) && supportedColorFormat == CodecCapabilities.COLOR_FormatYUV420Planar) {
            continue;
          }
          return codecColorFormat;
        }
      }
    }
    return null;
  }

  static boolean codecSupportsType(MediaCodecInfo info, VideoCodecType type) {
    for (String mimeType : info.getSupportedTypes()) {
      if (type.mimeType().equals(mimeType)) {
        return true;
      }
    }
    return false;
  }

  static Map<String, String> getCodecProperties(VideoCodecType type, boolean highProfile) {
    switch (type) {
      case VP8:
      case VP9:
        return new HashMap<String, String>();
      case H264:
        Map<String, String> properties = new HashMap<>();
        properties.put(VideoCodecInfo.H264_FMTP_LEVEL_ASYMMETRY_ALLOWED, "1");
        properties.put(VideoCodecInfo.H264_FMTP_PACKETIZATION_MODE, "1");
        properties.put(VideoCodecInfo.H264_FMTP_PROFILE_LEVEL_ID,
                highProfile ? VideoCodecInfo.H264_CONSTRAINED_HIGH_3_1
                        : VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1);
        return properties;
      case H265:
        Map<String, String> properties265 = new HashMap<>();
        properties265.put(VideoCodecInfo.H264_FMTP_LEVEL_ASYMMETRY_ALLOWED, "1");
        properties265.put(VideoCodecInfo.H264_FMTP_PACKETIZATION_MODE, "1");
        return properties265;
      default:
        throw new IllegalArgumentException("Unsupported codec: " + type);
    }
  }

  static boolean isInAVD_PREFIXS(MediaCodecInfo info) {
    String codecname = info.getName();
    for (String item : AVD_PREFIXS) {
      if (codecname.startsWith(item)) {
        return false;
      }
    }
    return true;
  }

  private MediaCodecUtils() {
    // This class should not be instantiated.
  }
}
