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
30using webrtc::CriticalSectionWrapper;
31using webrtc::CriticalSectionScoped;
32using webrtc::scoped_ptr;
33using webrtc::SleepMs;
34using webrtc::TickTime;
35using webrtc::VideoCaptureAlarm;
36using webrtc::VideoCaptureCapability;
37using webrtc::VideoCaptureDataCallback;
38using webrtc::VideoCaptureFactory;
39using webrtc::VideoCaptureFeedBack;
40using 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
61static const int kTimeOut = 5000;
62static const int kTestHeight = 288;
63static const int kTestWidth = 352;
64static const int kTestFramerate = 30;
65
66// Compares the content of two video frames.
67static 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
92class 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
199class 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
234class 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
281TEST_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
318TEST_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
381TEST_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.
429class 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.
473TEST_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
487TEST_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.
555TEST_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
592TEST_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