/*
 *  Copyright (c) 2011 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.
 */

/*
 * vp8.cc
 *
 * 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():
    _encodedImage(),
    _encodedCompleteCallback(NULL),
    _width(0),
    _height(0),
    _maxBitRateKbit(0),
    _maxFrameRate(30),
    _inited(false),
    _timeStamp(0),
    _pictureID(0),
    _simulcastIdx(0),
    _feedbackModeOn(false),
    _cpuSpeed(-6), // default value
    _rcMaxIntraTarget(0),
    _tokenPartitions(VP8_ONE_TOKENPARTITION),
    _rps(new ReferencePictureSelection),
#if WEBRTC_LIBVPX_VERSION >= 971
    _temporalLayers(NULL),
#endif
    _encoder(NULL),
    _cfg(NULL),
    _raw(NULL)
{
    WebRtc_UWord32 seed = (WebRtc_UWord32)TickTime::MillisecondTimestamp();
    srand(seed);
}

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

WebRtc_Word32
VP8Encoder::VersionStatic(WebRtc_Word8* version, WebRtc_Word32 length)
{
    const char* str = vpx_codec_iface_name(vpx_codec_vp8_cx());
    WebRtc_Word32 verLen = (WebRtc_Word32)strlen(str);
    // Accounting for "\0" and "\n" (to be added a bit later)
    if (verLen + 2 > length)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }
    strcpy(version, str);
    strcat(version, "\n");
    return (verLen + 2);
}

WebRtc_Word32
VP8Encoder::Version(WebRtc_Word8 *version, WebRtc_Word32 length) const
{
    return VersionStatic(version, length);
}

WebRtc_Word32
VP8Encoder::Release()
{
    if (_encodedImage._buffer != NULL)
    {
        delete [] _encodedImage._buffer;
        _encodedImage._buffer = NULL;
    }
    if (_encoder != NULL)
    {
        if (vpx_codec_destroy(_encoder))
        {
            return WEBRTC_VIDEO_CODEC_MEMORY;
        }
        delete _encoder;
        _encoder = NULL;
    }
    if (_cfg != NULL)
    {
        delete _cfg;
        _cfg = NULL;
    }
    if (_raw != NULL)
    {
        vpx_img_free(_raw);
        delete _raw;
        _raw = NULL;
    }
#if WEBRTC_LIBVPX_VERSION >= 971
    if (_temporalLayers != NULL)
    {
        delete _temporalLayers;
        _temporalLayers = NULL;
    }
#endif
    _inited = false;

    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
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();
}

WebRtc_Word32
VP8Encoder::SetRates(WebRtc_UWord32 newBitRateKbit, WebRtc_UWord32 newFrameRate)
{
    if (!_inited)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (_encoder->err)
    {
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
    if (newFrameRate < 1)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }

    // update bit rate
    if (_maxBitRateKbit > 0 &&
        newBitRateKbit > static_cast<WebRtc_UWord32>(_maxBitRateKbit))
    {
        newBitRateKbit = _maxBitRateKbit;
    }
    _cfg->rc_target_bitrate = newBitRateKbit; // in kbit/s

#if WEBRTC_LIBVPX_VERSION >= 971
    if (_temporalLayers)
    {
        _temporalLayers->ConfigureBitrates(newBitRateKbit, _cfg);
    }
#endif
    _maxFrameRate = newFrameRate;

    // update encoder context
    if (vpx_codec_enc_config_set(_encoder, _cfg))
    {
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Encoder::InitEncode(const VideoCodec* inst,
                       WebRtc_Word32 numberOfCores,
                       WebRtc_UWord32 /*maxPayloadSize */)
{
    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 (numberOfCores < 1)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }
    _feedbackModeOn = inst->codecSpecific.VP8.feedbackModeOn;

    WebRtc_Word32 retVal = Release();
    if (retVal < 0)
    {
        return retVal;
    }
    if (_encoder == NULL)
    {
        _encoder = new vpx_codec_ctx_t;
    }
    if (_cfg == NULL)
    {
        _cfg = new vpx_codec_enc_cfg_t;
    }
    if (_raw == NULL)
    {
        _raw = new vpx_image_t;
    }

    _timeStamp = 0;
    _maxBitRateKbit = inst->maxBitrate;
    _maxFrameRate = inst->maxFramerate;
    _width = inst->width;
    _height = inst->height;

#if WEBRTC_LIBVPX_VERSION >= 971
    if (inst->codecSpecific.VP8.numberOfTemporalLayers > 1)
    {
      assert(_temporalLayers == NULL);
      _temporalLayers =
          new TemporalLayers(inst->codecSpecific.VP8.numberOfTemporalLayers);
    }
#endif

    // random start 16 bits is enough.
    _pictureID = ((WebRtc_UWord16)rand()) & 0x7FFF;

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

    vpx_img_alloc(_raw, IMG_FMT_I420, inst->width, inst->height, 1);
    // populate encoder configuration with default values
    if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), _cfg, 0))
    {
         return WEBRTC_VIDEO_CODEC_ERROR;
    }
    _cfg->g_w = inst->width;
    _cfg->g_h = inst->height;
    if (_maxBitRateKbit > 0 &&
        inst->startBitrate > static_cast<unsigned int>(_maxBitRateKbit))
    {
        _cfg->rc_target_bitrate = _maxBitRateKbit;
    }
    else
    {
      _cfg->rc_target_bitrate = inst->startBitrate;  // in kbit/s
    }
#if WEBRTC_LIBVPX_VERSION >= 971
    if (_temporalLayers)
    {
        _temporalLayers->ConfigureBitrates(inst->startBitrate, _cfg);
    }
#endif
    // setting the time base of the codec
    _cfg->g_timebase.num = 1;
    _cfg->g_timebase.den = 90000;

    // Set the error resilience mode according to user settings.
    switch (inst->codecSpecific.VP8.resilience) {
      case kResilienceOff:
        _cfg->g_error_resilient = 0;
        break;
      case kResilientStream:
        _cfg->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
        _cfg->g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT |
                                  VPX_ERROR_RESILIENT_PARTITIONS;
#else
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;  // Not supported
#endif
        break;
    }

    _cfg->g_lag_in_frames = 0; // 0- no frame lagging

    // Determining number of threads based on the image size

    if (_width * _height > 704 * 576 && numberOfCores > 1)
      // 2 threads when larger than 4CIF
      _cfg->g_threads = 2;
    else
      _cfg->g_threads = 1;

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

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

    return InitAndSetControlSettings();
}


WebRtc_Word32
VP8Encoder::InitAndSetControlSettings()
{
    // construct encoder context
    vpx_codec_enc_cfg_t cfg_copy = *_cfg;
    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(), _cfg, flags))
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    vpx_codec_control(_encoder, VP8E_SET_STATIC_THRESHOLD, 800);
    vpx_codec_control(_encoder, VP8E_SET_CPUUSED, _cpuSpeed);
    vpx_codec_control(_encoder, VP8E_SET_TOKEN_PARTITIONS,
                      static_cast<vp8e_token_partitions>(_tokenPartitions));
    vpx_codec_control(_encoder, VP8E_SET_NOISE_SENSITIVITY, 2);
#if WEBRTC_LIBVPX_VERSION >= 971
    vpx_codec_control(_encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT,
                      _rcMaxIntraTarget);
#endif
    *_cfg = cfg_copy;

    _inited = true;
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_UWord32
VP8Encoder::MaxIntraTarget(WebRtc_UWord32 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;
    WebRtc_UWord32 targetPct = (optimalBuffersize * scalePar) *
                              _maxFrameRate / 10;

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

    return  targetPct;
}

WebRtc_Word32
VP8Encoder::Encode(const RawImage& inputImage,
                   const CodecSpecificInfo* codecSpecificInfo,
                   const VideoFrameType* frameTypes)
{
    if (!_inited)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (inputImage._buffer == NULL)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }
    if (_encodedCompleteCallback == NULL)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (codecSpecificInfo) 
    {
        _simulcastIdx = codecSpecificInfo->codecSpecific.VP8.simulcastIdx;
    }
    else
    {
        _simulcastIdx = 0; 
    }
    // image in vpx_image_t format
    _raw->planes[PLANE_Y] =  inputImage._buffer;
    _raw->planes[PLANE_U] =  &inputImage._buffer[_height * _width];
    _raw->planes[PLANE_V] =  &inputImage._buffer[_height * _width * 5 >> 2];

    int flags = 0;
#if WEBRTC_LIBVPX_VERSION >= 971
    if (_temporalLayers) {
      flags |= _temporalLayers->EncodeFlags();
    }
#endif
    bool sendKeyFrame = frameTypes && (*frameTypes == kKeyFrame);
    if (sendKeyFrame)
    {
      // Key frame request from caller.
      // Will update both golden and alt-ref.
      flags = VPX_EFLAG_FORCE_KF;
    } else if (_feedbackModeOn && codecSpecificInfo) {
      // Handle RPSI and SLI messages and set up the appropriate encode flags.
      bool sendRefresh = false;
      if (codecSpecificInfo->codecType == kVideoCodecVP8) {
        if (codecSpecificInfo->codecSpecific.VP8.hasReceivedRPSI) {
          _rps->ReceivedRPSI(
              codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI);
        }
        if (codecSpecificInfo->codecSpecific.VP8.hasReceivedSLI) {
          sendRefresh = _rps->ReceivedSLI(inputImage._timeStamp);
        }
      }
      flags = _rps->EncodeFlags(_pictureID, sendRefresh, inputImage._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(_maxFrameRate > 0);
    WebRtc_UWord32 duration = 90000 / _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(inputImage);
#else
    return GetEncodedFrame(inputImage);
#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 = _pictureID;
  vp8Info->simulcastIdx = _simulcastIdx;
  vp8Info->keyIdx = kNoKeyIdx;  // TODO(hlundin) populate this
  vp8Info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE);
#if WEBRTC_LIBVPX_VERSION >= 971
  if (_temporalLayers) {
    _temporalLayers->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
  _pictureID = (_pictureID + 1) & 0x7FFF;  // prepare next
}

WebRtc_Word32
VP8Encoder::GetEncodedFrame(const RawImage& input_image)
{
    vpx_codec_iter_t iter = NULL;
    _encodedImage._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 <= _encodedImage._size);
        memcpy(_encodedImage._buffer, pkt->data.frame.buf, pkt->data.frame.sz);
        _encodedImage._length = WebRtc_UWord32(pkt->data.frame.sz);
        _encodedImage._encodedHeight = _raw->h;
        _encodedImage._encodedWidth = _raw->w;

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

        if (_encodedImage._length > 0)
        {
            _encodedImage._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;
            WebRtc_UWord8 *firstByte = _encodedImage._buffer;
            WebRtc_UWord32 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] = _encodedImage._length -
                fragInfo.fragmentationLength[0];
            fragInfo.fragmentationPlType[1] = 0; // not known here
            fragInfo.fragmentationTimeDiff[1] = 0;

            _encodedCompleteCallback->Encoded(_encodedImage, &codecSpecific,
                &fragInfo);
        }
        return WEBRTC_VIDEO_CODEC_OK;
    }
    return WEBRTC_VIDEO_CODEC_ERROR;
}

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

  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(&_encodedImage._buffer[_encodedImage._length],
               pkt->data.frame.buf,
               pkt->data.frame.sz);
        frag_info.fragmentationOffset[part_idx] = _encodedImage._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;
        _encodedImage._length += pkt->data.frame.sz;
        assert(_encodedImage._length <= _encodedImage._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)
      {
          _encodedImage._frameType = kKeyFrame;
          _rps->EncodedKeyFrame(_pictureID);
      }
      PopulateCodecSpecific(&codecSpecific, *pkt);
      break;
    }
  }
  if (_encodedImage._length > 0) {
    _encodedImage._timeStamp = input_image._timeStamp;
    _encodedImage._encodedHeight = _raw->h;
    _encodedImage._encodedWidth = _raw->w;
    _encodedCompleteCallback->Encoded(_encodedImage, &codecSpecific,
        &frag_info);
  }
  return WEBRTC_VIDEO_CODEC_OK;
}
#endif

WebRtc_Word32
VP8Encoder::SetChannelParameters(WebRtc_UWord32 packetLoss, int rtt) {
  _rps->SetRtt(rtt);
  return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Encoder::RegisterEncodeCompleteCallback(EncodedImageCallback* callback)
{
    _encodedCompleteCallback = callback;
    return WEBRTC_VIDEO_CODEC_OK;
}

VP8Decoder::VP8Decoder():
    _decodeCompleteCallback(NULL),
    _inited(false),
    _feedbackModeOn(false),
    _decoder(NULL),
    _inst(NULL),
    _numCores(1),
    _lastKeyFrame(),
    _imageFormat(VPX_IMG_FMT_NONE),
    _refFrame(NULL),
    _propagationCnt(-1),
    _latestKeyFrameComplete(false)
{
}

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

WebRtc_Word32
VP8Decoder::Reset()
{
    if (!_inited)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (_inst != NULL)
    {
        VideoCodec inst;
        inst = *_inst;
        InitDecode(&inst, _numCores);
    }
    else
    {
        InitDecode(NULL, _numCores);
    }
    _propagationCnt = -1;
    _latestKeyFrameComplete = false;
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Decoder::InitDecode(const VideoCodec* inst,
                       WebRtc_Word32 numberOfCores)
{
    WebRtc_Word32 retVal = Release();
    if (retVal < 0 )
    {
        return retVal;
    }
    if (_decoder == NULL)
    {
        _decoder = new vpx_dec_ctx_t;
    }
    if (inst && inst->codecType == kVideoCodecVP8) {
      _feedbackModeOn = 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.
    if (inst && inst != _inst)
    {
        if (!_inst)
        {
            _inst = new VideoCodec;
        }
        *_inst = *inst;
    }
    _numCores = numberOfCores;
    _propagationCnt = -1;
    _latestKeyFrameComplete = false;

    _inited = true;
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Decoder::Decode(const EncodedImage& inputImage,
                   bool missingFrames,
                   const RTPFragmentationHeader* fragmentation,
                   const CodecSpecificInfo* codecSpecificInfo,
                   WebRtc_Word64 /*renderTimeMs*/)
{
    if (!_inited)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (_decodeCompleteCallback == NULL)
    {
        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
    }
    if (inputImage._buffer == NULL && inputImage._length > 0)
    {
        // Reset to avoid requesting key frames too often.
        if (_propagationCnt > 0)
            _propagationCnt = 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 (!_feedbackModeOn) {
      if (inputImage._frameType == kKeyFrame && inputImage._completeFrame)
        _propagationCnt = -1;
      // Start count on first loss.
      else if ((!inputImage._completeFrame || missingFrames) &&
                _propagationCnt == -1)
        _propagationCnt = 0;
      if (_propagationCnt >= 0)
        _propagationCnt++;
    }

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

    // Check for missing frames.
    if (missingFrames)
    {
        // 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 (_propagationCnt > 0)
                _propagationCnt = 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 (_propagationCnt > 0)
            _propagationCnt = 0;
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
#else
    WebRtc_UWord8* buffer = inputImage._buffer;
    if (inputImage._length == 0)
    {
        buffer = NULL; // Triggers full frame concealment.
    }
    if (vpx_codec_decode(_decoder,
                         buffer,
                         inputImage._length,
                         0,
                         VPX_DL_REALTIME))
    {
        // Reset to avoid requesting key frames too often.
        if (_propagationCnt > 0)
            _propagationCnt = 0;
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
#endif

    // Store encoded frame if key frame. (Used in Copy method.)
    if (inputImage._frameType == kKeyFrame && inputImage._buffer != NULL)
    {
        const WebRtc_UWord32 bytesToCopy = inputImage._length;
        if (_lastKeyFrame._size < bytesToCopy)
        {
            delete [] _lastKeyFrame._buffer;
            _lastKeyFrame._buffer = NULL;
            _lastKeyFrame._size = 0;
        }

        WebRtc_UWord8* tempBuffer = _lastKeyFrame._buffer; // Save buffer ptr.
        WebRtc_UWord32 tempSize = _lastKeyFrame._size; // Save size.
        _lastKeyFrame = inputImage; // Shallow copy.
        _lastKeyFrame._buffer = tempBuffer; // Restore buffer ptr.
        _lastKeyFrame._size = tempSize; // Restore buffer size.
        if (!_lastKeyFrame._buffer)
        {
            // Allocate memory.
            _lastKeyFrame._size = bytesToCopy;
            _lastKeyFrame._buffer = new WebRtc_UWord8[_lastKeyFrame._size];
        }
        // Copy encoded frame.
        memcpy(_lastKeyFrame._buffer, inputImage._buffer, bytesToCopy);
        _lastKeyFrame._length = bytesToCopy;
    }

    img = vpx_codec_get_frame(_decoder, &iter);
    ret = ReturnFrame(img, inputImage._timeStamp);
    if (ret != 0)
    {
        // Reset to avoid requesting key frames too often.
        if (ret < 0 && _propagationCnt > 0)
            _propagationCnt = 0;
        return ret;
    }

    if (_feedbackModeOn) {
      // 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 (inputImage._frameType == kKeyFrame)
        _latestKeyFrameComplete = inputImage._completeFrame;
      if (!_latestKeyFrameComplete)
        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 referenceUpdates = 0;
      if (vpx_codec_control(_decoder, VP8D_GET_LAST_REF_UPDATES,
                            &referenceUpdates)) {
        // Reset to avoid requesting key frames too often.
        if (_propagationCnt > 0)
          _propagationCnt = 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 (_propagationCnt > 0)
          _propagationCnt = 0;
        return WEBRTC_VIDEO_CODEC_ERROR;
      }
      WebRtc_Word16 pictureId = -1;
      if (codecSpecificInfo) {
        pictureId = codecSpecificInfo->codecSpecific.VP8.pictureId;
      }
      if (pictureId > -1) {
        if (((referenceUpdates & VP8_GOLD_FRAME) ||
             (referenceUpdates & VP8_ALTR_FRAME)) && !corrupted) {
          _decodeCompleteCallback->ReceivedDecodedReferenceFrame(pictureId);
        }
        _decodeCompleteCallback->ReceivedDecodedFrame(pictureId);
      }
      if (corrupted) {
        // we can decode but with artifacts
        return WEBRTC_VIDEO_CODEC_REQUEST_SLI;
      }
    }

    // Check Vs. threshold
    if (_propagationCnt > kVp8ErrorPropagationTh)
    {
        // Reset to avoid requesting key frames too often.
        _propagationCnt = 0;
        return WEBRTC_VIDEO_CODEC_ERROR;
    }
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Decoder::DecodePartitions(const EncodedImage& input_image,
                             const RTPFragmentationHeader* fragmentation) {
  for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) {
    const WebRtc_UWord8* partition = input_image._buffer +
        fragmentation->fragmentationOffset[i];
    const WebRtc_UWord32 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;
}

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

    // Allocate memory for decoded image
    WebRtc_UWord32 requiredSize = (3 * img->d_h * img->d_w) >> 1;
    if (requiredSize > _decodedImage._size)
    {
        delete [] _decodedImage._buffer;
        _decodedImage._buffer = NULL;
    }
    if (_decodedImage._buffer == NULL)
    {
        _decodedImage._size = requiredSize;
        _decodedImage._buffer = new WebRtc_UWord8[_decodedImage._size];
    }

    WebRtc_UWord8* buf;
    WebRtc_UWord32 pos = 0;
    WebRtc_UWord32 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(&_decodedImage._buffer[pos], buf, width);
            pos += width;
            buf += img->stride[plane];
        }
    }

    // Set image parameters
    _decodedImage._height = img->d_h;
    _decodedImage._width = img->d_w;
    _decodedImage._length = (3 * img->d_h * img->d_w) >> 1;
    _decodedImage._timeStamp = timeStamp;
    WebRtc_Word32 ret = _decodeCompleteCallback->Decoded(_decodedImage);
    if (ret != 0)
        return ret;

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

WebRtc_Word32
VP8Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
{
    _decodeCompleteCallback = callback;
    return WEBRTC_VIDEO_CODEC_OK;
}

WebRtc_Word32
VP8Decoder::Release()
{
    if (_decodedImage._buffer != NULL)
    {
        delete [] _decodedImage._buffer;
        _decodedImage._buffer = NULL;
    }
    if (_lastKeyFrame._buffer != NULL)
    {
        delete [] _lastKeyFrame._buffer;
        _lastKeyFrame._buffer = NULL;
    }
    if (_decoder != NULL)
    {
        if(vpx_codec_destroy(_decoder))
        {
            return WEBRTC_VIDEO_CODEC_MEMORY;
        }
        delete _decoder;
        _decoder = NULL;
    }
    if (_inst != NULL)
    {
        delete _inst;
        _inst = NULL;
    }
    if (_refFrame != NULL)
    {
        vpx_img_free(&_refFrame->img);
        delete _refFrame;
        _refFrame = NULL;
    }

    _inited = false;
    return WEBRTC_VIDEO_CODEC_OK;
}

VideoDecoder*
VP8Decoder::Copy()
{
    // Sanity checks.
    if (!_inited)
    {
        // Not initialized.
        assert(false);
        return NULL;
    }
    if (_decodedImage._buffer == NULL)
    {
        // Nothing has been decoded before; cannot clone.
        return NULL;
    }
    if (_lastKeyFrame._buffer == NULL)
    {
        // Cannot clone if we have no key frame to start with.
        return NULL;
    }

    // Create a new VideoDecoder object
    VP8Decoder *copyTo = new VP8Decoder;

    // Initialize the new decoder
    if (copyTo->InitDecode(_inst, _numCores) != WEBRTC_VIDEO_CODEC_OK)
    {
        delete copyTo;
        return NULL;
    }

    // Inject last key frame into new decoder.
    if (vpx_codec_decode(copyTo->_decoder, _lastKeyFrame._buffer,
        _lastKeyFrame._length, NULL, VPX_DL_REALTIME))
    {
        delete copyTo;
        return NULL;
    }

    // Allocate memory for reference image copy
    assert(_decodedImage._width > 0);
    assert(_decodedImage._height > 0);
    assert(_imageFormat > VPX_IMG_FMT_NONE);
    // Check if frame format has changed.
    if (_refFrame &&
        (_decodedImage._width != _refFrame->img.d_w ||
            _decodedImage._height != _refFrame->img.d_h ||
            _imageFormat != _refFrame->img.fmt))
    {
        vpx_img_free(&_refFrame->img);
        delete _refFrame;
        _refFrame = NULL;
    }


    if (!_refFrame)
    {
        _refFrame = new vpx_ref_frame_t;

        if(!vpx_img_alloc(&_refFrame->img,
            static_cast<vpx_img_fmt_t>(_imageFormat),
            _decodedImage._width, _decodedImage._height, 1))
        {
            assert(false);
            delete copyTo;
            return NULL;
        }
    }

    const vpx_ref_frame_type_t typeVec[] = { VP8_LAST_FRAME, VP8_GOLD_FRAME,
                                             VP8_ALTR_FRAME };
    for (WebRtc_UWord32 ix = 0;
         ix < sizeof(typeVec) / sizeof(vpx_ref_frame_type_t); ++ix)
    {
        _refFrame->frame_type = typeVec[ix];
        if (CopyReference(copyTo) < 0)
        {
            delete copyTo;
            return NULL;
        }
    }

    // Copy all member variables (that are not set in initialization).
    copyTo->_feedbackModeOn = _feedbackModeOn;
    copyTo->_imageFormat = _imageFormat;
    copyTo->_lastKeyFrame = _lastKeyFrame; // Shallow copy.
    // Allocate memory. (Discard copied _buffer pointer.)
    copyTo->_lastKeyFrame._buffer = new WebRtc_UWord8[_lastKeyFrame._size];
    memcpy(copyTo->_lastKeyFrame._buffer, _lastKeyFrame._buffer,
           _lastKeyFrame._length);

    // Initialize _decodedImage.
    copyTo->_decodedImage = _decodedImage;  // Shallow copy
    copyTo->_decodedImage._buffer = NULL;
    if (_decodedImage._size)
    {
        copyTo->_decodedImage._buffer = new WebRtc_UWord8[_decodedImage._size];
    }

    return static_cast<VideoDecoder*>(copyTo);
}

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


} // namespace webrtc
