Home | History | Annotate | Download | only in vp8
      1 /*
      2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_
     12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_
     13 
     14 #include <algorithm>
     15 #include <vector>
     16 
     17 #include "webrtc/base/checks.h"
     18 #include "webrtc/base/scoped_ptr.h"
     19 #include "webrtc/common.h"
     20 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
     21 #include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h"
     22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
     23 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
     24 #include "webrtc/video_frame.h"
     25 
     26 #include "gtest/gtest.h"
     27 
     28 using ::testing::_;
     29 using ::testing::AllOf;
     30 using ::testing::Field;
     31 using ::testing::Return;
     32 
     33 namespace webrtc {
     34 namespace testing {
     35 
     36 const int kDefaultWidth = 1280;
     37 const int kDefaultHeight = 720;
     38 const int kNumberOfSimulcastStreams = 3;
     39 const int kColorY = 66;
     40 const int kColorU = 22;
     41 const int kColorV = 33;
     42 const int kMaxBitrates[kNumberOfSimulcastStreams] = {150, 600, 1200};
     43 const int kMinBitrates[kNumberOfSimulcastStreams] = {50, 150, 600};
     44 const int kTargetBitrates[kNumberOfSimulcastStreams] = {100, 450, 1000};
     45 const int kDefaultTemporalLayerProfile[3] = {3, 3, 3};
     46 
     47 template <typename T>
     48 void SetExpectedValues3(T value0, T value1, T value2, T* expected_values) {
     49   expected_values[0] = value0;
     50   expected_values[1] = value1;
     51   expected_values[2] = value2;
     52 }
     53 
     54 class Vp8TestEncodedImageCallback : public EncodedImageCallback {
     55  public:
     56   Vp8TestEncodedImageCallback() : picture_id_(-1) {
     57     memset(temporal_layer_, -1, sizeof(temporal_layer_));
     58     memset(layer_sync_, false, sizeof(layer_sync_));
     59   }
     60 
     61   ~Vp8TestEncodedImageCallback() {
     62     delete[] encoded_key_frame_._buffer;
     63     delete[] encoded_frame_._buffer;
     64   }
     65 
     66   virtual int32_t Encoded(const EncodedImage& encoded_image,
     67                           const CodecSpecificInfo* codec_specific_info,
     68                           const RTPFragmentationHeader* fragmentation) {
     69     // Only store the base layer.
     70     if (codec_specific_info->codecSpecific.VP8.simulcastIdx == 0) {
     71       if (encoded_image._frameType == kVideoFrameKey) {
     72         delete[] encoded_key_frame_._buffer;
     73         encoded_key_frame_._buffer = new uint8_t[encoded_image._size];
     74         encoded_key_frame_._size = encoded_image._size;
     75         encoded_key_frame_._length = encoded_image._length;
     76         encoded_key_frame_._frameType = kVideoFrameKey;
     77         encoded_key_frame_._completeFrame = encoded_image._completeFrame;
     78         memcpy(encoded_key_frame_._buffer, encoded_image._buffer,
     79                encoded_image._length);
     80       } else {
     81         delete[] encoded_frame_._buffer;
     82         encoded_frame_._buffer = new uint8_t[encoded_image._size];
     83         encoded_frame_._size = encoded_image._size;
     84         encoded_frame_._length = encoded_image._length;
     85         memcpy(encoded_frame_._buffer, encoded_image._buffer,
     86                encoded_image._length);
     87       }
     88     }
     89     picture_id_ = codec_specific_info->codecSpecific.VP8.pictureId;
     90     layer_sync_[codec_specific_info->codecSpecific.VP8.simulcastIdx] =
     91         codec_specific_info->codecSpecific.VP8.layerSync;
     92     temporal_layer_[codec_specific_info->codecSpecific.VP8.simulcastIdx] =
     93         codec_specific_info->codecSpecific.VP8.temporalIdx;
     94     return 0;
     95   }
     96   void GetLastEncodedFrameInfo(int* picture_id,
     97                                int* temporal_layer,
     98                                bool* layer_sync,
     99                                int stream) {
    100     *picture_id = picture_id_;
    101     *temporal_layer = temporal_layer_[stream];
    102     *layer_sync = layer_sync_[stream];
    103   }
    104   void GetLastEncodedKeyFrame(EncodedImage* encoded_key_frame) {
    105     *encoded_key_frame = encoded_key_frame_;
    106   }
    107   void GetLastEncodedFrame(EncodedImage* encoded_frame) {
    108     *encoded_frame = encoded_frame_;
    109   }
    110 
    111  private:
    112   EncodedImage encoded_key_frame_;
    113   EncodedImage encoded_frame_;
    114   int picture_id_;
    115   int temporal_layer_[kNumberOfSimulcastStreams];
    116   bool layer_sync_[kNumberOfSimulcastStreams];
    117 };
    118 
    119 class Vp8TestDecodedImageCallback : public DecodedImageCallback {
    120  public:
    121   Vp8TestDecodedImageCallback() : decoded_frames_(0) {}
    122   int32_t Decoded(VideoFrame& decoded_image) override {
    123     for (int i = 0; i < decoded_image.width(); ++i) {
    124       EXPECT_NEAR(kColorY, decoded_image.buffer(kYPlane)[i], 1);
    125     }
    126 
    127     // TODO(mikhal): Verify the difference between U,V and the original.
    128     for (int i = 0; i < ((decoded_image.width() + 1) / 2); ++i) {
    129       EXPECT_NEAR(kColorU, decoded_image.buffer(kUPlane)[i], 4);
    130       EXPECT_NEAR(kColorV, decoded_image.buffer(kVPlane)[i], 4);
    131     }
    132     decoded_frames_++;
    133     return 0;
    134   }
    135   int32_t Decoded(VideoFrame& decoded_image, int64_t decode_time_ms) override {
    136     RTC_NOTREACHED();
    137     return -1;
    138   }
    139   int DecodedFrames() { return decoded_frames_; }
    140 
    141  private:
    142   int decoded_frames_;
    143 };
    144 
    145 class SkipEncodingUnusedStreamsTest {
    146  public:
    147   std::vector<unsigned int> RunTest(VP8Encoder* encoder,
    148                                     VideoCodec* settings,
    149                                     uint32_t target_bitrate) {
    150     Config options;
    151     SpyingTemporalLayersFactory* spy_factory =
    152         new SpyingTemporalLayersFactory();
    153     options.Set<TemporalLayers::Factory>(spy_factory);
    154     settings->extra_options = &options;
    155     EXPECT_EQ(0, encoder->InitEncode(settings, 1, 1200));
    156 
    157     encoder->SetRates(target_bitrate, 30);
    158 
    159     std::vector<unsigned int> configured_bitrates;
    160     for (std::vector<TemporalLayers*>::const_iterator it =
    161              spy_factory->spying_layers_.begin();
    162          it != spy_factory->spying_layers_.end(); ++it) {
    163       configured_bitrates.push_back(
    164           static_cast<SpyingTemporalLayers*>(*it)->configured_bitrate_);
    165     }
    166     return configured_bitrates;
    167   }
    168 
    169   class SpyingTemporalLayers : public TemporalLayers {
    170    public:
    171     explicit SpyingTemporalLayers(TemporalLayers* layers)
    172         : configured_bitrate_(0), layers_(layers) {}
    173 
    174     virtual ~SpyingTemporalLayers() { delete layers_; }
    175 
    176     virtual int EncodeFlags(uint32_t timestamp) {
    177       return layers_->EncodeFlags(timestamp);
    178     }
    179 
    180     bool ConfigureBitrates(int bitrate_kbit,
    181                            int max_bitrate_kbit,
    182                            int framerate,
    183                            vpx_codec_enc_cfg_t* cfg) override {
    184       configured_bitrate_ = bitrate_kbit;
    185       return layers_->ConfigureBitrates(bitrate_kbit, max_bitrate_kbit,
    186                                         framerate, cfg);
    187     }
    188 
    189     void PopulateCodecSpecific(bool base_layer_sync,
    190                                CodecSpecificInfoVP8* vp8_info,
    191                                uint32_t timestamp) override {
    192       layers_->PopulateCodecSpecific(base_layer_sync, vp8_info, timestamp);
    193     }
    194 
    195     void FrameEncoded(unsigned int size, uint32_t timestamp, int qp) override {
    196       layers_->FrameEncoded(size, timestamp, qp);
    197     }
    198 
    199     int CurrentLayerId() const override { return layers_->CurrentLayerId(); }
    200 
    201     bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) override {
    202       return false;
    203     }
    204 
    205     int configured_bitrate_;
    206     TemporalLayers* layers_;
    207   };
    208 
    209   class SpyingTemporalLayersFactory : public TemporalLayers::Factory {
    210    public:
    211     virtual ~SpyingTemporalLayersFactory() {}
    212     TemporalLayers* Create(int temporal_layers,
    213                            uint8_t initial_tl0_pic_idx) const override {
    214       SpyingTemporalLayers* layers =
    215           new SpyingTemporalLayers(TemporalLayers::Factory::Create(
    216               temporal_layers, initial_tl0_pic_idx));
    217       spying_layers_.push_back(layers);
    218       return layers;
    219     }
    220 
    221     mutable std::vector<TemporalLayers*> spying_layers_;
    222   };
    223 };
    224 
    225 class TestVp8Simulcast : public ::testing::Test {
    226  public:
    227   TestVp8Simulcast(VP8Encoder* encoder, VP8Decoder* decoder)
    228       : encoder_(encoder), decoder_(decoder) {}
    229 
    230   // Creates an VideoFrame from |plane_colors|.
    231   static void CreateImage(VideoFrame* frame, int plane_colors[kNumOfPlanes]) {
    232     for (int plane_num = 0; plane_num < kNumOfPlanes; ++plane_num) {
    233       int width =
    234           (plane_num != kYPlane ? (frame->width() + 1) / 2 : frame->width());
    235       int height =
    236           (plane_num != kYPlane ? (frame->height() + 1) / 2 : frame->height());
    237       PlaneType plane_type = static_cast<PlaneType>(plane_num);
    238       uint8_t* data = frame->buffer(plane_type);
    239       // Setting allocated area to zero - setting only image size to
    240       // requested values - will make it easier to distinguish between image
    241       // size and frame size (accounting for stride).
    242       memset(frame->buffer(plane_type), 0, frame->allocated_size(plane_type));
    243       for (int i = 0; i < height; i++) {
    244         memset(data, plane_colors[plane_num], width);
    245         data += frame->stride(plane_type);
    246       }
    247     }
    248   }
    249 
    250   static void DefaultSettings(VideoCodec* settings,
    251                               const int* temporal_layer_profile) {
    252     assert(settings);
    253     memset(settings, 0, sizeof(VideoCodec));
    254     strncpy(settings->plName, "VP8", 4);
    255     settings->codecType = kVideoCodecVP8;
    256     // 96 to 127 dynamic payload types for video codecs
    257     settings->plType = 120;
    258     settings->startBitrate = 300;
    259     settings->minBitrate = 30;
    260     settings->maxBitrate = 0;
    261     settings->maxFramerate = 30;
    262     settings->width = kDefaultWidth;
    263     settings->height = kDefaultHeight;
    264     settings->numberOfSimulcastStreams = kNumberOfSimulcastStreams;
    265     ASSERT_EQ(3, kNumberOfSimulcastStreams);
    266     ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, kMaxBitrates[0],
    267                     kMinBitrates[0], kTargetBitrates[0],
    268                     &settings->simulcastStream[0], temporal_layer_profile[0]);
    269     ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, kMaxBitrates[1],
    270                     kMinBitrates[1], kTargetBitrates[1],
    271                     &settings->simulcastStream[1], temporal_layer_profile[1]);
    272     ConfigureStream(kDefaultWidth, kDefaultHeight, kMaxBitrates[2],
    273                     kMinBitrates[2], kTargetBitrates[2],
    274                     &settings->simulcastStream[2], temporal_layer_profile[2]);
    275     settings->codecSpecific.VP8.resilience = kResilientStream;
    276     settings->codecSpecific.VP8.denoisingOn = true;
    277     settings->codecSpecific.VP8.errorConcealmentOn = false;
    278     settings->codecSpecific.VP8.automaticResizeOn = false;
    279     settings->codecSpecific.VP8.feedbackModeOn = false;
    280     settings->codecSpecific.VP8.frameDroppingOn = true;
    281     settings->codecSpecific.VP8.keyFrameInterval = 3000;
    282   }
    283 
    284   static void ConfigureStream(int width,
    285                               int height,
    286                               int max_bitrate,
    287                               int min_bitrate,
    288                               int target_bitrate,
    289                               SimulcastStream* stream,
    290                               int num_temporal_layers) {
    291     assert(stream);
    292     stream->width = width;
    293     stream->height = height;
    294     stream->maxBitrate = max_bitrate;
    295     stream->minBitrate = min_bitrate;
    296     stream->targetBitrate = target_bitrate;
    297     stream->numberOfTemporalLayers = num_temporal_layers;
    298     stream->qpMax = 45;
    299   }
    300 
    301  protected:
    302   virtual void SetUp() { SetUpCodec(kDefaultTemporalLayerProfile); }
    303 
    304   virtual void SetUpCodec(const int* temporal_layer_profile) {
    305     encoder_->RegisterEncodeCompleteCallback(&encoder_callback_);
    306     decoder_->RegisterDecodeCompleteCallback(&decoder_callback_);
    307     DefaultSettings(&settings_, temporal_layer_profile);
    308     EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
    309     EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1));
    310     int half_width = (kDefaultWidth + 1) / 2;
    311     input_frame_.CreateEmptyFrame(kDefaultWidth, kDefaultHeight, kDefaultWidth,
    312                                   half_width, half_width);
    313     memset(input_frame_.buffer(kYPlane), 0,
    314            input_frame_.allocated_size(kYPlane));
    315     memset(input_frame_.buffer(kUPlane), 0,
    316            input_frame_.allocated_size(kUPlane));
    317     memset(input_frame_.buffer(kVPlane), 0,
    318            input_frame_.allocated_size(kVPlane));
    319   }
    320 
    321   virtual void TearDown() {
    322     encoder_->Release();
    323     decoder_->Release();
    324   }
    325 
    326   void ExpectStreams(FrameType frame_type, int expected_video_streams) {
    327     ASSERT_GE(expected_video_streams, 0);
    328     ASSERT_LE(expected_video_streams, kNumberOfSimulcastStreams);
    329     if (expected_video_streams >= 1) {
    330       EXPECT_CALL(
    331           encoder_callback_,
    332           Encoded(
    333               AllOf(Field(&EncodedImage::_frameType, frame_type),
    334                     Field(&EncodedImage::_encodedWidth, kDefaultWidth / 4),
    335                     Field(&EncodedImage::_encodedHeight, kDefaultHeight / 4)),
    336               _, _))
    337           .Times(1)
    338           .WillRepeatedly(Return(0));
    339     }
    340     if (expected_video_streams >= 2) {
    341       EXPECT_CALL(
    342           encoder_callback_,
    343           Encoded(
    344               AllOf(Field(&EncodedImage::_frameType, frame_type),
    345                     Field(&EncodedImage::_encodedWidth, kDefaultWidth / 2),
    346                     Field(&EncodedImage::_encodedHeight, kDefaultHeight / 2)),
    347               _, _))
    348           .Times(1)
    349           .WillRepeatedly(Return(0));
    350     }
    351     if (expected_video_streams >= 3) {
    352       EXPECT_CALL(
    353           encoder_callback_,
    354           Encoded(AllOf(Field(&EncodedImage::_frameType, frame_type),
    355                         Field(&EncodedImage::_encodedWidth, kDefaultWidth),
    356                         Field(&EncodedImage::_encodedHeight, kDefaultHeight)),
    357                   _, _))
    358           .Times(1)
    359           .WillRepeatedly(Return(0));
    360     }
    361   }
    362 
    363   void VerifyTemporalIdxAndSyncForAllSpatialLayers(
    364       Vp8TestEncodedImageCallback* encoder_callback,
    365       const int* expected_temporal_idx,
    366       const bool* expected_layer_sync,
    367       int num_spatial_layers) {
    368     int picture_id = -1;
    369     int temporal_layer = -1;
    370     bool layer_sync = false;
    371     for (int i = 0; i < num_spatial_layers; i++) {
    372       encoder_callback->GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    373                                                 &layer_sync, i);
    374       EXPECT_EQ(expected_temporal_idx[i], temporal_layer);
    375       EXPECT_EQ(expected_layer_sync[i], layer_sync);
    376     }
    377   }
    378 
    379   // We currently expect all active streams to generate a key frame even though
    380   // a key frame was only requested for some of them.
    381   void TestKeyFrameRequestsOnAllStreams() {
    382     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    383     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    384                                        kVideoFrameDelta);
    385     ExpectStreams(kVideoFrameKey, kNumberOfSimulcastStreams);
    386     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    387 
    388     ExpectStreams(kVideoFrameDelta, kNumberOfSimulcastStreams);
    389     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    390     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    391 
    392     frame_types[0] = kVideoFrameKey;
    393     ExpectStreams(kVideoFrameKey, kNumberOfSimulcastStreams);
    394     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    395     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    396 
    397     std::fill(frame_types.begin(), frame_types.end(), kVideoFrameDelta);
    398     frame_types[1] = kVideoFrameKey;
    399     ExpectStreams(kVideoFrameKey, kNumberOfSimulcastStreams);
    400     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    401     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    402 
    403     std::fill(frame_types.begin(), frame_types.end(), kVideoFrameDelta);
    404     frame_types[2] = kVideoFrameKey;
    405     ExpectStreams(kVideoFrameKey, kNumberOfSimulcastStreams);
    406     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    407     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    408 
    409     std::fill(frame_types.begin(), frame_types.end(), kVideoFrameDelta);
    410     ExpectStreams(kVideoFrameDelta, kNumberOfSimulcastStreams);
    411     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    412     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    413   }
    414 
    415   void TestPaddingAllStreams() {
    416     // We should always encode the base layer.
    417     encoder_->SetRates(kMinBitrates[0] - 1, 30);
    418     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    419                                        kVideoFrameDelta);
    420     ExpectStreams(kVideoFrameKey, 1);
    421     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    422 
    423     ExpectStreams(kVideoFrameDelta, 1);
    424     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    425     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    426   }
    427 
    428   void TestPaddingTwoStreams() {
    429     // We have just enough to get only the first stream and padding for two.
    430     encoder_->SetRates(kMinBitrates[0], 30);
    431     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    432                                        kVideoFrameDelta);
    433     ExpectStreams(kVideoFrameKey, 1);
    434     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    435 
    436     ExpectStreams(kVideoFrameDelta, 1);
    437     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    438     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    439   }
    440 
    441   void TestPaddingTwoStreamsOneMaxedOut() {
    442     // We are just below limit of sending second stream, so we should get
    443     // the first stream maxed out (at |maxBitrate|), and padding for two.
    444     encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] - 1, 30);
    445     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    446                                        kVideoFrameDelta);
    447     ExpectStreams(kVideoFrameKey, 1);
    448     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    449 
    450     ExpectStreams(kVideoFrameDelta, 1);
    451     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    452     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    453   }
    454 
    455   void TestPaddingOneStream() {
    456     // We have just enough to send two streams, so padding for one stream.
    457     encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1], 30);
    458     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    459                                        kVideoFrameDelta);
    460     ExpectStreams(kVideoFrameKey, 2);
    461     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    462 
    463     ExpectStreams(kVideoFrameDelta, 2);
    464     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    465     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    466   }
    467 
    468   void TestPaddingOneStreamTwoMaxedOut() {
    469     // We are just below limit of sending third stream, so we should get
    470     // first stream's rate maxed out at |targetBitrate|, second at |maxBitrate|.
    471     encoder_->SetRates(
    472         kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] - 1, 30);
    473     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    474                                        kVideoFrameDelta);
    475     ExpectStreams(kVideoFrameKey, 2);
    476     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    477 
    478     ExpectStreams(kVideoFrameDelta, 2);
    479     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    480     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    481   }
    482 
    483   void TestSendAllStreams() {
    484     // We have just enough to send all streams.
    485     encoder_->SetRates(
    486         kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2], 30);
    487     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    488                                        kVideoFrameDelta);
    489     ExpectStreams(kVideoFrameKey, 3);
    490     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    491 
    492     ExpectStreams(kVideoFrameDelta, 3);
    493     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    494     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    495   }
    496 
    497   void TestDisablingStreams() {
    498     // We should get three media streams.
    499     encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2], 30);
    500     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    501                                        kVideoFrameDelta);
    502     ExpectStreams(kVideoFrameKey, 3);
    503     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    504 
    505     ExpectStreams(kVideoFrameDelta, 3);
    506     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    507     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    508 
    509     // We should only get two streams and padding for one.
    510     encoder_->SetRates(
    511         kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30);
    512     ExpectStreams(kVideoFrameDelta, 2);
    513     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    514     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    515 
    516     // We should only get the first stream and padding for two.
    517     encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] / 2, 30);
    518     ExpectStreams(kVideoFrameDelta, 1);
    519     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    520     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    521 
    522     // We don't have enough bitrate for the thumbnail stream, but we should get
    523     // it anyway with current configuration.
    524     encoder_->SetRates(kTargetBitrates[0] - 1, 30);
    525     ExpectStreams(kVideoFrameDelta, 1);
    526     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    527     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    528 
    529     // We should only get two streams and padding for one.
    530     encoder_->SetRates(
    531         kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30);
    532     // We get a key frame because a new stream is being enabled.
    533     ExpectStreams(kVideoFrameKey, 2);
    534     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    535     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    536 
    537     // We should get all three streams.
    538     encoder_->SetRates(
    539         kTargetBitrates[0] + kTargetBitrates[1] + kTargetBitrates[2], 30);
    540     // We get a key frame because a new stream is being enabled.
    541     ExpectStreams(kVideoFrameKey, 3);
    542     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    543     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    544   }
    545 
    546   void SwitchingToOneStream(int width, int height) {
    547     // Disable all streams except the last and set the bitrate of the last to
    548     // 100 kbps. This verifies the way GTP switches to screenshare mode.
    549     settings_.codecSpecific.VP8.numberOfTemporalLayers = 1;
    550     settings_.maxBitrate = 100;
    551     settings_.startBitrate = 100;
    552     settings_.width = width;
    553     settings_.height = height;
    554     for (int i = 0; i < settings_.numberOfSimulcastStreams - 1; ++i) {
    555       settings_.simulcastStream[i].maxBitrate = 0;
    556       settings_.simulcastStream[i].width = settings_.width;
    557       settings_.simulcastStream[i].height = settings_.height;
    558     }
    559     // Setting input image to new resolution.
    560     int half_width = (settings_.width + 1) / 2;
    561     input_frame_.CreateEmptyFrame(settings_.width, settings_.height,
    562                                   settings_.width, half_width, half_width);
    563     memset(input_frame_.buffer(kYPlane), 0,
    564            input_frame_.allocated_size(kYPlane));
    565     memset(input_frame_.buffer(kUPlane), 0,
    566            input_frame_.allocated_size(kUPlane));
    567     memset(input_frame_.buffer(kVPlane), 0,
    568            input_frame_.allocated_size(kVPlane));
    569 
    570     // The for loop above did not set the bitrate of the highest layer.
    571     settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1]
    572         .maxBitrate = 0;
    573     // The highest layer has to correspond to the non-simulcast resolution.
    574     settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].width =
    575         settings_.width;
    576     settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height =
    577         settings_.height;
    578     EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
    579 
    580     // Encode one frame and verify.
    581     encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30);
    582     std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
    583                                        kVideoFrameDelta);
    584     EXPECT_CALL(encoder_callback_,
    585                 Encoded(AllOf(Field(&EncodedImage::_frameType, kVideoFrameKey),
    586                               Field(&EncodedImage::_encodedWidth, width),
    587                               Field(&EncodedImage::_encodedHeight, height)),
    588                         _, _))
    589         .Times(1)
    590         .WillRepeatedly(Return(0));
    591     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    592 
    593     // Switch back.
    594     DefaultSettings(&settings_, kDefaultTemporalLayerProfile);
    595     // Start at the lowest bitrate for enabling base stream.
    596     settings_.startBitrate = kMinBitrates[0];
    597     EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
    598     encoder_->SetRates(settings_.startBitrate, 30);
    599     ExpectStreams(kVideoFrameKey, 1);
    600     // Resize |input_frame_| to the new resolution.
    601     half_width = (settings_.width + 1) / 2;
    602     input_frame_.CreateEmptyFrame(settings_.width, settings_.height,
    603                                   settings_.width, half_width, half_width);
    604     memset(input_frame_.buffer(kYPlane), 0,
    605            input_frame_.allocated_size(kYPlane));
    606     memset(input_frame_.buffer(kUPlane), 0,
    607            input_frame_.allocated_size(kUPlane));
    608     memset(input_frame_.buffer(kVPlane), 0,
    609            input_frame_.allocated_size(kVPlane));
    610     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, &frame_types));
    611   }
    612 
    613   void TestSwitchingToOneStream() { SwitchingToOneStream(1024, 768); }
    614 
    615   void TestSwitchingToOneOddStream() { SwitchingToOneStream(1023, 769); }
    616 
    617   void TestRPSIEncoder() {
    618     Vp8TestEncodedImageCallback encoder_callback;
    619     encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    620 
    621     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    622 
    623     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    624     int picture_id = -1;
    625     int temporal_layer = -1;
    626     bool layer_sync = false;
    627     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    628                                              &layer_sync, 0);
    629     EXPECT_EQ(0, temporal_layer);
    630     EXPECT_TRUE(layer_sync);
    631     int key_frame_picture_id = picture_id;
    632 
    633     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    634     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    635     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    636                                              &layer_sync, 0);
    637     EXPECT_EQ(2, temporal_layer);
    638     EXPECT_TRUE(layer_sync);
    639 
    640     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    641     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    642     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    643                                              &layer_sync, 0);
    644     EXPECT_EQ(1, temporal_layer);
    645     EXPECT_TRUE(layer_sync);
    646 
    647     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    648     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    649     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    650                                              &layer_sync, 0);
    651     EXPECT_EQ(2, temporal_layer);
    652     EXPECT_FALSE(layer_sync);
    653 
    654     CodecSpecificInfo codec_specific;
    655     codec_specific.codecType = kVideoCodecVP8;
    656     codec_specific.codecSpecific.VP8.hasReceivedRPSI = true;
    657 
    658     // Must match last key frame to trigger.
    659     codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id;
    660 
    661     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    662     EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));
    663     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    664                                              &layer_sync, 0);
    665 
    666     EXPECT_EQ(0, temporal_layer);
    667     EXPECT_TRUE(layer_sync);
    668 
    669     // Must match last key frame to trigger, test bad id.
    670     codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id + 17;
    671 
    672     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    673     EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));
    674     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    675                                              &layer_sync, 0);
    676 
    677     EXPECT_EQ(2, temporal_layer);
    678     // The previous frame was a base layer sync (since it was a frame that
    679     // only predicts from key frame and hence resets the temporal pattern),
    680     // so this frame (the next one) must have |layer_sync| set to true.
    681     EXPECT_TRUE(layer_sync);
    682   }
    683 
    684   void TestRPSIEncodeDecode() {
    685     Vp8TestEncodedImageCallback encoder_callback;
    686     Vp8TestDecodedImageCallback decoder_callback;
    687     encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    688     decoder_->RegisterDecodeCompleteCallback(&decoder_callback);
    689 
    690     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    691 
    692     // Set color.
    693     int plane_offset[kNumOfPlanes];
    694     plane_offset[kYPlane] = kColorY;
    695     plane_offset[kUPlane] = kColorU;
    696     plane_offset[kVPlane] = kColorV;
    697     CreateImage(&input_frame_, plane_offset);
    698 
    699     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    700     int picture_id = -1;
    701     int temporal_layer = -1;
    702     bool layer_sync = false;
    703     encoder_callback.GetLastEncodedFrameInfo(&picture_id, &temporal_layer,
    704                                              &layer_sync, 0);
    705     EXPECT_EQ(0, temporal_layer);
    706     EXPECT_TRUE(layer_sync);
    707     int key_frame_picture_id = picture_id;
    708 
    709     // Change color.
    710     plane_offset[kYPlane] += 1;
    711     plane_offset[kUPlane] += 1;
    712     plane_offset[kVPlane] += 1;
    713     CreateImage(&input_frame_, plane_offset);
    714     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    715     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    716 
    717     // Change color.
    718     plane_offset[kYPlane] += 1;
    719     plane_offset[kUPlane] += 1;
    720     plane_offset[kVPlane] += 1;
    721     CreateImage(&input_frame_, plane_offset);
    722 
    723     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    724     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    725 
    726     // Change color.
    727     plane_offset[kYPlane] += 1;
    728     plane_offset[kUPlane] += 1;
    729     plane_offset[kVPlane] += 1;
    730     CreateImage(&input_frame_, plane_offset);
    731 
    732     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    733     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    734 
    735     CodecSpecificInfo codec_specific;
    736     codec_specific.codecType = kVideoCodecVP8;
    737     codec_specific.codecSpecific.VP8.hasReceivedRPSI = true;
    738     // Must match last key frame to trigger.
    739     codec_specific.codecSpecific.VP8.pictureIdRPSI = key_frame_picture_id;
    740 
    741     // Change color back to original.
    742     plane_offset[kYPlane] = kColorY;
    743     plane_offset[kUPlane] = kColorU;
    744     plane_offset[kVPlane] = kColorV;
    745     CreateImage(&input_frame_, plane_offset);
    746 
    747     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    748     EXPECT_EQ(0, encoder_->Encode(input_frame_, &codec_specific, NULL));
    749 
    750     EncodedImage encoded_frame;
    751     encoder_callback.GetLastEncodedKeyFrame(&encoded_frame);
    752     decoder_->Decode(encoded_frame, false, NULL);
    753     encoder_callback.GetLastEncodedFrame(&encoded_frame);
    754     decoder_->Decode(encoded_frame, false, NULL);
    755     EXPECT_EQ(2, decoder_callback.DecodedFrames());
    756   }
    757 
    758   // Test the layer pattern and sync flag for various spatial-temporal patterns.
    759   // 3-3-3 pattern: 3 temporal layers for all spatial streams, so same
    760   // temporal_layer id and layer_sync is expected for all streams.
    761   void TestSaptioTemporalLayers333PatternEncoder() {
    762     Vp8TestEncodedImageCallback encoder_callback;
    763     encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    764     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    765 
    766     int expected_temporal_idx[3] = {-1, -1, -1};
    767     bool expected_layer_sync[3] = {false, false, false};
    768 
    769     // First frame: #0.
    770     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    771     SetExpectedValues3<int>(0, 0, 0, expected_temporal_idx);
    772     SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    773     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    774         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    775 
    776     // Next frame: #1.
    777     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    778     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    779     SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    780     SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    781     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    782         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    783 
    784     // Next frame: #2.
    785     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    786     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    787     SetExpectedValues3<int>(1, 1, 1, expected_temporal_idx);
    788     SetExpectedValues3<bool>(true, true, true, expected_layer_sync);
    789     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    790         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    791 
    792     // Next frame: #3.
    793     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    794     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    795     SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    796     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    797     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    798         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    799 
    800     // Next frame: #4.
    801     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    802     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    803     SetExpectedValues3<int>(0, 0, 0, expected_temporal_idx);
    804     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    805     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    806         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    807 
    808     // Next frame: #5.
    809     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    810     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    811     SetExpectedValues3<int>(2, 2, 2, expected_temporal_idx);
    812     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    813     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    814         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    815   }
    816 
    817   // Test the layer pattern and sync flag for various spatial-temporal patterns.
    818   // 3-2-1 pattern: 3 temporal layers for lowest resolution, 2 for middle, and
    819   // 1 temporal layer for highest resolution.
    820   // For this profile, we expect the temporal index pattern to be:
    821   // 1st stream: 0, 2, 1, 2, ....
    822   // 2nd stream: 0, 1, 0, 1, ...
    823   // 3rd stream: -1, -1, -1, -1, ....
    824   // Regarding the 3rd stream, note that a stream/encoder with 1 temporal layer
    825   // should always have temporal layer idx set to kNoTemporalIdx = -1.
    826   // Since CodecSpecificInfoVP8.temporalIdx is uint8_t, this will wrap to 255.
    827   // TODO(marpan): Although this seems safe for now, we should fix this.
    828   void TestSpatioTemporalLayers321PatternEncoder() {
    829     int temporal_layer_profile[3] = {3, 2, 1};
    830     SetUpCodec(temporal_layer_profile);
    831     Vp8TestEncodedImageCallback encoder_callback;
    832     encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    833     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    834 
    835     int expected_temporal_idx[3] = {-1, -1, -1};
    836     bool expected_layer_sync[3] = {false, false, false};
    837 
    838     // First frame: #0.
    839     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    840     SetExpectedValues3<int>(0, 0, 255, expected_temporal_idx);
    841     SetExpectedValues3<bool>(true, true, false, expected_layer_sync);
    842     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    843         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    844 
    845     // Next frame: #1.
    846     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    847     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    848     SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    849     SetExpectedValues3<bool>(true, true, false, expected_layer_sync);
    850     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    851         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    852 
    853     // Next frame: #2.
    854     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    855     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    856     SetExpectedValues3<int>(1, 0, 255, expected_temporal_idx);
    857     SetExpectedValues3<bool>(true, false, false, expected_layer_sync);
    858     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    859         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    860 
    861     // Next frame: #3.
    862     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    863     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    864     SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    865     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    866     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    867         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    868 
    869     // Next frame: #4.
    870     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    871     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    872     SetExpectedValues3<int>(0, 0, 255, expected_temporal_idx);
    873     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    874     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    875         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    876 
    877     // Next frame: #5.
    878     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    879     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    880     SetExpectedValues3<int>(2, 1, 255, expected_temporal_idx);
    881     SetExpectedValues3<bool>(false, false, false, expected_layer_sync);
    882     VerifyTemporalIdxAndSyncForAllSpatialLayers(
    883         &encoder_callback, expected_temporal_idx, expected_layer_sync, 3);
    884   }
    885 
    886   void TestStrideEncodeDecode() {
    887     Vp8TestEncodedImageCallback encoder_callback;
    888     Vp8TestDecodedImageCallback decoder_callback;
    889     encoder_->RegisterEncodeCompleteCallback(&encoder_callback);
    890     decoder_->RegisterDecodeCompleteCallback(&decoder_callback);
    891 
    892     encoder_->SetRates(kMaxBitrates[2], 30);  // To get all three streams.
    893     // Setting two (possibly) problematic use cases for stride:
    894     // 1. stride > width 2. stride_y != stride_uv/2
    895     int stride_y = kDefaultWidth + 20;
    896     int stride_uv = ((kDefaultWidth + 1) / 2) + 5;
    897     input_frame_.CreateEmptyFrame(kDefaultWidth, kDefaultHeight, stride_y,
    898                                   stride_uv, stride_uv);
    899     // Set color.
    900     int plane_offset[kNumOfPlanes];
    901     plane_offset[kYPlane] = kColorY;
    902     plane_offset[kUPlane] = kColorU;
    903     plane_offset[kVPlane] = kColorV;
    904     CreateImage(&input_frame_, plane_offset);
    905 
    906     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    907 
    908     // Change color.
    909     plane_offset[kYPlane] += 1;
    910     plane_offset[kUPlane] += 1;
    911     plane_offset[kVPlane] += 1;
    912     CreateImage(&input_frame_, plane_offset);
    913     input_frame_.set_timestamp(input_frame_.timestamp() + 3000);
    914     EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
    915 
    916     EncodedImage encoded_frame;
    917     // Only encoding one frame - so will be a key frame.
    918     encoder_callback.GetLastEncodedKeyFrame(&encoded_frame);
    919     EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, NULL));
    920     encoder_callback.GetLastEncodedFrame(&encoded_frame);
    921     decoder_->Decode(encoded_frame, false, NULL);
    922     EXPECT_EQ(2, decoder_callback.DecodedFrames());
    923   }
    924 
    925   void TestSkipEncodingUnusedStreams() {
    926     SkipEncodingUnusedStreamsTest test;
    927     std::vector<unsigned int> configured_bitrate =
    928         test.RunTest(encoder_.get(), &settings_,
    929                      1);  // Target bit rate 1, to force all streams but the
    930                           // base one to be exceeding bandwidth constraints.
    931     EXPECT_EQ(static_cast<size_t>(kNumberOfSimulcastStreams),
    932               configured_bitrate.size());
    933 
    934     unsigned int min_bitrate =
    935         std::max(settings_.simulcastStream[0].minBitrate, settings_.minBitrate);
    936     int stream = 0;
    937     for (std::vector<unsigned int>::const_iterator it =
    938              configured_bitrate.begin();
    939          it != configured_bitrate.end(); ++it) {
    940       if (stream == 0) {
    941         EXPECT_EQ(min_bitrate, *it);
    942       } else {
    943         EXPECT_EQ(0u, *it);
    944       }
    945       ++stream;
    946     }
    947   }
    948 
    949   rtc::scoped_ptr<VP8Encoder> encoder_;
    950   MockEncodedImageCallback encoder_callback_;
    951   rtc::scoped_ptr<VP8Decoder> decoder_;
    952   MockDecodedImageCallback decoder_callback_;
    953   VideoCodec settings_;
    954   VideoFrame input_frame_;
    955 };
    956 
    957 }  // namespace testing
    958 }  // namespace webrtc
    959 
    960 #endif  // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_
    961