/*
 *  Copyright (c) 2012 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.
 *
 * This file contains the WEBRTC VP8 wrapper implementation
 *
 */
#include "vp8.h"

#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "module_common_types.h"
#include "reference_picture_selection.h"
#include "temporal_layers.h"
#include "tick_util.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vp8cx.h"
#include "vpx/vp8dx.h"

enum { kVp8ErrorPropagationTh = 30 };

namespace webrtc
{

VP8Encoder* VP8Encoder::Create() {
  return new VP8Encoder();
}

VP8Encoder::VP8Encoder()
    : encoded_image_(),
      encoded_complete_callback_(NULL),
      inited_(false),
      timestamp_(0),
      picture_id_(0),
      feedback_mode_(false),
      cpu_speed_(-6), // default value
      rc_max_intra_target_(0),
      token_partitions_(VP8_ONE_TOKENPARTITION),
      rps_(new ReferencePictureSelection),
#if WEBRTC_LIBVPX_VERSION >= 971
      temporal_layers_(NULL),
#endif
      encoder_(NULL),
      config_(NULL),
      raw_(NULL) {
  uint32_t seed = static_cast<uint32_t>(TickTime::MillisecondTimestamp());
  srand(seed);
}

VP8Encoder::~VP8Encoder() {
  Release();
  delete rps_;
}

int VP8Encoder::Release() {
  if (encoded_image_._buffer != NULL) {
    delete [] encoded_image_._buffer;
    encoded_image_._buffer = NULL;
  }
  if (encoder_ != NULL) {
    if (vpx_codec_destroy(encoder_)) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    delete encoder_;
    encoder_ = NULL;
  }
  if (config_ != NULL) {
    delete config_;
    config_ = NULL;
  }
  if (raw_ != NULL) {
    vpx_img_free(raw_);
    delete raw_;
    raw_ = NULL;
  }
#if WEBRTC_LIBVPX_VERSION >= 971
  if (temporal_layers_ != NULL) {
    delete temporal_layers_;
    temporal_layers_ = NULL;
  }
#endif
  inited_ = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Encoder::SetRates(uint32_t new_bitrate_kbit, uint32_t new_framerate) {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (encoder_->err) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  if (new_framerate < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  // update bit rate
  if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
    new_bitrate_kbit = codec_.maxBitrate;
  }
  config_->rc_target_bitrate = new_bitrate_kbit; // in kbit/s

#if WEBRTC_LIBVPX_VERSION >= 971
  if (temporal_layers_) {
    temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_);
  }
#endif
  codec_.maxFramerate = new_framerate;

  // update encoder context
  if (vpx_codec_enc_config_set(encoder_, config_)) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Encoder::InitEncode(const VideoCodec* inst,
                           int number_of_cores,
                           uint32_t /*max_payload_size*/) {
  if (inst == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (inst->maxFramerate < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  // allow zero to represent an unspecified maxBitRate
  if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (inst->width < 1 || inst->height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (number_of_cores < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn;

  int retVal = Release();
  if (retVal < 0) {
    return retVal;
  }
  if (encoder_ == NULL) {
    encoder_ = new vpx_codec_ctx_t;
  }
  if (config_ == NULL) {
    config_ = new vpx_codec_enc_cfg_t;
  }
  if (raw_ == NULL) {
    raw_ = new vpx_image_t;
  }
  timestamp_ = 0;

  codec_ = *inst;

#if WEBRTC_LIBVPX_VERSION >= 971
  if (inst->codecSpecific.VP8.numberOfTemporalLayers > 1) {
    assert(temporal_layers_ == NULL);
    temporal_layers_ =
        new TemporalLayers(inst->codecSpecific.VP8.numberOfTemporalLayers);
  }
#endif
  // random start 16 bits is enough.
  picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;

  // allocate memory for encoded image
  if (encoded_image_._buffer != NULL) {
    delete [] encoded_image_._buffer;
  }
  encoded_image_._size = (3 * codec_.width * codec_.height) >> 1;
  encoded_image_._buffer = new uint8_t[encoded_image_._size];
  encoded_image_._completeFrame = true;

  vpx_img_alloc(raw_, IMG_FMT_I420, codec_.width, codec_.height, 1);
  // populate encoder configuration with default values
  if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), config_, 0)) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  config_->g_w = codec_.width;
  config_->g_h = codec_.height;
  config_->rc_target_bitrate = inst->startBitrate;  // in kbit/s

#if WEBRTC_LIBVPX_VERSION >= 971
  if (temporal_layers_) {
    temporal_layers_->ConfigureBitrates(inst->startBitrate, config_);
  }
#endif
  // setting the time base of the codec
  config_->g_timebase.num = 1;
  config_->g_timebase.den = 90000;

  // Set the error resilience mode according to user settings.
  switch (inst->codecSpecific.VP8.resilience) {
    case kResilienceOff:
      config_->g_error_resilient = 0;
#if WEBRTC_LIBVPX_VERSION >= 971
      if (temporal_layers_) {
        // Must be on for temporal layers.
        config_->g_error_resilient = 1;
      }
#endif
      break;
    case kResilientStream:
      config_->g_error_resilient = 1;  // TODO(holmer): Replace with
      // VPX_ERROR_RESILIENT_DEFAULT when we
      // drop support for libvpx 9.6.0.
      break;
    case kResilientFrames:
#ifdef INDEPENDENT_PARTITIONS
      config_->g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT |
      VPX_ERROR_RESILIENT_PARTITIONS;
      break;
#else
      return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;  // Not supported
#endif
  }
  config_->g_lag_in_frames = 0; // 0- no frame lagging

  // Determining number of threads based on the image size
  if (codec_.width * codec_.height > 704 * 576 && number_of_cores > 1) {
    // 2 threads when larger than 4CIF
    config_->g_threads = 2;
  } else {
    config_->g_threads = 1;
  }

  // rate control settings
  config_->rc_dropframe_thresh = 30;
  config_->rc_end_usage = VPX_CBR;
  config_->g_pass = VPX_RC_ONE_PASS;
  config_->rc_resize_allowed = 0;
  config_->rc_min_quantizer = 8;
  config_->rc_max_quantizer = 56;
  config_->rc_undershoot_pct = 100;
  config_->rc_overshoot_pct = 15;
  config_->rc_buf_initial_sz = 500;
  config_->rc_buf_optimal_sz = 600;
  config_->rc_buf_sz = 1000;
  // set the maximum target size of any key-frame.
  rc_max_intra_target_ = MaxIntraTarget(config_->rc_buf_optimal_sz);

  if (feedback_mode_) {
    // Disable periodic key frames if we get feedback from the decoder
    // through SLI and RPSI.
    config_->kf_mode = VPX_KF_DISABLED;
  } else {
    config_->kf_mode = VPX_KF_AUTO;
    config_->kf_max_dist = 3000;
  }
  switch (inst->codecSpecific.VP8.complexity) {
    case kComplexityHigh:
      cpu_speed_ = -5;
      break;
    case kComplexityHigher:
      cpu_speed_ = -4;
      break;
    case kComplexityMax:
      cpu_speed_ = -3;
      break;
    default:
      cpu_speed_ = -6;
      break;
  }
  rps_->Init();
  return InitAndSetControlSettings();
}

int VP8Encoder::InitAndSetControlSettings() {
  vpx_codec_flags_t flags = 0;
  // TODO(holmer): We should make a smarter decision on the number of
  // partitions. Eight is probably not the optimal number for low resolution
  // video.

#if WEBRTC_LIBVPX_VERSION >= 971
  flags |= VPX_CODEC_USE_OUTPUT_PARTITION;
#endif
  if (vpx_codec_enc_init(encoder_, vpx_codec_vp8_cx(), config_, flags)) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  vpx_codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 800);
  vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_);
  vpx_codec_control(encoder_, VP8E_SET_TOKEN_PARTITIONS,
                    static_cast<vp8e_token_partitions>(token_partitions_));
  vpx_codec_control(encoder_, VP8E_SET_NOISE_SENSITIVITY, 2);
#if WEBRTC_LIBVPX_VERSION >= 971
  vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
                    rc_max_intra_target_);
#endif
  inited_ = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

uint32_t VP8Encoder::MaxIntraTarget(uint32_t optimalBuffersize) {
  // Set max to the optimal buffer level (normalized by target BR),
  // and scaled by a scalePar.
  // Max target size = scalePar * optimalBufferSize * targetBR[Kbps].
  // This values is presented in percentage of perFrameBw:
  // perFrameBw = targetBR[Kbps] * 1000 / frameRate.
  // The target in % is as follows:

  float scalePar = 0.5;
  uint32_t targetPct = optimalBuffersize * scalePar * codec_.maxFramerate / 10;

  // Don't go below 3 times the per frame bandwidth.
  const uint32_t minIntraTh = 300;
  return (targetPct < minIntraTh) ? minIntraTh: targetPct;
}

int VP8Encoder::Encode(const RawImage& input_image,
                       const CodecSpecificInfo* codec_specific_info,
                       const VideoFrameType* frame_types) {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (input_image._buffer == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (encoded_complete_callback_ == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  // image in vpx_image_t format
  raw_->planes[PLANE_Y] = input_image._buffer;
  raw_->planes[PLANE_U] = &input_image._buffer[codec_.height * codec_.width];
  raw_->planes[PLANE_V] =
      &input_image._buffer[codec_.height * codec_.width * 5 >> 2];

  int flags = 0;
#if WEBRTC_LIBVPX_VERSION >= 971
  if (temporal_layers_) {
    flags |= temporal_layers_->EncodeFlags();
  }
#endif
  bool send_keyframe = frame_types && (*frame_types == kKeyFrame);
  if (send_keyframe) {
    // Key frame request from caller.
    // Will update both golden and alt-ref.
    flags = VPX_EFLAG_FORCE_KF;
  } else if (feedback_mode_ && codec_specific_info) {
    // Handle RPSI and SLI messages and set up the appropriate encode flags.
    bool sendRefresh = false;
    if (codec_specific_info->codecType == kVideoCodecVP8) {
      if (codec_specific_info->codecSpecific.VP8.hasReceivedRPSI) {
        rps_->ReceivedRPSI(
            codec_specific_info->codecSpecific.VP8.pictureIdRPSI);
      }
      if (codec_specific_info->codecSpecific.VP8.hasReceivedSLI) {
        sendRefresh = rps_->ReceivedSLI(input_image._timeStamp);
      }
    }
    flags = rps_->EncodeFlags(picture_id_, sendRefresh, input_image._timeStamp);
  }

  // TODO(holmer): Ideally the duration should be the timestamp diff of this
  // frame and the next frame to be encoded, which we don't have. Instead we
  // would like to use the duration of the previous frame. Unfortunately the
  // rate control seems to be off with that setup. Using the average input
  // frame rate to calculate an average duration for now.
  assert(codec_.maxFramerate > 0);
  uint32_t duration = 90000 / codec_.maxFramerate;
  if (vpx_codec_encode(encoder_, raw_, timestamp_, duration, flags,
                       VPX_DL_REALTIME)) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  timestamp_ += duration;

#if WEBRTC_LIBVPX_VERSION >= 971
  return GetEncodedPartitions(input_image);
#else
  return GetEncodedFrame(input_image);
#endif
}

void VP8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
                                       const vpx_codec_cx_pkt& pkt) {
  assert(codec_specific != NULL);
  codec_specific->codecType = kVideoCodecVP8;
  CodecSpecificInfoVP8 *vp8Info = &(codec_specific->codecSpecific.VP8);
  vp8Info->pictureId = picture_id_;
  vp8Info->simulcastIdx = 0;
  vp8Info->keyIdx = kNoKeyIdx;  // TODO(hlundin) populate this
  vp8Info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) != 0;
#if WEBRTC_LIBVPX_VERSION >= 971
  if (temporal_layers_) {
    temporal_layers_->PopulateCodecSpecific(
        (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false, vp8Info);
  } else {
#endif
    vp8Info->temporalIdx = kNoTemporalIdx;
    vp8Info->layerSync = false;
    vp8Info->tl0PicIdx = kNoTl0PicIdx;
#if WEBRTC_LIBVPX_VERSION >= 971
  }
#endif
  picture_id_ = (picture_id_ + 1) & 0x7FFF;  // prepare next
}

int VP8Encoder::GetEncodedFrame(const RawImage& input_image) {
  vpx_codec_iter_t iter = NULL;
  encoded_image_._frameType = kDeltaFrame;
  const vpx_codec_cx_pkt_t *pkt= vpx_codec_get_cx_data(encoder_, &iter);
  if (pkt == NULL) {
    if (!encoder_->err) {
      // dropped frame
      return WEBRTC_VIDEO_CODEC_OK;
    } else {
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
  } else if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
    CodecSpecificInfo codecSpecific;
    PopulateCodecSpecific(&codecSpecific, *pkt);

    assert(pkt->data.frame.sz <= encoded_image_._size);
    memcpy(encoded_image_._buffer, pkt->data.frame.buf, pkt->data.frame.sz);
    encoded_image_._length = uint32_t(pkt->data.frame.sz);
    encoded_image_._encodedHeight = raw_->h;
    encoded_image_._encodedWidth = raw_->w;

    // check if encoded frame is a key frame
    if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
      encoded_image_._frameType = kKeyFrame;
      rps_->EncodedKeyFrame(picture_id_);
    }

    if (encoded_image_._length > 0) {
      encoded_image_._timeStamp = input_image._timeStamp;

      // Figure out where partition boundaries are located.
      RTPFragmentationHeader fragInfo;
      fragInfo.VerifyAndAllocateFragmentationHeader(2);
      // two partitions: 1st and 2nd

      // First partition
      fragInfo.fragmentationOffset[0] = 0;
      uint8_t *firstByte = encoded_image_._buffer;
      uint32_t tmpSize = (firstByte[2] << 16) | (firstByte[1] << 8)
                    | firstByte[0];
      fragInfo.fragmentationLength[0] = (tmpSize >> 5) & 0x7FFFF;
      fragInfo.fragmentationPlType[0] = 0; // not known here
      fragInfo.fragmentationTimeDiff[0] = 0;

      // Second partition
      fragInfo.fragmentationOffset[1] = fragInfo.fragmentationLength[0];
      fragInfo.fragmentationLength[1] = encoded_image_._length -
          fragInfo.fragmentationLength[0];
      fragInfo.fragmentationPlType[1] = 0; // not known here
      fragInfo.fragmentationTimeDiff[1] = 0;

      encoded_complete_callback_->Encoded(encoded_image_, &codecSpecific,
                                        &fragInfo);
    }
    return WEBRTC_VIDEO_CODEC_OK;
  }
  return WEBRTC_VIDEO_CODEC_ERROR;
}

#if WEBRTC_LIBVPX_VERSION >= 971
int VP8Encoder::GetEncodedPartitions(const RawImage& input_image) {
  vpx_codec_iter_t iter = NULL;
  int part_idx = 0;
  encoded_image_._length = 0;
  encoded_image_._frameType = kDeltaFrame;
  RTPFragmentationHeader frag_info;
  frag_info.VerifyAndAllocateFragmentationHeader((1 << token_partitions_) + 1);
  CodecSpecificInfo codec_specific;

  const vpx_codec_cx_pkt_t *pkt = NULL;
  while ((pkt = vpx_codec_get_cx_data(encoder_, &iter)) != NULL) {
    switch(pkt->kind) {
      case VPX_CODEC_CX_FRAME_PKT: {
        memcpy(&encoded_image_._buffer[encoded_image_._length],
               pkt->data.frame.buf,
               pkt->data.frame.sz);
        frag_info.fragmentationOffset[part_idx] = encoded_image_._length;
        frag_info.fragmentationLength[part_idx] =  pkt->data.frame.sz;
        frag_info.fragmentationPlType[part_idx] = 0;  // not known here
        frag_info.fragmentationTimeDiff[part_idx] = 0;
        encoded_image_._length += pkt->data.frame.sz;
        assert(encoded_image_._length <= encoded_image_._size);
        ++part_idx;
        break;
      }
      default: {
        break;
      }
    }
    // End of frame
    if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) {
      // check if encoded frame is a key frame
      if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
          encoded_image_._frameType = kKeyFrame;
          rps_->EncodedKeyFrame(picture_id_);
      }
      PopulateCodecSpecific(&codec_specific, *pkt);
      break;
    }
  }
  if (encoded_image_._length > 0) {
    encoded_image_._timeStamp = input_image._timeStamp;
    encoded_image_._encodedHeight = raw_->h;
    encoded_image_._encodedWidth = raw_->w;
    encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
                                      &frag_info);
  }
  return WEBRTC_VIDEO_CODEC_OK;
}
#endif

int VP8Encoder::SetChannelParameters(uint32_t /*packet_loss*/, int rtt) {
  rps_->SetRtt(rtt);
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Encoder::RegisterEncodeCompleteCallback(
    EncodedImageCallback* callback) {
  encoded_complete_callback_ = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

VP8Decoder* VP8Decoder::Create() {
  return new VP8Decoder();
}

VP8Decoder::VP8Decoder()
    : decode_complete_callback_(NULL),
      inited_(false),
      feedback_mode_(false),
      decoder_(NULL),
      last_keyframe_(),
      image_format_(VPX_IMG_FMT_NONE),
      ref_frame_(NULL),
      propagation_cnt_(-1),
      latest_keyframe_complete_(false),
      mfqe_enabled_(false) {
}

VP8Decoder::~VP8Decoder() {
  inited_ = true; // in order to do the actual release
  Release();
}

int VP8Decoder::Reset() {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  InitDecode(&codec_, 1);
  propagation_cnt_ = -1;
  latest_keyframe_complete_ = false;
  mfqe_enabled_ = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::InitDecode(const VideoCodec* inst, int number_of_cores) {
  int ret_val = Release();
  if (ret_val < 0 ) {
    return ret_val;
  }
  if (decoder_ == NULL) {
    decoder_ = new vpx_dec_ctx_t;
  }
  if (inst && inst->codecType == kVideoCodecVP8) {
    feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn;
  }
  vpx_codec_dec_cfg_t  cfg;
  // Setting number of threads to a constant value (1)
  cfg.threads = 1;
  cfg.h = cfg.w = 0; // set after decode

  vpx_codec_flags_t flags = 0;
#if WEBRTC_LIBVPX_VERSION >= 971
  flags = VPX_CODEC_USE_ERROR_CONCEALMENT | VPX_CODEC_USE_POSTPROC;
#ifdef INDEPENDENT_PARTITIONS
  flags |= VPX_CODEC_USE_INPUT_PARTITION;
#endif
#endif

  if (vpx_codec_dec_init(decoder_, vpx_codec_vp8_dx(), &cfg, flags)) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }

#if WEBRTC_LIBVPX_VERSION >= 971
  vp8_postproc_cfg_t  ppcfg;
  // Disable deblocking for now due to uninitialized memory being returned.
  ppcfg.post_proc_flag = 0;
  // Strength of deblocking filter. Valid range:[0,16]
  //ppcfg.deblocking_level = 3;
  vpx_codec_control(decoder_, VP8_SET_POSTPROC, &ppcfg);
#endif

  // Save VideoCodec instance for later; mainly for duplicating the decoder.
  codec_ = *inst;
  propagation_cnt_ = -1;
  latest_keyframe_complete_ = false;

  inited_ = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::Decode(const EncodedImage& input_image,
                       bool missing_frames,
                       const RTPFragmentationHeader* fragmentation,
                       const CodecSpecificInfo* codec_specific_info,
                       int64_t /*render_time_ms*/) {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (decode_complete_callback_ == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (input_image._buffer == NULL && input_image._length > 0) {
    // Reset to avoid requesting key frames too often.
    if (propagation_cnt_ > 0)
      propagation_cnt_ = 0;
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }

#ifdef INDEPENDENT_PARTITIONS
  if (fragmentation == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
#endif

#if WEBRTC_LIBVPX_VERSION >= 971
  if (!mfqe_enabled_ && codec_specific_info &&
      codec_specific_info->codecSpecific.VP8.temporalIdx > 0) {
    // Enable MFQE if we are receiving layers.
    // temporalIdx is set in the jitter buffer according to what the RTP
    // header says.
    mfqe_enabled_ = true;
    vp8_postproc_cfg_t  ppcfg;
    ppcfg.post_proc_flag = VP8_MFQE;
    vpx_codec_control(decoder_, VP8_SET_POSTPROC, &ppcfg);
  }
#endif

  // Restrict error propagation using key frame requests. Disabled when
  // the feedback mode is enabled (RPS).
  // Reset on a key frame refresh.
  if (!feedback_mode_) {
    if (input_image._frameType == kKeyFrame && input_image._completeFrame)
      propagation_cnt_ = -1;
    // Start count on first loss.
    else if ((!input_image._completeFrame || missing_frames) &&
        propagation_cnt_ == -1)
      propagation_cnt_ = 0;
    if (propagation_cnt_ >= 0)
      propagation_cnt_++;
  }

  vpx_dec_iter_t iter = NULL;
  vpx_image_t* img;
  int ret;

  // Check for missing frames.
  if (missing_frames) {
    // Call decoder with zero data length to signal missing frames.
    if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) {
      // Reset to avoid requesting key frames too often.
      if (propagation_cnt_ > 0)
        propagation_cnt_ = 0;
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    img = vpx_codec_get_frame(decoder_, &iter);
    iter = NULL;
  }

#ifdef INDEPENDENT_PARTITIONS
  if (DecodePartitions(inputImage, fragmentation)) {
    // Reset to avoid requesting key frames too often.
    if (propagation_cnt_ > 0) {
      propagation_cnt_ = 0;
    }
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
#else
  uint8_t* buffer = input_image._buffer;
  if (input_image._length == 0) {
    buffer = NULL; // Triggers full frame concealment.
  }
  if (vpx_codec_decode(decoder_,
                       buffer,
                       input_image._length,
                       0,
                       VPX_DL_REALTIME)) {
    // Reset to avoid requesting key frames too often.
    if (propagation_cnt_ > 0)
      propagation_cnt_ = 0;
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
#endif

  // Store encoded frame if key frame. (Used in Copy method.)
  if (input_image._frameType == kKeyFrame && input_image._buffer != NULL) {
    const uint32_t bytes_to_copy = input_image._length;
    if (last_keyframe_._size < bytes_to_copy) {
      delete [] last_keyframe_._buffer;
      last_keyframe_._buffer = NULL;
      last_keyframe_._size = 0;
    }

    uint8_t* temp_buffer = last_keyframe_._buffer; // Save buffer ptr.
    uint32_t temp_size = last_keyframe_._size; // Save size.
    last_keyframe_ = input_image; // Shallow copy.
    last_keyframe_._buffer = temp_buffer; // Restore buffer ptr.
    last_keyframe_._size = temp_size; // Restore buffer size.
    if (!last_keyframe_._buffer) {
      // Allocate memory.
      last_keyframe_._size = bytes_to_copy;
      last_keyframe_._buffer = new uint8_t[last_keyframe_._size];
    }
    // Copy encoded frame.
    memcpy(last_keyframe_._buffer, input_image._buffer, bytes_to_copy);
    last_keyframe_._length = bytes_to_copy;
  }

  img = vpx_codec_get_frame(decoder_, &iter);
  ret = ReturnFrame(img, input_image._timeStamp);
  if (ret != 0) {
    // Reset to avoid requesting key frames too often.
    if (ret < 0 && propagation_cnt_ > 0)
      propagation_cnt_ = 0;
    return ret;
  }
  if (feedback_mode_) {
    // Whenever we receive an incomplete key frame all reference buffers will
    // be corrupt. If that happens we must request new key frames until we
    // decode a complete.
    if (input_image._frameType == kKeyFrame)
      latest_keyframe_complete_ = input_image._completeFrame;
    if (!latest_keyframe_complete_)
      return WEBRTC_VIDEO_CODEC_ERROR;

    // Check for reference updates and last reference buffer corruption and
    // signal successful reference propagation or frame corruption to the
    // encoder.
    int reference_updates = 0;
    if (vpx_codec_control(decoder_, VP8D_GET_LAST_REF_UPDATES,
                          &reference_updates)) {
      // Reset to avoid requesting key frames too often.
      if (propagation_cnt_ > 0)
        propagation_cnt_ = 0;
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    int corrupted = 0;
    if (vpx_codec_control(decoder_, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
      // Reset to avoid requesting key frames too often.
      if (propagation_cnt_ > 0)
        propagation_cnt_ = 0;
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    int16_t picture_id = -1;
    if (codec_specific_info) {
      picture_id = codec_specific_info->codecSpecific.VP8.pictureId;
    }
    if (picture_id > -1) {
      if (((reference_updates & VP8_GOLD_FRAME) ||
          (reference_updates & VP8_ALTR_FRAME)) && !corrupted) {
        decode_complete_callback_->ReceivedDecodedReferenceFrame(picture_id);
      }
      decode_complete_callback_->ReceivedDecodedFrame(picture_id);
    }
    if (corrupted) {
      // we can decode but with artifacts
      return WEBRTC_VIDEO_CODEC_REQUEST_SLI;
    }
  }
  // Check Vs. threshold
  if (propagation_cnt_ > kVp8ErrorPropagationTh) {
    // Reset to avoid requesting key frames too often.
    propagation_cnt_ = 0;
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::DecodePartitions(
    const EncodedImage& input_image,
    const RTPFragmentationHeader* fragmentation) {
  for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) {
    const uint8_t* partition = input_image._buffer +
        fragmentation->fragmentationOffset[i];
    const uint32_t partition_length =
        fragmentation->fragmentationLength[i];
    if (vpx_codec_decode(decoder_,
                         partition,
                         partition_length,
                         0,
                         VPX_DL_REALTIME)) {
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
  }
  // Signal end of frame data. If there was no frame data this will trigger
  // a full frame concealment.
  if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME))
    return WEBRTC_VIDEO_CODEC_ERROR;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::ReturnFrame(const vpx_image_t* img, uint32_t timestamp) {
  if (img == NULL) {
    // Decoder OK and NULL image => No show frame
    return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
  }

  // Allocate memory for decoded image
  uint32_t required_size = (3 * img->d_h * img->d_w) >> 1;
  if (required_size > decoded_image_._size) {
    delete [] decoded_image_._buffer;
    decoded_image_._buffer = NULL;
  }
  if (decoded_image_._buffer == NULL) {
    decoded_image_._size = required_size;
    decoded_image_._buffer = new uint8_t[decoded_image_._size];
  }
  uint8_t* buf;
  uint32_t pos = 0;
  uint32_t plane, y;

  for (plane = 0; plane < 3; plane++) {
    unsigned int width = (plane ? (img->d_w + 1) >> 1 : img->d_w);
    unsigned int height = (plane ? (img->d_h + 1) >> 1 : img->d_h);
    buf = img->planes[plane];
    for(y = 0; y < height; y++) {
      memcpy(&decoded_image_._buffer[pos], buf, width);
      pos += width;
      buf += img->stride[plane];
    }
  }

  // Set image parameters
  decoded_image_._height = img->d_h;
  decoded_image_._width = img->d_w;
  decoded_image_._length = (3 * img->d_h * img->d_w) >> 1;
  decoded_image_._timeStamp = timestamp;
  int ret = decode_complete_callback_->Decoded(decoded_image_);
  if (ret != 0)
    return ret;

  // Remember image format for later
  image_format_ = img->fmt;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::RegisterDecodeCompleteCallback(
    DecodedImageCallback* callback) {
  decode_complete_callback_ = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int VP8Decoder::Release() {
  if (decoded_image_._buffer != NULL) {
    delete [] decoded_image_._buffer;
    decoded_image_._buffer = NULL;
  }
  if (last_keyframe_._buffer != NULL) {
    delete [] last_keyframe_._buffer;
    last_keyframe_._buffer = NULL;
  }
  if (decoder_ != NULL) {
    if(vpx_codec_destroy(decoder_)) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    delete decoder_;
    decoder_ = NULL;
  }
  if (ref_frame_ != NULL) {
    vpx_img_free(&ref_frame_->img);
    delete ref_frame_;
    ref_frame_ = NULL;
  }
  inited_ = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

VideoDecoder* VP8Decoder::Copy() {
  // Sanity checks.
  if (!inited_) {
    // Not initialized.
    assert(false);
    return NULL;
  }
  if (decoded_image_._buffer == NULL) {
    // Nothing has been decoded before; cannot clone.
    return NULL;
  }
  if (last_keyframe_._buffer == NULL) {
    // Cannot clone if we have no key frame to start with.
    return NULL;
  }
  // Create a new VideoDecoder object
  VP8Decoder *copy = new VP8Decoder;

  // Initialize the new decoder
  if (copy->InitDecode(&codec_, 1) != WEBRTC_VIDEO_CODEC_OK) {
    delete copy;
    return NULL;
  }
  // Inject last key frame into new decoder.
  if (vpx_codec_decode(copy->decoder_, last_keyframe_._buffer,
                       last_keyframe_._length, NULL, VPX_DL_REALTIME)) {
    delete copy;
    return NULL;
  }
  // Allocate memory for reference image copy
  assert(decoded_image_._width > 0);
  assert(decoded_image_._height > 0);
  assert(image_format_ > VPX_IMG_FMT_NONE);
  // Check if frame format has changed.
  if (ref_frame_ &&
      (decoded_image_._width != ref_frame_->img.d_w ||
          decoded_image_._height != ref_frame_->img.d_h ||
          image_format_ != ref_frame_->img.fmt)) {
    vpx_img_free(&ref_frame_->img);
    delete ref_frame_;
    ref_frame_ = NULL;
  }


  if (!ref_frame_) {
    ref_frame_ = new vpx_ref_frame_t;

    if (!vpx_img_alloc(&ref_frame_->img,
                       static_cast<vpx_img_fmt_t>(image_format_),
                       decoded_image_._width, decoded_image_._height, 1)) {
      assert(false);
      delete copy;
      return NULL;
    }
  }
  const vpx_ref_frame_type_t type_vec[] = { VP8_LAST_FRAME, VP8_GOLD_FRAME,
      VP8_ALTR_FRAME };
  for (uint32_t ix = 0;
      ix < sizeof(type_vec) / sizeof(vpx_ref_frame_type_t); ++ix) {
    ref_frame_->frame_type = type_vec[ix];
    if (CopyReference(copy) < 0) {
      delete copy;
      return NULL;
    }
  }
  // Copy all member variables (that are not set in initialization).
  copy->feedback_mode_ = feedback_mode_;
  copy->image_format_ = image_format_;
  copy->last_keyframe_ = last_keyframe_; // Shallow copy.
  // Allocate memory. (Discard copied _buffer pointer.)
  copy->last_keyframe_._buffer = new uint8_t[last_keyframe_._size];
  memcpy(copy->last_keyframe_._buffer, last_keyframe_._buffer,
         last_keyframe_._length);

  // Initialize decoded_image_.
  copy->decoded_image_ = decoded_image_;  // Shallow copy
  copy->decoded_image_._buffer = NULL;
  if (decoded_image_._size) {
    copy->decoded_image_._buffer = new uint8_t[decoded_image_._size];
  }
  return static_cast<VideoDecoder*>(copy);
}

int VP8Decoder::CopyReference(VP8Decoder* copyTo) {
  // The type of frame to copy should be set in ref_frame_->frame_type
  // before the call to this function.
  if (vpx_codec_control(decoder_, VP8_COPY_REFERENCE, ref_frame_)
      != VPX_CODEC_OK) {
    return -1;
  }
  if (vpx_codec_control(copyTo->decoder_, VP8_SET_REFERENCE, ref_frame_)
      != VPX_CODEC_OK) {
    return -1;
  }
  return 0;
}

} // namespace webrtc
