1// 2// DesktopCaptureSourceView.m 3// TgVoipWebrtc 4// 5// Created by Mikhail Filimonov on 28.12.2020. 6// Copyright © 2020 Mikhail Filimonov. All rights reserved. 7// 8 9#import "DesktopCaptureSourceView.h" 10#import "platform/darwin/VideoMetalViewMac.h" 11 12@interface DesktopCaptureSourceView () 13 14@end 15 16@implementation DesktopCaptureSourceView 17 18-(id)initWithHelper:(tgcalls::DesktopCaptureSourceHelper)helper { 19 if (self = [super initWithFrame:CGRectZero]) { 20 std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink = [self getSink]; 21 helper.setOutput(sink); 22 [self setVideoContentMode:kCAGravityResizeAspectFill]; 23 } 24 return self; 25} 26 27@end 28 29@interface DesktopCaptureSourceScope () 30-(tgcalls::DesktopCaptureSourceData)getData; 31-(tgcalls::DesktopCaptureSource)getSource; 32@end 33 34@implementation DesktopCaptureSourceScope 35{ 36 absl::optional<tgcalls::DesktopCaptureSourceData> _data; 37 absl::optional<tgcalls::DesktopCaptureSource> _source; 38} 39 40-(id)initWithSource:(tgcalls::DesktopCaptureSource)source data:(tgcalls::DesktopCaptureSourceData)data { 41 if (self = [super init]) { 42 _data = data; 43 _source = source; 44 } 45 return self; 46} 47 48-(tgcalls::DesktopCaptureSourceData)getData { 49 return _data.value(); 50} 51-(tgcalls::DesktopCaptureSource)getSource { 52 return _source.value(); 53} 54 55-(NSString *)cachedKey { 56 return [[NSString alloc] initWithFormat:@"%@:%@", [NSString stringWithUTF8String:_source.value().VideoSource::uniqueKey().c_str()], [NSString stringWithUTF8String:_data.value().cachedKey().c_str()]]; 57} 58 59@end 60 61@implementation DesktopCaptureSourceViewManager 62{ 63 std::map<NSString*, tgcalls::DesktopCaptureSourceHelper> _cached; 64} 65 66-(NSView *)createForScope:(DesktopCaptureSourceScope*)scope { 67 auto i = _cached.find(scope.cachedKey); 68 if (i == end(_cached)) { 69 i = _cached.emplace( 70 scope.cachedKey, 71 tgcalls::DesktopCaptureSourceHelper([scope getSource], [scope getData])).first; 72 } 73 return [[DesktopCaptureSourceView alloc] initWithHelper:i->second]; 74} 75 76-(void)start:(DesktopCaptureSourceScope *)scope { 77 const auto i = _cached.find(scope.cachedKey); 78 if (i != end(_cached)) { 79 i->second.start(); 80 } 81} 82 83-(void)stop:(DesktopCaptureSourceScope *)scope { 84 const auto i = _cached.find(scope.cachedKey); 85 if (i != end(_cached)) { 86 i->second.stop(); 87 } 88} 89 90-(void)dealloc { 91 for (auto &[key, helper] : _cached) { 92 helper.stop(); 93 } 94} 95 96@end 97