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

#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_

#include <algorithm>
#include <vector>

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
#include "webrtc/video_frame.h"

#include "gtest/gtest.h"

using ::testing::_;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Return;

namespace webrtc {
namespace testing {

const int kDefaultWidth = 1280;
const int kDefaultHeight = 720;
const int kNumberOfSimulcastStreams = 3;
const int kColorY = 66;
const int kColorU = 22;
const int kColorV = 33;
const int kMaxBitrates[kNumberOfSimulcastStreams] = {150, 600, 1200};
const int kMinBitrates[kNumberOfSimulcastStreams] = {50, 150, 600};
const int kTargetBitrates[kNumberOfSimulcastStreams] = {100, 450, 1000};
const int kDefaultTemporalLayerProfile[3] = {3, 3, 3};

template<typename T> void SetExpectedValues3(T value0,
                                             T value1,
                                             T value2,
                                             T* expected_values) {
  expected_values[0] = value0;
  expected_values[1] = value1;
  expected_values[2] = value2;
}

class Vp8TestEncodedImageCallback : public EncodedImageCallback {
 public:
  Vp8TestEncodedImageCallback()
       : picture_id_(-1) {
    memset(temporal_layer_, -1, sizeof(temporal_layer_));
    memset(layer_sync_, false, sizeof(layer_sync_));
  }

  ~Vp8TestEncodedImageCallback() {
    delete [] encoded_key_frame_._buffer;
    delete [] encoded_frame_._buffer;
  }

  virtual int32_t Encoded(const EncodedImage& encoded_image,
                          const CodecSpecificInfo* codec_specific_info,
                          const RTPFragmentationHeader* fragmentation) {
    // Only store the base layer.
    if (codec_specific_info->codecSpecific.VP8.simulcastIdx == 0) {
      if (encoded_image._frameType == kKeyFrame) {
        delete [] encoded_key_frame_._buffer;
        encoded_key_frame_._buffer = new uint8_t[encoded_image._size];
        encoded_key_frame_._size = encoded_image._size;
        encoded_key_frame_._length = encoded_image._length;
        encoded_key_frame_._frameType = kKeyFrame;
        encoded_key_frame_._completeFrame = encoded_image._completeFrame;
        memcpy(encoded_key_frame_._buffer,
               encoded_image._buffer,
               encoded_image._length);
      } else {
        delete [] encoded_frame_._buffer;
        encoded_frame_._buffer = new uint8_t[encoded_image._size];
        encoded_frame_._size = encoded_image._size;
        encoded_frame_._length = encoded_image._length;
        memcpy(encoded_frame_._buffer,
               encoded_image._buffer,
               encoded_image._length);
      }
    }
    picture_id_ = codec_specific_info->codecSpecific.VP8.pictureId;
    layer_sync_[codec_specific_info->codecSpecific.VP8.simulcastIdx] =
        codec_specific_info->codecSpecific.VP8.layerSync;
    temporal_layer_[codec_specific_info->codecSpecific.VP8.simulcastIdx] =
        codec_specific_info->codecSpecific.VP8.temporalIdx;
    return 0;
  }
  void GetLastEncodedFrameInfo(int* picture_id, int* temporal_layer,
                               bool* layer_sync, int stream) {
    *picture_id = picture_id_;
    *temporal_layer = temporal_layer_[stream];
    *layer_sync = layer_sync_[stream];
  }
  void GetLastEncodedKeyFrame(EncodedImage* encoded_key_frame) {
    *encoded_key_frame = encoded_key_frame_;
  }
  void GetLastEncodedFrame(EncodedImage* encoded_frame) {
    *encoded_frame = encoded_frame_;
  }

 private:
  EncodedImage encoded_key_frame_;
  EncodedImage encoded_frame_;
  int picture_id_;
  int temporal_layer_[kNumberOfSimulcastStreams];
  bool layer_sync_[kNumberOfSimulcastStreams];
};

class Vp8TestDecodedImageCallback : public DecodedImageCallback {
 public:
  Vp8TestDecodedImageCallback()
      : decoded_frames_(0) {
  }
  virtual int32_t Decoded(VideoFrame& decoded_image) {
    for (int i = 0; i < decoded_image.width(); ++i) {
      EXPECT_NEAR(kColorY, decoded_image.buffer(kYPlane)[i], 1);
    }

    // TODO(mikhal): Verify the difference between U,V and the original.
    for (int i = 0; i < ((decoded_image.width() + 1) / 2); ++i) {
      EXPECT_NEAR(kColorU, decoded_image.buffer(kUPlane)[i], 4);
      EXPECT_NEAR(kColorV, decoded_image.buffer(kVPlane)[i], 4);
    }
    decoded_frames_++;
    return 0;
  }
  int DecodedFrames() {
    return decoded_frames_;
  }

 private:
  int decoded_frames_;
};

class SkipEncodingUnusedStreamsTest {
 public:
  std::vector<unsigned int> RunTest(VP8Encoder* encoder,
                                    VideoCodec* settings,
                                    uint32_t target_bitrate) {
    Config options;
    SpyingTemporalLayersFactory* spy_factory =
        new SpyingTemporalLayersFactory();
    options.Set<TemporalLayers::Factory>(spy_factory);
    settings->extra_options = &options;
    EXPECT_EQ(0, encoder->InitEncode(settings, 1, 1200));

    encoder->SetRates(target_bitrate, 30);

    std::vector<unsigned int> configured_bitrates;
    for (std::vector<TemporalLayers*>::const_iterator it =
             spy_factory->spying_layers_.begin();
         it != spy_factory->spying_layers_.end();
         ++it) {
      configured_bitrates.push_back(
          static_cast<SpyingTemporalLayers*>(*it)->configured_bitrate_);
    }
    return configured_bitrates;
  }

  class SpyingTemporalLayers : public TemporalLayers {
   public:
    explicit SpyingTemporalLayers(TemporalLayers* layers)
        : configured_bitrate_(0), layers_(layers) {}

    virtual ~SpyingTemporalLayers() { delete layers_; }

    virtual int EncodeFlags(uint32_t timestamp) {
      return layers_->EncodeFlags(timestamp);
    }

    bool ConfigureBitrates(int bitrate_kbit,
                           int max_bitrate_kbit,
                           int framerate,
                           vpx_codec_enc_cfg_t* cfg) override {
      configured_bitrate_ = bitrate_kbit;
      return layers_->ConfigureBitrates(
          bitrate_kbit, max_bitrate_kbit, framerate, cfg);
    }

    void PopulateCodecSpecific(bool base_layer_sync,
                               CodecSpecificInfoVP8* vp8_info,
                               uint32_t timestamp) override {
      layers_->PopulateCodecSpecific(base_layer_sync, vp8_info, timestamp);
    }

    void FrameEncoded(unsigned int size, uint32_t timestamp, int qp) override {
      layers_->FrameEncoded(size, timestamp, qp);
    }

    int CurrentLayerId() const override { return layers_->CurrentLayerId(); }

    bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) override {
      return false;
    }

    int configured_bitrate_;
    TemporalLayers* layers_;
  };

  class SpyingTemporalLayersFactory : public TemporalLayers::Factory {
   public:
    virtual ~SpyingTemporalLayersFactory() {}
    TemporalLayers* Create(int temporal_layers,
                           uint8_t initial_tl0_pic_idx) const override {
      SpyingTemporalLayers* layers =
          new SpyingTemporalLayers(TemporalLayers::Factory::Create(
              temporal_layers, initial_tl0_pic_idx));
      spying_layers_.push_back(layers);
      return layers;
    }

    mutable std::vector<TemporalLayers*> spying_layers_;
  };
};

class TestVp8Simulcast : public ::testing::Test {
 public:
  TestVp8Simulcast(VP8Encoder* encoder, VP8Decoder* decoder)
     : encoder_(encoder),
       decoder_(decoder) {}

  // Creates an VideoFrame from |plane_colors|.
  static void CreateImage(VideoFrame* frame, int plane_colors[kNumOfPlanes]) {
    for (int plane_num = 0; plane_num < kNumOfPlanes; ++plane_num) {
      int width = (plane_num != kYPlane ? (frame->width() + 1) / 2 :
        frame->width());
      int height = (plane_num != kYPlane ? (frame->height() + 1) / 2 :
        frame->height());
      PlaneType plane_type = static_cast<PlaneType>(plane_num);
      uint8_t* data = frame->buffer(plane_type);
      // Setting allocated area to zero - setting only image size to
      // requested values - will make it easier to distinguish between image
      // size and frame size (accounting for stride).
      memset(frame->buffer(plane_type), 0, frame->allocated_size(plane_type));
      for (int i = 0; i < height; i++) {
        memset(data, plane_colors[plane_num], width);
        data += frame->stride(plane_type);
      }
    }
  }

  static void DefaultSettings(VideoCodec* settings,
                              const int* temporal_layer_profile) {
    assert(settings);
    memset(settings, 0, sizeof(VideoCodec));
    strncpy(settings->plName, "VP8", 4);
    settings->codecType = kVideoCodecVP8;
    // 96 to 127 dynamic payload types for video codecs
    settings->plType = 120;
    settings->startBitrate = 300;
    settings->minBitrate = 30;
    settings->maxBitrate = 0;
    settings->maxFramerate = 30;
    settings->width = kDefaultWidth;
    settings->height = kDefaultHeight;
    settings->numberOfSimulcastStreams = kNumberOfSimulcastStreams;
    ASSERT_EQ(3, kNumberOfSimulcastStreams);
    ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4,
                    kMaxBitrates[0],
                    kMinBitrates[0],
                    kTargetBitrates[0],
                    &settings->simulcastStream[0],
                    temporal_layer_profile[0]);
    ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2,
                    kMaxBitrates[1],
                    kMinBitrates[1],
                    kTargetBitrates[1],
                    &settings->simulcastStream[1],
                    temporal_layer_profile[1]);
    ConfigureStream(kDefaultWidth, kDefaultHeight,
                    kMaxBitrates[2],
                    kMinBitrates[2],
                    kTargetBitrates[2],
                    &settings->simulcastStream[2],
                    temporal_layer_profile[2]);
    settings->codecSpecific.VP8.resilience = kResilientStream;
    settings->codecSpecific.VP8.denoisingOn = true;
    settings->codecSpecific.VP8.errorConcealmentOn = false;
    settings->codecSpecific.VP8.automaticResizeOn = false;
    settings->codecSpecific.VP8.feedbackModeOn = false;
    settings->codecSpecific.VP8.frameDroppingOn = true;
    settings->codecSpecific.VP8.keyFrameInterval = 3000;
  }

  static void ConfigureStream(int width,
                              int height,
                              int max_bitrate,
                              int min_bitrate,
                              int target_bitrate,
                              SimulcastStream* stream,
                              int num_temporal_layers) {
    assert(stream);
    stream->width = width;
    stream->height = height;
    stream->maxBitrate = max_bitrate;
    stream->minBitrate = min_bitrate;
    stream->targetBitrate = target_bitrate;
    stream->numberOfTemporalLayers = num_temporal_layers;
    stream->qpMax = 45;
  }

 protected:
  virtual void SetUp() {
    SetUpCodec(kDefaultTemporalLayerProfile);
  }

  virtual void SetUpCodec(const int* temporal_layer_profile) {
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback_);
    decoder_->RegisterDecodeCompleteCallback(&decoder_callback_);
    DefaultSettings(&settings_, temporal_layer_profile);
    EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
    EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1));
    int half_width = (kDefaultWidth + 1) / 2;
    input_frame_.CreateEmptyFrame(kDefaultWidth, kDefaultHeight,
                                  kDefaultWidth, half_width, half_width);
    memset(input_frame_.buffer(kYPlane), 0,
        input_frame_.allocated_size(kYPlane));
    memset(input_frame_.buffer(kUPlane), 0,
        input_frame_.allocated_size(kUPlane));
    memset(input_frame_.buffer(kVPlane), 0,
        input_frame_.allocated_size(kVPlane));
  }

  virtual void TearDown() {
    encoder_->Release();
    decoder_->Release();
  }

  void ExpectStreams(VideoFrameType frame_type, int expected_video_streams) {
    ASSERT_GE(expected_video_streams, 0);
    ASSERT_LE(expected_video_streams, kNumberOfSimulcastStreams);
    if (expected_video_streams >= 1) {
      EXPECT_CALL(encoder_callback_, Encoded(
          AllOf(Field(&EncodedImage::_frameType, frame_type),
                Field(&EncodedImage::_encodedWidth, kDefaultWidth / 4),
                Field(&EncodedImage::_encodedHeight, kDefaultHeight / 4)), _, _)
                  )
          .Times(1)
          .WillRepeatedly(Return(0));
    }
    if (expected_video_streams >= 2) {
      EXPECT_CALL(encoder_callback_, Encoded(
          AllOf(Field(&EncodedImage::_frameType, frame_type),
                Field(&EncodedImage::_encodedWidth, kDefaultWidth / 2),
                Field(&EncodedImage::_encodedHeight, kDefaultHeight / 2)), _, _)
                  )
          .Times(1)
          .WillRepeatedly(Return(0));
    }
    if (expected_video_streams >= 3) {
      EXPECT_CALL(encoder_callback_, Encoded(
          AllOf(Field(&EncodedImage::_frameType, frame_type),
                Field(&EncodedImage::_encodedWidth, kDefaultWidth),
                Field(&EncodedImage::_encodedHeight, kDefaultHeight)), _, _))
          .Times(1)
          .WillRepeatedly(Return(0));
    }
  }

  void VerifyTemporalIdxAndSyncForAllSpatialLayers(
      Vp8TestEncodedImageCallback* encoder_callback,
      const int* expected_temporal_idx,
      const bool* expected_layer_sync,
      int num_spatial_layers) {
    int picture_id = -1;
    int temporal_layer = -1;
    bool layer_sync = false;
    for (int i = 0; i < num_spatial_layers; i++) {
      encoder_callback->GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                                &layer_sync, i);
      EXPECT_EQ(expected_temporal_idx[i], temporal_layer);
      EXPECT_EQ(expected_layer_sync[i], layer_sync);
    }
  }

  // We currently expect all active streams to generate a key frame even though
  // a key frame was only requested for some of them.
  void TestKeyFrameRequestsOnAllStreams() {
    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, kNumberOfSimulcastStreams);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, kNumberOfSimulcastStreams);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    frame_types[0] = kKeyFrame;
    ExpectStreams(kKeyFrame, kNumberOfSimulcastStreams);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    std::fill(frame_types.begin(), frame_types.end(), kDeltaFrame);
    frame_types[1] = kKeyFrame;
    ExpectStreams(kKeyFrame, kNumberOfSimulcastStreams);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    std::fill(frame_types.begin(), frame_types.end(), kDeltaFrame);
    frame_types[2] = kKeyFrame;
    ExpectStreams(kKeyFrame, kNumberOfSimulcastStreams);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    std::fill(frame_types.begin(), frame_types.end(), kDeltaFrame);
    ExpectStreams(kDeltaFrame, kNumberOfSimulcastStreams);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestPaddingAllStreams() {
    // We should always encode the base layer.
    encoder_->SetRates(kMinBitrates[0] - 1, 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 1);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 1);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestPaddingTwoStreams() {
    // We have just enough to get only the first stream and padding for two.
    encoder_->SetRates(kMinBitrates[0], 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 1);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 1);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestPaddingTwoStreamsOneMaxedOut() {
    // We are just below limit of sending second stream, so we should get
    // the first stream maxed out (at |maxBitrate|), and padding for two.
    encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] - 1, 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 1);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 1);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestPaddingOneStream() {
    // We have just enough to send two streams, so padding for one stream.
    encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1], 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 2);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 2);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestPaddingOneStreamTwoMaxedOut() {
    // We are just below limit of sending third stream, so we should get
    // first stream's rate maxed out at |targetBitrate|, second at |maxBitrate|.
    encoder_->SetRates(kTargetBitrates[0] + kTargetBitrates[1] +
                       kMinBitrates[2] - 1, 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 2);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 2);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestSendAllStreams() {
    // We have just enough to send all streams.
    encoder_->SetRates(kTargetBitrates[0] + kTargetBitrates[1] +
                       kMinBitrates[2], 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 3);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 3);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestDisablingStreams() {
    // We should get three media streams.
    encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1] +
                       kMaxBitrates[2], 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    ExpectStreams(kKeyFrame, 3);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    ExpectStreams(kDeltaFrame, 3);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // We should only get two streams and padding for one.
    encoder_->SetRates(kTargetBitrates[0] + kTargetBitrates[1] +
                       kMinBitrates[2] / 2, 30);
    ExpectStreams(kDeltaFrame, 2);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // We should only get the first stream and padding for two.
    encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] / 2, 30);
    ExpectStreams(kDeltaFrame, 1);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // We don't have enough bitrate for the thumbnail stream, but we should get
    // it anyway with current configuration.
    encoder_->SetRates(kTargetBitrates[0] - 1, 30);
    ExpectStreams(kDeltaFrame, 1);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // We should only get two streams and padding for one.
    encoder_->SetRates(kTargetBitrates[0] + kTargetBitrates[1] +
                       kMinBitrates[2] / 2, 30);
    // We get a key frame because a new stream is being enabled.
    ExpectStreams(kKeyFrame, 2);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // We should get all three streams.
    encoder_->SetRates(kTargetBitrates[0] + kTargetBitrates[1] +
                       kTargetBitrates[2], 30);
    // We get a key frame because a new stream is being enabled.
    ExpectStreams(kKeyFrame, 3);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void SwitchingToOneStream(int width, int height) {
    // Disable all streams except the last and set the bitrate of the last to
    // 100 kbps. This verifies the way GTP switches to screenshare mode.
    settings_.codecSpecific.VP8.numberOfTemporalLayers = 1;
    settings_.maxBitrate = 100;
    settings_.startBitrate = 100;
    settings_.width = width;
    settings_.height = height;
    for (int i = 0; i < settings_.numberOfSimulcastStreams - 1; ++i) {
      settings_.simulcastStream[i].maxBitrate = 0;
      settings_.simulcastStream[i].width = settings_.width;
      settings_.simulcastStream[i].height = settings_.height;
    }
    // Setting input image to new resolution.
    int half_width = (settings_.width + 1) / 2;
    input_frame_.CreateEmptyFrame(settings_.width, settings_.height,
                                  settings_.width, half_width, half_width);
    memset(input_frame_.buffer(kYPlane), 0,
        input_frame_.allocated_size(kYPlane));
    memset(input_frame_.buffer(kUPlane), 0,
        input_frame_.allocated_size(kUPlane));
    memset(input_frame_.buffer(kVPlane), 0,
        input_frame_.allocated_size(kVPlane));

    // The for loop above did not set the bitrate of the highest layer.
    settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].
        maxBitrate = 0;
    // The highest layer has to correspond to the non-simulcast resolution.
    settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].
        width = settings_.width;
    settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].
        height = settings_.height;
    EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));

    // Encode one frame and verify.
    encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30);
    std::vector<VideoFrameType> frame_types(kNumberOfSimulcastStreams,
                                            kDeltaFrame);
    EXPECT_CALL(encoder_callback_, Encoded(
        AllOf(Field(&EncodedImage::_frameType, kKeyFrame),
              Field(&EncodedImage::_encodedWidth, width),
              Field(&EncodedImage::_encodedHeight, height)), _, _))
        .Times(1)
        .WillRepeatedly(Return(0));
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));

    // Switch back.
    DefaultSettings(&settings_, kDefaultTemporalLayerProfile);
    // Start at the lowest bitrate for enabling base stream.
    settings_.startBitrate = kMinBitrates[0];
    EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
    encoder_->SetRates(settings_.startBitrate, 30);
    ExpectStreams(kKeyFrame, 1);
    // Resize |input_frame_| to the new resolution.
    half_width = (settings_.width + 1) / 2;
    input_frame_.CreateEmptyFrame(settings_.width, settings_.height,
                                  settings_.width, half_width, half_width);
    memset(input_frame_.buffer(kYPlane), 0,
        input_frame_.allocated_size(kYPlane));
    memset(input_frame_.buffer(kUPlane), 0,
        input_frame_.allocated_size(kUPlane));
    memset(input_frame_.buffer(kVPlane), 0,
        input_frame_.allocated_size(kVPlane));
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
  }

  void TestSwitchingToOneStream() {
    SwitchingToOneStream(1024, 768);
  }

  void TestSwitchingToOneOddStream() {
    SwitchingToOneStream(1023, 769);
  }

  void TestRPSIEncoder() {
    Vp8TestEncodedImageCallback encoder_callback;
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback);

    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.

    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    int picture_id = -1;
    int temporal_layer = -1;
    bool layer_sync = false;
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);
    EXPECT_EQ(0, temporal_layer);
    EXPECT_TRUE(layer_sync);
    int key_frame_picture_id = picture_id;

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);
    EXPECT_EQ(2, temporal_layer);
    EXPECT_TRUE(layer_sync);

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);
    EXPECT_EQ(1, temporal_layer);
    EXPECT_TRUE(layer_sync);

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);
    EXPECT_EQ(2, temporal_layer);
    EXPECT_FALSE(layer_sync);

    CodecSpecificInfo codec_specific;
    codec_specific.codecType = kVideoCodecVP8;
    codec_specific.codecSpecific.VP8.hasReceivedRPSI = true;

    // Must match last key frame to trigger.
    codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id;

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);

    EXPECT_EQ(0, temporal_layer);
    EXPECT_TRUE(layer_sync);

    // Must match last key frame to trigger, test bad id.
    codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id + 17;

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);

    EXPECT_EQ(2, temporal_layer);
    // The previous frame was a base layer sync (since it was a frame that
    // only predicts from key frame and hence resets the temporal pattern),
    // so this frame (the next one) must have |layer_sync| set to true.
    EXPECT_TRUE(layer_sync);
  }

  void TestRPSIEncodeDecode() {
    Vp8TestEncodedImageCallback encoder_callback;
    Vp8TestDecodedImageCallback decoder_callback;
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    decoder_->RegisterDecodeCompleteCallback(&decoder_callback);

    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.

    // Set color.
    int plane_offset[kNumOfPlanes];
    plane_offset[kYPlane] = kColorY;
    plane_offset[kUPlane] = kColorU;
    plane_offset[kVPlane] = kColorV;
    CreateImage(&input_frame_, plane_offset);

    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    int picture_id = -1;
    int temporal_layer = -1;
    bool layer_sync = false;
    encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
                                             &layer_sync, 0);
    EXPECT_EQ(0, temporal_layer);
    EXPECT_TRUE(layer_sync);
    int key_frame_picture_id = picture_id;

    // Change color.
    plane_offset[kYPlane] += 1;
    plane_offset[kUPlane] += 1;
    plane_offset[kVPlane] += 1;
    CreateImage(&input_frame_, plane_offset);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));

    // Change color.
    plane_offset[kYPlane] += 1;
    plane_offset[kUPlane] += 1;
    plane_offset[kVPlane] += 1;
    CreateImage(&input_frame_, plane_offset);

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));

    // Change color.
    plane_offset[kYPlane] += 1;
    plane_offset[kUPlane] += 1;
    plane_offset[kVPlane] += 1;
    CreateImage(&input_frame_, plane_offset);

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));

    CodecSpecificInfo codec_specific;
    codec_specific.codecType = kVideoCodecVP8;
    codec_specific.codecSpecific.VP8.hasReceivedRPSI = true;
    // Must match last key frame to trigger.
    codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id;

    // Change color back to original.
    plane_offset[kYPlane] = kColorY;
    plane_offset[kUPlane] = kColorU;
    plane_offset[kVPlane] = kColorV;
    CreateImage(&input_frame_, plane_offset);

    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));

    EncodedImage encoded_frame;
    encoder_callback.GetLastEncodedKeyFrame(&encoded_frame);
    decoder_->Decode(encoded_frame, false, NULL);
    encoder_callback.GetLastEncodedFrame(&encoded_frame);
    decoder_->Decode(encoded_frame, false, NULL);
    EXPECT_EQ(2, decoder_callback.DecodedFrames());
  }

  // Test the layer pattern and sync flag for various spatial-temporal patterns.
  // 3-3-3 pattern: 3 temporal layers for all spatial streams, so same
  // temporal_layer id and layer_sync is expected for all streams.
  void TestSaptioTemporalLayers333PatternEncoder() {
    Vp8TestEncodedImageCallback encoder_callback;
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.

    int expected_temporal_idx[3] = { -1, -1, -1};
    bool expected_layer_sync[3] = {false, false, false};

    // First frame: #0.
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(0, 0, 0, expected_temporal_idx);
    SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #1.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #2.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(1, 1, 1, expected_temporal_idx);
    SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #3.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #4.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(0, 0, 0, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #5.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);
  }

  // Test the layer pattern and sync flag for various spatial-temporal patterns.
  // 3-2-1 pattern: 3 temporal layers for lowest resolution, 2 for middle, and
  // 1 temporal layer for highest resolution.
  // For this profile, we expect the temporal index pattern to be:
  // 1st stream: 0, 2, 1, 2, ....
  // 2nd stream: 0, 1, 0, 1, ...
  // 3rd stream: -1, -1, -1, -1, ....
  // Regarding the 3rd stream, note that a stream/encoder with 1 temporal layer
  // should always have temporal layer idx set to kNoTemporalIdx = -1.
  // Since CodecSpecificInfoVP8.temporalIdx is uint8_t, this will wrap to 255.
  // TODO(marpan): Although this seems safe for now, we should fix this.
  void TestSpatioTemporalLayers321PatternEncoder() {
    int temporal_layer_profile[3] = {3, 2, 1};
    SetUpCodec(temporal_layer_profile);
    Vp8TestEncodedImageCallback encoder_callback;
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.

    int expected_temporal_idx[3] = { -1, -1, -1};
    bool expected_layer_sync[3] = {false, false, false};

    // First frame: #0.
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(0, 0, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(true, true, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #1.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(true, true, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #2.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(1, 0, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(true, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #3.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #4.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(0, 0, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);

    // Next frame: #5.
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    VerifyTemporalIdxAndSyncForAllSpatialLayers(&encoder_callback,
                                                expected_temporal_idx,
                                                expected_layer_sync,
                                                3);
  }

  void TestStrideEncodeDecode() {
    Vp8TestEncodedImageCallback encoder_callback;
    Vp8TestDecodedImageCallback decoder_callback;
    encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    decoder_->RegisterDecodeCompleteCallback(&decoder_callback);

    encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    // Setting two (possibly) problematic use cases for stride:
    // 1. stride > width 2. stride_y != stride_uv/2
    int stride_y = kDefaultWidth + 20;
    int stride_uv = ((kDefaultWidth + 1) / 2) + 5;
    input_frame_.CreateEmptyFrame(kDefaultWidth, kDefaultHeight,
                                 stride_y, stride_uv, stride_uv);
    // Set color.
    int plane_offset[kNumOfPlanes];
    plane_offset[kYPlane] = kColorY;
    plane_offset[kUPlane] = kColorU;
    plane_offset[kVPlane] = kColorV;
    CreateImage(&input_frame_, plane_offset);

    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));

    // Change color.
    plane_offset[kYPlane] += 1;
    plane_offset[kUPlane] += 1;
    plane_offset[kVPlane] += 1;
    CreateImage(&input_frame_, plane_offset);
    input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));

    EncodedImage encoded_frame;
    // Only encoding one frame - so will be a key frame.
    encoder_callback.GetLastEncodedKeyFrame(&encoded_frame);
    EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, NULL));
    encoder_callback.GetLastEncodedFrame(&encoded_frame);
    decoder_->Decode(encoded_frame, false, NULL);
    EXPECT_EQ(2, decoder_callback.DecodedFrames());
  }

  void TestSkipEncodingUnusedStreams() {
    SkipEncodingUnusedStreamsTest test;
    std::vector<unsigned int> configured_bitrate =
        test.RunTest(encoder_.get(),
                     &settings_,
                     1);    // Target bit rate 1, to force all streams but the
                            // base one to be exceeding bandwidth constraints.
    EXPECT_EQ(static_cast<size_t>(kNumberOfSimulcastStreams),
              configured_bitrate.size());

    unsigned int min_bitrate =
        std::max(settings_.simulcastStream[0].minBitrate, settings_.minBitrate);
    int stream = 0;
    for (std::vector<unsigned int>::const_iterator it =
             configured_bitrate.begin();
         it != configured_bitrate.end();
         ++it) {
      if (stream == 0) {
        EXPECT_EQ(min_bitrate, *it);
      } else {
        EXPECT_EQ(0u, *it);
      }
      ++stream;
    }
  }

  rtc::scoped_ptr<VP8Encoder> encoder_;
  MockEncodedImageCallback encoder_callback_;
  rtc::scoped_ptr<VP8Decoder> decoder_;
  MockDecodedImageCallback decoder_callback_;
  VideoCodec settings_;
  VideoFrame input_frame_;
};

}  // namespace testing
}  // namespace webrtc

#endif  // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_
