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