Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding External Screen Support [Feature Request #11] #411

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions Limelight/Stream/VideoDecoderRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ @implementation VideoDecoderRenderer {
CMVideoFormatDescriptionRef formatDesc;

CADisplayLink* _displayLink;
}

}
- (void)reinitializeDisplayLayer
{
CALayer *oldLayer = displayLayer;

displayLayer = [[AVSampleBufferDisplayLayer alloc] init];
displayLayer.bounds = _view.bounds;
displayLayer.backgroundColor = [OSColor blackColor].CGColor;

displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds));
displayLayer.videoGravity = AVLayerVideoGravityResizeAspect;

Expand Down Expand Up @@ -68,7 +66,14 @@ - (id)initWithView:(StreamView*)view
_view = view;

[self reinitializeDisplayLayer];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reinitializeDisplayLayer)
name:@"ScreenConnected"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reinitializeDisplayLayer)
name:@"ScreenDisconnected"
object:nil];
return self;
}

Expand Down Expand Up @@ -381,4 +386,4 @@ - (int)submitDecodeBuffer:(unsigned char *)data length:(int)length bufferType:(i
return DR_OK;
}

@end
@end
90 changes: 82 additions & 8 deletions Limelight/ViewControllers/StreamFrameViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,41 @@ @implementation StreamFrameViewController {
UITextView *_overlayView;
StreamView *_streamView;
BOOL _userIsInteracting;
UIWindow *_extWindow;
UIView *_renderView;
UIWindow *_deviceWindow;
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

_deviceWindow = self.view.window;

if (UIScreen.screens.count > 1) {
[self prepExtScreen:UIScreen.screens.lastObject];
}
else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the indentation got a bit mangled here

dispatch_async(dispatch_get_main_queue(), ^{
[self.view insertSubview:self->_renderView atIndex:0];
});
}

// check to see if external screen is connected/disconnected

[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(extScreenDidConnect:)
name: UIScreenDidConnectNotification
object: nil];

[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(extScreenDidDisconnect:)
name: UIScreenDidDisconnectNotification
object: nil];




#if !TARGET_OS_TV
[[self revealViewController] setPrimaryViewController:self];
#endif
Expand Down Expand Up @@ -61,8 +90,9 @@ - (void)viewDidLoad

_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig presenceDelegate:self];
_inactivityTimer = nil;

_renderView = (StreamView*)[[UIView alloc] initWithFrame:self.view.frame];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not safe to cast a UIView to a StreamView.

Copy link
Author

@mattrussell7 mattrussell7 May 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgutman What would you suggest to be a better alternative? Should it be a split to a #IF os(iOS)? Is this due to StreamView being a possible OSView for non iOS devices?

_streamView = (StreamView*)self.view;
_renderView.bounds = _streamView.bounds;
[_streamView setupStreamView:_controllerSupport swipeDelegate:self interactionDelegate:self config:self.streamConfig];

#if TARGET_OS_TV
Expand Down Expand Up @@ -91,11 +121,10 @@ - (void)viewDidLoad
self.tipLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height * 0.9);

_streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig
renderView:self.view
connectionCallbacks:self];
renderView:_renderView
connectionCallbacks:self];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:_streamMan];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
Expand Down Expand Up @@ -160,6 +189,51 @@ - (void)updateOverlayText:(NSString*)text {

- (void) returnToMainFrame {
[self.navigationController popToRootViewControllerAnimated:YES];
_extWindow = nil;
}

// External Screen connected
- (void)extScreenDidConnect:(NSNotification *)notification {
Log(LOG_I, @"External Screen Connected");
dispatch_async(dispatch_get_main_queue(), ^{
[self prepExtScreen:notification.object];
});
}

// External Screen disconnected
- (void)extScreenDidDisconnect:(NSNotification *)notification {
Log(LOG_I, @"External Screen Disconnected");
if(UIScreen.screens.count < 2)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self removeExtScreen];
});
}
}

// Prepare Screen
- (void)prepExtScreen:(UIScreen*)extScreen {
Log(LOG_I, @"Preparing External Screen");
CGRect frame = extScreen.bounds;
extScreen.overscanCompensation = 3;
_extWindow = [[UIWindow alloc] initWithFrame:frame];
_extWindow.screen = extScreen;
_renderView.bounds = frame;
_renderView.frame = frame;
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"ScreenConnected" object:self];
[_extWindow addSubview:_renderView];
_extWindow.hidden = NO;
}

- (void)removeExtScreen {
Log(LOG_I, @"Removing External Screen");
_extWindow.hidden = YES;
_renderView.bounds = _deviceWindow.bounds;
_renderView.frame = _deviceWindow.frame;
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"ScreenDisconnected" object:self];
[self.view insertSubview:_renderView atIndex:0];
}

// This will fire if the user opens control center or gets a low battery message
Expand Down Expand Up @@ -221,12 +295,12 @@ - (void)edgeSwiped {
- (void) connectionStarted {
Log(LOG_I, @"Connection started");
dispatch_async(dispatch_get_main_queue(), ^{
// Leave the spinner spinning until it's obscured by
// the first frame of video.
mattrussell7 marked this conversation as resolved.
Show resolved Hide resolved
self.stageLabel.hidden = YES;
self.tipLabel.hidden = YES;

[self->_streamView showOnScreenControls];
self.spinner.hidden = YES;

});
}

Expand Down Expand Up @@ -270,8 +344,8 @@ - (void)connectionTerminated:(int)errorCode {
}

- (void) stageStarting:(const char*)stageName {
Log(LOG_I, @"Starting %s", stageName);
dispatch_async(dispatch_get_main_queue(), ^{
Log(LOG_I, @"Starting %s", stageName);
NSString* lowerCase = [NSString stringWithFormat:@"%s in progress...", stageName];
NSString* titleCase = [[[lowerCase substringToIndex:1] uppercaseString] stringByAppendingString:[lowerCase substringFromIndex:1]];
[self.stageLabel setText:titleCase];
Expand Down Expand Up @@ -414,4 +488,4 @@ - (BOOL)shouldAutorotate {
}
#endif

@end
@end