Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2012 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 #include <stdio.h>
     12 
     13 #include <map>
     14 #include <sstream>
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "webrtc/common_video/interface/i420_video_frame.h"
     18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
     19 #include "webrtc/modules/utility/interface/process_thread.h"
     20 #include "webrtc/modules/video_capture/ensure_initialized.h"
     21 #include "webrtc/modules/video_capture/include/video_capture.h"
     22 #include "webrtc/modules/video_capture/include/video_capture_factory.h"
     23 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     24 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     25 #include "webrtc/system_wrappers/interface/scoped_refptr.h"
     26 #include "webrtc/system_wrappers/interface/sleep.h"
     27 #include "webrtc/system_wrappers/interface/tick_util.h"
     28 #include "webrtc/test/testsupport/gtest_disable.h"
     29 
     30 using webrtc::CriticalSectionWrapper;
     31 using webrtc::CriticalSectionScoped;
     32 using webrtc::scoped_ptr;
     33 using webrtc::SleepMs;
     34 using webrtc::TickTime;
     35 using webrtc::VideoCaptureAlarm;
     36 using webrtc::VideoCaptureCapability;
     37 using webrtc::VideoCaptureDataCallback;
     38 using webrtc::VideoCaptureFactory;
     39 using webrtc::VideoCaptureFeedBack;
     40 using webrtc::VideoCaptureModule;
     41 
     42 
     43 #define WAIT_(ex, timeout, res) \
     44   do { \
     45     res = (ex); \
     46     int64_t start = TickTime::MillisecondTimestamp(); \
     47     while (!res && TickTime::MillisecondTimestamp() < start + timeout) { \
     48       SleepMs(5); \
     49       res = (ex); \
     50     } \
     51   } while (0);\
     52 
     53 #define EXPECT_TRUE_WAIT(ex, timeout) \
     54   do { \
     55     bool res; \
     56     WAIT_(ex, timeout, res); \
     57     if (!res) EXPECT_TRUE(ex); \
     58   } while (0);
     59 
     60 
     61 static const int kTimeOut = 5000;
     62 static const int kTestHeight = 288;
     63 static const int kTestWidth = 352;
     64 static const int kTestFramerate = 30;
     65 
     66 // Compares the content of two video frames.
     67 static bool CompareFrames(const webrtc::I420VideoFrame& frame1,
     68                           const webrtc::I420VideoFrame& frame2) {
     69   bool result =
     70       (frame1.stride(webrtc::kYPlane) == frame2.stride(webrtc::kYPlane)) &&
     71       (frame1.stride(webrtc::kUPlane) == frame2.stride(webrtc::kUPlane)) &&
     72       (frame1.stride(webrtc::kVPlane) == frame2.stride(webrtc::kVPlane)) &&
     73       (frame1.width() == frame2.width()) &&
     74       (frame1.height() == frame2.height());
     75 
     76   if (!result)
     77     return false;
     78   for (int plane = 0; plane < webrtc::kNumOfPlanes; plane ++) {
     79       webrtc::PlaneType plane_type = static_cast<webrtc::PlaneType>(plane);
     80       int allocated_size1 = frame1.allocated_size(plane_type);
     81       int allocated_size2 = frame2.allocated_size(plane_type);
     82       if (allocated_size1 != allocated_size2)
     83         return false;
     84       const uint8_t* plane_buffer1 = frame1.buffer(plane_type);
     85       const uint8_t* plane_buffer2 = frame2.buffer(plane_type);
     86       if (memcmp(plane_buffer1, plane_buffer2, allocated_size1))
     87         return false;
     88     }
     89     return true;
     90 }
     91 
     92 class TestVideoCaptureCallback : public VideoCaptureDataCallback {
     93  public:
     94   TestVideoCaptureCallback()
     95     : capture_cs_(CriticalSectionWrapper::CreateCriticalSection()),
     96       capture_delay_(-1),
     97       last_render_time_ms_(0),
     98       incoming_frames_(0),
     99       timing_warnings_(0),
    100       rotate_frame_(webrtc::kCameraRotate0){
    101   }
    102 
    103   ~TestVideoCaptureCallback() {
    104     if (timing_warnings_ > 0)
    105       printf("No of timing warnings %d\n", timing_warnings_);
    106   }
    107 
    108   virtual void OnIncomingCapturedFrame(const int32_t id,
    109                                        webrtc::I420VideoFrame& videoFrame) {
    110     CriticalSectionScoped cs(capture_cs_.get());
    111 
    112     int height = videoFrame.height();
    113     int width = videoFrame.width();
    114     if (rotate_frame_ == webrtc::kCameraRotate90 ||
    115         rotate_frame_ == webrtc::kCameraRotate270) {
    116       EXPECT_EQ(width, capability_.height);
    117       EXPECT_EQ(height, capability_.width);
    118     } else {
    119       EXPECT_EQ(height, capability_.height);
    120       EXPECT_EQ(width, capability_.width);
    121     }
    122     // RenderTimstamp should be the time now.
    123     EXPECT_TRUE(
    124         videoFrame.render_time_ms() >= TickTime::MillisecondTimestamp()-30 &&
    125         videoFrame.render_time_ms() <= TickTime::MillisecondTimestamp());
    126 
    127     if ((videoFrame.render_time_ms() >
    128             last_render_time_ms_ + (1000 * 1.1) / capability_.maxFPS &&
    129             last_render_time_ms_ > 0) ||
    130         (videoFrame.render_time_ms() <
    131             last_render_time_ms_ + (1000 * 0.9) / capability_.maxFPS &&
    132             last_render_time_ms_ > 0)) {
    133       timing_warnings_++;
    134     }
    135 
    136     incoming_frames_++;
    137     last_render_time_ms_ = videoFrame.render_time_ms();
    138     last_frame_.CopyFrame(videoFrame);
    139   }
    140   virtual void OnIncomingCapturedEncodedFrame(const int32_t id,
    141                                               webrtc::VideoFrame& videoFrame,
    142                                               webrtc::VideoCodecType codecType)
    143  {
    144      assert(false);
    145  }
    146 
    147   virtual void OnCaptureDelayChanged(const int32_t id,
    148                                      const int32_t delay) {
    149     CriticalSectionScoped cs(capture_cs_.get());
    150     capture_delay_ = delay;
    151   }
    152 
    153   void SetExpectedCapability(VideoCaptureCapability capability) {
    154     CriticalSectionScoped cs(capture_cs_.get());
    155     capability_= capability;
    156     incoming_frames_ = 0;
    157     last_render_time_ms_ = 0;
    158     capture_delay_ = -1;
    159   }
    160   int incoming_frames() {
    161     CriticalSectionScoped cs(capture_cs_.get());
    162     return incoming_frames_;
    163   }
    164 
    165   int capture_delay() {
    166     CriticalSectionScoped cs(capture_cs_.get());
    167     return capture_delay_;
    168   }
    169   int timing_warnings() {
    170     CriticalSectionScoped cs(capture_cs_.get());
    171     return timing_warnings_;
    172   }
    173   VideoCaptureCapability capability() {
    174     CriticalSectionScoped cs(capture_cs_.get());
    175     return capability_;
    176   }
    177 
    178   bool CompareLastFrame(const webrtc::I420VideoFrame& frame) {
    179     CriticalSectionScoped cs(capture_cs_.get());
    180     return CompareFrames(last_frame_, frame);
    181   }
    182 
    183   void SetExpectedCaptureRotation(webrtc::VideoCaptureRotation rotation) {
    184     CriticalSectionScoped cs(capture_cs_.get());
    185     rotate_frame_ = rotation;
    186   }
    187 
    188  private:
    189   scoped_ptr<CriticalSectionWrapper> capture_cs_;
    190   VideoCaptureCapability capability_;
    191   int capture_delay_;
    192   int64_t last_render_time_ms_;
    193   int incoming_frames_;
    194   int timing_warnings_;
    195   webrtc::I420VideoFrame last_frame_;
    196   webrtc::VideoCaptureRotation rotate_frame_;
    197 };
    198 
    199 class TestVideoCaptureFeedBack : public VideoCaptureFeedBack {
    200  public:
    201   TestVideoCaptureFeedBack() :
    202     capture_cs_(CriticalSectionWrapper::CreateCriticalSection()),
    203     frame_rate_(0),
    204     alarm_(webrtc::Cleared) {
    205   }
    206 
    207   virtual void OnCaptureFrameRate(const int32_t id,
    208                                   const uint32_t frameRate) {
    209     CriticalSectionScoped cs(capture_cs_.get());
    210     frame_rate_ = frameRate;
    211   }
    212 
    213   virtual void OnNoPictureAlarm(const int32_t id,
    214                                 const VideoCaptureAlarm reported_alarm) {
    215     CriticalSectionScoped cs(capture_cs_.get());
    216     alarm_ = reported_alarm;
    217   }
    218   int frame_rate() {
    219     CriticalSectionScoped cs(capture_cs_.get());
    220     return frame_rate_;
    221 
    222   }
    223   VideoCaptureAlarm alarm() {
    224     CriticalSectionScoped cs(capture_cs_.get());
    225     return alarm_;
    226   }
    227 
    228  private:
    229   scoped_ptr<CriticalSectionWrapper> capture_cs_;
    230   unsigned int frame_rate_;
    231   VideoCaptureAlarm alarm_;
    232 };
    233 
    234 class VideoCaptureTest : public testing::Test {
    235  public:
    236   VideoCaptureTest() : number_of_devices_(0) {}
    237 
    238   void SetUp() {
    239     webrtc::videocapturemodule::EnsureInitialized();
    240     device_info_.reset(VideoCaptureFactory::CreateDeviceInfo(0));
    241     assert(device_info_.get());
    242     number_of_devices_ = device_info_->NumberOfDevices();
    243     ASSERT_GT(number_of_devices_, 0u);
    244   }
    245 
    246   webrtc::scoped_refptr<VideoCaptureModule> OpenVideoCaptureDevice(
    247       unsigned int device,
    248       VideoCaptureDataCallback* callback) {
    249     char device_name[256];
    250     char unique_name[256];
    251 
    252     EXPECT_EQ(0, device_info_->GetDeviceName(
    253         device, device_name, 256, unique_name, 256));
    254 
    255     webrtc::scoped_refptr<VideoCaptureModule> module(
    256         VideoCaptureFactory::Create(device, unique_name));
    257     if (module.get() == NULL)
    258       return NULL;
    259 
    260     EXPECT_FALSE(module->CaptureStarted());
    261 
    262     module->RegisterCaptureDataCallback(*callback);
    263     return module;
    264   }
    265 
    266   void StartCapture(VideoCaptureModule* capture_module,
    267                     VideoCaptureCapability capability) {
    268     ASSERT_EQ(0, capture_module->StartCapture(capability));
    269     EXPECT_TRUE(capture_module->CaptureStarted());
    270 
    271     VideoCaptureCapability resulting_capability;
    272     EXPECT_EQ(0, capture_module->CaptureSettings(resulting_capability));
    273     EXPECT_EQ(capability.width, resulting_capability.width);
    274     EXPECT_EQ(capability.height, resulting_capability.height);
    275   }
    276 
    277   scoped_ptr<VideoCaptureModule::DeviceInfo> device_info_;
    278   unsigned int number_of_devices_;
    279 };
    280 
    281 TEST_F(VideoCaptureTest, CreateDelete) {
    282   for (int i = 0; i < 5; ++i) {
    283     int64_t start_time = TickTime::MillisecondTimestamp();
    284     TestVideoCaptureCallback capture_observer;
    285     webrtc::scoped_refptr<VideoCaptureModule> module(OpenVideoCaptureDevice(
    286         0, &capture_observer));
    287     ASSERT_TRUE(module.get() != NULL);
    288 
    289     VideoCaptureCapability capability;
    290 #ifndef WEBRTC_MAC
    291     device_info_->GetCapability(module->CurrentDeviceName(), 0, capability);
    292 #else
    293     capability.width = kTestWidth;
    294     capability.height = kTestHeight;
    295     capability.maxFPS = kTestFramerate;
    296     capability.rawType = webrtc::kVideoUnknown;
    297 #endif
    298     capture_observer.SetExpectedCapability(capability);
    299     ASSERT_NO_FATAL_FAILURE(StartCapture(module.get(), capability));
    300 
    301     // Less than 4s to start the camera.
    302     EXPECT_LE(TickTime::MillisecondTimestamp() - start_time, 4000);
    303 
    304     // Make sure 5 frames are captured.
    305     EXPECT_TRUE_WAIT(capture_observer.incoming_frames() >= 5, kTimeOut);
    306 
    307     EXPECT_GE(capture_observer.capture_delay(), 0);
    308 
    309     int64_t stop_time = TickTime::MillisecondTimestamp();
    310     EXPECT_EQ(0, module->StopCapture());
    311     EXPECT_FALSE(module->CaptureStarted());
    312 
    313     // Less than 3s to stop the camera.
    314     EXPECT_LE(TickTime::MillisecondTimestamp() - stop_time, 3000);
    315   }
    316 }
    317 
    318 TEST_F(VideoCaptureTest, Capabilities) {
    319 #ifdef WEBRTC_MAC
    320   printf("Video capture capabilities are not supported on Mac.\n");
    321   return;
    322 #endif
    323 
    324   TestVideoCaptureCallback capture_observer;
    325 
    326   webrtc::scoped_refptr<VideoCaptureModule> module(OpenVideoCaptureDevice(
    327           0, &capture_observer));
    328   ASSERT_TRUE(module.get() != NULL);
    329 
    330   int number_of_capabilities = device_info_->NumberOfCapabilities(
    331       module->CurrentDeviceName());
    332   EXPECT_GT(number_of_capabilities, 0);
    333   // Key is <width>x<height>, value is vector of maxFPS values at that
    334   // resolution.
    335   typedef std::map<std::string, std::vector<int> > FrameRatesByResolution;
    336   FrameRatesByResolution frame_rates_by_resolution;
    337   for (int i = 0; i < number_of_capabilities; ++i) {
    338     VideoCaptureCapability capability;
    339     EXPECT_EQ(0, device_info_->GetCapability(module->CurrentDeviceName(), i,
    340                                              capability));
    341     std::ostringstream resolutionStream;
    342     resolutionStream << capability.width << "x" << capability.height;
    343     resolutionStream.flush();
    344     std::string resolution = resolutionStream.str();
    345     frame_rates_by_resolution[resolution].push_back(capability.maxFPS);
    346 
    347     // Since Android presents so many resolution/FPS combinations and the test
    348     // runner imposes a timeout, we only actually start the capture and test
    349     // that a frame was captured for 2 frame-rates at each resolution.
    350     if (frame_rates_by_resolution[resolution].size() > 2)
    351       continue;
    352 
    353     capture_observer.SetExpectedCapability(capability);
    354     ASSERT_NO_FATAL_FAILURE(StartCapture(module.get(), capability));
    355     // Make sure at least one frame is captured.
    356     EXPECT_TRUE_WAIT(capture_observer.incoming_frames() >= 1, kTimeOut);
    357 
    358     EXPECT_EQ(0, module->StopCapture());
    359   }
    360 
    361 #if ANDROID
    362   // There's no reason for this to _necessarily_ be true, but in practice all
    363   // Android devices this test runs on in fact do support multiple capture
    364   // resolutions and multiple frame-rates per captured resolution, so we assert
    365   // this fact here as a regression-test against the time that we only noticed a
    366   // single frame-rate per resolution (bug 2974).  If this test starts being run
    367   // on devices for which this is untrue (e.g. Nexus4) then the following should
    368   // probably be wrapped in a base::android::BuildInfo::model()/device() check.
    369   EXPECT_GT(frame_rates_by_resolution.size(), 1U);
    370   for (FrameRatesByResolution::const_iterator it =
    371            frame_rates_by_resolution.begin();
    372        it != frame_rates_by_resolution.end();
    373        ++it) {
    374     EXPECT_GT(it->second.size(), 1U) << it->first;
    375   }
    376 #endif  // ANDROID
    377 }
    378 
    379 // NOTE: flaky, crashes sometimes.
    380 // http://code.google.com/p/webrtc/issues/detail?id=777
    381 TEST_F(VideoCaptureTest, DISABLED_TestTwoCameras) {
    382   if (number_of_devices_ < 2) {
    383     printf("There are not two cameras available. Aborting test. \n");
    384     return;
    385   }
    386 
    387   TestVideoCaptureCallback capture_observer1;
    388   webrtc::scoped_refptr<VideoCaptureModule> module1(OpenVideoCaptureDevice(
    389           0, &capture_observer1));
    390   ASSERT_TRUE(module1.get() != NULL);
    391   VideoCaptureCapability capability1;
    392 #ifndef WEBRTC_MAC
    393   device_info_->GetCapability(module1->CurrentDeviceName(), 0, capability1);
    394 #else
    395   capability1.width = kTestWidth;
    396   capability1.height = kTestHeight;
    397   capability1.maxFPS = kTestFramerate;
    398   capability1.rawType = webrtc::kVideoUnknown;
    399 #endif
    400   capture_observer1.SetExpectedCapability(capability1);
    401 
    402   TestVideoCaptureCallback capture_observer2;
    403   webrtc::scoped_refptr<VideoCaptureModule> module2(OpenVideoCaptureDevice(
    404           1, &capture_observer2));
    405   ASSERT_TRUE(module1.get() != NULL);
    406 
    407 
    408   VideoCaptureCapability capability2;
    409 #ifndef WEBRTC_MAC
    410   device_info_->GetCapability(module2->CurrentDeviceName(), 0, capability2);
    411 #else
    412   capability2.width = kTestWidth;
    413   capability2.height = kTestHeight;
    414   capability2.maxFPS = kTestFramerate;
    415   capability2.rawType = webrtc::kVideoUnknown;
    416 #endif
    417   capture_observer2.SetExpectedCapability(capability2);
    418 
    419   ASSERT_NO_FATAL_FAILURE(StartCapture(module1.get(), capability1));
    420   ASSERT_NO_FATAL_FAILURE(StartCapture(module2.get(), capability2));
    421   EXPECT_TRUE_WAIT(capture_observer1.incoming_frames() >= 5, kTimeOut);
    422   EXPECT_TRUE_WAIT(capture_observer2.incoming_frames() >= 5, kTimeOut);
    423   EXPECT_EQ(0, module2->StopCapture());
    424   EXPECT_EQ(0, module1->StopCapture());
    425 }
    426 
    427 // Test class for testing external capture and capture feedback information
    428 // such as frame rate and picture alarm.
    429 class VideoCaptureExternalTest : public testing::Test {
    430  public:
    431   void SetUp() {
    432     capture_module_ = VideoCaptureFactory::Create(0, capture_input_interface_);
    433     process_module_ = webrtc::ProcessThread::CreateProcessThread();
    434     process_module_->Start();
    435     process_module_->RegisterModule(capture_module_);
    436 
    437     VideoCaptureCapability capability;
    438     capability.width = kTestWidth;
    439     capability.height = kTestHeight;
    440     capability.rawType = webrtc::kVideoYV12;
    441     capability.maxFPS = kTestFramerate;
    442     capture_callback_.SetExpectedCapability(capability);
    443 
    444     test_frame_.CreateEmptyFrame(kTestWidth, kTestHeight, kTestWidth,
    445                                  ((kTestWidth + 1) / 2), (kTestWidth + 1) / 2);
    446     SleepMs(1); // Wait 1ms so that two tests can't have the same timestamp.
    447     memset(test_frame_.buffer(webrtc::kYPlane), 127, kTestWidth * kTestHeight);
    448     memset(test_frame_.buffer(webrtc::kUPlane), 127,
    449            ((kTestWidth + 1) / 2) * ((kTestHeight + 1) / 2));
    450     memset(test_frame_.buffer(webrtc::kVPlane), 127,
    451            ((kTestWidth + 1) / 2) * ((kTestHeight + 1) / 2));
    452 
    453     capture_module_->RegisterCaptureDataCallback(capture_callback_);
    454     capture_module_->RegisterCaptureCallback(capture_feedback_);
    455     capture_module_->EnableFrameRateCallback(true);
    456     capture_module_->EnableNoPictureAlarm(true);
    457   }
    458 
    459   void TearDown() {
    460     process_module_->Stop();
    461     webrtc::ProcessThread::DestroyProcessThread(process_module_);
    462   }
    463 
    464   webrtc::VideoCaptureExternal* capture_input_interface_;
    465   webrtc::scoped_refptr<VideoCaptureModule> capture_module_;
    466   webrtc::ProcessThread* process_module_;
    467   webrtc::I420VideoFrame test_frame_;
    468   TestVideoCaptureCallback capture_callback_;
    469   TestVideoCaptureFeedBack capture_feedback_;
    470 };
    471 
    472 // Test input of external video frames.
    473 TEST_F(VideoCaptureExternalTest, TestExternalCapture) {
    474   unsigned int length = webrtc::CalcBufferSize(webrtc::kI420,
    475                                                test_frame_.width(),
    476                                                test_frame_.height());
    477   webrtc::scoped_ptr<uint8_t[]> test_buffer(new uint8_t[length]);
    478   webrtc::ExtractBuffer(test_frame_, length, test_buffer.get());
    479   EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    480       length, capture_callback_.capability(), 0));
    481   EXPECT_TRUE(capture_callback_.CompareLastFrame(test_frame_));
    482 }
    483 
    484 // Test input of planar I420 frames.
    485 // NOTE: flaky, sometimes fails on the last CompareLastFrame.
    486 // http://code.google.com/p/webrtc/issues/detail?id=777
    487 TEST_F(VideoCaptureExternalTest, DISABLED_TestExternalCaptureI420) {
    488   webrtc::I420VideoFrame frame_i420;
    489   frame_i420.CopyFrame(test_frame_);
    490 
    491   EXPECT_EQ(0,
    492             capture_input_interface_->IncomingI420VideoFrame(&frame_i420, 0));
    493   EXPECT_TRUE(capture_callback_.CompareLastFrame(frame_i420));
    494 
    495   // Test with a frame with pitch not equal to width
    496   memset(test_frame_.buffer(webrtc::kYPlane), 0xAA,
    497          test_frame_.allocated_size(webrtc::kYPlane));
    498   memset(test_frame_.buffer(webrtc::kUPlane), 0xAA,
    499          test_frame_.allocated_size(webrtc::kUPlane));
    500   memset(test_frame_.buffer(webrtc::kVPlane), 0xAA,
    501          test_frame_.allocated_size(webrtc::kVPlane));
    502   webrtc::I420VideoFrame aligned_test_frame;
    503   int y_pitch = kTestWidth + 2;
    504   int u_pitch = kTestWidth / 2 + 1;
    505   int v_pitch = u_pitch;
    506   aligned_test_frame.CreateEmptyFrame(kTestWidth, kTestHeight,
    507                                       y_pitch, u_pitch, v_pitch);
    508   memset(aligned_test_frame.buffer(webrtc::kYPlane), 0,
    509          kTestWidth * kTestHeight);
    510   memset(aligned_test_frame.buffer(webrtc::kUPlane), 0,
    511          (kTestWidth + 1) / 2  * (kTestHeight + 1) / 2);
    512   memset(aligned_test_frame.buffer(webrtc::kVPlane), 0,
    513          (kTestWidth + 1) / 2  * (kTestHeight + 1) / 2);
    514   // Copy the test_frame_ to aligned_test_frame.
    515   int y_width = kTestWidth;
    516   int uv_width = kTestWidth / 2;
    517   int y_rows = kTestHeight;
    518   int uv_rows = kTestHeight / 2;
    519   unsigned char* y_plane = test_frame_.buffer(webrtc::kYPlane);
    520   unsigned char* u_plane = test_frame_.buffer(webrtc::kUPlane);
    521   unsigned char* v_plane = test_frame_.buffer(webrtc::kVPlane);
    522   // Copy Y
    523   unsigned char* current_pointer = aligned_test_frame.buffer(webrtc::kYPlane);
    524   for (int i = 0; i < y_rows; ++i) {
    525     memcpy(current_pointer, y_plane, y_width);
    526     // Remove the alignment which ViE doesn't support.
    527     current_pointer += y_pitch;
    528     y_plane += y_width;
    529   }
    530   // Copy U
    531   current_pointer = aligned_test_frame.buffer(webrtc::kUPlane);
    532   for (int i = 0; i < uv_rows; ++i) {
    533     memcpy(current_pointer, u_plane, uv_width);
    534     // Remove the alignment which ViE doesn't support.
    535     current_pointer += u_pitch;
    536     u_plane += uv_width;
    537   }
    538   // Copy V
    539   current_pointer = aligned_test_frame.buffer(webrtc::kVPlane);
    540   for (int i = 0; i < uv_rows; ++i) {
    541     memcpy(current_pointer, v_plane, uv_width);
    542     // Remove the alignment which ViE doesn't support.
    543     current_pointer += v_pitch;
    544     v_plane += uv_width;
    545   }
    546   frame_i420.CopyFrame(aligned_test_frame);
    547 
    548   EXPECT_EQ(0,
    549             capture_input_interface_->IncomingI420VideoFrame(&frame_i420, 0));
    550   EXPECT_TRUE(capture_callback_.CompareLastFrame(test_frame_));
    551 }
    552 
    553 // Test frame rate and no picture alarm.
    554 // Flaky on Win32, see webrtc:3270.
    555 TEST_F(VideoCaptureExternalTest, DISABLED_ON_WIN(FrameRate)) {
    556   int64_t testTime = 3;
    557   TickTime startTime = TickTime::Now();
    558 
    559   while ((TickTime::Now() - startTime).Milliseconds() < testTime * 1000) {
    560      unsigned int length = webrtc::CalcBufferSize(webrtc::kI420,
    561                                                  test_frame_.width(),
    562                                                  test_frame_.height());
    563      webrtc::scoped_ptr<uint8_t[]> test_buffer(new uint8_t[length]);
    564      webrtc::ExtractBuffer(test_frame_, length, test_buffer.get());
    565      EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    566        length, capture_callback_.capability(), 0));
    567     SleepMs(100);
    568   }
    569   EXPECT_TRUE(capture_feedback_.frame_rate() >= 8 &&
    570               capture_feedback_.frame_rate() <= 10);
    571   SleepMs(500);
    572   EXPECT_EQ(webrtc::Raised, capture_feedback_.alarm());
    573 
    574   startTime = TickTime::Now();
    575   while ((TickTime::Now() - startTime).Milliseconds() < testTime * 1000) {
    576     unsigned int length = webrtc::CalcBufferSize(webrtc::kI420,
    577                                                  test_frame_.width(),
    578                                                  test_frame_.height());
    579     webrtc::scoped_ptr<uint8_t[]> test_buffer(new uint8_t[length]);
    580     webrtc::ExtractBuffer(test_frame_, length, test_buffer.get());
    581     EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    582       length, capture_callback_.capability(), 0));
    583     SleepMs(1000 / 30);
    584   }
    585   EXPECT_EQ(webrtc::Cleared, capture_feedback_.alarm());
    586   // Frame rate might be less than 33 since we have paused providing
    587   // frames for a while.
    588   EXPECT_TRUE(capture_feedback_.frame_rate() >= 25 &&
    589               capture_feedback_.frame_rate() <= 33);
    590 }
    591 
    592 TEST_F(VideoCaptureExternalTest, Rotation) {
    593   EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kCameraRotate0));
    594   unsigned int length = webrtc::CalcBufferSize(webrtc::kI420,
    595                                                test_frame_.width(),
    596                                                test_frame_.height());
    597   webrtc::scoped_ptr<uint8_t[]> test_buffer(new uint8_t[length]);
    598   webrtc::ExtractBuffer(test_frame_, length, test_buffer.get());
    599   EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    600     length, capture_callback_.capability(), 0));
    601   EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kCameraRotate90));
    602   capture_callback_.SetExpectedCaptureRotation(webrtc::kCameraRotate90);
    603   EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    604     length, capture_callback_.capability(), 0));
    605   EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kCameraRotate180));
    606   capture_callback_.SetExpectedCaptureRotation(webrtc::kCameraRotate180);
    607   EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    608     length, capture_callback_.capability(), 0));
    609   EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kCameraRotate270));
    610   capture_callback_.SetExpectedCaptureRotation(webrtc::kCameraRotate270);
    611   EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(),
    612     length, capture_callback_.capability(), 0));
    613 }
    614