perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 1 | /* |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 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 | |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 13 | #include <map> |
kwiberg | e065fcf | 2016-03-02 01:01:11 -0800 | [diff] [blame] | 14 | #include <memory> |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 15 | #include <sstream> |
| 16 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 17 | #include "webrtc/api/video/i420_buffer.h" |
| 18 | #include "webrtc/api/video/video_frame.h" |
pbos@webrtc.org | a9b74ad | 2013-07-12 10:03:52 +0000 | [diff] [blame] | 19 | #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
Henrik Kjellander | ff761fb | 2015-11-04 08:31:52 +0100 | [diff] [blame] | 20 | #include "webrtc/modules/utility/include/process_thread.h" |
Henrik Kjellander | 5dda80a | 2015-11-12 12:46:09 +0100 | [diff] [blame] | 21 | #include "webrtc/modules/video_capture/video_capture.h" |
| 22 | #include "webrtc/modules/video_capture/video_capture_factory.h" |
Edward Lemur | c20978e | 2017-07-06 19:44:34 +0200 | [diff] [blame] | 23 | #include "webrtc/rtc_base/criticalsection.h" |
| 24 | #include "webrtc/rtc_base/scoped_ref_ptr.h" |
| 25 | #include "webrtc/rtc_base/timeutils.h" |
Henrik Kjellander | 98f5351 | 2015-10-28 18:17:40 +0100 | [diff] [blame] | 26 | #include "webrtc/system_wrappers/include/sleep.h" |
nisse | c9c142f | 2016-05-17 04:05:47 -0700 | [diff] [blame] | 27 | #include "webrtc/test/frame_utils.h" |
kwiberg | ac9f876 | 2016-09-30 22:29:43 -0700 | [diff] [blame] | 28 | #include "webrtc/test/gtest.h" |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 29 | |
hta@webrtc.org | f494fd0 | 2012-06-25 11:33:34 +0000 | [diff] [blame] | 30 | using webrtc::SleepMs; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 31 | using webrtc::VideoCaptureCapability; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 32 | using webrtc::VideoCaptureFactory; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 33 | using webrtc::VideoCaptureModule; |
| 34 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 35 | |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 36 | #define WAIT_(ex, timeout, res) \ |
| 37 | do { \ |
| 38 | res = (ex); \ |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 39 | int64_t start = rtc::TimeMillis(); \ |
| 40 | while (!res && rtc::TimeMillis() < start + timeout) { \ |
hta@webrtc.org | f494fd0 | 2012-06-25 11:33:34 +0000 | [diff] [blame] | 41 | SleepMs(5); \ |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 42 | res = (ex); \ |
| 43 | } \ |
torbjorng | a089257 | 2015-12-16 18:38:31 -0800 | [diff] [blame] | 44 | } while (0) |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 45 | |
| 46 | #define EXPECT_TRUE_WAIT(ex, timeout) \ |
| 47 | do { \ |
| 48 | bool res; \ |
| 49 | WAIT_(ex, timeout, res); \ |
| 50 | if (!res) EXPECT_TRUE(ex); \ |
torbjorng | a089257 | 2015-12-16 18:38:31 -0800 | [diff] [blame] | 51 | } while (0) |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 52 | |
| 53 | |
| 54 | static const int kTimeOut = 5000; |
| 55 | static const int kTestHeight = 288; |
| 56 | static const int kTestWidth = 352; |
| 57 | static const int kTestFramerate = 30; |
| 58 | |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 59 | class TestVideoCaptureCallback |
| 60 | : public rtc::VideoSinkInterface<webrtc::VideoFrame> { |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 61 | public: |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 62 | TestVideoCaptureCallback() : |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 63 | last_render_time_ms_(0), |
| 64 | incoming_frames_(0), |
| 65 | timing_warnings_(0), |
| 66 | rotate_frame_(webrtc::kVideoRotation_0) {} |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 67 | |
| 68 | ~TestVideoCaptureCallback() { |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 69 | if (timing_warnings_ > 0) |
| 70 | printf("No of timing warnings %d\n", timing_warnings_); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 71 | } |
| 72 | |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 73 | void OnFrame(const webrtc::VideoFrame& videoFrame) override { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 74 | rtc::CritScope cs(&capture_cs_); |
magjed@webrtc.org | 2056ee3 | 2015-03-16 13:46:52 +0000 | [diff] [blame] | 75 | int height = videoFrame.height(); |
| 76 | int width = videoFrame.width(); |
kwiberg | 77eab70 | 2016-09-28 17:42:01 -0700 | [diff] [blame] | 77 | #if defined(ANDROID) && ANDROID |
glaznev@webrtc.org | f7030d4 | 2014-10-17 16:25:06 +0000 | [diff] [blame] | 78 | // Android camera frames may be rotated depending on test device |
| 79 | // orientation. |
| 80 | EXPECT_TRUE(height == capability_.height || height == capability_.width); |
| 81 | EXPECT_TRUE(width == capability_.width || width == capability_.height); |
| 82 | #else |
deadbeef | f5629ad | 2016-03-18 11:38:26 -0700 | [diff] [blame] | 83 | EXPECT_EQ(height, capability_.height); |
| 84 | EXPECT_EQ(width, capability_.width); |
| 85 | EXPECT_EQ(rotate_frame_, videoFrame.rotation()); |
glaznev@webrtc.org | f7030d4 | 2014-10-17 16:25:06 +0000 | [diff] [blame] | 86 | #endif |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 87 | // RenderTimstamp should be the time now. |
| 88 | EXPECT_TRUE( |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 89 | videoFrame.render_time_ms() >= rtc::TimeMillis()-30 && |
| 90 | videoFrame.render_time_ms() <= rtc::TimeMillis()); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 91 | |
magjed@webrtc.org | 2056ee3 | 2015-03-16 13:46:52 +0000 | [diff] [blame] | 92 | if ((videoFrame.render_time_ms() > |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 93 | last_render_time_ms_ + (1000 * 1.1) / capability_.maxFPS && |
| 94 | last_render_time_ms_ > 0) || |
magjed@webrtc.org | 2056ee3 | 2015-03-16 13:46:52 +0000 | [diff] [blame] | 95 | (videoFrame.render_time_ms() < |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 96 | last_render_time_ms_ + (1000 * 0.9) / capability_.maxFPS && |
| 97 | last_render_time_ms_ > 0)) { |
| 98 | timing_warnings_++; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 99 | } |
| 100 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 101 | incoming_frames_++; |
magjed@webrtc.org | 2056ee3 | 2015-03-16 13:46:52 +0000 | [diff] [blame] | 102 | last_render_time_ms_ = videoFrame.render_time_ms(); |
nisse | c9c142f | 2016-05-17 04:05:47 -0700 | [diff] [blame] | 103 | last_frame_ = videoFrame.video_frame_buffer(); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 104 | } |
| 105 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 106 | void SetExpectedCapability(VideoCaptureCapability capability) { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 107 | rtc::CritScope cs(&capture_cs_); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 108 | capability_= capability; |
| 109 | incoming_frames_ = 0; |
| 110 | last_render_time_ms_ = 0; |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 111 | } |
| 112 | int incoming_frames() { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 113 | rtc::CritScope cs(&capture_cs_); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 114 | return incoming_frames_; |
| 115 | } |
| 116 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 117 | int timing_warnings() { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 118 | rtc::CritScope cs(&capture_cs_); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 119 | return timing_warnings_; |
| 120 | } |
| 121 | VideoCaptureCapability capability() { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 122 | rtc::CritScope cs(&capture_cs_); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 123 | return capability_; |
| 124 | } |
| 125 | |
Miguel Casas-Sanchez | 4765070 | 2015-05-29 17:21:40 -0700 | [diff] [blame] | 126 | bool CompareLastFrame(const webrtc::VideoFrame& frame) { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 127 | rtc::CritScope cs(&capture_cs_); |
nisse | c9c142f | 2016-05-17 04:05:47 -0700 | [diff] [blame] | 128 | return webrtc::test::FrameBufsEqual(last_frame_, |
| 129 | frame.video_frame_buffer()); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 130 | } |
| 131 | |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 132 | void SetExpectedCaptureRotation(webrtc::VideoRotation rotation) { |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 133 | rtc::CritScope cs(&capture_cs_); |
mikhal@webrtc.org | 0f34fd7 | 2012-11-19 21:15:35 +0000 | [diff] [blame] | 134 | rotate_frame_ = rotation; |
| 135 | } |
| 136 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 137 | private: |
kthelgason | ff046c7 | 2017-03-31 02:03:55 -0700 | [diff] [blame] | 138 | rtc::CriticalSection capture_cs_; |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 139 | VideoCaptureCapability capability_; |
pbos@webrtc.org | dfc5bb9 | 2013-04-10 08:23:13 +0000 | [diff] [blame] | 140 | int64_t last_render_time_ms_; |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 141 | int incoming_frames_; |
| 142 | int timing_warnings_; |
nisse | c9c142f | 2016-05-17 04:05:47 -0700 | [diff] [blame] | 143 | rtc::scoped_refptr<webrtc::VideoFrameBuffer> last_frame_; |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 144 | webrtc::VideoRotation rotate_frame_; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 145 | }; |
| 146 | |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 147 | class VideoCaptureTest : public testing::Test { |
| 148 | public: |
| 149 | VideoCaptureTest() : number_of_devices_(0) {} |
| 150 | |
| 151 | void SetUp() { |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 152 | device_info_.reset(VideoCaptureFactory::CreateDeviceInfo()); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 153 | assert(device_info_.get()); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 154 | number_of_devices_ = device_info_->NumberOfDevices(); |
| 155 | ASSERT_GT(number_of_devices_, 0u); |
| 156 | } |
| 157 | |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 158 | rtc::scoped_refptr<VideoCaptureModule> OpenVideoCaptureDevice( |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 159 | unsigned int device, |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 160 | rtc::VideoSinkInterface<webrtc::VideoFrame>* callback) { |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 161 | char device_name[256]; |
| 162 | char unique_name[256]; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 163 | |
| 164 | EXPECT_EQ(0, device_info_->GetDeviceName( |
| 165 | device, device_name, 256, unique_name, 256)); |
| 166 | |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 167 | rtc::scoped_refptr<VideoCaptureModule> module( |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 168 | VideoCaptureFactory::Create(unique_name)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 169 | if (module.get() == NULL) |
| 170 | return NULL; |
| 171 | |
| 172 | EXPECT_FALSE(module->CaptureStarted()); |
| 173 | |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 174 | module->RegisterCaptureDataCallback(callback); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 175 | return module; |
| 176 | } |
| 177 | |
| 178 | void StartCapture(VideoCaptureModule* capture_module, |
| 179 | VideoCaptureCapability capability) { |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 180 | ASSERT_EQ(0, capture_module->StartCapture(capability)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 181 | EXPECT_TRUE(capture_module->CaptureStarted()); |
| 182 | |
| 183 | VideoCaptureCapability resulting_capability; |
| 184 | EXPECT_EQ(0, capture_module->CaptureSettings(resulting_capability)); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 185 | EXPECT_EQ(capability.width, resulting_capability.width); |
| 186 | EXPECT_EQ(capability.height, resulting_capability.height); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 187 | } |
| 188 | |
kwiberg | e065fcf | 2016-03-02 01:01:11 -0800 | [diff] [blame] | 189 | std::unique_ptr<VideoCaptureModule::DeviceInfo> device_info_; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 190 | unsigned int number_of_devices_; |
| 191 | }; |
| 192 | |
kjellander | 335ecf5 | 2016-01-06 05:23:09 -0800 | [diff] [blame] | 193 | #ifdef WEBRTC_MAC |
| 194 | // Currently fails on Mac 64-bit, see |
| 195 | // https://bugs.chromium.org/p/webrtc/issues/detail?id=5406 |
| 196 | #define MAYBE_CreateDelete DISABLED_CreateDelete |
| 197 | #else |
| 198 | #define MAYBE_CreateDelete CreateDelete |
| 199 | #endif |
| 200 | TEST_F(VideoCaptureTest, MAYBE_CreateDelete) { |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 201 | for (int i = 0; i < 5; ++i) { |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 202 | int64_t start_time = rtc::TimeMillis(); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 203 | TestVideoCaptureCallback capture_observer; |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 204 | rtc::scoped_refptr<VideoCaptureModule> module( |
| 205 | OpenVideoCaptureDevice(0, &capture_observer)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 206 | ASSERT_TRUE(module.get() != NULL); |
| 207 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 208 | VideoCaptureCapability capability; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 209 | #ifndef WEBRTC_MAC |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 210 | device_info_->GetCapability(module->CurrentDeviceName(), 0, capability); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 211 | #else |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 212 | capability.width = kTestWidth; |
| 213 | capability.height = kTestHeight; |
| 214 | capability.maxFPS = kTestFramerate; |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 215 | capability.videoType = webrtc::VideoType::kUnknown; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 216 | #endif |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 217 | capture_observer.SetExpectedCapability(capability); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 218 | ASSERT_NO_FATAL_FAILURE(StartCapture(module.get(), capability)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 219 | |
| 220 | // Less than 4s to start the camera. |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 221 | EXPECT_LE(rtc::TimeMillis() - start_time, 4000); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 222 | |
| 223 | // Make sure 5 frames are captured. |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 224 | EXPECT_TRUE_WAIT(capture_observer.incoming_frames() >= 5, kTimeOut); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 225 | |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 226 | int64_t stop_time = rtc::TimeMillis(); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 227 | EXPECT_EQ(0, module->StopCapture()); |
| 228 | EXPECT_FALSE(module->CaptureStarted()); |
| 229 | |
| 230 | // Less than 3s to stop the camera. |
Niels Möller | d28db7f | 2016-05-10 16:31:47 +0200 | [diff] [blame] | 231 | EXPECT_LE(rtc::TimeMillis() - stop_time, 3000); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 232 | } |
| 233 | } |
| 234 | |
kjellander | 335ecf5 | 2016-01-06 05:23:09 -0800 | [diff] [blame] | 235 | #ifdef WEBRTC_MAC |
| 236 | // Currently fails on Mac 64-bit, see |
| 237 | // https://bugs.chromium.org/p/webrtc/issues/detail?id=5406 |
| 238 | #define MAYBE_Capabilities DISABLED_Capabilities |
| 239 | #else |
| 240 | #define MAYBE_Capabilities Capabilities |
| 241 | #endif |
| 242 | TEST_F(VideoCaptureTest, MAYBE_Capabilities) { |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 243 | #ifdef WEBRTC_MAC |
| 244 | printf("Video capture capabilities are not supported on Mac.\n"); |
| 245 | return; |
| 246 | #endif |
| 247 | |
| 248 | TestVideoCaptureCallback capture_observer; |
| 249 | |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 250 | rtc::scoped_refptr<VideoCaptureModule> module( |
| 251 | OpenVideoCaptureDevice(0, &capture_observer)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 252 | ASSERT_TRUE(module.get() != NULL); |
| 253 | |
| 254 | int number_of_capabilities = device_info_->NumberOfCapabilities( |
| 255 | module->CurrentDeviceName()); |
| 256 | EXPECT_GT(number_of_capabilities, 0); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 257 | // Key is <width>x<height>, value is vector of maxFPS values at that |
| 258 | // resolution. |
| 259 | typedef std::map<std::string, std::vector<int> > FrameRatesByResolution; |
| 260 | FrameRatesByResolution frame_rates_by_resolution; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 261 | for (int i = 0; i < number_of_capabilities; ++i) { |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 262 | VideoCaptureCapability capability; |
| 263 | EXPECT_EQ(0, device_info_->GetCapability(module->CurrentDeviceName(), i, |
| 264 | capability)); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 265 | std::ostringstream resolutionStream; |
| 266 | resolutionStream << capability.width << "x" << capability.height; |
| 267 | resolutionStream.flush(); |
| 268 | std::string resolution = resolutionStream.str(); |
| 269 | frame_rates_by_resolution[resolution].push_back(capability.maxFPS); |
| 270 | |
| 271 | // Since Android presents so many resolution/FPS combinations and the test |
| 272 | // runner imposes a timeout, we only actually start the capture and test |
| 273 | // that a frame was captured for 2 frame-rates at each resolution. |
| 274 | if (frame_rates_by_resolution[resolution].size() > 2) |
| 275 | continue; |
| 276 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 277 | capture_observer.SetExpectedCapability(capability); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 278 | ASSERT_NO_FATAL_FAILURE(StartCapture(module.get(), capability)); |
| 279 | // Make sure at least one frame is captured. |
| 280 | EXPECT_TRUE_WAIT(capture_observer.incoming_frames() >= 1, kTimeOut); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 281 | |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 282 | EXPECT_EQ(0, module->StopCapture()); |
| 283 | } |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 284 | |
kwiberg | 77eab70 | 2016-09-28 17:42:01 -0700 | [diff] [blame] | 285 | #if defined(ANDROID) && ANDROID |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 286 | // There's no reason for this to _necessarily_ be true, but in practice all |
| 287 | // Android devices this test runs on in fact do support multiple capture |
| 288 | // resolutions and multiple frame-rates per captured resolution, so we assert |
| 289 | // this fact here as a regression-test against the time that we only noticed a |
| 290 | // single frame-rate per resolution (bug 2974). If this test starts being run |
| 291 | // on devices for which this is untrue (e.g. Nexus4) then the following should |
| 292 | // probably be wrapped in a base::android::BuildInfo::model()/device() check. |
| 293 | EXPECT_GT(frame_rates_by_resolution.size(), 1U); |
| 294 | for (FrameRatesByResolution::const_iterator it = |
| 295 | frame_rates_by_resolution.begin(); |
| 296 | it != frame_rates_by_resolution.end(); |
| 297 | ++it) { |
| 298 | EXPECT_GT(it->second.size(), 1U) << it->first; |
| 299 | } |
| 300 | #endif // ANDROID |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 301 | } |
| 302 | |
phoglund@webrtc.org | 6b84b61 | 2012-08-27 15:16:20 +0000 | [diff] [blame] | 303 | // NOTE: flaky, crashes sometimes. |
| 304 | // http://code.google.com/p/webrtc/issues/detail?id=777 |
| 305 | TEST_F(VideoCaptureTest, DISABLED_TestTwoCameras) { |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 306 | if (number_of_devices_ < 2) { |
| 307 | printf("There are not two cameras available. Aborting test. \n"); |
| 308 | return; |
| 309 | } |
| 310 | |
| 311 | TestVideoCaptureCallback capture_observer1; |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 312 | rtc::scoped_refptr<VideoCaptureModule> module1( |
| 313 | OpenVideoCaptureDevice(0, &capture_observer1)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 314 | ASSERT_TRUE(module1.get() != NULL); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 315 | VideoCaptureCapability capability1; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 316 | #ifndef WEBRTC_MAC |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 317 | device_info_->GetCapability(module1->CurrentDeviceName(), 0, capability1); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 318 | #else |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 319 | capability1.width = kTestWidth; |
| 320 | capability1.height = kTestHeight; |
| 321 | capability1.maxFPS = kTestFramerate; |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 322 | capability1.videoType = webrtc::VideoType::kUnknown; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 323 | #endif |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 324 | capture_observer1.SetExpectedCapability(capability1); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 325 | |
| 326 | TestVideoCaptureCallback capture_observer2; |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 327 | rtc::scoped_refptr<VideoCaptureModule> module2( |
| 328 | OpenVideoCaptureDevice(1, &capture_observer2)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 329 | ASSERT_TRUE(module1.get() != NULL); |
| 330 | |
| 331 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 332 | VideoCaptureCapability capability2; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 333 | #ifndef WEBRTC_MAC |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 334 | device_info_->GetCapability(module2->CurrentDeviceName(), 0, capability2); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 335 | #else |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 336 | capability2.width = kTestWidth; |
| 337 | capability2.height = kTestHeight; |
| 338 | capability2.maxFPS = kTestFramerate; |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 339 | capability2.videoType = webrtc::VideoType::kUnknown; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 340 | #endif |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 341 | capture_observer2.SetExpectedCapability(capability2); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 342 | |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 343 | ASSERT_NO_FATAL_FAILURE(StartCapture(module1.get(), capability1)); |
| 344 | ASSERT_NO_FATAL_FAILURE(StartCapture(module2.get(), capability2)); |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 345 | EXPECT_TRUE_WAIT(capture_observer1.incoming_frames() >= 5, kTimeOut); |
| 346 | EXPECT_TRUE_WAIT(capture_observer2.incoming_frames() >= 5, kTimeOut); |
fischman@webrtc.org | b0b135e | 2014-04-09 01:18:32 +0000 | [diff] [blame] | 347 | EXPECT_EQ(0, module2->StopCapture()); |
| 348 | EXPECT_EQ(0, module1->StopCapture()); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 349 | } |
| 350 | |
| 351 | // Test class for testing external capture and capture feedback information |
| 352 | // such as frame rate and picture alarm. |
| 353 | class VideoCaptureExternalTest : public testing::Test { |
| 354 | public: |
| 355 | void SetUp() { |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 356 | capture_module_ = VideoCaptureFactory::Create(capture_input_interface_); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 357 | |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 358 | VideoCaptureCapability capability; |
| 359 | capability.width = kTestWidth; |
| 360 | capability.height = kTestHeight; |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 361 | capability.videoType = webrtc::VideoType::kYV12; |
perkj@webrtc.org | c2fde80 | 2012-08-08 14:01:09 +0000 | [diff] [blame] | 362 | capability.maxFPS = kTestFramerate; |
| 363 | capture_callback_.SetExpectedCapability(capability); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 364 | |
Magnus Jedvert | 7a721e8 | 2017-06-14 11:28:08 +0200 | [diff] [blame] | 365 | rtc::scoped_refptr<webrtc::I420Buffer> buffer = |
| 366 | webrtc::I420Buffer::Create(kTestWidth, kTestHeight); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 367 | |
Magnus Jedvert | 7a721e8 | 2017-06-14 11:28:08 +0200 | [diff] [blame] | 368 | memset(buffer->MutableDataY(), 127, buffer->height() * buffer->StrideY()); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 369 | memset(buffer->MutableDataU(), 127, |
Magnus Jedvert | 7a721e8 | 2017-06-14 11:28:08 +0200 | [diff] [blame] | 370 | buffer->ChromaHeight() * buffer->StrideU()); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 371 | memset(buffer->MutableDataV(), 127, |
Magnus Jedvert | 7a721e8 | 2017-06-14 11:28:08 +0200 | [diff] [blame] | 372 | buffer->ChromaHeight() * buffer->StrideV()); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 373 | test_frame_.reset( |
| 374 | new webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); |
| 375 | |
| 376 | SleepMs(1); // Wait 1ms so that two tests can't have the same timestamp. |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 377 | |
nisse | b29b9c8 | 2016-12-12 00:22:56 -0800 | [diff] [blame] | 378 | capture_module_->RegisterCaptureDataCallback(&capture_callback_); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 379 | } |
| 380 | |
| 381 | void TearDown() { |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 382 | } |
| 383 | |
| 384 | webrtc::VideoCaptureExternal* capture_input_interface_; |
Peter Boström | 26b0860 | 2015-06-04 15:18:17 +0200 | [diff] [blame] | 385 | rtc::scoped_refptr<VideoCaptureModule> capture_module_; |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 386 | std::unique_ptr<webrtc::VideoFrame> test_frame_; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 387 | TestVideoCaptureCallback capture_callback_; |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 388 | }; |
| 389 | |
| 390 | // Test input of external video frames. |
andresp@webrtc.org | 3bd5603 | 2014-09-17 11:56:25 +0000 | [diff] [blame] | 391 | TEST_F(VideoCaptureExternalTest, TestExternalCapture) { |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 392 | size_t length = webrtc::CalcBufferSize( |
| 393 | webrtc::VideoType::kI420, test_frame_->width(), test_frame_->height()); |
kwiberg | e065fcf | 2016-03-02 01:01:11 -0800 | [diff] [blame] | 394 | std::unique_ptr<uint8_t[]> test_buffer(new uint8_t[length]); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 395 | webrtc::ExtractBuffer(*test_frame_, length, test_buffer.get()); |
mikhal@webrtc.org | 9fedff7 | 2012-10-24 18:33:04 +0000 | [diff] [blame] | 396 | EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(), |
| 397 | length, capture_callback_.capability(), 0)); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 398 | EXPECT_TRUE(capture_callback_.CompareLastFrame(*test_frame_)); |
perkj@webrtc.org | 8627adc | 2011-12-05 09:58:55 +0000 | [diff] [blame] | 399 | } |
| 400 | |
andresp@webrtc.org | 3bd5603 | 2014-09-17 11:56:25 +0000 | [diff] [blame] | 401 | TEST_F(VideoCaptureExternalTest, Rotation) { |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 402 | EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kVideoRotation_0)); |
nisse | eb44b39 | 2017-04-28 07:18:05 -0700 | [diff] [blame] | 403 | size_t length = webrtc::CalcBufferSize( |
| 404 | webrtc::VideoType::kI420, test_frame_->width(), test_frame_->height()); |
kwiberg | e065fcf | 2016-03-02 01:01:11 -0800 | [diff] [blame] | 405 | std::unique_ptr<uint8_t[]> test_buffer(new uint8_t[length]); |
nisse | 64ec8f8 | 2016-09-27 00:17:25 -0700 | [diff] [blame] | 406 | webrtc::ExtractBuffer(*test_frame_, length, test_buffer.get()); |
mikhal@webrtc.org | 0f34fd7 | 2012-11-19 21:15:35 +0000 | [diff] [blame] | 407 | EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(), |
| 408 | length, capture_callback_.capability(), 0)); |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 409 | EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kVideoRotation_90)); |
| 410 | capture_callback_.SetExpectedCaptureRotation(webrtc::kVideoRotation_90); |
mikhal@webrtc.org | 0f34fd7 | 2012-11-19 21:15:35 +0000 | [diff] [blame] | 411 | EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(), |
| 412 | length, capture_callback_.capability(), 0)); |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 413 | EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kVideoRotation_180)); |
| 414 | capture_callback_.SetExpectedCaptureRotation(webrtc::kVideoRotation_180); |
mikhal@webrtc.org | 0f34fd7 | 2012-11-19 21:15:35 +0000 | [diff] [blame] | 415 | EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(), |
| 416 | length, capture_callback_.capability(), 0)); |
guoweis@webrtc.org | 5a7dc39 | 2015-02-13 14:31:26 +0000 | [diff] [blame] | 417 | EXPECT_EQ(0, capture_module_->SetCaptureRotation(webrtc::kVideoRotation_270)); |
| 418 | capture_callback_.SetExpectedCaptureRotation(webrtc::kVideoRotation_270); |
mikhal@webrtc.org | 0f34fd7 | 2012-11-19 21:15:35 +0000 | [diff] [blame] | 419 | EXPECT_EQ(0, capture_input_interface_->IncomingFrame(test_buffer.get(), |
| 420 | length, capture_callback_.capability(), 0)); |
| 421 | } |