diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 427ddb6d52..8cb4849a47 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -695,6 +695,7 @@ if (is_linux || is_win) {
"../rtc_base/third_party/sigslot",
"../system_wrappers:field_trial",
"../test:field_trial",
+ "../test:platform_video_capturer",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -847,6 +848,7 @@ if (is_win || is_android) {
"../pc:libjingle_peerconnection",
"../pc:peerconnection",
"../rtc_base:rtc_base",
+ "../test:platform_video_capturer",
"../test:video_test_common",
"//third_party/abseil-cpp/absl/memory",
]
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 03cf0c4133..464276c40d 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -366,6 +366,7 @@ if (is_ios || is_mac) {
"..:common_objc",
":used_from_extension",
]
+ libs = [ "VideoToolbox.framework" ]
}
rtc_static_library("video_objc") {
diff --git a/test/BUILD.gn b/test/BUILD.gn
index c1e6362521..c0b3f17dec 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -49,8 +49,6 @@ rtc_source_set("video_test_common") {
"frame_utils.h",
"test_video_capturer.cc",
"test_video_capturer.h",
- "vcm_capturer.cc",
- "vcm_capturer.h",
"video_codec_settings.h",
]
@@ -67,7 +65,6 @@ rtc_source_set("video_test_common") {
"../call:video_stream_api",
"../common_video",
"../media:rtc_media_base",
- "../modules/video_capture:video_capture_module",
"../rtc_base:checks",
"../rtc_base:rtc_base",
"../rtc_base:rtc_task_queue",
@@ -78,6 +75,55 @@ rtc_source_set("video_test_common") {
]
}
+if (!build_with_chromium) {
+ if (is_mac || is_ios) {
+ rtc_source_set("video_test_mac") {
+ testonly = true
+ sources = [
+ "mac_capturer.h",
+ "mac_capturer.mm",
+ ]
+ deps = [
+ ":video_test_common",
+ "../api:libjingle_peerconnection_api",
+ "../api:scoped_refptr",
+ "../modules/video_capture:video_capture_module",
+ "../rtc_base:rtc_base",
+ "../sdk:base_objc",
+ "../sdk:native_api",
+ "../sdk:native_video",
+ "../sdk:videocapture_objc",
+ ]
+ }
+ }
+
+ rtc_source_set("platform_video_capturer") {
+ testonly = true
+ sources = [
+ "platform_video_capturer.cc",
+ "platform_video_capturer.h",
+ ]
+ deps = [
+ ":video_test_common",
+ "//third_party/abseil-cpp/absl/memory",
+ ]
+ if (is_mac || is_ios) {
+ deps += [ ":video_test_mac" ]
+ } else {
+ sources += [
+ "vcm_capturer.cc",
+ "vcm_capturer.h",
+ ]
+ deps += [
+ "../api:scoped_refptr",
+ "../modules/video_capture:video_capture_module",
+ "../rtc_base:checks",
+ "../rtc_base:logging",
+ ]
+ }
+ }
+}
+
rtc_source_set("rtp_test_utils") {
testonly = true
sources = [
@@ -185,9 +231,9 @@ rtc_source_set("test_support") {
"gtest.h",
]
- public_deps = []
+ public_deps = [] # no-presubmit-check TODO(webrtc:8603)
if (is_ios) {
- public_deps += [ ":test_support_objc" ]
+ public_deps += [ ":test_support_objc" ] # no-presubmit-check TODO(webrtc:8603)
}
public_configs = [ ":test_main_direct_config" ]
@@ -485,11 +531,11 @@ rtc_source_set("fileutils_override_impl") {
rtc_source_set("run_test") {
testonly = true
if (is_mac) {
- public_deps = [
+ public_deps = [ # no-presubmit-check TODO(webrtc:8603)
":run_test_objc",
]
} else {
- public_deps = [
+ public_deps = [ # no-presubmit-check TODO(webrtc:8603)
":run_test_generic",
]
}
@@ -560,7 +606,7 @@ rtc_source_set("direct_transport") {
"../system_wrappers",
"//third_party/abseil-cpp/absl/memory",
]
- public_deps = [
+ public_deps = [ # no-presubmit-check TODO(webrtc:8603)
":single_threaded_task_queue",
"../call:fake_network",
]
@@ -719,12 +765,12 @@ rtc_source_set("test_common") {
}
rtc_source_set("test_renderer") {
- public_deps = [
+ public_deps = [ # no-presubmit-check TODO(webrtc:8603)
":test_renderer_generic",
]
testonly = true
if (is_mac) {
- public_deps += [ ":test_renderer_objc" ]
+ public_deps += [ ":test_renderer_objc" ] # no-presubmit-check TODO(webrtc:8603)
}
}
diff --git a/test/mac/Info.plist b/test/mac/Info.plist
new file mode 100644
index 0000000000..8a2b5cf0a0
--- /dev/null
+++ b/test/mac/Info.plist
@@ -0,0 +1,16 @@
+
+
+
+
+ CFBundleIdentifier
+ org.webrtc.video_loopback
+ CFBundleName
+ video_loopback
+ CFBundlePackageType
+ APPL
+ NSCameraUsageDescription
+ Camera access needed for video calling
+ NSMicrophoneUsageDescription
+ Microphone access needed for video calling
+
+
diff --git a/test/mac_capturer.h b/test/mac_capturer.h
new file mode 100644
index 0000000000..3d7ee77b45
--- /dev/null
+++ b/test/mac_capturer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef TEST_MAC_CAPTURER_H_
+#define TEST_MAC_CAPTURER_H_
+
+#include
+#include
+
+#include "api/media_stream_interface.h"
+#include "api/scoped_refptr.h"
+#include "modules/video_capture/video_capture.h"
+#include "rtc_base/thread.h"
+#include "test/test_video_capturer.h"
+
+namespace webrtc {
+namespace test {
+
+class MacCapturer : public TestVideoCapturer,
+ public rtc::VideoSinkInterface {
+ public:
+ static MacCapturer* Create(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index);
+ ~MacCapturer() override;
+
+ void OnFrame(const VideoFrame& frame) override;
+
+ private:
+ MacCapturer(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index);
+ void Destroy();
+
+ void* capturer_;
+ void* adapter_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // TEST_MAC_CAPTURER_H_
diff --git a/test/mac_capturer.mm b/test/mac_capturer.mm
new file mode 100644
index 0000000000..004900a42e
--- /dev/null
+++ b/test/mac_capturer.mm
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/mac_capturer.h"
+
+#import "sdk/objc/base/RTCVideoCapturer.h"
+#import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
+#import "sdk/objc/native/api/video_capturer.h"
+#import "sdk/objc/native/src/objc_frame_buffer.h"
+
+@interface RTCTestVideoSourceAdapter : NSObject
+@property(nonatomic) webrtc::test::MacCapturer *capturer;
+@end
+
+@implementation RTCTestVideoSourceAdapter
+@synthesize capturer = _capturer;
+
+- (void)capturer:(RTCVideoCapturer *)capturer didCaptureVideoFrame:(RTCVideoFrame *)frame {
+ const int64_t timestamp_us = frame.timeStampNs / rtc::kNumNanosecsPerMicrosec;
+ rtc::scoped_refptr buffer =
+ new rtc::RefCountedObject(frame.buffer);
+ _capturer->OnFrame(webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_rotation(webrtc::kVideoRotation_0)
+ .set_timestamp_us(timestamp_us)
+ .build());
+}
+
+@end
+
+namespace webrtc {
+namespace test {
+
+MacCapturer::MacCapturer(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index) {
+ RTCTestVideoSourceAdapter *adapter = [[RTCTestVideoSourceAdapter alloc] init];
+ adapter_ = (__bridge_retained void *)adapter;
+ adapter.capturer = this;
+
+ RTCCameraVideoCapturer *capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:adapter];
+ capturer_ = (__bridge_retained void *)capturer;
+
+ AVCaptureDevice *device =
+ [[RTCCameraVideoCapturer captureDevices] objectAtIndex:capture_device_index];
+ AVCaptureDeviceFormat *format =
+ [[RTCCameraVideoCapturer supportedFormatsForDevice:device] objectAtIndex:0];
+ [capturer startCaptureWithDevice:device format:format fps:target_fps];
+}
+
+MacCapturer *MacCapturer::Create(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index) {
+ return new MacCapturer(width, height, target_fps, capture_device_index);
+}
+
+void MacCapturer::Destroy() {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-variable"
+ RTCTestVideoSourceAdapter *adapter = (__bridge_transfer RTCTestVideoSourceAdapter *)adapter_;
+ RTCCameraVideoCapturer *capturer = (__bridge_transfer RTCCameraVideoCapturer *)capturer_;
+ [capturer stopCapture];
+#pragma clang diagnostic pop
+}
+
+MacCapturer::~MacCapturer() {
+ Destroy();
+}
+
+void MacCapturer::OnFrame(const VideoFrame &frame) {
+ TestVideoCapturer::OnFrame(frame);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/test/platform_video_capturer.cc b/test/platform_video_capturer.cc
new file mode 100644
index 0000000000..fb3392a052
--- /dev/null
+++ b/test/platform_video_capturer.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "test/platform_video_capturer.h"
+
+#include "absl/memory/memory.h"
+#if defined(WEBRTC_MAC)
+#include "test/mac_capturer.h"
+#else
+#include "test/vcm_capturer.h"
+#endif
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr CreateVideoCapturer(
+ size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index) {
+#if defined(WEBRTC_MAC)
+ return absl::WrapUnique(test::MacCapturer::Create(
+ width, height, target_fps, capture_device_index));
+#else
+ return absl::WrapUnique(test::VcmCapturer::Create(
+ width, height, target_fps, capture_device_index));
+#endif
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/test/platform_video_capturer.h b/test/platform_video_capturer.h
new file mode 100644
index 0000000000..241ba87df8
--- /dev/null
+++ b/test/platform_video_capturer.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef TEST_PLATFORM_VIDEO_CAPTURER_H_
+#define TEST_PLATFORM_VIDEO_CAPTURER_H_
+
+#include
+
+#include "test/test_video_capturer.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr CreateVideoCapturer(
+ size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // TEST_PLATFORM_VIDEO_CAPTURER_H_
diff --git a/test/test_video_capturer.h b/test/test_video_capturer.h
index 9c5b498f9f..0f1886bb44 100644
--- a/test/test_video_capturer.h
+++ b/test/test_video_capturer.h
@@ -25,7 +25,7 @@ namespace test {
class TestVideoCapturer : public rtc::VideoSourceInterface {
public:
TestVideoCapturer();
- virtual ~TestVideoCapturer();
+ ~TestVideoCapturer() override;
void AddOrUpdateSink(rtc::VideoSinkInterface* sink,
const rtc::VideoSinkWants& wants) override;
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 17b05de4c2..5bb0411466 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -271,6 +271,7 @@ if (rtc_include_tests) {
"../test:fake_video_codecs",
"../test:fileutils",
"../test:perf_test",
+ "../test:platform_video_capturer",
"../test:rtp_test_utils",
"../test:test_common",
"../test:test_renderer",
@@ -280,6 +281,10 @@ if (rtc_include_tests) {
"../test:video_test_support",
"//third_party/abseil-cpp/absl/memory:memory",
]
+
+ if (is_mac || is_ios) {
+ deps += [ "../test:video_test_mac" ]
+ }
}
rtc_source_set("video_full_stack_tests") {
@@ -309,10 +314,11 @@ if (rtc_include_tests) {
]
}
- rtc_executable("video_loopback") {
+ rtc_static_library("video_loopback_lib") {
testonly = true
sources = [
"video_loopback.cc",
+ "video_loopback.h",
]
deps = [
":video_quality_test",
@@ -335,6 +341,29 @@ if (rtc_include_tests) {
]
}
+ if (is_mac) {
+ mac_app_bundle("video_loopback") {
+ testonly = true
+ sources = [
+ "video_loopback_main.mm",
+ ]
+ info_plist = "../test/mac/Info.plist"
+ deps = [
+ ":video_loopback_lib",
+ ]
+ }
+ } else {
+ rtc_executable("video_loopback") {
+ testonly = true
+ sources = [
+ "video_loopback_main.cc",
+ ]
+ deps = [
+ ":video_loopback_lib",
+ ]
+ }
+ }
+
rtc_executable("screenshare_loopback") {
testonly = true
sources = [
diff --git a/video/video_loopback.cc b/video/video_loopback.cc
index ef32ae64dd..9ceb124ba1 100644
--- a/video/video_loopback.cc
+++ b/video/video_loopback.cc
@@ -7,6 +7,7 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
+#include "video/video_loopback.h"
#include
#include
@@ -389,9 +390,8 @@ void Loopback() {
fixture->RunWithRenderers(params);
}
}
-} // namespace webrtc
-int main(int argc, char* argv[]) {
+int RunLoopbackTest(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
if (webrtc::flags::FLAG_help) {
@@ -411,3 +411,4 @@ int main(int argc, char* argv[]) {
webrtc::test::RunTest(webrtc::Loopback);
return 0;
}
+} // namespace webrtc
diff --git a/video/video_loopback.h b/video/video_loopback.h
new file mode 100644
index 0000000000..51c7707640
--- /dev/null
+++ b/video/video_loopback.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VIDEO_VIDEO_LOOPBACK_H_
+#define VIDEO_VIDEO_LOOPBACK_H_
+
+namespace webrtc {
+// Expose the main test method.
+int RunLoopbackTest(int argc, char* argv[]);
+} // namespace webrtc
+
+#endif // VIDEO_VIDEO_LOOPBACK_H_
diff --git a/video/video_loopback_main.cc b/video/video_loopback_main.cc
new file mode 100644
index 0000000000..f4e5cdd8a5
--- /dev/null
+++ b/video/video_loopback_main.cc
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "video/video_loopback.h"
+
+int main(int argc, char* argv[]) {
+ webrtc::RunLoopbackTest(argc, argv);
+}
diff --git a/video/video_loopback_main.mm b/video/video_loopback_main.mm
new file mode 100644
index 0000000000..61b47a54da
--- /dev/null
+++ b/video/video_loopback_main.mm
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "video/video_loopback.h"
+
+int main(int argc, char* argv[]) {
+ @autoreleasepool {
+ webrtc::RunLoopbackTest(argc, argv);
+ }
+}
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index 2b20a8dca2..bdb1035589 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -35,9 +35,9 @@
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/strings/string_builder.h"
+#include "test/platform_video_capturer.h"
#include "test/run_loop.h"
#include "test/testsupport/file_utils.h"
-#include "test/vcm_capturer.h"
#include "test/video_renderer.h"
#include "video/frame_dumping_decoder.h"
#ifdef WEBRTC_WIN
@@ -1076,10 +1076,10 @@ void VideoQualityTest::CreateCapturers() {
test::FrameGenerator::OutputType::I010, absl::nullopt,
params_.video[video_idx].fps, clock_));
} else if (params_.video[video_idx].clip_name.empty()) {
- video_sources_[video_idx].reset(test::VcmCapturer::Create(
+ video_sources_[video_idx] = test::CreateVideoCapturer(
params_.video[video_idx].width, params_.video[video_idx].height,
params_.video[video_idx].fps,
- params_.video[video_idx].capture_device_index));
+ params_.video[video_idx].capture_device_index);
if (!video_sources_[video_idx]) {
// Failed to get actual camera, use chroma generator as backup.
video_sources_[video_idx].reset(test::FrameGeneratorCapturer::Create(