blob: 9b14f28c2afda51ef53612b225067167e1d8c0e9 [file] [log] [blame]
Kári Tristan Helgasonede7cb22019-03-06 09:34:091/*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
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 "test/mac_capturer.h"
12
13#import "sdk/objc/base/RTCVideoCapturer.h"
14#import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
15#import "sdk/objc/native/api/video_capturer.h"
16#import "sdk/objc/native/src/objc_frame_buffer.h"
17
Mirko Bonadeia81e9c82020-05-04 14:14:3218@interface RTCTestVideoSourceAdapter : NSObject <RTC_OBJC_TYPE (RTCVideoCapturerDelegate)>
Kári Tristan Helgasonede7cb22019-03-06 09:34:0919@property(nonatomic) webrtc::test::MacCapturer *capturer;
20@end
21
22@implementation RTCTestVideoSourceAdapter
23@synthesize capturer = _capturer;
24
Mirko Bonadeia81e9c82020-05-04 14:14:3225- (void)capturer:(RTC_OBJC_TYPE(RTCVideoCapturer) *)capturer
26 didCaptureVideoFrame:(RTC_OBJC_TYPE(RTCVideoFrame) *)frame {
Kári Tristan Helgasonede7cb22019-03-06 09:34:0927 const int64_t timestamp_us = frame.timeStampNs / rtc::kNumNanosecsPerMicrosec;
28 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
Niels Möllerac0d1832022-01-17 14:26:5429 rtc::make_ref_counted<webrtc::ObjCFrameBuffer>(frame.buffer);
Kári Tristan Helgasonede7cb22019-03-06 09:34:0930 _capturer->OnFrame(webrtc::VideoFrame::Builder()
31 .set_video_frame_buffer(buffer)
32 .set_rotation(webrtc::kVideoRotation_0)
33 .set_timestamp_us(timestamp_us)
34 .build());
35}
36
37@end
38
Kári Tristan Helgason10db5972019-03-13 10:18:4439namespace {
40
41AVCaptureDeviceFormat *SelectClosestFormat(AVCaptureDevice *device, size_t width, size_t height) {
42 NSArray<AVCaptureDeviceFormat *> *formats =
Mirko Bonadeia81e9c82020-05-04 14:14:3243 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:device];
Kári Tristan Helgason10db5972019-03-13 10:18:4444 AVCaptureDeviceFormat *selectedFormat = nil;
45 int currentDiff = INT_MAX;
46 for (AVCaptureDeviceFormat *format in formats) {
47 CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
48 int diff =
49 std::abs((int64_t)width - dimension.width) + std::abs((int64_t)height - dimension.height);
50 if (diff < currentDiff) {
51 selectedFormat = format;
52 currentDiff = diff;
53 }
54 }
55 return selectedFormat;
56}
57
58} // namespace
59
Kári Tristan Helgasonede7cb22019-03-06 09:34:0960namespace webrtc {
61namespace test {
62
63MacCapturer::MacCapturer(size_t width,
64 size_t height,
65 size_t target_fps,
66 size_t capture_device_index) {
Artem Titov6fd5f33d2023-03-25 20:15:0967 width_ = width;
68 height_ = height;
Kári Tristan Helgasonede7cb22019-03-06 09:34:0969 RTCTestVideoSourceAdapter *adapter = [[RTCTestVideoSourceAdapter alloc] init];
70 adapter_ = (__bridge_retained void *)adapter;
71 adapter.capturer = this;
72
Mirko Bonadeia81e9c82020-05-04 14:14:3273 RTC_OBJC_TYPE(RTCCameraVideoCapturer) *capturer =
74 [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] initWithDelegate:adapter];
Kári Tristan Helgasonede7cb22019-03-06 09:34:0975 capturer_ = (__bridge_retained void *)capturer;
76
77 AVCaptureDevice *device =
Mirko Bonadeia81e9c82020-05-04 14:14:3278 [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices] objectAtIndex:capture_device_index];
Kári Tristan Helgason10db5972019-03-13 10:18:4479 AVCaptureDeviceFormat *format = SelectClosestFormat(device, width, height);
Kári Tristan Helgasonede7cb22019-03-06 09:34:0980 [capturer startCaptureWithDevice:device format:format fps:target_fps];
81}
82
83MacCapturer *MacCapturer::Create(size_t width,
84 size_t height,
85 size_t target_fps,
86 size_t capture_device_index) {
87 return new MacCapturer(width, height, target_fps, capture_device_index);
88}
89
90void MacCapturer::Destroy() {
91#pragma clang diagnostic push
92#pragma clang diagnostic ignored "-Wunused-variable"
93 RTCTestVideoSourceAdapter *adapter = (__bridge_transfer RTCTestVideoSourceAdapter *)adapter_;
Mirko Bonadeia81e9c82020-05-04 14:14:3294 RTC_OBJC_TYPE(RTCCameraVideoCapturer) *capturer =
95 (__bridge_transfer RTC_OBJC_TYPE(RTCCameraVideoCapturer) *)capturer_;
Kári Tristan Helgasonede7cb22019-03-06 09:34:0996 [capturer stopCapture];
97#pragma clang diagnostic pop
98}
99
100MacCapturer::~MacCapturer() {
101 Destroy();
102}
103
104void MacCapturer::OnFrame(const VideoFrame &frame) {
105 TestVideoCapturer::OnFrame(frame);
106}
107
108} // namespace test
109} // namespace webrtc