Preserve stream aspect ratio even when host resolution changes

This commit is contained in:
Cameron Gutman
2022-02-06 16:57:23 -06:00
parent bd582aa6c0
commit f21c58306e
3 changed files with 19 additions and 6 deletions
+1 -1
View File
@@ -100,7 +100,7 @@
// Initializing the renderer must be done on the main thread // Initializing the renderer must be done on the main thread
dispatch_async(dispatch_get_main_queue(), ^{ 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]; self->_connection = [[Connection alloc] initWithConfig:self->_config renderer:renderer connectionCallbacks:self->_callbacks];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init]; NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:self->_connection]; [opQueue addOperation:self->_connection];
+1 -1
View File
@@ -12,7 +12,7 @@
@interface VideoDecoderRenderer : NSObject @interface VideoDecoderRenderer : NSObject
- (id)initWithView:(UIView*)view callbacks:(id<ConnectionCallbacks>)callbacks; - (id)initWithView:(UIView*)view callbacks:(id<ConnectionCallbacks>)callbacks streamAspectRatio:(float)aspectRatio;
- (void)setupWithVideoFormat:(int)videoFormat frameRate:(int)frameRate; - (void)setupWithVideoFormat:(int)videoFormat frameRate:(int)frameRate;
- (void)start; - (void)start;
+16 -3
View File
@@ -14,6 +14,7 @@
@implementation VideoDecoderRenderer { @implementation VideoDecoderRenderer {
StreamView* _view; StreamView* _view;
id<ConnectionCallbacks> _callbacks; id<ConnectionCallbacks> _callbacks;
float _streamAspectRatio;
AVSampleBufferDisplayLayer* displayLayer; AVSampleBufferDisplayLayer* displayLayer;
Boolean waitingForSps, waitingForPps, waitingForVps; Boolean waitingForSps, waitingForPps, waitingForVps;
@@ -31,11 +32,22 @@
CALayer *oldLayer = displayLayer; CALayer *oldLayer = displayLayer;
displayLayer = [[AVSampleBufferDisplayLayer alloc] init]; displayLayer = [[AVSampleBufferDisplayLayer alloc] init];
displayLayer.bounds = _view.bounds;
displayLayer.backgroundColor = [UIColor blackColor].CGColor; 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.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 // Hide the layer until we get an IDR frame. This ensures we
// can see the loading progress label as the stream is starting. // can see the loading progress label as the stream is starting.
@@ -63,12 +75,13 @@
} }
} }
- (id)initWithView:(StreamView*)view callbacks:(id<ConnectionCallbacks>)callbacks - (id)initWithView:(StreamView*)view callbacks:(id<ConnectionCallbacks>)callbacks streamAspectRatio:(float)aspectRatio
{ {
self = [super init]; self = [super init];
_view = view; _view = view;
_callbacks = callbacks; _callbacks = callbacks;
_streamAspectRatio = aspectRatio;
[self reinitializeDisplayLayer]; [self reinitializeDisplayLayer];