Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,207 @@
|
|||
//
|
||||
// DesktopCaptureSourceView.m
|
||||
// TgVoipWebrtc
|
||||
//
|
||||
// Created by Mikhail Filimonov on 28.12.2020.
|
||||
// Copyright © 2020 Mikhail Filimonov. All rights reserved.
|
||||
//
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "DesktopCaptureSourceViewMac.h"
|
||||
#import "platform/darwin/VideoMetalViewMac.h"
|
||||
#import "tgcalls/desktop_capturer/DesktopCaptureSource.h"
|
||||
#import "tgcalls/desktop_capturer/DesktopCaptureSourceHelper.h"
|
||||
#import "tgcalls/desktop_capturer/DesktopCaptureSourceManager.h"
|
||||
#import "platform/darwin/VideoMetalViewMac.h"
|
||||
|
||||
|
||||
|
||||
@interface DesktopCaptureSourceViewMetal : VideoMetalView
|
||||
@end
|
||||
|
||||
|
||||
@implementation DesktopCaptureSourceViewMetal
|
||||
|
||||
-(id)initWithHelper:(tgcalls::DesktopCaptureSourceHelper)helper {
|
||||
if (self = [super initWithFrame:CGRectZero]) {
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink = [self getSink];
|
||||
helper.setOutput(sink);
|
||||
[self setVideoContentMode:kCAGravityResizeAspectFill];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation DesktopCaptureSourceDataMac
|
||||
-(id)initWithSize:(CGSize)size fps:(double)fps captureMouse:(bool)captureMouse {
|
||||
if (self = [super init]) {
|
||||
self.aspectSize = size;
|
||||
self.fps = fps;
|
||||
self.captureMouse = captureMouse;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSString *)cachedKey {
|
||||
return [[NSString alloc] initWithFormat:@"%@:%f:%d", NSStringFromSize(self.aspectSize), self.fps, self.captureMouse];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface DesktopCaptureSourceMac ()
|
||||
{
|
||||
absl::optional<tgcalls::DesktopCaptureSource> _source;
|
||||
BOOL _isWindow;
|
||||
}
|
||||
-(id)initWithSource:(tgcalls::DesktopCaptureSource)source isWindow:(BOOL)isWindow;
|
||||
-(tgcalls::DesktopCaptureSource)getSource;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DesktopCaptureSourceMac
|
||||
|
||||
-(tgcalls::DesktopCaptureSource)getSource {
|
||||
return _source.value();
|
||||
}
|
||||
|
||||
-(NSString *)title {
|
||||
if (_isWindow) {
|
||||
const tgcalls::DesktopCaptureSource source = _source.value();
|
||||
return [[NSString alloc] initWithCString:source.title().c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
else
|
||||
return [[NSString alloc] initWithFormat:@"Screen"];
|
||||
}
|
||||
|
||||
-(long)uniqueId {
|
||||
return _source.value().uniqueId();
|
||||
}
|
||||
-(BOOL)isWindow {
|
||||
return _isWindow;
|
||||
}
|
||||
-(NSString *)uniqueKey {
|
||||
return [[NSString alloc] initWithFormat:@"%ld:%@", self.uniqueId, _isWindow ? @"Window" : @"Screen"];
|
||||
}
|
||||
|
||||
-(NSString *)deviceIdKey {
|
||||
return [[NSString alloc] initWithFormat:@"desktop_capturer_%@_%ld", _isWindow ? @"window" : @"screen", self.uniqueId];
|
||||
}
|
||||
|
||||
-(BOOL)isEqual:(id)object {
|
||||
return [[((DesktopCaptureSourceMac *)object) uniqueKey] isEqualToString:[self uniqueKey]];
|
||||
}
|
||||
- (BOOL)isEqualTo:(id)object {
|
||||
return [[((DesktopCaptureSourceMac *)object) uniqueKey] isEqualToString:[self uniqueKey]];
|
||||
}
|
||||
|
||||
-(id)initWithSource:(tgcalls::DesktopCaptureSource)source isWindow:(BOOL)isWindow {
|
||||
if (self = [super init]) {
|
||||
_source = source;
|
||||
_isWindow = isWindow;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface DesktopCaptureSourceScopeMac ()
|
||||
-(tgcalls::DesktopCaptureSourceData)getData;
|
||||
-(tgcalls::DesktopCaptureSource)getSource;
|
||||
@end
|
||||
|
||||
@implementation DesktopCaptureSourceScopeMac
|
||||
|
||||
-(id)initWithSource:(DesktopCaptureSourceMac *)source data:(DesktopCaptureSourceDataMac *)data {
|
||||
if (self = [super init]) {
|
||||
_data = data;
|
||||
_source = source;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSString *)cachedKey {
|
||||
return [[NSString alloc] initWithFormat:@"%@:%@", _source.uniqueKey, _data.cachedKey];
|
||||
}
|
||||
|
||||
-(tgcalls::DesktopCaptureSourceData)getData {
|
||||
tgcalls::DesktopCaptureSourceData data{
|
||||
/*.aspectSize = */{ (int)_data.aspectSize.width, (int)_data.aspectSize.height},
|
||||
/*.fps = */_data.fps,
|
||||
/*.captureMouse = */_data.captureMouse,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
-(tgcalls::DesktopCaptureSource)getSource {
|
||||
return [_source getSource];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DesktopCaptureSourceManagerMac
|
||||
{
|
||||
std::map<std::string, tgcalls::DesktopCaptureSourceHelper> _cached;
|
||||
std::unique_ptr<tgcalls::DesktopCaptureSourceManager> _manager;
|
||||
BOOL _isWindow;
|
||||
}
|
||||
|
||||
-(instancetype)init_s {
|
||||
if (self = [super init]) {
|
||||
_manager = std::make_unique<tgcalls::DesktopCaptureSourceManager>(tgcalls::DesktopCaptureType::Screen);
|
||||
_isWindow = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
-(instancetype)init_w {
|
||||
if (self = [super init]) {
|
||||
_manager = std::make_unique<tgcalls::DesktopCaptureSourceManager>(tgcalls::DesktopCaptureType::Window);
|
||||
_isWindow = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSArray<DesktopCaptureSourceMac *> *)list {
|
||||
std::vector<tgcalls::DesktopCaptureSource> sources = _manager->sources();
|
||||
NSMutableArray<DesktopCaptureSourceMac *> *macSources = [[NSMutableArray alloc] init];
|
||||
for (auto i = sources.begin(); i != sources.end(); ++i) {
|
||||
[macSources addObject:[[DesktopCaptureSourceMac alloc] initWithSource:*i isWindow:_isWindow]];
|
||||
}
|
||||
return macSources;
|
||||
}
|
||||
|
||||
-(NSView *)createForScope:(DesktopCaptureSourceScopeMac*)scope {
|
||||
auto i = _cached.find(std::string([scope.cachedKey UTF8String]));
|
||||
if (i == _cached.end()) {
|
||||
i = _cached.emplace(
|
||||
std::string([scope.cachedKey UTF8String]),
|
||||
tgcalls::DesktopCaptureSourceHelper([scope getSource], [scope getData])).first;
|
||||
}
|
||||
|
||||
DesktopCaptureSourceViewMetal *view = [[DesktopCaptureSourceViewMetal alloc] initWithHelper:i->second];
|
||||
if (scope.data.captureMouse) {
|
||||
[view setVideoContentMode:kCAGravityResizeAspect];
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
-(void)start:(DesktopCaptureSourceScopeMac *)scope {
|
||||
const auto i = _cached.find(std::string([scope.cachedKey UTF8String]));
|
||||
if (i != _cached.end()) {
|
||||
i->second.start();
|
||||
}
|
||||
}
|
||||
|
||||
-(void)stop:(DesktopCaptureSourceScopeMac *)scope {
|
||||
const auto i = _cached.find(std::string([scope.cachedKey UTF8String]));
|
||||
if (i != _cached.end()) {
|
||||
i->second.stop();
|
||||
}
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
for (auto &[key, helper] : _cached) {
|
||||
helper.stop();
|
||||
}
|
||||
_manager.reset();
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
Add table
Add a link
Reference in a new issue