Rewrite video_loopback to use new mac capturer.

The old one has been deprecated for a long time.

Bug: webrtc:6333, webrtc:6898, webrtc:7861
Change-Id: Ib9b798262817e80019afcacc5b41d18957a28101
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/124827
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Peter Hanspers <peterhanspers@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26993}
diff --git a/test/BUILD.gn b/test/BUILD.gn
index c1e6362..c0b3f17 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -49,8 +49,6 @@
     "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 @@
     "../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 @@
   ]
 }
 
+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 @@
     "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("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 @@
     "../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_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 0000000..8a2b5cf
--- /dev/null
+++ b/test/mac/Info.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleIdentifier</key>
+	<string>org.webrtc.video_loopback</string>
+	<key>CFBundleName</key>
+	<string>video_loopback</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>NSCameraUsageDescription</key>
+	<string>Camera access needed for video calling</string>
+	<key>NSMicrophoneUsageDescription</key>
+	<string>Microphone access needed for video calling</string>
+</dict>
+</plist>
diff --git a/test/mac_capturer.h b/test/mac_capturer.h
new file mode 100644
index 0000000..3d7ee77
--- /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 <memory>
+#include <vector>
+
+#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<VideoFrame> {
+ 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 0000000..004900a
--- /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 <RTCVideoCapturerDelegate>
+@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<webrtc::VideoFrameBuffer> buffer =
+      new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(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 0000000..fb3392a
--- /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<TestVideoCapturer> CreateVideoCapturer(
+    size_t width,
+    size_t height,
+    size_t target_fps,
+    size_t capture_device_index) {
+#if defined(WEBRTC_MAC)
+  return absl::WrapUnique<TestVideoCapturer>(test::MacCapturer::Create(
+      width, height, target_fps, capture_device_index));
+#else
+  return absl::WrapUnique<TestVideoCapturer>(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 0000000..241ba87
--- /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 <memory>
+
+#include "test/test_video_capturer.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<TestVideoCapturer> 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 9c5b498..0f1886b 100644
--- a/test/test_video_capturer.h
+++ b/test/test_video_capturer.h
@@ -25,7 +25,7 @@
 class TestVideoCapturer : public rtc::VideoSourceInterface<VideoFrame> {
  public:
   TestVideoCapturer();
-  virtual ~TestVideoCapturer();
+  ~TestVideoCapturer() override;
 
   void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
                        const rtc::VideoSinkWants& wants) override;