| /* | |
| * 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 / webrtc::kNumNanosecsPerMicrosec; | |
| webrtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = | |
| webrtc::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 |