/*
 *  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::Reset() {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (encoder_ != NULL) {
    if (vpx_codec_destroy(encoder_)) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    delete encoder_;
    encoder_ = NULL;
  }
  timestamp_ = 0;
  encoder_ = new vpx_codec_ctx_t;
  rps_->Init();

  return InitAndSetControlSettings();
}

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) {
}

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;
  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

  // 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
