From f21c58306ed73ffdffe79f1d7ee5f9144f1ed646 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Feb 2022 16:57:23 -0600 Subject: [PATCH] Preserve stream aspect ratio even when host resolution changes --- Limelight/Stream/StreamManager.m | 2 +- Limelight/Stream/VideoDecoderRenderer.h | 2 +- Limelight/Stream/VideoDecoderRenderer.m | 21 +++++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Limelight/Stream/StreamManager.m b/Limelight/Stream/StreamManager.m index 6437862..6abb87a 100644 --- a/Limelight/Stream/StreamManager.m +++ b/Limelight/Stream/StreamManager.m @@ -100,7 +100,7 @@ // Initializing the renderer must be done on the main thread dispatch_async(dispatch_get_main_queue(), ^{ - VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc] initWithView:self->_renderView callbacks:self->_callbacks]; + VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc] initWithView:self->_renderView callbacks:self->_callbacks streamAspectRatio:(float)self->_config.width / (float)self->_config.height]; self->_connection = [[Connection alloc] initWithConfig:self->_config renderer:renderer connectionCallbacks:self->_callbacks]; NSOperationQueue* opQueue = [[NSOperationQueue alloc] init]; [opQueue addOperation:self->_connection]; diff --git a/Limelight/Stream/VideoDecoderRenderer.h b/Limelight/Stream/VideoDecoderRenderer.h index 5a6fb4b..62f82de 100644 --- a/Limelight/Stream/VideoDecoderRenderer.h +++ b/Limelight/Stream/VideoDecoderRenderer.h @@ -12,7 +12,7 @@ @interface VideoDecoderRenderer : NSObject -- (id)initWithView:(UIView*)view callbacks:(id)callbacks; +- (id)initWithView:(UIView*)view callbacks:(id)callbacks streamAspectRatio:(float)aspectRatio; - (void)setupWithVideoFormat:(int)videoFormat frameRate:(int)frameRate; - (void)start; diff --git a/Limelight/Stream/VideoDecoderRenderer.m b/Limelight/Stream/VideoDecoderRenderer.m index bc553ac..7bccbdd 100644 --- a/Limelight/Stream/VideoDecoderRenderer.m +++ b/Limelight/Stream/VideoDecoderRenderer.m @@ -14,6 +14,7 @@ @implementation VideoDecoderRenderer { StreamView* _view; id _callbacks; + float _streamAspectRatio; AVSampleBufferDisplayLayer* displayLayer; Boolean waitingForSps, waitingForPps, waitingForVps; @@ -31,12 +32,23 @@ CALayer *oldLayer = displayLayer; displayLayer = [[AVSampleBufferDisplayLayer alloc] init]; - displayLayer.bounds = _view.bounds; displayLayer.backgroundColor = [UIColor blackColor].CGColor; + // Ensure the AVSampleBufferDisplayLayer is sized to preserve the aspect ratio + // of the video stream. We used to use AVLayerVideoGravityResizeAspect, but that + // respects the PAR encoded in the SPS which causes our computed video-relative + // touch location to be wrong in StreamView if the aspect ratio of the host + // desktop doesn't match the aspect ratio of the stream. + CGSize videoSize; + if (_view.bounds.size.width > _view.bounds.size.height * _streamAspectRatio) { + videoSize = CGSizeMake(_view.bounds.size.height * _streamAspectRatio, _view.bounds.size.height); + } else { + videoSize = CGSizeMake(_view.bounds.size.width, _view.bounds.size.width / _streamAspectRatio); + } displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds)); - displayLayer.videoGravity = AVLayerVideoGravityResizeAspect; - + displayLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height); + displayLayer.videoGravity = AVLayerVideoGravityResize; + // Hide the layer until we get an IDR frame. This ensures we // can see the loading progress label as the stream is starting. displayLayer.hidden = YES; @@ -63,12 +75,13 @@ } } -- (id)initWithView:(StreamView*)view callbacks:(id)callbacks +- (id)initWithView:(StreamView*)view callbacks:(id)callbacks streamAspectRatio:(float)aspectRatio { self = [super init]; _view = view; _callbacks = callbacks; + _streamAspectRatio = aspectRatio; [self reinitializeDisplayLayer];