summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/mac
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/libwebrtc/test/mac/Info.plist16
-rw-r--r--third_party/libwebrtc/test/mac/run_test.mm73
-rw-r--r--third_party/libwebrtc/test/mac/video_renderer_mac.h40
-rw-r--r--third_party/libwebrtc/test/mac/video_renderer_mac.mm127
-rw-r--r--third_party/libwebrtc/test/mac_capturer.h66
-rw-r--r--third_party/libwebrtc/test/mac_capturer.mm109
6 files changed, 431 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/mac/Info.plist b/third_party/libwebrtc/test/mac/Info.plist
new file mode 100644
index 0000000000..8a2b5cf0a0
--- /dev/null
+++ b/third_party/libwebrtc/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/third_party/libwebrtc/test/mac/run_test.mm b/third_party/libwebrtc/test/mac/run_test.mm
new file mode 100644
index 0000000000..38c6c8f8c1
--- /dev/null
+++ b/third_party/libwebrtc/test/mac/run_test.mm
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013 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 <Cocoa/Cocoa.h>
+
+#include "test/run_test.h"
+
+// Converting a C++ function pointer to an Objective-C block.
+typedef void(^TestBlock)();
+TestBlock functionToBlock(void(*function)()) {
+ return [^(void) { function(); } copy];
+}
+
+// Class calling the test function on the platform specific thread.
+@interface TestRunner : NSObject {
+ BOOL running_;
+}
+- (void)runAllTests:(TestBlock)ignored;
+- (BOOL)running;
+@end
+
+@implementation TestRunner
+- (id)init {
+ self = [super init];
+ if (self) {
+ running_ = YES;
+ }
+ return self;
+}
+
+- (void)runAllTests:(TestBlock)testBlock {
+ @autoreleasepool {
+ testBlock();
+ running_ = NO;
+ }
+}
+
+- (BOOL)running {
+ return running_;
+}
+@end
+
+namespace webrtc {
+namespace test {
+
+void RunTest(void(*test)()) {
+ @autoreleasepool {
+ [NSApplication sharedApplication];
+
+ // Convert the function pointer to an Objective-C block and call on a
+ // separate thread, to avoid blocking the main thread.
+ TestRunner *testRunner = [[TestRunner alloc] init];
+ TestBlock testBlock = functionToBlock(test);
+ [NSThread detachNewThreadSelector:@selector(runAllTests:)
+ toTarget:testRunner
+ withObject:testBlock];
+
+ NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
+ while ([testRunner running] && [runLoop runMode:NSDefaultRunLoopMode
+ beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]])
+ ;
+ }
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/test/mac/video_renderer_mac.h b/third_party/libwebrtc/test/mac/video_renderer_mac.h
new file mode 100644
index 0000000000..8e629b0a49
--- /dev/null
+++ b/third_party/libwebrtc/test/mac/video_renderer_mac.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 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_VIDEO_RENDERER_MAC_H_
+#define TEST_MAC_VIDEO_RENDERER_MAC_H_
+
+#include "test/gl/gl_renderer.h"
+
+@class CocoaWindow;
+
+namespace webrtc {
+namespace test {
+
+class MacRenderer : public GlRenderer {
+ public:
+ MacRenderer();
+ virtual ~MacRenderer();
+
+ MacRenderer(const MacRenderer&) = delete;
+ MacRenderer& operator=(const MacRenderer&) = delete;
+
+ bool Init(const char* window_title, int width, int height);
+
+ // Implements GlRenderer.
+ void OnFrame(const VideoFrame& frame) override;
+
+ private:
+ CocoaWindow* window_;
+};
+} // namespace test
+} // namespace webrtc
+
+#endif // TEST_MAC_VIDEO_RENDERER_MAC_H_
diff --git a/third_party/libwebrtc/test/mac/video_renderer_mac.mm b/third_party/libwebrtc/test/mac/video_renderer_mac.mm
new file mode 100644
index 0000000000..7103375383
--- /dev/null
+++ b/third_party/libwebrtc/test/mac/video_renderer_mac.mm
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013 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/video_renderer_mac.h"
+
+#import <Cocoa/Cocoa.h>
+
+// Creates a Cocoa Window with an OpenGL context, used together with an OpenGL
+// renderer.
+@interface CocoaWindow : NSObject {
+ @private
+ NSWindow *window_;
+ NSOpenGLContext *context_;
+ NSString *title_;
+ int width_;
+ int height_;
+}
+
+- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height;
+// 'createWindow' must be called on the main thread.
+- (void)createWindow:(NSObject *)ignored;
+- (void)makeCurrentContext;
+
+@end
+
+@implementation CocoaWindow
+ static NSInteger nextXOrigin_;
+ static NSInteger nextYOrigin_;
+
+- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height {
+ if (self = [super init]) {
+ title_ = title;
+ width_ = width;
+ height_ = height;
+ }
+ return self;
+}
+
+- (void)createWindow:(NSObject *)ignored {
+ NSInteger xOrigin = nextXOrigin_;
+ NSRect screenFrame = [[NSScreen mainScreen] frame];
+ if (nextXOrigin_ + width_ < screenFrame.size.width) {
+ nextXOrigin_ += width_;
+ } else {
+ xOrigin = 0;
+ nextXOrigin_ = 0;
+ nextYOrigin_ += height_;
+ }
+ if (nextYOrigin_ + height_ > screenFrame.size.height) {
+ xOrigin = 0;
+ nextXOrigin_ = 0;
+ nextYOrigin_ = 0;
+ }
+ NSInteger yOrigin = nextYOrigin_;
+ NSRect windowFrame = NSMakeRect(xOrigin, yOrigin, width_, height_);
+ window_ = [[NSWindow alloc] initWithContentRect:windowFrame
+ styleMask:NSWindowStyleMaskTitled
+ backing:NSBackingStoreBuffered
+ defer:NO];
+
+ NSRect viewFrame = NSMakeRect(0, 0, width_, height_);
+ NSOpenGLView *view = [[NSOpenGLView alloc] initWithFrame:viewFrame pixelFormat:nil];
+ context_ = [view openGLContext];
+
+ [[window_ contentView] addSubview:view];
+ [window_ setTitle:title_];
+ [window_ makeKeyAndOrderFront:NSApp];
+}
+
+- (void)makeCurrentContext {
+ [context_ makeCurrentContext];
+}
+
+@end
+
+namespace webrtc {
+namespace test {
+
+VideoRenderer* VideoRenderer::CreatePlatformRenderer(const char* window_title,
+ size_t width,
+ size_t height) {
+ MacRenderer* renderer = new MacRenderer();
+ if (!renderer->Init(window_title, width, height)) {
+ delete renderer;
+ return NULL;
+ }
+ return renderer;
+}
+
+MacRenderer::MacRenderer()
+ : window_(NULL) {}
+
+MacRenderer::~MacRenderer() {
+ GlRenderer::Destroy();
+}
+
+bool MacRenderer::Init(const char* window_title, int width, int height) {
+ window_ = [[CocoaWindow alloc]
+ initWithTitle:[NSString stringWithUTF8String:window_title]
+ width:width
+ height:height];
+ if (!window_)
+ return false;
+ [window_ performSelectorOnMainThread:@selector(createWindow:)
+ withObject:nil
+ waitUntilDone:YES];
+
+ [window_ makeCurrentContext];
+ GlRenderer::Init();
+ GlRenderer::ResizeViewport(width, height);
+ return true;
+}
+
+void MacRenderer::OnFrame(const VideoFrame& frame) {
+ [window_ makeCurrentContext];
+ GlRenderer::OnFrame(frame);
+}
+
+} // test
+} // webrtc
diff --git a/third_party/libwebrtc/test/mac_capturer.h b/third_party/libwebrtc/test/mac_capturer.h
new file mode 100644
index 0000000000..58ccfc0675
--- /dev/null
+++ b/third_party/libwebrtc/test/mac_capturer.h
@@ -0,0 +1,66 @@
+/*
+ * 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 <cstddef>
+#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/logging.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 Start() override {
+ RTC_LOG(LS_WARNING) << "Capturer doesn't support resume/pause and always "
+ "produces the video";
+ }
+ void Stop() override {
+ RTC_LOG(LS_WARNING) << "Capturer doesn't support resume/pause and always "
+ "produces the video";
+ }
+
+ void OnFrame(const VideoFrame& frame) override;
+
+ int GetFrameWidth() const override { return static_cast<int>(width_); }
+ int GetFrameHeight() const override { return static_cast<int>(height_); }
+
+ private:
+ MacCapturer(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index);
+ void Destroy();
+
+ size_t width_;
+ size_t height_;
+ void* capturer_;
+ void* adapter_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // TEST_MAC_CAPTURER_H_
diff --git a/third_party/libwebrtc/test/mac_capturer.mm b/third_party/libwebrtc/test/mac_capturer.mm
new file mode 100644
index 0000000000..9b14f28c2a
--- /dev/null
+++ b/third_party/libwebrtc/test/mac_capturer.mm
@@ -0,0 +1,109 @@
+/*
+ * 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 <RTC_OBJC_TYPE (RTCVideoCapturerDelegate)>
+@property(nonatomic) webrtc::test::MacCapturer *capturer;
+@end
+
+@implementation RTCTestVideoSourceAdapter
+@synthesize capturer = _capturer;
+
+- (void)capturer:(RTC_OBJC_TYPE(RTCVideoCapturer) *)capturer
+ didCaptureVideoFrame:(RTC_OBJC_TYPE(RTCVideoFrame) *)frame {
+ const int64_t timestamp_us = frame.timeStampNs / rtc::kNumNanosecsPerMicrosec;
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
+ rtc::make_ref_counted<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 {
+
+AVCaptureDeviceFormat *SelectClosestFormat(AVCaptureDevice *device, size_t width, size_t height) {
+ NSArray<AVCaptureDeviceFormat *> *formats =
+ [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:device];
+ AVCaptureDeviceFormat *selectedFormat = nil;
+ int currentDiff = INT_MAX;
+ for (AVCaptureDeviceFormat *format in formats) {
+ CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
+ int diff =
+ std::abs((int64_t)width - dimension.width) + std::abs((int64_t)height - dimension.height);
+ if (diff < currentDiff) {
+ selectedFormat = format;
+ currentDiff = diff;
+ }
+ }
+ return selectedFormat;
+}
+
+} // namespace
+
+namespace webrtc {
+namespace test {
+
+MacCapturer::MacCapturer(size_t width,
+ size_t height,
+ size_t target_fps,
+ size_t capture_device_index) {
+ width_ = width;
+ height_ = height;
+ RTCTestVideoSourceAdapter *adapter = [[RTCTestVideoSourceAdapter alloc] init];
+ adapter_ = (__bridge_retained void *)adapter;
+ adapter.capturer = this;
+
+ RTC_OBJC_TYPE(RTCCameraVideoCapturer) *capturer =
+ [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] initWithDelegate:adapter];
+ capturer_ = (__bridge_retained void *)capturer;
+
+ AVCaptureDevice *device =
+ [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices] objectAtIndex:capture_device_index];
+ AVCaptureDeviceFormat *format = SelectClosestFormat(device, width, height);
+ [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_;
+ RTC_OBJC_TYPE(RTCCameraVideoCapturer) *capturer =
+ (__bridge_transfer RTC_OBJC_TYPE(RTCCameraVideoCapturer) *)capturer_;
+ [capturer stopCapture];
+#pragma clang diagnostic pop
+}
+
+MacCapturer::~MacCapturer() {
+ Destroy();
+}
+
+void MacCapturer::OnFrame(const VideoFrame &frame) {
+ TestVideoCapturer::OnFrame(frame);
+}
+
+} // namespace test
+} // namespace webrtc