/*
 *  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.util.Log;

import java.util.Arrays;
import java.util.LinkedHashSet;

import javax.annotation.Nullable;

import cn.tee3.avd.AVDEngine;

public class DefaultVideoEncoderFactory implements VideoEncoderFactory {
  private static final String TAG = "DefaultVideoEncoderFactory";
  private final VideoEncoderFactory hardwareVideoEncoderFactory;
  private final VideoEncoderFactory softwareVideoEncoderFactory;

  public DefaultVideoEncoderFactory(
      EglBase.Context eglContext, boolean enableIntelVp8Encoder, boolean enableH264HighProfile) {
    hardwareVideoEncoderFactory = new HardwareVideoEncoderFactory(
        eglContext, enableIntelVp8Encoder, enableH264HighProfile, false /* fallbackToSoftware */);
    softwareVideoEncoderFactory = new SoftwareVideoEncoderFactory();
  }

  /* This is used for testing. */
  DefaultVideoEncoderFactory(VideoEncoderFactory hardwareVideoEncoderFactory) {
    this.hardwareVideoEncoderFactory = hardwareVideoEncoderFactory;
    softwareVideoEncoderFactory = new SoftwareVideoEncoderFactory();
  }

  @Nullable
  @Override
  public VideoEncoder createEncoder(VideoCodecInfo info) {
    String string = AVDEngine.instance().getOption(AVDEngine.Option.eo_video_codec_hw_encode);
    if ("true".equals(string)){
      final VideoEncoder videoEncoder = hardwareVideoEncoderFactory.createEncoder(info);
      if (videoEncoder != null) {
        Logging.d(TAG, "createEncoder hardware: "+ info.name);
        return videoEncoder;
      }
    }
    Logging.d(TAG, "createEncoder software: "+ info.name);
    return softwareVideoEncoderFactory.createEncoder(info);
  }

  @Override
  public VideoCodecInfo[] getSupportedCodecs() {
    LinkedHashSet<VideoCodecInfo> supportedCodecInfos = new LinkedHashSet<VideoCodecInfo>();
    supportedCodecInfos.addAll(Arrays.asList(softwareVideoEncoderFactory.getSupportedCodecs()));
    VideoCodecInfo[] codecs = hardwareVideoEncoderFactory.getSupportedCodecs();
    for (VideoCodecInfo videoCodecInfo : codecs) {
      if ("H264".equals(videoCodecInfo.name) && !VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1.equals(videoCodecInfo.params.get(VideoCodecInfo.H264_FMTP_PROFILE_LEVEL_ID))) {
        supportedCodecInfos.add(videoCodecInfo);
      }
      else if ("H265".equals(videoCodecInfo.name)) {
        supportedCodecInfos.add(videoCodecInfo);
      }
    }

    return supportedCodecInfos.toArray(new VideoCodecInfo[supportedCodecInfos.size()]);
  }
}
