/*
 *  Copyright 2015 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.
 */

// NOTICE: androidmediaencoder_jni.h must be included before
// androidmediacodeccommon.h to avoid build errors.
#include "sdk/android/src/jni/androidmediaencoder_jni.h"

#include <algorithm>
#include <list>
#include <memory>
#include <string>
#include <utility>

#include "api/video_codecs/video_encoder.h"
#include "common_types.h"  // NOLINT(build/include)
#include "common_video/h264/h264_bitstream_parser.h"
#include "common_video/h264/h264_common.h"
#include "common_video/h264/profile_level_id.h"
#include "media/engine/internalencoderfactory.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/utility/quality_scaler.h"
#include "modules/video_coding/utility/vp8_header_parser.h"
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/random.h"
#include "rtc_base/sequenced_task_checker.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread.h"
#include "rtc_base/timeutils.h"
#include "rtc_base/weak_ptr.h"
#include "sdk/android/generated_video_jni/jni/MediaCodecVideoEncoder_jni.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/src/jni/androidmediacodeccommon.h"
#include "sdk/android/src/jni/androidmediadecoder_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/videoframe.h"
#include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/convert_from.h"
#include "third_party/libyuv/include/libyuv/video_common.h"

using rtc::Bind;
using rtc::Thread;
using rtc::ThreadManager;

namespace webrtc {
namespace jni {

// Maximum supported HW video encoder fps.
#define MAX_VIDEO_FPS 30
// Maximum allowed fps value in SetRates() call.
#define MAX_ALLOWED_VIDEO_FPS 60
// Maximum allowed frames in encoder input queue.
#define MAX_ENCODER_Q_SIZE 2
// Maximum amount of dropped frames caused by full encoder queue - exceeding
// this threshold means that encoder probably got stuck and need to be reset.
#define ENCODER_STALL_FRAMEDROP_THRESHOLD 60

// Logging macros.
#define TAG_ENCODER "MediaCodecVideoEncoder"
#ifdef TRACK_BUFFER_TIMING
#define ALOGV(...)
__android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__)
#else
#define ALOGV(...)
#endif
#define ALOGD RTC_LOG_TAG(rtc::LS_INFO, TAG_ENCODER)
#define ALOGW RTC_LOG_TAG(rtc::LS_WARNING, TAG_ENCODER)
#define ALOGE RTC_LOG_TAG(rtc::LS_ERROR, TAG_ENCODER)

namespace {
  // Maximum time limit between incoming frames before requesting a key frame.
  const size_t kFrameDiffThresholdMs = 350;
  const int kMinKeyFrameInterval = 6;
  const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile";
  const char kCustomQPThresholdsFieldTrial[] = "WebRTC-CustomQPThresholds";
}  // namespace

// MediaCodecVideoEncoder is a VideoEncoder implementation that uses
// Android's MediaCodec SDK API behind the scenes to implement (hopefully)
// HW-backed video encode.  This C++ class is implemented as a very thin shim,
// delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder.
// MediaCodecVideoEncoder must be operated on a single task queue, currently
// this is the encoder queue from ViE encoder.
class MediaCodecVideoEncoder : public VideoEncoder {
 public:
  virtual ~MediaCodecVideoEncoder();
  MediaCodecVideoEncoder(JNIEnv* jni,
                         const cricket::VideoCodec& codec,
                         jobject egl_context);

  // VideoEncoder implementation.
  int32_t InitEncode(const VideoCodec* codec_settings,
                     int32_t /* number_of_cores */,
                     size_t /* max_payload_size */) override;
  int32_t Encode(const VideoFrame& input_image,
                 const CodecSpecificInfo* /* codec_specific_info */,
                 const std::vector<FrameType>* frame_types) override;
  int32_t RegisterEncodeCompleteCallback(
      EncodedImageCallback* callback) override;
  int32_t Release() override;
  int32_t SetChannelParameters(uint32_t /* packet_loss */,
                               int64_t /* rtt */) override;
  int32_t SetRateAllocation(const BitrateAllocation& rate_allocation,
                            uint32_t frame_rate) override;

  bool SupportsNativeHandle() const override { return egl_context_ != nullptr; }
  const char* ImplementationName() const override;

  // Fills the input buffer with data from the buffers passed as parameters.
  bool FillInputBuffer(JNIEnv* jni,
                       int input_buffer_index,
                       uint8_t const* buffer_y,
                       int stride_y,
                       uint8_t const* buffer_u,
                       int stride_u,
                       uint8_t const* buffer_v,
                       int stride_v);

 private:
  class EncodeTask : public rtc::QueuedTask {
   public:
    explicit EncodeTask(rtc::WeakPtr<MediaCodecVideoEncoder> encoder);
    bool Run() override;

   private:
    rtc::WeakPtr<MediaCodecVideoEncoder> encoder_;
  };

  // ResetCodec() calls Release() and InitEncodeInternal() in an attempt to
  // restore the codec to an operable state. Necessary after all manner of
  // OMX-layer errors. Returns true if the codec was reset successfully.
  bool ResetCodec();

  // Fallback to a software encoder if one is supported else try to reset the
  // encoder. Called with |reset_if_fallback_unavailable| equal to false from
  // init/release encoder so that we don't go into infinite recursion.
  // Returns true if the codec was reset successfully.
  bool ProcessHWError(bool reset_if_fallback_unavailable);

  // Calls ProcessHWError(true). Returns WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE if
  // sw_fallback_required_ was set or WEBRTC_VIDEO_CODEC_ERROR otherwise.
  int32_t ProcessHWErrorOnEncode();

  // If width==0 then this is assumed to be a re-initialization and the
  // previously-current values are reused instead of the passed parameters
  // (makes it easier to reason about thread-safety).
  int32_t InitEncodeInternal(int width,
                             int height,
                             int kbps,
                             int fps,
                             bool use_surface);
  // Reconfigure to match |frame| in width, height. Also reconfigures the
  // encoder if |frame| is a texture/byte buffer and the encoder is initialized
  // for byte buffer/texture. Returns false if reconfiguring fails.
  bool MaybeReconfigureEncoder(JNIEnv* jni, const VideoFrame& frame);

  // Returns true if the frame is a texture frame and we should use surface
  // based encoding.
  bool IsTextureFrame(JNIEnv* jni, const VideoFrame& frame);

  bool EncodeByteBuffer(JNIEnv* jni,
                        bool key_frame,
                        const VideoFrame& frame,
                        int input_buffer_index);
  bool EncodeTexture(JNIEnv* jni, bool key_frame, const VideoFrame& frame);
  // Encodes a new style org.webrtc.VideoFrame. Might be a I420 or a texture
  // frame.
  bool EncodeJavaFrame(JNIEnv* jni,
                       bool key_frame,
                       const JavaRef<jobject>& frame,
                       int input_buffer_index);

  // Deliver any outputs pending in the MediaCodec to our |callback_| and return
  // true on success.
  bool DeliverPendingOutputs(JNIEnv* jni);

  VideoEncoder::ScalingSettings GetScalingSettings() const override;

  // Displays encoder statistics.
  void LogStatistics(bool force_log);

  VideoCodecType GetCodecType() const;

#if RTC_DCHECK_IS_ON
  // Mutex for protecting inited_. It is only used for correctness checking on
  // debug build. It is used for checking that encoder has been released in the
  // destructor. Because this might happen on a different thread, we need a
  // mutex.
  rtc::CriticalSection inited_crit_;
#endif

  // Type of video codec.
  const cricket::VideoCodec codec_;

  EncodedImageCallback* callback_;

  // State that is constant for the lifetime of this object once the ctor
  // returns.
  rtc::SequencedTaskChecker encoder_queue_checker_;
  ScopedJavaGlobalRef<jobject> j_media_codec_video_encoder_;

  // State that is valid only between InitEncode() and the next Release().
  int width_;   // Frame width in pixels.
  int height_;  // Frame height in pixels.
  bool inited_;
  bool use_surface_;
  enum libyuv::FourCC encoder_fourcc_;  // Encoder color space format.
  int last_set_bitrate_kbps_;  // Last-requested bitrate in kbps.
  int last_set_fps_;  // Last-requested frame rate.
  int64_t current_timestamp_us_;  // Current frame timestamps in us.
  int frames_received_;  // Number of frames received by encoder.
  int frames_encoded_;  // Number of frames encoded by encoder.
  int frames_dropped_media_encoder_;  // Number of frames dropped by encoder.
  // Number of dropped frames caused by full queue.
  int consecutive_full_queue_frame_drops_;
  int64_t stat_start_time_ms_;  // Start time for statistics.
  int current_frames_;  // Number of frames in the current statistics interval.
  int current_bytes_;  // Encoded bytes in the current statistics interval.
  int current_acc_qp_;  // Accumulated QP in the current statistics interval.
  int current_encoding_time_ms_;  // Overall encoding time in the current second
  int64_t last_input_timestamp_ms_;  // Timestamp of last received yuv frame.
  int64_t last_output_timestamp_ms_;  // Timestamp of last encoded frame.
  // Holds the task while the polling loop is paused.
  std::unique_ptr<rtc::QueuedTask> encode_task_;

  struct InputFrameInfo {
    InputFrameInfo(int64_t encode_start_time,
                   int32_t frame_timestamp,
                   int64_t frame_render_time_ms,
                   VideoRotation rotation)
        : encode_start_time(encode_start_time),
          frame_timestamp(frame_timestamp),
          frame_render_time_ms(frame_render_time_ms),
          rotation(rotation) {}
    // Time when video frame is sent to encoder input.
    const int64_t encode_start_time;

    // Input frame information.
    const int32_t frame_timestamp;
    const int64_t frame_render_time_ms;
    const VideoRotation rotation;
  };
  std::list<InputFrameInfo> input_frame_infos_;
  int32_t output_timestamp_;       // Last output frame timestamp from
                                   // |input_frame_infos_|.
  int64_t output_render_time_ms_;  // Last output frame render time from
                                   // |input_frame_infos_|.
  VideoRotation output_rotation_;  // Last output frame rotation from
                                   // |input_frame_infos_|.

  // Frame size in bytes fed to MediaCodec.
  int yuv_size_;
  // True only when between a callback_->OnEncodedImage() call return a positive
  // value and the next Encode() call being ignored.
  bool drop_next_input_frame_;
  bool scale_;
  H264::Profile profile_;
  // Global references; must be deleted in Release().
  std::vector<ScopedJavaGlobalRef<jobject>> input_buffers_;
  H264BitstreamParser h264_bitstream_parser_;

  // VP9 variables to populate codec specific structure.
  GofInfoVP9 gof_;  // Contains each frame's temporal information for
                    // non-flexible VP9 mode.
  size_t gof_idx_;

  // EGL context - owned by factory, should not be allocated/destroyed
  // by MediaCodecVideoEncoder.
  jobject egl_context_;

  // Temporary fix for VP8.
  // Sends a key frame if frames are largely spaced apart (possibly
  // corresponding to a large image change).
  int64_t last_frame_received_ms_;
  int frames_received_since_last_key_;
  VideoCodecMode codec_mode_;

  // RTP state.
  uint16_t picture_id_;
  uint8_t tl0_pic_idx_;

  bool sw_fallback_required_;

  // All other member variables should be before WeakPtrFactory. Valid only from
  // InitEncode to Release.
  std::unique_ptr<rtc::WeakPtrFactory<MediaCodecVideoEncoder>> weak_factory_;
};

MediaCodecVideoEncoder::~MediaCodecVideoEncoder() {
#if RTC_DCHECK_IS_ON
  rtc::CritScope lock(&inited_crit_);
  RTC_DCHECK(!inited_);
#endif
}

MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni,
                                               const cricket::VideoCodec& codec,
                                               jobject egl_context)
    : codec_(codec),
      callback_(NULL),
      j_media_codec_video_encoder_(
          jni,
          Java_MediaCodecVideoEncoder_Constructor(jni)),
      inited_(false),
      use_surface_(false),
      egl_context_(egl_context),
      sw_fallback_required_(false) {
  encoder_queue_checker_.Detach();

  Random random(rtc::TimeMicros());
  picture_id_ = random.Rand<uint16_t>() & 0x7FFF;
  tl0_pic_idx_ = random.Rand<uint8_t>();
}

int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings,
                                           int32_t /* number_of_cores */,
                                           size_t /* max_payload_size */) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  if (codec_settings == NULL) {
    ALOGE << "NULL VideoCodec instance";
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  // Factory should guard against other codecs being used with us.
  const VideoCodecType codec_type = GetCodecType();
  RTC_CHECK(codec_settings->codecType == codec_type)
      << "Unsupported codec " << codec_settings->codecType << " for "
      << codec_type;
  if (sw_fallback_required_) {
    return WEBRTC_VIDEO_CODEC_OK;
  }
  codec_mode_ = codec_settings->mode;
  int init_width = codec_settings->width;
  int init_height = codec_settings->height;
  // Scaling is optionally enabled for VP8 and VP9.
  // TODO(pbos): Extract automaticResizeOn out of VP8 settings.
  scale_ = false;
  if (codec_type == kVideoCodecVP8) {
    scale_ = codec_settings->VP8().automaticResizeOn;
  } else if (codec_type == kVideoCodecVP9) {
    scale_ = codec_settings->VP9().automaticResizeOn;
  } else {
    scale_ = true;
  }

  ALOGD << "InitEncode request: " << init_width << " x " << init_height;
  ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled");

  // Check allowed H.264 profile
  profile_ = H264::Profile::kProfileBaseline;
  if (codec_type == kVideoCodecH264) {
    const rtc::Optional<H264::ProfileLevelId> profile_level_id =
        H264::ParseSdpProfileLevelId(codec_.params);
    RTC_DCHECK(profile_level_id);
    profile_ = profile_level_id->profile;
    ALOGD << "H.264 profile: " << profile_;
  }

  return InitEncodeInternal(
      init_width, init_height, codec_settings->startBitrate,
      codec_settings->maxFramerate,
      codec_settings->expect_encode_from_texture && (egl_context_ != nullptr));
}

int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */,
                                                     int64_t /* rtt */) {
  return WEBRTC_VIDEO_CODEC_OK;
}

bool MediaCodecVideoEncoder::ResetCodec() {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  ALOGE << "Reset";
  if (Release() != WEBRTC_VIDEO_CODEC_OK) {
    ALOGE << "Releasing codec failed during reset.";
    return false;
  }
  if (InitEncodeInternal(width_, height_, 0, 0, false) !=
      WEBRTC_VIDEO_CODEC_OK) {
    ALOGE << "Initializing encoder failed during reset.";
    return false;
  }
  return true;
}

MediaCodecVideoEncoder::EncodeTask::EncodeTask(
    rtc::WeakPtr<MediaCodecVideoEncoder> encoder)
    : encoder_(encoder) {}

bool MediaCodecVideoEncoder::EncodeTask::Run() {
  if (!encoder_) {
    // Encoder was destroyed.
    return true;
  }

  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_->encoder_queue_checker_);
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);

  if (!encoder_->inited_) {
    encoder_->encode_task_ = std::unique_ptr<rtc::QueuedTask>(this);
    return false;
  }

  // It would be nice to recover from a failure here if one happened, but it's
  // unclear how to signal such a failure to the app, so instead we stay silent
  // about it and let the next app-called API method reveal the borkedness.
  encoder_->DeliverPendingOutputs(jni);

  if (!encoder_) {
    // Encoder can be destroyed in DeliverPendingOutputs.
    return true;
  }

  // Call log statistics here so it's called even if no frames are being
  // delivered.
  encoder_->LogStatistics(false);

  // If there aren't more frames to deliver, we can start polling at lower rate.
  if (encoder_->input_frame_infos_.empty()) {
    rtc::TaskQueue::Current()->PostDelayedTask(
        std::unique_ptr<rtc::QueuedTask>(this), kMediaCodecPollNoFramesMs);
  } else {
    rtc::TaskQueue::Current()->PostDelayedTask(
        std::unique_ptr<rtc::QueuedTask>(this), kMediaCodecPollMs);
  }

  return false;
}

bool IsFormatSupported(
    const std::vector<webrtc::SdpVideoFormat>& supported_formats,
    const std::string& name) {
  for (const webrtc::SdpVideoFormat& supported_format : supported_formats) {
    if (cricket::CodecNamesEq(name, supported_format.name))
      return true;
  }
  return false;
}

bool MediaCodecVideoEncoder::ProcessHWError(
    bool reset_if_fallback_unavailable) {
  ALOGE << "ProcessHWError";
  if (IsFormatSupported(InternalEncoderFactory().GetSupportedFormats(),
                        codec_.name)) {
    ALOGE << "Fallback to SW encoder.";
    sw_fallback_required_ = true;
    return false;
  } else if (reset_if_fallback_unavailable) {
    ALOGE << "Reset encoder.";
    return ResetCodec();
  }
  return false;
}

int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncode() {
  ProcessHWError(true /* reset_if_fallback_unavailable */);
  return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE
                               : WEBRTC_VIDEO_CODEC_ERROR;
}

VideoCodecType MediaCodecVideoEncoder::GetCodecType() const {
  return PayloadStringToCodecType(codec_.name);
}

int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
                                                   int height,
                                                   int kbps,
                                                   int fps,
                                                   bool use_surface) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  if (sw_fallback_required_) {
    return WEBRTC_VIDEO_CODEC_OK;
  }
  RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set.";
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);

  const VideoCodecType codec_type = GetCodecType();
  ALOGD << "InitEncodeInternal Type: " << static_cast<int>(codec_type) << ", "
        << width << " x " << height << ". Bitrate: " << kbps
        << " kbps. Fps: " << fps << ". Profile: " << profile_ << ".";
  if (kbps == 0) {
    kbps = last_set_bitrate_kbps_;
  }
  if (fps == 0) {
    fps = MAX_VIDEO_FPS;
  }

  width_ = width;
  height_ = height;
  last_set_bitrate_kbps_ = kbps;
  last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS;
  yuv_size_ = width_ * height_ * 3 / 2;
  frames_received_ = 0;
  frames_encoded_ = 0;
  frames_dropped_media_encoder_ = 0;
  consecutive_full_queue_frame_drops_ = 0;
  current_timestamp_us_ = 0;
  stat_start_time_ms_ = rtc::TimeMillis();
  current_frames_ = 0;
  current_bytes_ = 0;
  current_acc_qp_ = 0;
  current_encoding_time_ms_ = 0;
  last_input_timestamp_ms_ = -1;
  last_output_timestamp_ms_ = -1;
  output_timestamp_ = 0;
  output_render_time_ms_ = 0;
  input_frame_infos_.clear();
  drop_next_input_frame_ = false;
  use_surface_ = use_surface;
  gof_.SetGofInfoVP9(TemporalStructureMode::kTemporalStructureMode1);
  gof_idx_ = 0;
  last_frame_received_ms_ = -1;
  frames_received_since_last_key_ = kMinKeyFrameInterval;

  // We enforce no extra stride/padding in the format creation step.
  ScopedJavaLocalRef<jobject> j_video_codec_enum =
      Java_VideoCodecType_fromNativeIndex(jni, codec_type);
  const bool encode_status = Java_MediaCodecVideoEncoder_initEncode(
      jni, j_media_codec_video_encoder_, j_video_codec_enum, profile_, width,
      height, kbps, fps,
      JavaParamRef<jobject>(use_surface ? egl_context_ : nullptr));
  if (!encode_status) {
    ALOGE << "Failed to configure encoder.";
    ProcessHWError(false /* reset_if_fallback_unavailable */);
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  if (CheckException(jni)) {
    ALOGE << "Exception in init encode.";
    ProcessHWError(false /* reset_if_fallback_unavailable */);
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  if (!use_surface) {
    ScopedJavaLocalRef<jobjectArray> input_buffers =
        Java_MediaCodecVideoEncoder_getInputBuffers(
            jni, j_media_codec_video_encoder_);
    if (CheckException(jni)) {
      ALOGE << "Exception in get input buffers.";
      ProcessHWError(false /* reset_if_fallback_unavailable */);
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    if (IsNull(jni, input_buffers)) {
      ProcessHWError(false /* reset_if_fallback_unavailable */);
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    switch (Java_MediaCodecVideoEncoder_getColorFormat(
        jni, j_media_codec_video_encoder_)) {
      case COLOR_FormatYUV420Planar:
        encoder_fourcc_ = libyuv::FOURCC_YU12;
        break;
      case COLOR_FormatYUV420SemiPlanar:
      case COLOR_QCOM_FormatYUV420SemiPlanar:
      case COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m:
        encoder_fourcc_ = libyuv::FOURCC_NV12;
        break;
      default:
        RTC_LOG(LS_ERROR) << "Wrong color format.";
        ProcessHWError(false /* reset_if_fallback_unavailable */);
        return WEBRTC_VIDEO_CODEC_ERROR;
    }

    RTC_CHECK(input_buffers_.empty())
        << "Unexpected double InitEncode without Release";
    input_buffers_ = JavaToNativeVector<ScopedJavaGlobalRef<jobject>>(
        jni, input_buffers, [](JNIEnv* env, const JavaRef<jobject>& o) {
          return ScopedJavaGlobalRef<jobject>(env, o);
        });
    for (const ScopedJavaGlobalRef<jobject>& buffer : input_buffers_) {
      int64_t yuv_buffer_capacity = jni->GetDirectBufferCapacity(buffer.obj());
      if (CheckException(jni)) {
        ALOGE << "Exception in get direct buffer capacity.";
        ProcessHWError(false /* reset_if_fallback_unavailable */);
        return WEBRTC_VIDEO_CODEC_ERROR;
      }
      RTC_CHECK(yuv_buffer_capacity >= yuv_size_) << "Insufficient capacity";
    }
  }

  {
#if RTC_DCHECK_IS_ON
    rtc::CritScope lock(&inited_crit_);
#endif
    inited_ = true;
  }
  weak_factory_.reset(new rtc::WeakPtrFactory<MediaCodecVideoEncoder>(this));
  encode_task_.reset(new EncodeTask(weak_factory_->GetWeakPtr()));

  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t MediaCodecVideoEncoder::Encode(
    const VideoFrame& frame,
    const CodecSpecificInfo* /* codec_specific_info */,
    const std::vector<FrameType>* frame_types) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  if (sw_fallback_required_)
    return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);
  const int64_t frame_input_time_ms = rtc::TimeMillis();

  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  bool send_key_frame = false;
  if (codec_mode_ == kRealtimeVideo) {
    ++frames_received_since_last_key_;
    int64_t now_ms = rtc::TimeMillis();
    if (last_frame_received_ms_ != -1 &&
        (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) {
      // Add limit to prevent triggering a key for every frame for very low
      // framerates (e.g. if frame diff > kFrameDiffThresholdMs).
      if (frames_received_since_last_key_ > kMinKeyFrameInterval) {
        ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_);
        send_key_frame = true;
      }
      frames_received_since_last_key_ = 0;
    }
    last_frame_received_ms_ = now_ms;
  }

  frames_received_++;
  if (!DeliverPendingOutputs(jni)) {
    if (!ProcessHWError(true /* reset_if_fallback_unavailable */)) {
      return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE
                                   : WEBRTC_VIDEO_CODEC_ERROR;
    }
  }
  if (frames_encoded_ < kMaxEncodedLogFrames) {
    ALOGD << "Encoder frame in # " << (frames_received_ - 1)
          << ". TS: " << static_cast<int>(current_timestamp_us_ / 1000)
          << ". Q: " << input_frame_infos_.size() << ". Fps: " << last_set_fps_
          << ". Kbps: " << last_set_bitrate_kbps_;
  }

  if (drop_next_input_frame_) {
    ALOGW << "Encoder drop frame - failed callback.";
    drop_next_input_frame_ = false;
    current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
    frames_dropped_media_encoder_++;
    return WEBRTC_VIDEO_CODEC_OK;
  }

  RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";

  // Check if we accumulated too many frames in encoder input buffers and drop
  // frame if so.
  if (input_frame_infos_.size() > MAX_ENCODER_Q_SIZE) {
    ALOGD << "Already " << input_frame_infos_.size()
          << " frames in the queue, dropping"
          << ". TS: " << static_cast<int>(current_timestamp_us_ / 1000)
          << ". Fps: " << last_set_fps_
          << ". Consecutive drops: " << consecutive_full_queue_frame_drops_;
    current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
    consecutive_full_queue_frame_drops_++;
    if (consecutive_full_queue_frame_drops_ >=
        ENCODER_STALL_FRAMEDROP_THRESHOLD) {
      ALOGE << "Encoder got stuck.";
      return ProcessHWErrorOnEncode();
    }
    frames_dropped_media_encoder_++;
    return WEBRTC_VIDEO_CODEC_OK;
  }
  consecutive_full_queue_frame_drops_ = 0;

  rtc::scoped_refptr<VideoFrameBuffer> input_buffer(frame.video_frame_buffer());

  VideoFrame input_frame(input_buffer, frame.timestamp(),
                         frame.render_time_ms(), frame.rotation());

  if (!MaybeReconfigureEncoder(jni, input_frame)) {
    ALOGE << "Failed to reconfigure encoder.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  const bool key_frame =
      frame_types->front() != kVideoFrameDelta || send_key_frame;
  bool encode_status = true;

  int j_input_buffer_index = -1;
  if (!use_surface_) {
    j_input_buffer_index = Java_MediaCodecVideoEncoder_dequeueInputBuffer(
        jni, j_media_codec_video_encoder_);
    if (CheckException(jni)) {
      ALOGE << "Exception in dequeu input buffer.";
      return ProcessHWErrorOnEncode();
    }
    if (j_input_buffer_index == -1) {
      // Video codec falls behind - no input buffer available.
      ALOGW << "Encoder drop frame - no input buffers available";
      if (frames_received_ > 1) {
        current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
        frames_dropped_media_encoder_++;
      } else {
        // Input buffers are not ready after codec initialization, HW is still
        // allocating thme - this is expected and should not result in drop
        // frame report.
        frames_received_ = 0;
      }
      return WEBRTC_VIDEO_CODEC_OK;  // TODO(fischman): see webrtc bug 2887.
    } else if (j_input_buffer_index == -2) {
      return ProcessHWErrorOnEncode();
    }
  }

  if (input_frame.video_frame_buffer()->type() !=
      VideoFrameBuffer::Type::kNative) {
    encode_status =
        EncodeByteBuffer(jni, key_frame, input_frame, j_input_buffer_index);
  } else {
    AndroidVideoFrameBuffer* android_buffer =
        static_cast<AndroidVideoFrameBuffer*>(
            input_frame.video_frame_buffer().get());
    switch (android_buffer->android_type()) {
      case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer:
        encode_status = EncodeTexture(jni, key_frame, input_frame);
        break;
      case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer: {
        ScopedJavaLocalRef<jobject> j_frame =
            NativeToJavaVideoFrame(jni, frame);
        encode_status =
            EncodeJavaFrame(jni, key_frame, j_frame, j_input_buffer_index);
        ReleaseJavaVideoFrame(jni, j_frame);
        break;
      }
      default:
        RTC_NOTREACHED();
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
  }

  if (!encode_status) {
    ALOGE << "Failed encode frame with timestamp: " << input_frame.timestamp();
    return ProcessHWErrorOnEncode();
  }

  // Save input image timestamps for later output.
  input_frame_infos_.emplace_back(frame_input_time_ms, input_frame.timestamp(),
                                  input_frame.render_time_ms(),
                                  input_frame.rotation());

  last_input_timestamp_ms_ =
      current_timestamp_us_ / rtc::kNumMicrosecsPerMillisec;

  current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;

  // Start the polling loop if it is not started.
  if (encode_task_) {
    rtc::TaskQueue::Current()->PostDelayedTask(std::move(encode_task_),
                                               kMediaCodecPollMs);
  }

  if (!DeliverPendingOutputs(jni)) {
    return ProcessHWErrorOnEncode();
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

bool MediaCodecVideoEncoder::MaybeReconfigureEncoder(JNIEnv* jni,
                                                     const VideoFrame& frame) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);

  bool is_texture = IsTextureFrame(jni, frame);
  const bool reconfigure_due_to_format = is_texture != use_surface_;
  const bool reconfigure_due_to_size =
      frame.width() != width_ || frame.height() != height_;

  if (reconfigure_due_to_format) {
      ALOGD << "Reconfigure encoder due to format change. "
            << (use_surface_ ?
                "Reconfiguring to encode from byte buffer." :
                "Reconfiguring to encode from texture.");
      LogStatistics(true);
  }
  if (reconfigure_due_to_size) {
    ALOGW << "Reconfigure encoder due to frame resolution change from "
        << width_ << " x " << height_ << " to " << frame.width() << " x "
        << frame.height();
    LogStatistics(true);
    width_ = frame.width();
    height_ = frame.height();
  }

  if (!reconfigure_due_to_format && !reconfigure_due_to_size)
    return true;

  Release();

  return InitEncodeInternal(width_, height_, 0, 0, is_texture) ==
         WEBRTC_VIDEO_CODEC_OK;
}

bool MediaCodecVideoEncoder::IsTextureFrame(JNIEnv* jni,
                                            const VideoFrame& frame) {
  if (frame.video_frame_buffer()->type() != VideoFrameBuffer::Type::kNative) {
    return false;
  }

  AndroidVideoFrameBuffer* android_buffer =
      static_cast<AndroidVideoFrameBuffer*>(frame.video_frame_buffer().get());
  switch (android_buffer->android_type()) {
    case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer:
      return true;
    case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer:
      return Java_MediaCodecVideoEncoder_isTextureBuffer(
          jni, static_cast<AndroidVideoBuffer*>(android_buffer)
                   ->video_frame_buffer());
    default:
      RTC_NOTREACHED();
      return false;
  }
}

bool MediaCodecVideoEncoder::EncodeByteBuffer(JNIEnv* jni,
                                              bool key_frame,
                                              const VideoFrame& frame,
                                              int input_buffer_index) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  RTC_CHECK(!use_surface_);

  rtc::scoped_refptr<I420BufferInterface> i420_buffer =
      frame.video_frame_buffer()->ToI420();
  if (!FillInputBuffer(jni, input_buffer_index, i420_buffer->DataY(),
                       i420_buffer->StrideY(), i420_buffer->DataU(),
                       i420_buffer->StrideU(), i420_buffer->DataV(),
                       i420_buffer->StrideV())) {
    return false;
  }
  bool encode_status = Java_MediaCodecVideoEncoder_encodeBuffer(
      jni, j_media_codec_video_encoder_, key_frame, input_buffer_index,
      yuv_size_, current_timestamp_us_);
  if (CheckException(jni)) {
    ALOGE << "Exception in encode buffer.";
    ProcessHWError(true /* reset_if_fallback_unavailable */);
    return false;
  }
  return encode_status;
}

bool MediaCodecVideoEncoder::FillInputBuffer(JNIEnv* jni,
                                             int input_buffer_index,
                                             uint8_t const* buffer_y,
                                             int stride_y,
                                             uint8_t const* buffer_u,
                                             int stride_u,
                                             uint8_t const* buffer_v,
                                             int stride_v) {
  uint8_t* yuv_buffer = reinterpret_cast<uint8_t*>(
      jni->GetDirectBufferAddress(input_buffers_[input_buffer_index].obj()));
  if (CheckException(jni)) {
    ALOGE << "Exception in get direct buffer address.";
    ProcessHWError(true /* reset_if_fallback_unavailable */);
    return false;
  }
  RTC_CHECK(yuv_buffer) << "Indirect buffer??";

  RTC_CHECK(!libyuv::ConvertFromI420(buffer_y, stride_y, buffer_u, stride_u,
                                     buffer_v, stride_v, yuv_buffer, width_,
                                     width_, height_, encoder_fourcc_))
      << "ConvertFromI420 failed";
  return true;
}

bool MediaCodecVideoEncoder::EncodeTexture(JNIEnv* jni,
                                           bool key_frame,
                                           const VideoFrame& frame) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  RTC_CHECK(use_surface_);
  NativeHandleImpl handle =
      static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get())
          ->native_handle_impl();

  bool encode_status = Java_MediaCodecVideoEncoder_encodeTexture(
      jni, j_media_codec_video_encoder_, key_frame, handle.oes_texture_id,
      handle.sampling_matrix.ToJava(jni), current_timestamp_us_);
  if (CheckException(jni)) {
    ALOGE << "Exception in encode texture.";
    ProcessHWError(true /* reset_if_fallback_unavailable */);
    return false;
  }
  return encode_status;
}

bool MediaCodecVideoEncoder::EncodeJavaFrame(JNIEnv* jni,
                                             bool key_frame,
                                             const JavaRef<jobject>& frame,
                                             int input_buffer_index) {
  bool encode_status = Java_MediaCodecVideoEncoder_encodeFrame(
      jni, j_media_codec_video_encoder_, jlongFromPointer(this), key_frame,
      frame, input_buffer_index, current_timestamp_us_);
  if (CheckException(jni)) {
    ALOGE << "Exception in encode frame.";
    ProcessHWError(true /* reset_if_fallback_unavailable */);
    return false;
  }
  return encode_status;
}

int32_t MediaCodecVideoEncoder::RegisterEncodeCompleteCallback(
    EncodedImageCallback* callback) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);
  callback_ = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t MediaCodecVideoEncoder::Release() {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_OK;
  }
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ALOGD << "EncoderRelease: Frames received: " << frames_received_
        << ". Encoded: " << frames_encoded_
        << ". Dropped: " << frames_dropped_media_encoder_;
  encode_task_.reset(nullptr);
  weak_factory_.reset(nullptr);
  ScopedLocalRefFrame local_ref_frame(jni);
  input_buffers_.clear();
  Java_MediaCodecVideoEncoder_release(jni, j_media_codec_video_encoder_);
  if (CheckException(jni)) {
    ALOGE << "Exception in release.";
    ProcessHWError(false /* reset_if_fallback_unavailable */);
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  {
#if RTC_DCHECK_IS_ON
    rtc::CritScope lock(&inited_crit_);
#endif
    inited_ = false;
  }
  use_surface_ = false;
  ALOGD << "EncoderRelease done.";
  // It's legal to move the encoder to another queue now.
  encoder_queue_checker_.Detach();
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t MediaCodecVideoEncoder::SetRateAllocation(
    const BitrateAllocation& rate_allocation,
    uint32_t frame_rate) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
  const uint32_t new_bit_rate = rate_allocation.get_sum_kbps();
  if (sw_fallback_required_)
    return WEBRTC_VIDEO_CODEC_OK;
  frame_rate =
      (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS;
  if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) {
    return WEBRTC_VIDEO_CODEC_OK;
  }
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);
  if (new_bit_rate > 0) {
    last_set_bitrate_kbps_ = new_bit_rate;
  }
  if (frame_rate > 0) {
    last_set_fps_ = frame_rate;
  }
  bool ret = Java_MediaCodecVideoEncoder_setRates(
      jni, j_media_codec_video_encoder_, last_set_bitrate_kbps_, last_set_fps_);
  if (CheckException(jni) || !ret) {
    ProcessHWError(true /* reset_if_fallback_unavailable */);
    return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_OK
                                 : WEBRTC_VIDEO_CODEC_ERROR;
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
  RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);

  while (true) {
    ScopedJavaLocalRef<jobject> j_output_buffer_info =
        Java_MediaCodecVideoEncoder_dequeueOutputBuffer(
            jni, j_media_codec_video_encoder_);
    if (CheckException(jni)) {
      ALOGE << "Exception in set dequeue output buffer.";
      ProcessHWError(true /* reset_if_fallback_unavailable */);
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    if (IsNull(jni, j_output_buffer_info)) {
      break;
    }

    int output_buffer_index =
        Java_OutputBufferInfo_getIndex(jni, j_output_buffer_info);
    if (output_buffer_index == -1) {
      ProcessHWError(true /* reset_if_fallback_unavailable */);
      return false;
    }

    // Get key and config frame flags.
    ScopedJavaLocalRef<jobject> j_output_buffer =
        Java_OutputBufferInfo_getBuffer(jni, j_output_buffer_info);
    bool key_frame =
        Java_OutputBufferInfo_isKeyFrame(jni, j_output_buffer_info);

    // Get frame timestamps from a queue - for non config frames only.
    int64_t encoding_start_time_ms = 0;
    int64_t frame_encoding_time_ms = 0;
    last_output_timestamp_ms_ =
        Java_OutputBufferInfo_getPresentationTimestampUs(jni,
                                                         j_output_buffer_info) /
        rtc::kNumMicrosecsPerMillisec;
    if (!input_frame_infos_.empty()) {
      const InputFrameInfo& frame_info = input_frame_infos_.front();
      output_timestamp_ = frame_info.frame_timestamp;
      output_render_time_ms_ = frame_info.frame_render_time_ms;
      output_rotation_ = frame_info.rotation;
      encoding_start_time_ms = frame_info.encode_start_time;
      input_frame_infos_.pop_front();
    }

    // Extract payload.
    size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer.obj());
    uint8_t* payload = reinterpret_cast<uint8_t*>(
        jni->GetDirectBufferAddress(j_output_buffer.obj()));
    if (CheckException(jni)) {
      ALOGE << "Exception in get direct buffer address.";
      ProcessHWError(true /* reset_if_fallback_unavailable */);
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    // Callback - return encoded frame.
    const VideoCodecType codec_type = GetCodecType();
    EncodedImageCallback::Result callback_result(
        EncodedImageCallback::Result::OK);
    if (callback_) {
      std::unique_ptr<EncodedImage> image(
          new EncodedImage(payload, payload_size, payload_size));
      image->_encodedWidth = width_;
      image->_encodedHeight = height_;
      image->_timeStamp = output_timestamp_;
      image->capture_time_ms_ = output_render_time_ms_;
      image->rotation_ = output_rotation_;
      image->content_type_ = (codec_mode_ == VideoCodecMode::kScreensharing)
                                 ? VideoContentType::SCREENSHARE
                                 : VideoContentType::UNSPECIFIED;
      image->timing_.flags = TimingFrameFlags::kInvalid;
      image->_frameType = (key_frame ? kVideoFrameKey : kVideoFrameDelta);
      image->_completeFrame = true;
      CodecSpecificInfo info;
      memset(&info, 0, sizeof(info));
      info.codecType = codec_type;
      if (codec_type == kVideoCodecVP8) {
        info.codecSpecific.VP8.pictureId = picture_id_;
        info.codecSpecific.VP8.nonReference = false;
        info.codecSpecific.VP8.simulcastIdx = 0;
        info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;
        info.codecSpecific.VP8.layerSync = false;
        info.codecSpecific.VP8.tl0PicIdx = kNoTl0PicIdx;
        info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
      } else if (codec_type == kVideoCodecVP9) {
        if (key_frame) {
          gof_idx_ = 0;
        }
        info.codecSpecific.VP9.picture_id = picture_id_;
        info.codecSpecific.VP9.inter_pic_predicted = key_frame ? false : true;
        info.codecSpecific.VP9.flexible_mode = false;
        info.codecSpecific.VP9.ss_data_available = key_frame ? true : false;
        info.codecSpecific.VP9.tl0_pic_idx = tl0_pic_idx_++;
        info.codecSpecific.VP9.temporal_idx = kNoTemporalIdx;
        info.codecSpecific.VP9.spatial_idx = kNoSpatialIdx;
        info.codecSpecific.VP9.temporal_up_switch = true;
        info.codecSpecific.VP9.inter_layer_predicted = false;
        info.codecSpecific.VP9.gof_idx =
            static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof);
        info.codecSpecific.VP9.num_spatial_layers = 1;
        info.codecSpecific.VP9.spatial_layer_resolution_present = false;
        if (info.codecSpecific.VP9.ss_data_available) {
          info.codecSpecific.VP9.spatial_layer_resolution_present = true;
          info.codecSpecific.VP9.width[0] = width_;
          info.codecSpecific.VP9.height[0] = height_;
          info.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_);
        }
      }
      picture_id_ = (picture_id_ + 1) & 0x7FFF;

      // Generate a header describing a single fragment.
      RTPFragmentationHeader header;
      memset(&header, 0, sizeof(header));
      if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecVP9) {
        header.VerifyAndAllocateFragmentationHeader(1);
        header.fragmentationOffset[0] = 0;
        header.fragmentationLength[0] = image->_length;
        header.fragmentationPlType[0] = 0;
        header.fragmentationTimeDiff[0] = 0;
        if (codec_type == kVideoCodecVP8) {
          int qp;
          if (vp8::GetQp(payload, payload_size, &qp)) {
            current_acc_qp_ += qp;
            image->qp_ = qp;
          }
        } else if (codec_type == kVideoCodecVP9) {
          int qp;
          if (vp9::GetQp(payload, payload_size, &qp)) {
            current_acc_qp_ += qp;
            image->qp_ = qp;
          }
        }
      } else if (codec_type == kVideoCodecH264) {
        h264_bitstream_parser_.ParseBitstream(payload, payload_size);
        int qp;
        if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
          current_acc_qp_ += qp;
          image->qp_ = qp;
        }
        // For H.264 search for start codes.
        const std::vector<H264::NaluIndex> nalu_idxs =
            H264::FindNaluIndices(payload, payload_size);
        if (nalu_idxs.empty()) {
          ALOGE << "Start code is not found!";
          ALOGE << "Data:" <<  image->_buffer[0] << " " << image->_buffer[1]
              << " " << image->_buffer[2] << " " << image->_buffer[3]
              << " " << image->_buffer[4] << " " << image->_buffer[5];
          ProcessHWError(true /* reset_if_fallback_unavailable */);
          return false;
        }
        header.VerifyAndAllocateFragmentationHeader(nalu_idxs.size());
        for (size_t i = 0; i < nalu_idxs.size(); i++) {
          header.fragmentationOffset[i] = nalu_idxs[i].payload_start_offset;
          header.fragmentationLength[i] = nalu_idxs[i].payload_size;
          header.fragmentationPlType[i] = 0;
          header.fragmentationTimeDiff[i] = 0;
        }
      }

      callback_result = callback_->OnEncodedImage(*image, &info, &header);
    }

    // Return output buffer back to the encoder.
    bool success = Java_MediaCodecVideoEncoder_releaseOutputBuffer(
        jni, j_media_codec_video_encoder_, output_buffer_index);
    if (CheckException(jni) || !success) {
      ProcessHWError(true /* reset_if_fallback_unavailable */);
      return false;
    }

    // Print per frame statistics.
    if (encoding_start_time_ms > 0) {
      frame_encoding_time_ms = rtc::TimeMillis() - encoding_start_time_ms;
    }
    if (frames_encoded_ < kMaxEncodedLogFrames) {
      int current_latency = static_cast<int>(last_input_timestamp_ms_ -
                                             last_output_timestamp_ms_);
      ALOGD << "Encoder frame out # " << frames_encoded_
            << ". Key: " << key_frame << ". Size: " << payload_size
            << ". TS: " << static_cast<int>(last_output_timestamp_ms_)
            << ". Latency: " << current_latency
            << ". EncTime: " << frame_encoding_time_ms;
    }

    // Calculate and print encoding statistics - every 3 seconds.
    frames_encoded_++;
    current_frames_++;
    current_bytes_ += payload_size;
    current_encoding_time_ms_ += frame_encoding_time_ms;
    LogStatistics(false);

    // Errors in callback_result are currently ignored.
    if (callback_result.drop_next_frame)
      drop_next_input_frame_ = true;
  }
  return true;
}

void MediaCodecVideoEncoder::LogStatistics(bool force_log) {
  int statistic_time_ms = rtc::TimeMillis() - stat_start_time_ms_;
  if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log)
      && statistic_time_ms > 0) {
    // Prevent division by zero.
    int current_frames_divider = current_frames_ != 0 ? current_frames_ : 1;

    int current_bitrate = current_bytes_ * 8 / statistic_time_ms;
    int current_fps =
        (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms;
    ALOGD << "Encoded frames: " << frames_encoded_ <<
        ". Bitrate: " << current_bitrate <<
        ", target: " << last_set_bitrate_kbps_ << " kbps" <<
        ", fps: " << current_fps <<
        ", encTime: " << (current_encoding_time_ms_ / current_frames_divider) <<
        ". QP: " << (current_acc_qp_ / current_frames_divider) <<
        " for last " << statistic_time_ms << " ms.";
    stat_start_time_ms_ = rtc::TimeMillis();
    current_frames_ = 0;
    current_bytes_ = 0;
    current_acc_qp_ = 0;
    current_encoding_time_ms_ = 0;
  }
}

VideoEncoder::ScalingSettings MediaCodecVideoEncoder::GetScalingSettings()
    const {
  if (field_trial::IsEnabled(kCustomQPThresholdsFieldTrial)) {
    const VideoCodecType codec_type = GetCodecType();
    std::string experiment_string =
        field_trial::FindFullName(kCustomQPThresholdsFieldTrial);
    ALOGD << "QP custom thresholds: " << experiment_string << " for codec "
          << codec_type;
    int low_vp8_qp_threshold;
    int high_vp8_qp_threshold;
    int low_h264_qp_threshold;
    int high_h264_qp_threshold;
    int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%u,%u,%u,%u",
                               &low_vp8_qp_threshold, &high_vp8_qp_threshold,
                               &low_h264_qp_threshold, &high_h264_qp_threshold);
    if (parsed_values == 4) {
      RTC_CHECK_GT(high_vp8_qp_threshold, low_vp8_qp_threshold);
      RTC_CHECK_GT(low_vp8_qp_threshold, 0);
      RTC_CHECK_GT(high_h264_qp_threshold, low_h264_qp_threshold);
      RTC_CHECK_GT(low_h264_qp_threshold, 0);
      if (codec_type == kVideoCodecVP8) {
        return VideoEncoder::ScalingSettings(scale_, low_vp8_qp_threshold,
                                             high_vp8_qp_threshold);
      } else if (codec_type == kVideoCodecH264) {
        return VideoEncoder::ScalingSettings(scale_, low_h264_qp_threshold,
                                             high_h264_qp_threshold);
      }
    }
  }
  return VideoEncoder::ScalingSettings(scale_);
}

const char* MediaCodecVideoEncoder::ImplementationName() const {
  return "MediaCodec";
}

MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
    : egl_context_(nullptr) {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);
  supported_codecs_.clear();

  bool is_vp8_hw_supported = Java_MediaCodecVideoEncoder_isVp8HwSupported(jni);
  if (is_vp8_hw_supported) {
    ALOGD << "VP8 HW Encoder supported.";
    supported_codecs_.push_back(cricket::VideoCodec(cricket::kVp8CodecName));
  }

  bool is_vp9_hw_supported = Java_MediaCodecVideoEncoder_isVp9HwSupported(jni);
  if (is_vp9_hw_supported) {
    ALOGD << "VP9 HW Encoder supported.";
    supported_codecs_.push_back(cricket::VideoCodec(cricket::kVp9CodecName));
  }
  supported_codecs_with_h264_hp_ = supported_codecs_;

  // Check if high profile is supported by decoder. If yes, encoder can always
  // fall back to baseline profile as a subset as high profile.
  bool is_h264_high_profile_hw_supported =
      MediaCodecVideoDecoderFactory::IsH264HighProfileSupported(jni);
  if (is_h264_high_profile_hw_supported) {
    ALOGD << "H.264 High Profile HW Encoder supported.";
    // TODO(magjed): Enumerate actual level instead of using hardcoded level
    // 3.1. Level 3.1 is 1280x720@30fps which is enough for now.
    cricket::VideoCodec constrained_high(cricket::kH264CodecName);
    const H264::ProfileLevelId constrained_high_profile(
        H264::kProfileConstrainedHigh, H264::kLevel3_1);
    constrained_high.SetParam(
        cricket::kH264FmtpProfileLevelId,
        *H264::ProfileLevelIdToString(constrained_high_profile));
    constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
    constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1");
    supported_codecs_with_h264_hp_.push_back(constrained_high);
  }

  bool is_h264_hw_supported =
      Java_MediaCodecVideoEncoder_isH264HwSupported(jni);
  if (is_h264_hw_supported) {
    ALOGD << "H.264 HW Encoder supported.";
    // TODO(magjed): Push Constrained High profile as well when negotiation is
    // ready, http://crbug/webrtc/6337. We can negotiate Constrained High
    // profile as long as we have decode support for it and still send Baseline
    // since Baseline is a subset of the High profile.
    cricket::VideoCodec constrained_baseline(cricket::kH264CodecName);
    const H264::ProfileLevelId constrained_baseline_profile(
        H264::kProfileConstrainedBaseline, H264::kLevel3_1);
    constrained_baseline.SetParam(
        cricket::kH264FmtpProfileLevelId,
        *H264::ProfileLevelIdToString(constrained_baseline_profile));
    constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
    constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1");
    supported_codecs_.push_back(constrained_baseline);
    supported_codecs_with_h264_hp_.push_back(constrained_baseline);
  }
}

MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {
  ALOGD << "MediaCodecVideoEncoderFactory dtor";
  if (egl_context_) {
    JNIEnv* jni = AttachCurrentThreadIfNeeded();
    jni->DeleteGlobalRef(egl_context_);
  }
}

void MediaCodecVideoEncoderFactory::SetEGLContext(
    JNIEnv* jni, jobject egl_context) {
  ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext";
  if (egl_context_) {
    jni->DeleteGlobalRef(egl_context_);
    egl_context_ = nullptr;
  }
  egl_context_ = jni->NewGlobalRef(egl_context);
  if (CheckException(jni)) {
    ALOGE << "error calling NewGlobalRef for EGL Context.";
  }
}

VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder(
    const cricket::VideoCodec& codec) {
  if (supported_codecs().empty()) {
    ALOGW << "No HW video encoder for codec " << codec.name;
    return nullptr;
  }
  if (FindMatchingCodec(supported_codecs(), codec)) {
    ALOGD << "Create HW video encoder for " << codec.name;
    JNIEnv* jni = AttachCurrentThreadIfNeeded();
    ScopedLocalRefFrame local_ref_frame(jni);
    return new MediaCodecVideoEncoder(jni, codec, egl_context_);
  }
  ALOGW << "Can not find HW video encoder for type " << codec.name;
  return nullptr;
}

const std::vector<cricket::VideoCodec>&
MediaCodecVideoEncoderFactory::supported_codecs() const {
  if (field_trial::IsEnabled(kH264HighProfileFieldTrial)) {
    return supported_codecs_with_h264_hp_;
  } else {
    return supported_codecs_;
  }
}

void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
  ALOGD << "Destroy video encoder.";
  delete encoder;
}

static void JNI_MediaCodecVideoEncoder_FillInputBuffer(
    JNIEnv* jni,
    const JavaParamRef<jclass>&,
    jlong native_encoder,
    jint input_buffer,
    const JavaParamRef<jobject>& j_buffer_y,
    jint stride_y,
    const JavaParamRef<jobject>& j_buffer_u,
    jint stride_u,
    const JavaParamRef<jobject>& j_buffer_v,
    jint stride_v) {
  uint8_t* buffer_y =
      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_y.obj()));
  uint8_t* buffer_u =
      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_u.obj()));
  uint8_t* buffer_v =
      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v.obj()));

  RTC_DCHECK(buffer_y) << "GetDirectBufferAddress returned null. Ensure that "
                          "getDataY returns a direct ByteBuffer.";
  RTC_DCHECK(buffer_u) << "GetDirectBufferAddress returned null. Ensure that "
                          "getDataU returns a direct ByteBuffer.";
  RTC_DCHECK(buffer_v) << "GetDirectBufferAddress returned null. Ensure that "
                          "getDataV returns a direct ByteBuffer.";

  reinterpret_cast<MediaCodecVideoEncoder*>(native_encoder)
      ->FillInputBuffer(jni, input_buffer, buffer_y, stride_y, buffer_u,
                        stride_u, buffer_v, stride_v);
}

}  // namespace jni
}  // namespace webrtc
