From aac227ab58b24c4296e24dea5ddf782985a021e6 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 25 May 2016 18:28:03 -0700 Subject: [PATCH 01/11] Added support for allowing developers to set custom video encoder settings. --- .../SDLStreamingMediaManager.h | 12 ++ .../SDLStreamingMediaManager.m | 117 ++++++++---------- 2 files changed, 67 insertions(+), 62 deletions(-) diff --git a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h index 05a855e13..2e3a6dbb1 100644 --- a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h @@ -82,9 +82,21 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); */ - (BOOL)sendAudioData:(NSData *)pcmAudioData; +/** + * The settings used in a VTCompressionSessionRef encoder. These will be verified when the video stream is started. Acceptable properties for this are located in VTCompressionProperties. If set to nil, the defaultVideoEncoderSettings will be used. + * + * @warning Video streaming must not be connected to update the encoder properties. If it is running, issue a stopVideoSession before updating. + */ +@property (strong, nonatomic, nullable) NSDictionary* videoEncoderSettings; + @property (assign, nonatomic, readonly) BOOL videoSessionConnected; @property (assign, nonatomic, readonly) BOOL audioSessionConnected; +/** + * Provides default video encoder settings used. + */ +@property (strong, nonatomic, readonly) NSDictionary* defaultVideoEncoderSettings; + @end diff --git a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m index 9b7f5a8ac..74a9f634d 100644 --- a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m @@ -127,6 +127,30 @@ - (BOOL)sendAudioData:(NSData *)pcmAudioData { return YES; } +#pragma mark - Update video encoder + +- (void)setVideoEncoderSettings:( NSDictionary * _Nullable)videoEncoderSettings { + if (self.videoSessionConnected) { + @throw [NSException exceptionWithName:SDLErrorDomainStreamingMediaVideo reason:@"Cannot update video encoder settings while video session is connected." userInfo:nil]; + return; + } + + _videoEncoderSettings = videoEncoderSettings; +} + +- (NSDictionary*)defaultVideoEncoderSettings { + static NSDictionary* defaultVideoEncoderSettings = nil; + if (defaultVideoEncoderSettings == nil) { + defaultVideoEncoderSettings = @{ + (__bridge NSString*)kVTCompressionPropertyKey_AverageBitRate : @(5000 * 1024), + (__bridge NSString*)kVTCompressionPropertyKey_ProfileLevel : (__bridge NSString*)kVTProfileLevel_H264_Baseline_AutoLevel, + (__bridge NSString*)kVTCompressionPropertyKey_RealTime : @(YES), + (__bridge NSString*)kVTCompressionPropertyKey_MaxKeyFrameInterval : @(50) + }; + } + return defaultVideoEncoderSettings; +} + #pragma mark - SDLProtocolListener Methods @@ -229,83 +253,52 @@ - (BOOL)sdl_configureVideoEncoderWithError:(NSError *__autoreleasing *)error { if (status != noErr) { // TODO: Log the error - if (*error != nil) { + if (*error == nil) { *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus" : @(status) }]; } return NO; } - - // Set the bitrate of our video compression - int bitRate = 5000; - CFNumberRef bitRateNumRef = CFNumberCreate(NULL, kCFNumberSInt32Type, &bitRate); - if (bitRateNumRef == NULL) { - // TODO: Log & end session - if (*error != nil) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationAllocationFailure userInfo:nil]; - } - - return NO; + + if (self.videoEncoderSettings == nil) { + self.videoEncoderSettings = self.defaultVideoEncoderSettings; } - status = VTSessionSetProperty(self.compressionSession, kVTCompressionPropertyKey_AverageBitRate, bitRateNumRef); - - // Release our bitrate number - CFRelease(bitRateNumRef); - bitRateNumRef = NULL; - + // Validate that the video encoder properties are valid. + CFDictionaryRef supportedProperties; + status = VTSessionCopySupportedPropertyDictionary(self.compressionSession, &supportedProperties); if (status != noErr) { - // TODO: Log & End session - if (*error != nil) { + if (*error == nil) { *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus" : @(status) }]; } - + return NO; } - - // Set the profile level of the video stream - status = VTSessionSetProperty(self.compressionSession, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_Baseline_AutoLevel); - if (status != noErr) { - if (*error != nil) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus" : @(status) }]; - } - - return NO; - } - - // Set the session to compress in real time - status = VTSessionSetProperty(self.compressionSession, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue); - if (status != noErr) { - if (*error != nil) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus" : @(status) }]; - } - - return NO; - } - - // Set the key-frame interval - // TODO: This may be unnecessary, can the encoder do a better job than us? - int interval = 50; - CFNumberRef intervalNumRef = CFNumberCreate(NULL, kCFNumberSInt32Type, &interval); - if (intervalNumRef == NULL) { - if (*error != nil) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationAllocationFailure userInfo:nil]; + + for (NSString* key in self.videoEncoderSettings.allKeys) { + if (CFDictionaryContainsKey(supportedProperties, (__bridge CFStringRef)key) == false) { + if (*error == nil) { + NSString* description = [NSString stringWithFormat:@"\"%@\" is not a supported key.", key]; + *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{NSLocalizedDescriptionKey : description}]; + } + CFRelease(supportedProperties); + return NO; } - - return NO; } - - status = VTSessionSetProperty(self.compressionSession, kVTCompressionPropertyKey_MaxKeyFrameInterval, intervalNumRef); - - CFRelease(intervalNumRef); - intervalNumRef = NULL; - - if (status != noErr) { - if (*error != nil) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus" : @(status) }]; + CFRelease(supportedProperties); + + // Populate the video encoder settings from provided dictionary. + for (NSString* key in self.videoEncoderSettings.allKeys) { + id value = self.videoEncoderSettings[key]; + + status = VTSessionSetProperty(self.compressionSession, (__bridge CFStringRef)key, (__bridge CFTypeRef)value); + if (status != noErr) { + if (*error == nil) { + *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus" : @(status) }]; + } + + return NO; } - - return NO; } return YES; From abfb28d91fe1f24afacee711d21fb1c6a59ad3d6 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 25 May 2016 18:32:41 -0700 Subject: [PATCH 02/11] Updated SDLStreamingManager's vide encoder to use optimal settings. --- .../SmartDeviceLink/SDLStreamingMediaManager.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m index 74a9f634d..3604cb84e 100644 --- a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.m @@ -142,10 +142,8 @@ - (NSDictionary*)defaultVideoEncoderSettings { static NSDictionary* defaultVideoEncoderSettings = nil; if (defaultVideoEncoderSettings == nil) { defaultVideoEncoderSettings = @{ - (__bridge NSString*)kVTCompressionPropertyKey_AverageBitRate : @(5000 * 1024), (__bridge NSString*)kVTCompressionPropertyKey_ProfileLevel : (__bridge NSString*)kVTProfileLevel_H264_Baseline_AutoLevel, - (__bridge NSString*)kVTCompressionPropertyKey_RealTime : @(YES), - (__bridge NSString*)kVTCompressionPropertyKey_MaxKeyFrameInterval : @(50) + (__bridge NSString*)kVTCompressionPropertyKey_RealTime : @(YES) }; } return defaultVideoEncoderSettings; From 845664de3b885820f58cb4e1a2cf0d0177e150d3 Mon Sep 17 00:00:00 2001 From: Joel Fischer Date: Fri, 27 May 2016 13:55:54 -0400 Subject: [PATCH 03/11] SDLStreamingMediaManager deprecate and fix enum name --- .../SmartDeviceLink/SDLStreamingMediaManager.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h index 05a855e13..de36519a3 100644 --- a/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink-iOS/SmartDeviceLink/SDLStreamingMediaManager.h @@ -17,11 +17,12 @@ NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSInteger, SDLStreamingVideoError) { - SDLStreamingVideoErrorHeadUnitNACK, - SDLSTreamingVideoErrorInvalidOperatingSystemVersion, - SDLStreamingVideoErrorConfigurationCompressionSessionCreationFailure, - SDLStreamingVideoErrorConfigurationAllocationFailure, - SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure + SDLStreamingVideoErrorHeadUnitNACK = 0, + SDLSTreamingVideoErrorInvalidOperatingSystemVersion __deprecated_enum_msg("Use SDLStreamingVideoErrorInvalidOperatingSystemVersion instead") = 1, + SDLStreamingVideoErrorInvalidOperatingSystemVersion = 1, + SDLStreamingVideoErrorConfigurationCompressionSessionCreationFailure = 2, + SDLStreamingVideoErrorConfigurationAllocationFailure = 3, + SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure = 4 }; typedef NS_ENUM(NSInteger, SDLStreamingAudioError) { From f3eb4248f799b396e4bffbe16fc724db968c9c81 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 27 Jul 2016 14:47:00 -0700 Subject: [PATCH 04/11] Removed surrounding parenthesis on NSNumber-wrapped boolean. --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 3604cb84e..665917745 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -143,7 +143,7 @@ - (NSDictionary*)defaultVideoEncoderSettings { if (defaultVideoEncoderSettings == nil) { defaultVideoEncoderSettings = @{ (__bridge NSString*)kVTCompressionPropertyKey_ProfileLevel : (__bridge NSString*)kVTProfileLevel_H264_Baseline_AutoLevel, - (__bridge NSString*)kVTCompressionPropertyKey_RealTime : @(YES) + (__bridge NSString*)kVTCompressionPropertyKey_RealTime : @YES }; } return defaultVideoEncoderSettings; From 4694398cef6114fd7f38df98ed2b1c870423013e Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 27 Jul 2016 14:47:32 -0700 Subject: [PATCH 05/11] Changed videoEncoderSettings to be null_resettable instead of nullable, because that is essentially what we are doing. --- SmartDeviceLink/SDLStreamingMediaManager.h | 2 +- SmartDeviceLink/SDLStreamingMediaManager.m | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 2e3a6dbb1..344ac52f0 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -87,7 +87,7 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); * * @warning Video streaming must not be connected to update the encoder properties. If it is running, issue a stopVideoSession before updating. */ -@property (strong, nonatomic, nullable) NSDictionary* videoEncoderSettings; +@property (strong, nonatomic, null_resettable) NSDictionary* videoEncoderSettings; @property (assign, nonatomic, readonly) BOOL videoSessionConnected; @property (assign, nonatomic, readonly) BOOL audioSessionConnected; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 665917745..ec07f369b 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -39,6 +39,8 @@ @interface SDLStreamingMediaManager () @implementation SDLStreamingMediaManager +@synthesize videoEncoderSettings = _videoEncoderSettings; + #pragma mark - Class Lifecycle - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol { @@ -129,13 +131,24 @@ - (BOOL)sendAudioData:(NSData *)pcmAudioData { #pragma mark - Update video encoder -- (void)setVideoEncoderSettings:( NSDictionary * _Nullable)videoEncoderSettings { +- (void)setVideoEncoderSettings:(NSDictionary * _Nullable)videoEncoderSettings { if (self.videoSessionConnected) { @throw [NSException exceptionWithName:SDLErrorDomainStreamingMediaVideo reason:@"Cannot update video encoder settings while video session is connected." userInfo:nil]; return; } - _videoEncoderSettings = videoEncoderSettings; + if (videoEncoderSettings) { + _videoEncoderSettings = videoEncoderSettings; + } else { + _videoEncoderSettings = self.defaultVideoEncoderSettings; + } +} + +- (NSDictionary*)videoEncoderSettings { + if (!_videoEncoderSettings) { + _videoEncoderSettings = self.defaultVideoEncoderSettings; + } + return _videoEncoderSettings; } - (NSDictionary*)defaultVideoEncoderSettings { @@ -257,10 +270,6 @@ - (BOOL)sdl_configureVideoEncoderWithError:(NSError *__autoreleasing *)error { return NO; } - - if (self.videoEncoderSettings == nil) { - self.videoEncoderSettings = self.defaultVideoEncoderSettings; - } // Validate that the video encoder properties are valid. CFDictionaryRef supportedProperties; From 74ae86f50e94fb93a89a66040f4892d02f615b64 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 27 Jul 2016 15:12:02 -0700 Subject: [PATCH 06/11] Added nullable property to streaming media manager for proper cleanup when destructing the proxy. --- SmartDeviceLink/SDLProxy.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index f14985819..b9f172d7f 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -56,7 +56,7 @@ @interface SDLProxy () { } @property (strong, nonatomic) NSMutableSet *mutableProxyListeners; -@property (nonatomic, strong, readwrite) SDLStreamingMediaManager *streamingMediaManager; +@property (nonatomic, strong, readwrite, nullable) SDLStreamingMediaManager *streamingMediaManager; @end @@ -101,6 +101,7 @@ - (void)destructObjects { _transport = nil; _protocol = nil; _mutableProxyListeners = nil; + _streamingMediaManager = nil; } } From 2e929ed5296eca2befc00d3836687cb95871bbea Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Wed, 27 Jul 2016 15:12:34 -0700 Subject: [PATCH 07/11] Added support for retrieving screen dimensions from a successful register app interface for use in the video encoder. --- SmartDeviceLink/SDLProxy.m | 12 +++++++++++- SmartDeviceLink/SDLStreamingMediaManager.h | 19 +++++++++++++++---- SmartDeviceLink/SDLStreamingMediaManager.m | 22 +++++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index b9f172d7f..c8faa4a6d 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -29,7 +29,7 @@ #import "SDLProtocolMessage.h" #import "SDLProtocolMessage.h" #import "SDLPutFile.h" -#import "SDLRPCPayload.h" +#import "SDLRegisterAppInterfaceResponse.h" #import "SDLRPCPayload.h" #import "SDLRPCRequestFactory.h" #import "SDLRPCResponse.h" @@ -57,6 +57,7 @@ @interface SDLProxy () { @property (strong, nonatomic) NSMutableSet *mutableProxyListeners; @property (nonatomic, strong, readwrite, nullable) SDLStreamingMediaManager *streamingMediaManager; +@property (nonatomic, strong, nullable) SDLDisplayCapabilities* displayCapabilities; @end @@ -102,6 +103,7 @@ - (void)destructObjects { _protocol = nil; _mutableProxyListeners = nil; _streamingMediaManager = nil; + _displayCapabilities = nil; } } @@ -167,7 +169,11 @@ - (NSString *)proxyVersion { - (SDLStreamingMediaManager *)streamingMediaManager { if (_streamingMediaManager == nil) { + if (self.displayCapabilities == nil) { + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"SDLStreamingMediaManager must be accessed only after a successful RegisterAppInterfaceResponse" userInfo:nil]; + } _streamingMediaManager = [[SDLStreamingMediaManager alloc] initWithProtocol:self.protocol]; + _streamingMediaManager.displayCapabilities = self.displayCapabilities; [self.protocol.protocolDelegateTable addObject:_streamingMediaManager]; } @@ -329,6 +335,10 @@ - (void)handleRegisterAppInterfaceResponse:(SDLRPCResponse *)response { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMobileHMIState) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMobileHMIState) name:UIApplicationDidEnterBackgroundNotification object:nil]; } + + // Extract the display capabilties to successfully build SDLStreamingMediaManager's video encoder. + SDLRegisterAppInterfaceResponse* registerResponse = (SDLRegisterAppInterfaceResponse*)response; + self.displayCapabilities = registerResponse.displayCapabilities; } - (void)handleSyncPData:(SDLRPCMessage *)message { diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 344ac52f0..1d41fb5d6 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -12,6 +12,7 @@ #import "SDLProtocolListener.h" @class SDLAbstractProtocol; +@class SDLDisplayCapabilities; NS_ASSUME_NONNULL_BEGIN @@ -82,6 +83,9 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); */ - (BOOL)sendAudioData:(NSData *)pcmAudioData; +@property (assign, nonatomic, readonly) BOOL videoSessionConnected; +@property (assign, nonatomic, readonly) BOOL audioSessionConnected; + /** * The settings used in a VTCompressionSessionRef encoder. These will be verified when the video stream is started. Acceptable properties for this are located in VTCompressionProperties. If set to nil, the defaultVideoEncoderSettings will be used. * @@ -89,14 +93,21 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); */ @property (strong, nonatomic, null_resettable) NSDictionary* videoEncoderSettings; -@property (assign, nonatomic, readonly) BOOL videoSessionConnected; -@property (assign, nonatomic, readonly) BOOL audioSessionConnected; - /** - * Provides default video encoder settings used. + * Provides default video encoder settings used. */ @property (strong, nonatomic, readonly) NSDictionary* defaultVideoEncoderSettings; +/** + * The capabilities of the display that is currently connected to. + * + */ +@property (strong, nonatomic) SDLDisplayCapabilities* displayCapabilities; + +/** + * This is the current screen size of a connected display. This will be the size the video encoder uses to encode the raw image data. + */ +@property (assign, nonatomic, readonly) CGSize screenSize; @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index ec07f369b..3580e1d07 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -11,8 +11,10 @@ @import UIKit; #import "SDLAbstractProtocol.h" +#import "SDLDisplayCapabilities.h" #import "SDLGlobals.h" - +#import "SDLImageResolution.h" +#import "SDLScreenParams.h" NSString *const SDLErrorDomainStreamingMediaVideo = @"com.sdl.streamingmediamanager.video"; NSString *const SDLErrorDomainStreamingMediaAudio = @"com.sdl.streamingmediamanager.audio"; @@ -58,6 +60,8 @@ - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol { _videoStartBlock = nil; _audioStartBlock = nil; + + _screenSize = CGSizeMake(640, 480); return self; } @@ -162,6 +166,19 @@ - (NSDictionary*)defaultVideoEncoderSettings { return defaultVideoEncoderSettings; } +- (void)setDisplayCapabilities:(SDLDisplayCapabilities *)displayCapabilities { + _displayCapabilities = displayCapabilities; + + SDLImageResolution* resolution = displayCapabilities.screenParams.resolution; + if (resolution != nil) { + _screenSize = CGSizeMake(resolution.resolutionWidth.floatValue, + resolution.resolutionHeight.floatValue); + } else { + NSLog(@"Could not retrieve screen size. Defaulting to 640 x 480."); + _screenSize = CGSizeMake(640, + 480); + } +} #pragma mark - SDLProtocolListener Methods @@ -259,8 +276,7 @@ - (BOOL)sdl_configureVideoEncoderWithError:(NSError *__autoreleasing *)error { OSStatus status; // Create a compression session - // TODO (Joel F.)[2015-08-18]: Dimensions should be from the Head Unit - status = VTCompressionSessionCreate(NULL, 640, 480, kCMVideoCodecType_H264, NULL, NULL, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); + status = VTCompressionSessionCreate(NULL, self.screenSize.width, self.screenSize.height, kCMVideoCodecType_H264, NULL, NULL, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); if (status != noErr) { // TODO: Log the error From 1c82de4333ee3d7967403ff3859eeed1d908ea7e Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Thu, 28 Jul 2016 10:46:40 -0700 Subject: [PATCH 08/11] Updated SDLStreamingMediaManager's init function to include display capabilities. --- SmartDeviceLink/SDLProxy.m | 3 +-- SmartDeviceLink/SDLStreamingMediaManager.h | 4 +++- SmartDeviceLink/SDLStreamingMediaManager.m | 24 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index c8faa4a6d..53b373ddf 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -172,8 +172,7 @@ - (SDLStreamingMediaManager *)streamingMediaManager { if (self.displayCapabilities == nil) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"SDLStreamingMediaManager must be accessed only after a successful RegisterAppInterfaceResponse" userInfo:nil]; } - _streamingMediaManager = [[SDLStreamingMediaManager alloc] initWithProtocol:self.protocol]; - _streamingMediaManager.displayCapabilities = self.displayCapabilities; + _streamingMediaManager = [[SDLStreamingMediaManager alloc] initWithProtocol:self.protocol displayCapabilities:self.displayCapabilities]; [self.protocol.protocolDelegateTable addObject:_streamingMediaManager]; } diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 1d41fb5d6..1e6975ec5 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -37,7 +37,9 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); @interface SDLStreamingMediaManager : NSObject -- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol; +- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol __deprecated_msg(("Please use initWithProtocol:displayCapabilities: instead")); + +- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities*)displayCapabilities; /** * This method will attempt to start a streaming video session. It will set up iOS's video encoder, and call out to the head unit asking if it will start a video session. diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 3580e1d07..e48297f65 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -45,6 +45,30 @@ @implementation SDLStreamingMediaManager #pragma mark - Class Lifecycle +- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities*)displayCapabilities { + self = [super init]; + if (!self) { + return nil; + } + + _compressionSession = NULL; + + _currentFrameNumber = 0; + _videoSessionConnected = NO; + _audioSessionConnected = NO; + _protocol = protocol; + + _videoStartBlock = nil; + _audioStartBlock = nil; + + _screenSize = CGSizeMake(640, 480); + + self.displayCapabilities = displayCapabilities; + + return self; + +} + - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol { self = [super init]; if (!self) { From 6bb971b7cde58c15270369e0aabccad87342b1f3 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Thu, 28 Jul 2016 10:48:53 -0700 Subject: [PATCH 09/11] Consolidated inits with a base init that both the deprecated and new init use. --- SmartDeviceLink/SDLStreamingMediaManager.m | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index e48297f65..3eb47163b 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -46,23 +46,13 @@ @implementation SDLStreamingMediaManager #pragma mark - Class Lifecycle - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities*)displayCapabilities { - self = [super init]; + self = [self init]; if (!self) { return nil; } - _compressionSession = NULL; - - _currentFrameNumber = 0; - _videoSessionConnected = NO; - _audioSessionConnected = NO; _protocol = protocol; - - _videoStartBlock = nil; - _audioStartBlock = nil; - - _screenSize = CGSizeMake(640, 480); - + self.displayCapabilities = displayCapabilities; return self; @@ -70,18 +60,28 @@ - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabili } - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol { - self = [super init]; + self = [self init]; if (!self) { return nil; } - _compressionSession = NULL; + _protocol = protocol; + + return self; +} +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + _compressionSession = NULL; + _currentFrameNumber = 0; _videoSessionConnected = NO; _audioSessionConnected = NO; - _protocol = protocol; - + _videoStartBlock = nil; _audioStartBlock = nil; From 1ac0a6be800449fd7eb301935bd6dd1c6922d663 Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Thu, 28 Jul 2016 10:55:28 -0700 Subject: [PATCH 10/11] Removed synthesize of videoEncoderSettings. --- SmartDeviceLink/SDLStreamingMediaManager.m | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 3eb47163b..995f53526 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -41,8 +41,6 @@ @interface SDLStreamingMediaManager () @implementation SDLStreamingMediaManager -@synthesize videoEncoderSettings = _videoEncoderSettings; - #pragma mark - Class Lifecycle - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities*)displayCapabilities { @@ -86,6 +84,8 @@ - (instancetype)init { _audioStartBlock = nil; _screenSize = CGSizeMake(640, 480); + + _videoEncoderSettings = self.defaultVideoEncoderSettings; return self; } @@ -172,13 +172,6 @@ - (void)setVideoEncoderSettings:(NSDictionary * _Nullable)videoEncoderSettings { } } -- (NSDictionary*)videoEncoderSettings { - if (!_videoEncoderSettings) { - _videoEncoderSettings = self.defaultVideoEncoderSettings; - } - return _videoEncoderSettings; -} - - (NSDictionary*)defaultVideoEncoderSettings { static NSDictionary* defaultVideoEncoderSettings = nil; if (defaultVideoEncoderSettings == nil) { From 5f7b6c3adbc2980b738f2b4362821a247c48583a Mon Sep 17 00:00:00 2001 From: "Muller, Alexander (A.)" Date: Thu, 28 Jul 2016 11:00:38 -0700 Subject: [PATCH 11/11] Removed external displayCapabilities property. --- SmartDeviceLink/SDLStreamingMediaManager.h | 6 ------ SmartDeviceLink/SDLStreamingMediaManager.m | 24 ++++++++-------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 1e6975ec5..8f9d67e99 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -100,12 +100,6 @@ typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); */ @property (strong, nonatomic, readonly) NSDictionary* defaultVideoEncoderSettings; -/** - * The capabilities of the display that is currently connected to. - * - */ -@property (strong, nonatomic) SDLDisplayCapabilities* displayCapabilities; - /** * This is the current screen size of a connected display. This will be the size the video encoder uses to encode the raw image data. */ diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 995f53526..7318a7d05 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -51,7 +51,15 @@ - (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabili _protocol = protocol; - self.displayCapabilities = displayCapabilities; + SDLImageResolution* resolution = displayCapabilities.screenParams.resolution; + if (resolution != nil) { + _screenSize = CGSizeMake(resolution.resolutionWidth.floatValue, + resolution.resolutionHeight.floatValue); + } else { + NSLog(@"Could not retrieve screen size. Defaulting to 640 x 480."); + _screenSize = CGSizeMake(640, + 480); + } return self; @@ -183,20 +191,6 @@ - (NSDictionary*)defaultVideoEncoderSettings { return defaultVideoEncoderSettings; } -- (void)setDisplayCapabilities:(SDLDisplayCapabilities *)displayCapabilities { - _displayCapabilities = displayCapabilities; - - SDLImageResolution* resolution = displayCapabilities.screenParams.resolution; - if (resolution != nil) { - _screenSize = CGSizeMake(resolution.resolutionWidth.floatValue, - resolution.resolutionHeight.floatValue); - } else { - NSLog(@"Could not retrieve screen size. Defaulting to 640 x 480."); - _screenSize = CGSizeMake(640, - 480); - } -} - #pragma mark - SDLProtocolListener Methods - (void)handleProtocolStartSessionACK:(SDLServiceType)serviceType sessionID:(Byte)sessionID version:(Byte)version {