summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2018-06-19 13:41:35 -0400
committerJoel Fischer <joeljfischer@gmail.com>2018-06-19 13:41:35 -0400
commitb108fcac30765aacfcc8fbeb450be104432a6420 (patch)
treebd0feecec120959f165a2230cfe693f5bf53509e
parent3ba2b1bf041ebc17e86f4a6c152a2a67626b4232 (diff)
downloadsdl_ios-b108fcac30765aacfcc8fbeb450be104432a6420.tar.gz
Separate video / audio streaming lifecycle manager code
-rw-r--r--SmartDeviceLink-iOS.podspec1
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj26
-rw-r--r--SmartDeviceLink.podspec1
-rwxr-xr-xSmartDeviceLink/SDLCarWindow.h4
-rwxr-xr-xSmartDeviceLink/SDLCarWindow.m6
-rw-r--r--SmartDeviceLink/SDLStreamingAudioLifecycleManager.h94
-rw-r--r--SmartDeviceLink/SDLStreamingAudioLifecycleManager.m345
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManager.m56
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManagerConstants.h17
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManagerConstants.m14
-rw-r--r--SmartDeviceLink/SDLStreamingVideoLifecycleManager.h (renamed from SmartDeviceLink/SDLStreamingMediaLifecycleManager.h)69
-rw-r--r--SmartDeviceLink/SDLStreamingVideoLifecycleManager.m (renamed from SmartDeviceLink/SDLStreamingMediaLifecycleManager.m)225
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h1
13 files changed, 570 insertions, 289 deletions
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index bb6c44e3e..4bc15a3de 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -327,6 +327,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLVideoStreamingCodec.h',
'SmartDeviceLink/SDLVideoStreamingFormat.h',
'SmartDeviceLink/SDLVideoStreamingProtocol.h',
+'SmartDeviceLink/SDLVideoStreamingState.h',
'SmartDeviceLink/SDLVoiceCommand.h',
'SmartDeviceLink/SDLVrCapabilities.h',
'SmartDeviceLink/SDLVrHelpItem.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 391f4e1f2..8464876ab 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -333,8 +333,12 @@
5D0A9F971F1559EC00CC80DD /* SDLSystemCapabilitySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A9F961F1559EC00CC80DD /* SDLSystemCapabilitySpec.m */; };
5D0A9F9A1F15636800CC80DD /* SDLGetSystemCapabilitiesSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A9F991F15636800CC80DD /* SDLGetSystemCapabilitiesSpec.m */; };
5D0A9F9C1F1565EB00CC80DD /* SDLGetSystemCapabilityResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A9F9B1F1565EB00CC80DD /* SDLGetSystemCapabilityResponseSpec.m */; };
- 5D0C29FC20D93D8C008B56CD /* SDLVideoStreamingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D0C29FA20D93D8C008B56CD /* SDLVideoStreamingState.h */; };
+ 5D0C29FC20D93D8C008B56CD /* SDLVideoStreamingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D0C29FA20D93D8C008B56CD /* SDLVideoStreamingState.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D0C29FD20D93D8C008B56CD /* SDLVideoStreamingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0C29FB20D93D8C008B56CD /* SDLVideoStreamingState.m */; };
+ 5D0C2A0020D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D0C29FE20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h */; };
+ 5D0C2A0120D9479B008B56CD /* SDLStreamingVideoLifecycleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0C29FF20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.m */; };
+ 5D0C2A0420D947AB008B56CD /* SDLStreamingAudioLifecycleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D0C2A0220D947AB008B56CD /* SDLStreamingAudioLifecycleManager.h */; };
+ 5D0C2A0520D947AB008B56CD /* SDLStreamingAudioLifecycleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D0C2A0320D947AB008B56CD /* SDLStreamingAudioLifecycleManager.m */; };
5D1654561D3E754F00554D93 /* SDLLifecycleManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1654551D3E754F00554D93 /* SDLLifecycleManagerSpec.m */; };
5D16545A1D3E7A1600554D93 /* SDLLifecycleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D1654581D3E7A1600554D93 /* SDLLifecycleManager.h */; };
5D16545B1D3E7A1600554D93 /* SDLLifecycleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1654591D3E7A1600554D93 /* SDLLifecycleManager.m */; };
@@ -1145,8 +1149,6 @@
DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4F47951E771AA100FC809E /* SDLEnum.m */; };
DA6223BD1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6223BB1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h */; };
DA6223BE1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6223BC1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m */; };
- DA8966EB1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */; };
- DA8966EC1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */; };
DA8966EF1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */; };
DA8966F21E56973700413EAB /* SDLStreamingMediaManagerConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8966F11E56973700413EAB /* SDLStreamingMediaManagerConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA96C0661D4D4F730022F520 /* SDLAppInfoSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA96C0651D4D4F730022F520 /* SDLAppInfoSpec.m */; };
@@ -1641,6 +1643,10 @@
5D0A9F9B1F1565EB00CC80DD /* SDLGetSystemCapabilityResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLGetSystemCapabilityResponseSpec.m; sourceTree = "<group>"; };
5D0C29FA20D93D8C008B56CD /* SDLVideoStreamingState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingState.h; sourceTree = "<group>"; };
5D0C29FB20D93D8C008B56CD /* SDLVideoStreamingState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingState.m; sourceTree = "<group>"; };
+ 5D0C29FE20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLStreamingVideoLifecycleManager.h; sourceTree = "<group>"; };
+ 5D0C29FF20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingVideoLifecycleManager.m; sourceTree = "<group>"; };
+ 5D0C2A0220D947AB008B56CD /* SDLStreamingAudioLifecycleManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLStreamingAudioLifecycleManager.h; sourceTree = "<group>"; };
+ 5D0C2A0320D947AB008B56CD /* SDLStreamingAudioLifecycleManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingAudioLifecycleManager.m; sourceTree = "<group>"; };
5D1654551D3E754F00554D93 /* SDLLifecycleManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLLifecycleManagerSpec.m; path = DevAPISpecs/SDLLifecycleManagerSpec.m; sourceTree = "<group>"; };
5D1654581D3E7A1600554D93 /* SDLLifecycleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLifecycleManager.h; sourceTree = "<group>"; };
5D1654591D3E7A1600554D93 /* SDLLifecycleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLifecycleManager.m; sourceTree = "<group>"; };
@@ -2491,8 +2497,6 @@
DA6223BB1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CVPixelBufferRef+SDLUtil.h"; sourceTree = "<group>"; };
DA6223BC1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CVPixelBufferRef+SDLUtil.m"; sourceTree = "<group>"; };
DA661E2B1E553E7E001C1345 /* SDLStreamingMediaManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaManagerSpec.m; sourceTree = "<group>"; };
- DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaLifecycleManager.h; sourceTree = "<group>"; };
- DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaLifecycleManager.m; sourceTree = "<group>"; };
DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaLifecycleManagerSpec.m; sourceTree = "<group>"; };
DA8966F11E56973700413EAB /* SDLStreamingMediaManagerConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaManagerConstants.h; sourceTree = "<group>"; };
DA8966F31E56977C00413EAB /* SDLStreamingMediaManagerConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaManagerConstants.m; sourceTree = "<group>"; };
@@ -5023,8 +5027,10 @@
DA8966E81E56938C00413EAB /* Lifecycle */ = {
isa = PBXGroup;
children = (
- DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */,
- DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */,
+ 5D0C2A0220D947AB008B56CD /* SDLStreamingAudioLifecycleManager.h */,
+ 5D0C2A0320D947AB008B56CD /* SDLStreamingAudioLifecycleManager.m */,
+ 5D0C29FE20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h */,
+ 5D0C29FF20D9479B008B56CD /* SDLStreamingVideoLifecycleManager.m */,
);
name = Lifecycle;
sourceTree = "<group>";
@@ -5283,6 +5289,7 @@
5D61FDE91A84238C00846EE7 /* SDLUnsubscribeButtonResponse.h in Headers */,
5D61FCD51A84238C00846EE7 /* SDLImageType.h in Headers */,
5D61FC2F1A84238C00846EE7 /* SDLAddCommandResponse.h in Headers */,
+ 5D0C2A0020D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h in Headers */,
5D61FD631A84238C00846EE7 /* SDLResetGlobalProperties.h in Headers */,
5D61FDD71A84238C00846EE7 /* SDLTouchType.h in Headers */,
5D61FDD31A84238C00846EE7 /* SDLTouchEvent.h in Headers */,
@@ -5372,6 +5379,7 @@
5D61FDB91A84238C00846EE7 /* SDLSyncPDataResponse.h in Headers */,
DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */,
5D61FC311A84238C00846EE7 /* SDLAddSubMenu.h in Headers */,
+ 5D0C2A0420D947AB008B56CD /* SDLStreamingAudioLifecycleManager.h in Headers */,
5D61FD171A84238C00846EE7 /* SDLOnPermissionsChange.h in Headers */,
5D4631081F21261A0092EFDC /* SDLControlFramePayloadRPCStartServiceAck.h in Headers */,
5D61FDD51A84238C00846EE7 /* SDLTouchEventCapabilities.h in Headers */,
@@ -5450,7 +5458,6 @@
5D61FD5B1A84238C00846EE7 /* SDLReadDIDResponse.h in Headers */,
5D61FDEF1A84238C00846EE7 /* SDLUpdateMode.h in Headers */,
EED5CA001F4D18DC00F04000 /* SDLRAWH264Packetizer.h in Headers */,
- DA8966EB1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h in Headers */,
5D293AFE1FE078A9000CBD7E /* SDLCarWindowViewController.h in Headers */,
5D61FDDB1A84238C00846EE7 /* SDLTriggerSource.h in Headers */,
5D61FD8F1A84238C00846EE7 /* SDLShow.h in Headers */,
@@ -5776,6 +5783,7 @@
1E4920B31F6A6463008F2CC3 /* SDLOnInteriorVehicleData.m in Sources */,
1E4920B21F6A6455008F2CC3 /* SDLGetInteriorVehicleDataResponse.m in Sources */,
1E4920B11F6A6443008F2CC3 /* SDLRadioState.m in Sources */,
+ 5D0C2A0120D9479B008B56CD /* SDLStreamingVideoLifecycleManager.m in Sources */,
5DA8A0EA1E955FE00039C50D /* SDLLogModel.m in Sources */,
5DA8A0E91E955F710039C50D /* SDLStreamingMediaManagerConstants.m in Sources */,
332A914F1CED9CC60043824C /* SDLAppInfo.m in Sources */,
@@ -5803,6 +5811,7 @@
5D61FD1A1A84238C00846EE7 /* SDLOnSyncPData.m in Sources */,
8B7B319F1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.m in Sources */,
5D61FC461A84238C00846EE7 /* SDLAudioPassThruCapabilities.m in Sources */,
+ 5D0C2A0520D947AB008B56CD /* SDLStreamingAudioLifecycleManager.m in Sources */,
5D61FD301A84238C00846EE7 /* SDLPermissionStatus.m in Sources */,
5D61FDEE1A84238C00846EE7 /* SDLUnsubscribeVehicleDataResponse.m in Sources */,
8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */,
@@ -6122,7 +6131,6 @@
5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */,
5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */,
5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */,
- DA8966EC1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m in Sources */,
DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */,
5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */,
5DCD7AF71FCCA8E400A0FC7F /* SDLScreenshotViewController.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index edda2f508..efbc2ae5f 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -327,6 +327,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLVideoStreamingCodec.h',
'SmartDeviceLink/SDLVideoStreamingFormat.h',
'SmartDeviceLink/SDLVideoStreamingProtocol.h',
+'SmartDeviceLink/SDLVideoStreamingState.h',
'SmartDeviceLink/SDLVoiceCommand.h',
'SmartDeviceLink/SDLVrCapabilities.h',
'SmartDeviceLink/SDLVrHelpItem.h',
diff --git a/SmartDeviceLink/SDLCarWindow.h b/SmartDeviceLink/SDLCarWindow.h
index 076f24b23..aaed77b35 100755
--- a/SmartDeviceLink/SDLCarWindow.h
+++ b/SmartDeviceLink/SDLCarWindow.h
@@ -8,7 +8,7 @@
#import <UIKit/UIKit.h>
@class SDLStreamingMediaConfiguration;
-@class SDLStreamingMediaLifecycleManager;
+@class SDLStreamingVideoLifecycleManager;
NS_ASSUME_NONNULL_BEGIN
@@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
@param configuration The streaming media configuration
@return An instance of this class
*/
-- (instancetype)initWithStreamManager:(SDLStreamingMediaLifecycleManager *)streamManager configuration:(SDLStreamingMediaConfiguration *)configuration;
+- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager configuration:(SDLStreamingMediaConfiguration *)configuration;
/**
* View Controller that will be streamed.
diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m
index 448478fce..2d6c6f4b2 100755
--- a/SmartDeviceLink/SDLCarWindow.m
+++ b/SmartDeviceLink/SDLCarWindow.m
@@ -19,14 +19,14 @@
#import "SDLError.h"
#import "SDLStateMachine.h"
#import "SDLStreamingMediaConfiguration.h"
-#import "SDLStreamingMediaLifecycleManager.h"
+#import "SDLStreamingVideoLifecycleManager.h"
#import "SDLStreamingMediaManagerConstants.h"
NS_ASSUME_NONNULL_BEGIN
@interface SDLCarWindow ()
-@property (weak, nonatomic, nullable) SDLStreamingMediaLifecycleManager *streamManager;
+@property (weak, nonatomic, nullable) SDLStreamingVideoLifecycleManager *streamManager;
@property (assign, nonatomic) SDLCarWindowRenderingType renderingType;
@property (assign, nonatomic) BOOL drawsAfterScreenUpdates;
@@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLCarWindow
-- (instancetype)initWithStreamManager:(SDLStreamingMediaLifecycleManager *)streamManager configuration:(nonnull SDLStreamingMediaConfiguration *)configuration {
+- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager configuration:(nonnull SDLStreamingMediaConfiguration *)configuration {
self = [super init];
if (!self) { return nil; }
diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h
new file mode 100644
index 000000000..defc18e17
--- /dev/null
+++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h
@@ -0,0 +1,94 @@
+//
+// SDLStreamingAudioLifecycleManager.h
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 6/19/18.
+// Copyright © 2018 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLHMILevel.h"
+#import "SDLProtocolListener.h"
+#import "SDLStreamingAudioManagerType.h"
+#import "SDLStreamingMediaManagerConstants.h"
+
+@class SDLAudioStreamManager;
+@class SDLProtocol;
+@class SDLStateMachine;
+@class SDLStreamingMediaConfiguration;
+
+@protocol SDLConnectionManagerType;
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLStreamingAudioLifecycleManager : NSObject <SDLProtocolListener, SDLStreamingAudioManagerType>
+
+@property (nonatomic, strong, readonly) SDLAudioStreamManager *audioManager;
+
+@property (strong, nonatomic, readonly) SDLStateMachine *audioStreamStateMachine;
+@property (strong, nonatomic, readonly) SDLAudioStreamState *currentAudioStreamState;
+
+@property (strong, nonatomic, readonly) SDLStateMachine *appStateMachine;
+@property (strong, nonatomic, readonly) SDLAppState *currentAppState;
+
+@property (copy, nonatomic, nullable) SDLHMILevel hmiLevel;
+
+/**
+ * Whether or not the audio session is connected.
+ */
+@property (assign, nonatomic, readonly, getter=isAudioConnected) BOOL audioConnected;
+
+/**
+ * Whether or not the audio session is encrypted. This may be different than the requestedEncryptionType.
+ */
+@property (assign, nonatomic, readonly, getter=isAudioEncrypted) BOOL audioEncrypted;
+
+/**
+ * Whether or not video streaming is supported
+ *
+ * @see SDLRegisterAppInterface SDLDisplayCapabilities
+ */
+@property (assign, nonatomic, readonly, getter=isStreamingSupported) BOOL streamingSupported;
+
+/**
+ * The requested encryption type when a session attempts to connect. This setting applies to both video and audio sessions.
+ *
+ * DEFAULT: SDLStreamingEncryptionFlagAuthenticateAndEncrypt
+ */
+@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ Create a new streaming media manager for navigation and VPM apps with a specified configuration
+
+ @param connectionManager The pass-through for RPCs
+ @param configuration The configuration of this streaming media session
+ @return A new streaming manager
+ */
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager configuration:(SDLStreamingMediaConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
+
+/**
+ * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`.
+ */
+- (void)startWithProtocol:(SDLProtocol *)protocol;
+
+/**
+ * Stop the manager. This method is used internally.
+ */
+- (void)stop;
+
+/**
+ * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback
+ *
+ * @param audioData The data in PCM audio format, to be played
+ *
+ * @return Whether or not the data was successfully sent.
+ */
+- (BOOL)sendAudioData:(NSData *)audioData;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m
new file mode 100644
index 000000000..4cc07967a
--- /dev/null
+++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m
@@ -0,0 +1,345 @@
+//
+// SDLStreamingAudioLifecycleManager.m
+// SmartDeviceLink
+//
+// Created by Joel Fischer on 6/19/18.
+// Copyright © 2018 smartdevicelink. All rights reserved.
+//
+
+#import "SDLStreamingAudioLifecycleManager.h"
+
+#import "SDLAudioStreamManager.h"
+#import "SDLConnectionManagerType.h"
+#import "SDLControlFramePayloadAudioStartServiceAck.h"
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadNak.h"
+#import "SDLDisplayCapabilities.h"
+#import "SDLGlobals.h"
+#import "SDLHMICapabilities.h"
+#import "SDLLogMacros.h"
+#import "SDLOnHMIStatus.h"
+#import "SDLProtocol.h"
+#import "SDLProtocolMessage.h"
+#import "SDLRegisterAppInterfaceResponse.h"
+#import "SDLRPCNotificationNotification.h"
+#import "SDLRPCResponseNotification.h"
+#import "SDLStateMachine.h"
+#import "SDLStreamingMediaConfiguration.h"
+#import "SDLVehicleType.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLStreamingAudioLifecycleManager()
+
+@property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine;
+@property (strong, nonatomic, readwrite) SDLStateMachine *audioStreamStateMachine;
+@property (assign, nonatomic, readonly, getter=isHmiStateAudioStreamCapable) BOOL hmiStateAudioStreamCapable;
+
+@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
+@property (weak, nonatomic) SDLProtocol *protocol;
+
+@property (copy, nonatomic) NSArray<NSString *> *secureMakes;
+@property (copy, nonatomic) NSString *connectedVehicleMake;
+
+@end
+
+@implementation SDLStreamingAudioLifecycleManager
+
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager configuration:(SDLStreamingMediaConfiguration *)configuration {
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+
+ SDLLogV(@"Creating AudioStreamingLifecycleManager");
+
+ _connectionManager = connectionManager;
+
+ _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self];
+
+ _requestedEncryptionType = configuration.maximumDesiredEncryption;
+
+ NSMutableArray<NSString *> *tempMakeArray = [NSMutableArray array];
+ for (Class securityManagerClass in configuration.securityManagers) {
+ [tempMakeArray addObjectsFromArray:[securityManagerClass availableMakes].allObjects];
+ }
+ _secureMakes = [tempMakeArray copy];
+
+ SDLAppState *initialState = SDLAppStateInactive;
+ switch ([[UIApplication sharedApplication] applicationState]) {
+ case UIApplicationStateActive: {
+ initialState = SDLAppStateActive;
+ } break;
+ case UIApplicationStateInactive: // fallthrough
+ case UIApplicationStateBackground: {
+ initialState = SDLAppStateInactive;
+ } break;
+ default: break;
+ }
+
+ _appStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:initialState states:[self.class sdl_appStateTransitionDictionary]];
+ _audioStreamStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLAudioStreamStateStopped states:[self.class sdl_audioStreamingStateTransitionDictionary]];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_didReceiveRegisterAppInterfaceResponse:) name:SDLDidReceiveRegisterAppInterfaceResponse object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiLevelDidChange:) name:SDLDidChangeHMIStatusNotification object:nil];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationDidBecomeActiveNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationWillResignActiveNotification object:nil];
+
+ return self;
+}
+
+- (void)startWithProtocol:(SDLProtocol *)protocol {
+ _protocol = protocol;
+
+ if (![self.protocol.protocolDelegateTable containsObject:self]) {
+ [self.protocol.protocolDelegateTable addObject:self];
+ }
+}
+
+- (void)stop {
+ SDLLogD(@"Stopping manager");
+ [self sdl_stopAudioSession];
+
+ self.hmiLevel = SDLHMILevelNone;
+
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
+}
+
+- (BOOL)sendAudioData:(NSData*)audioData {
+ if (!self.isAudioConnected) {
+ return NO;
+ }
+
+ SDLLogV(@"Sending raw audio data");
+ if (self.isAudioEncrypted) {
+ [self.protocol sendEncryptedRawData:audioData onService:SDLServiceTypeAudio];
+ } else {
+ [self.protocol sendRawData:audioData withServiceType:SDLServiceTypeAudio];
+ }
+ return YES;
+}
+
+#pragma mark Getters
+
+- (BOOL)isAudioConnected {
+ return [self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateReady];
+}
+
+- (SDLAppState *)currentAppState {
+ return self.appStateMachine.currentState;
+}
+
+- (SDLAudioStreamState *)currentAudioStreamState {
+ return self.audioStreamStateMachine.currentState;
+}
+
+#pragma mark - State Machines
+#pragma mark App State
++ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_appStateTransitionDictionary {
+ return @{
+ // Will go from Inactive to Active if coming from a Phone Call.
+ // Will go from Inactive to IsRegainingActive if coming from Background.
+ SDLAppStateInactive : @[SDLAppStateActive],
+ SDLAppStateActive : @[SDLAppStateInactive]
+ };
+}
+
+- (void)sdl_appStateDidUpdate:(NSNotification*)notification {
+ if (notification.name == UIApplicationWillResignActiveNotification) {
+ [self.appStateMachine transitionToState:SDLAppStateInactive];
+ } else if (notification.name == UIApplicationDidBecomeActiveNotification) {
+ [self.appStateMachine transitionToState:SDLAppStateActive];
+ }
+}
+
+- (void)didEnterStateAppInactive {
+ SDLLogD(@"App became inactive");
+ [self sdl_stopAudioSession];
+}
+
+// Per Apple's guidelines: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html
+// We should be waiting to start any OpenGL drawing until UIApplicationDidBecomeActive is called.
+- (void)didEnterStateAppActive {
+ SDLLogD(@"App became active");
+ [self sdl_startAudioSession];
+}
+
+#pragma mark Audio
++ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_audioStreamingStateTransitionDictionary {
+ return @{
+ SDLAudioStreamStateStopped : @[SDLAudioStreamStateStarting],
+ SDLAudioStreamStateStarting : @[SDLAudioStreamStateStopped, SDLAudioStreamStateReady],
+ SDLAudioStreamStateReady : @[SDLAudioStreamStateShuttingDown, SDLAudioStreamStateStopped],
+ SDLAudioStreamStateShuttingDown : @[SDLAudioStreamStateStopped]
+ };
+}
+
+- (void)didEnterStateAudioStreamStopped {
+ SDLLogD(@"Audio stream stopped");
+ _audioEncrypted = NO;
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStopNotification object:nil];
+}
+
+- (void)didEnterStateAudioStreamStarting {
+ SDLLogD(@"Audio stream starting");
+ if ((self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) && ([self.secureMakes containsObject:self.connectedVehicleMake])) {
+ [self.protocol startSecureServiceWithType:SDLServiceTypeAudio payload:nil completionHandler:^(BOOL success, NSError * _Nonnull error) {
+ if (error) {
+ SDLLogE(@"TLS setup error: %@", error);
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
+ }
+ }];
+ } else {
+ [self.protocol startServiceWithType:SDLServiceTypeAudio payload:nil];
+ }
+}
+
+- (void)didEnterStateAudioStreamReady {
+ SDLLogD(@"Audio stream ready");
+ [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStartNotification object:nil];
+}
+
+- (void)didEnterStateAudioStreamShuttingDown {
+ SDLLogD(@"Audio stream shutting down");
+ [self.protocol endServiceWithType:SDLServiceTypeAudio];
+}
+
+#pragma mark - SDLProtocolListener
+#pragma mark Video / Audio Start Service ACK
+
+- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
+ switch (startServiceACK.header.serviceType) {
+ case SDLServiceTypeAudio: {
+ [self sdl_handleAudioStartServiceAck:startServiceACK];
+ } break;
+ default: break;
+ }
+}
+
+- (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAck {
+ SDLLogD(@"Audio service started");
+ _audioEncrypted = audioStartServiceAck.header.encrypted;
+
+ SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:audioStartServiceAck.payload];
+ SDLLogV(@"ACK: %@", audioAckPayload);
+
+ if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) {
+ [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio];
+ }
+
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateReady];
+}
+
+#pragma mark Video / Audio Start Service NAK
+
+- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK {
+ switch (startServiceNAK.header.serviceType) {
+ case SDLServiceTypeAudio: {
+ [self sdl_handleAudioStartServiceNak:startServiceNAK];
+ } break;
+ default: break;
+ }
+}
+
+- (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNak {
+ SDLLogW(@"Audio service failed to start due to NAK");
+ [self sdl_transitionToStoppedState:SDLServiceTypeAudio];
+}
+
+#pragma mark Video / Audio End Service
+
+- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK {
+ SDLLogD(@"%@ service ended", (endServiceACK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio"));
+ [self sdl_transitionToStoppedState:endServiceACK.header.serviceType];
+}
+
+- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK {
+ SDLLogW(@"%@ service ended with end service NAK", (endServiceNAK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio"));
+ [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType];
+}
+
+#pragma mark - SDL RPC Notification callbacks
+
+- (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification *)notification {
+ NSAssert([notification.response isKindOfClass:[SDLRegisterAppInterfaceResponse class]], @"A notification was sent with an unanticipated object");
+ if (![notification.response isKindOfClass:[SDLRegisterAppInterfaceResponse class]]) {
+ return;
+ }
+
+ SDLLogD(@"Received Register App Interface");
+ SDLRegisterAppInterfaceResponse* registerResponse = (SDLRegisterAppInterfaceResponse*)notification.response;
+
+ SDLLogV(@"Determining whether streaming is supported");
+ _streamingSupported = registerResponse.hmiCapabilities.videoStreaming ? registerResponse.hmiCapabilities.videoStreaming.boolValue : registerResponse.displayCapabilities.graphicSupported.boolValue;
+
+ if (!self.isStreamingSupported) {
+ SDLLogE(@"Graphics are not supported on this head unit. We are are assuming screen size is also unavailable and exiting.");
+ return;
+ }
+
+ self.connectedVehicleMake = registerResponse.vehicleType.make;
+}
+
+- (void)sdl_hmiLevelDidChange:(SDLRPCNotificationNotification *)notification {
+ NSAssert([notification.notification isKindOfClass:[SDLOnHMIStatus class]], @"A notification was sent with an unanticipated object");
+ if (![notification.notification isKindOfClass:[SDLOnHMIStatus class]]) {
+ return;
+ }
+
+ SDLOnHMIStatus *hmiStatus = (SDLOnHMIStatus*)notification.notification;
+ SDLLogD(@"HMI level changed from level %@ to level %@", self.hmiLevel, hmiStatus.hmiLevel);
+ self.hmiLevel = hmiStatus.hmiLevel;
+
+ if (self.isHmiStateAudioStreamCapable) {
+ [self sdl_startAudioSession];
+ } else {
+ [self sdl_stopAudioSession];
+ }
+}
+
+#pragma mark - Streaming session helpers
+
+- (void)sdl_startAudioSession {
+ SDLLogV(@"Attempting to start audio session");
+ if (!self.isStreamingSupported) {
+ return;
+ }
+
+ if ([self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateStopped]
+ && self.isHmiStateAudioStreamCapable) {
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStarting];
+ }
+}
+
+- (void)sdl_stopAudioSession {
+ SDLLogV(@"Attempting to stop audio session");
+ if (!self.isStreamingSupported) {
+ return;
+ }
+
+ if (self.isAudioConnected) {
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateShuttingDown];
+ }
+}
+
+- (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType {
+ switch (serviceType) {
+ case SDLServiceTypeAudio:
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
+ break;
+ default: break;
+ }
+}
+
+#pragma mark Setters / Getters
+
+- (BOOL)isHmiStateAudioStreamCapable {
+ return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m
index ade1165e7..0d57cd6bd 100644
--- a/SmartDeviceLink/SDLStreamingMediaManager.m
+++ b/SmartDeviceLink/SDLStreamingMediaManager.m
@@ -12,7 +12,8 @@
#import "SDLConnectionManagerType.h"
#import "SDLStreamingMediaConfiguration.h"
#import "SDLStreamingMediaManagerDataSource.h"
-#import "SDLStreamingMediaLifecycleManager.h"
+#import "SDLStreamingAudioLifecycleManager.h"
+#import "SDLStreamingVideoLifecycleManager.h"
#import "SDLTouchManager.h"
@@ -20,7 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLStreamingMediaManager ()
-@property (strong, nonatomic) SDLStreamingMediaLifecycleManager *lifecycleManager;
+@property (strong, nonatomic) SDLStreamingAudioLifecycleManager *audioLifecycleManager;
+@property (strong, nonatomic) SDLStreamingVideoLifecycleManager *videoLifecycleManager;
@end
@@ -36,101 +38,105 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
- _lifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithConnectionManager:connectionManager configuration:configuration];
+ _audioLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:connectionManager configuration:configuration];
+ _videoLifecycleManager = [[SDLStreamingVideoLifecycleManager alloc] initWithConnectionManager:connectionManager configuration:configuration];
return self;
}
- (void)startWithProtocol:(SDLProtocol *)protocol {
- [self.lifecycleManager startWithProtocol:protocol];
+ [self.audioLifecycleManager startWithProtocol:protocol];
+ [self.videoLifecycleManager startWithProtocol:protocol];
}
- (void)stop {
- [self.lifecycleManager stop];
+ [self.audioLifecycleManager stop];
+ [self.videoLifecycleManager stop];
}
- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer {
- return [self.lifecycleManager sendVideoData:imageBuffer];
+ return [self.videoLifecycleManager sendVideoData:imageBuffer];
}
- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTime)presentationTimestamp {
- return [self.lifecycleManager sendVideoData:imageBuffer presentationTimestamp:presentationTimestamp];
+ return [self.videoLifecycleManager sendVideoData:imageBuffer presentationTimestamp:presentationTimestamp];
}
- (BOOL)sendAudioData:(NSData*)audioData {
- return [self.lifecycleManager sendAudioData:audioData];
+ return [self.audioLifecycleManager sendAudioData:audioData];
}
#pragma mark - Getters
- (SDLTouchManager *)touchManager {
- return self.lifecycleManager.touchManager;
+ return self.videoLifecycleManager.touchManager;
}
- (SDLAudioStreamManager *)audioManager {
- return self.lifecycleManager.audioManager;
+ return self.audioLifecycleManager.audioManager;
}
- (UIViewController *)rootViewController {
- return self.lifecycleManager.rootViewController;
+ return self.videoLifecycleManager.rootViewController;
}
- (nullable id<SDLFocusableItemLocatorType>)focusableItemManager {
- return self.lifecycleManager.focusableItemManager;
+ return self.videoLifecycleManager.focusableItemManager;
}
- (BOOL)isStreamingSupported {
- return self.lifecycleManager.isStreamingSupported;
+ return self.videoLifecycleManager.isStreamingSupported;
}
- (BOOL)isAudioConnected {
- return self.lifecycleManager.isAudioConnected;
+ return self.audioLifecycleManager.isAudioConnected;
}
- (BOOL)isVideoConnected {
- return self.lifecycleManager.isVideoConnected;
+ return self.videoLifecycleManager.isVideoConnected;
}
- (BOOL)isAudioEncrypted {
- return self.lifecycleManager.isAudioEncrypted;
+ return self.audioLifecycleManager.isAudioEncrypted;
}
- (BOOL)isVideoEncrypted {
- return self.lifecycleManager.isVideoEncrypted;
+ return self.videoLifecycleManager.isVideoEncrypted;
}
- (BOOL)isVideoStreamingPaused {
- return self.lifecycleManager.isVideoStreamingPaused;
+ return self.videoLifecycleManager.isVideoStreamingPaused;
}
- (CGSize)screenSize {
- return self.lifecycleManager.screenSize;
+ return self.videoLifecycleManager.screenSize;
}
- (nullable SDLVideoStreamingFormat *)videoFormat {
- return self.lifecycleManager.videoFormat;
+ return self.videoLifecycleManager.videoFormat;
}
- (NSArray<SDLVideoStreamingFormat *> *)supportedFormats {
- return self.lifecycleManager.supportedFormats;
+ return self.videoLifecycleManager.supportedFormats;
}
- (CVPixelBufferPoolRef __nullable)pixelBufferPool {
- return self.lifecycleManager.pixelBufferPool;
+ return self.videoLifecycleManager.pixelBufferPool;
}
- (SDLStreamingEncryptionFlag)requestedEncryptionType {
- return self.lifecycleManager.requestedEncryptionType;
+ return self.videoLifecycleManager.requestedEncryptionType;
}
#pragma mark - Setters
- (void)setRootViewController:(UIViewController *)rootViewController {
- self.lifecycleManager.rootViewController = rootViewController;
+ self.videoLifecycleManager.rootViewController = rootViewController;
}
- (void)setRequestedEncryptionType:(SDLStreamingEncryptionFlag)requestedEncryptionType {
- self.lifecycleManager.requestedEncryptionType = requestedEncryptionType;
+ self.videoLifecycleManager.requestedEncryptionType = requestedEncryptionType;
+ self.audioLifecycleManager.requestedEncryptionType = requestedEncryptionType;
}
@end
diff --git a/SmartDeviceLink/SDLStreamingMediaManagerConstants.h b/SmartDeviceLink/SDLStreamingMediaManagerConstants.h
index acb455ccd..c3e7b52f3 100644
--- a/SmartDeviceLink/SDLStreamingMediaManagerConstants.h
+++ b/SmartDeviceLink/SDLStreamingMediaManagerConstants.h
@@ -37,4 +37,21 @@ extern NSString *const SDLLockScreenManagerDidPresentLockScreenViewController;
extern NSString *const SDLLockScreenManagerWillDismissLockScreenViewController;
extern NSString *const SDLLockScreenManagerDidDismissLockScreenViewController;
+typedef NSString SDLVideoStreamState;
+extern SDLVideoStreamState *const SDLVideoStreamStateStopped;
+extern SDLVideoStreamState *const SDLVideoStreamStateStarting;
+extern SDLVideoStreamState *const SDLVideoStreamStateReady;
+extern SDLVideoStreamState *const SDLVideoStreamStateSuspended;
+extern SDLVideoStreamState *const SDLVideoStreamStateShuttingDown;
+
+typedef NSString SDLAudioStreamState;
+extern SDLAudioStreamState *const SDLAudioStreamStateStopped;
+extern SDLAudioStreamState *const SDLAudioStreamStateStarting;
+extern SDLAudioStreamState *const SDLAudioStreamStateReady;
+extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
+
+typedef NSString SDLAppState;
+extern SDLAppState *const SDLAppStateInactive;
+extern SDLAppState *const SDLAppStateActive;
+
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingMediaManagerConstants.m b/SmartDeviceLink/SDLStreamingMediaManagerConstants.m
index f80107e25..0a6e2a5ee 100644
--- a/SmartDeviceLink/SDLStreamingMediaManagerConstants.m
+++ b/SmartDeviceLink/SDLStreamingMediaManagerConstants.m
@@ -22,3 +22,17 @@ NSString *const SDLLockScreenManagerWillPresentLockScreenViewController = @"com.
NSString *const SDLLockScreenManagerDidPresentLockScreenViewController = @"com.sdl.lockscreen.didPresent";
NSString *const SDLLockScreenManagerWillDismissLockScreenViewController = @"com.sdl.lockscreen.willDismiss";
NSString *const SDLLockScreenManagerDidDismissLockScreenViewController = @"com.sdl.lockscreen.didDismiss";
+
+SDLVideoStreamState *const SDLVideoStreamStateStopped = @"VideoStreamStopped";
+SDLVideoStreamState *const SDLVideoStreamStateStarting = @"VideoStreamStarting";
+SDLVideoStreamState *const SDLVideoStreamStateReady = @"VideoStreamReady";
+SDLVideoStreamState *const SDLVideoStreamStateSuspended = @"VideoStreamSuspended";
+SDLVideoStreamState *const SDLVideoStreamStateShuttingDown = @"VideoStreamShuttingDown";
+
+SDLAudioStreamState *const SDLAudioStreamStateStopped = @"AudioStreamStopped";
+SDLAudioStreamState *const SDLAudioStreamStateStarting = @"AudioStreamStarting";
+SDLAudioStreamState *const SDLAudioStreamStateReady = @"AudioStreamReady";
+SDLAudioStreamState *const SDLAudioStreamStateShuttingDown = @"AudioStreamShuttingDown";
+
+SDLAppState *const SDLAppStateInactive = @"AppInactive";
+SDLAppState *const SDLAppStateActive = @"AppActive";
diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h
index 3fc753585..d0ce607e1 100644
--- a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h
+++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h
@@ -1,74 +1,47 @@
//
-// SDLStreamingMediaLifecycleManager.h
-// SmartDeviceLink-iOS
+// SDLStreamingVideoLifecycleManager.h
+// SmartDeviceLink
//
-// Created by Muller, Alexander (A.) on 2/16/17.
-// Copyright © 2017 smartdevicelink. All rights reserved.
+// Created by Joel Fischer on 6/19/18.
+// Copyright © 2018 smartdevicelink. All rights reserved.
//
-#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
#import <VideoToolbox/VideoToolbox.h>
-#import "SDLConnectionManagerType.h"
#import "SDLHMILevel.h"
#import "SDLProtocolListener.h"
-#import "SDLStreamingAudioManagerType.h"
#import "SDLStreamingMediaManagerConstants.h"
+#import "SDLVideoStreamingFormat.h"
-@class SDLAudioStreamManager;
@class SDLCarWindow;
@class SDLImageResolution;
@class SDLProtocol;
@class SDLStateMachine;
@class SDLStreamingMediaConfiguration;
@class SDLTouchManager;
-@class SDLVideoStreamingFormat;
+@protocol SDLConnectionManagerType;
@protocol SDLFocusableItemLocatorType;
@protocol SDLStreamingMediaManagerDataSource;
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NSString SDLAppState;
-extern SDLAppState *const SDLAppStateInactive;
-extern SDLAppState *const SDLAppStateActive;
-
-typedef NSString SDLVideoStreamState;
-extern SDLVideoStreamState *const SDLVideoStreamStateStopped;
-extern SDLVideoStreamState *const SDLVideoStreamStateStarting;
-extern SDLVideoStreamState *const SDLVideoStreamStateReady;
-extern SDLVideoStreamState *const SDLVideoStreamStateSuspended;
-extern SDLVideoStreamState *const SDLVideoStreamStateShuttingDown;
-typedef NSString SDLAudioStreamState;
-extern SDLAudioStreamState *const SDLAudioStreamStateStopped;
-extern SDLAudioStreamState *const SDLAudioStreamStateStarting;
-extern SDLAudioStreamState *const SDLAudioStreamStateReady;
-extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
+NS_ASSUME_NONNULL_BEGIN
-#pragma mark - Interface
-
-@interface SDLStreamingMediaLifecycleManager : NSObject <SDLProtocolListener, SDLStreamingAudioManagerType>
+@interface SDLStreamingVideoLifecycleManager : NSObject <SDLProtocolListener>
-@property (strong, nonatomic, readonly) SDLStateMachine *appStateMachine;
@property (strong, nonatomic, readonly) SDLStateMachine *videoStreamStateMachine;
-@property (strong, nonatomic, readonly) SDLStateMachine *audioStreamStateMachine;
-
-@property (strong, nonatomic, readonly) SDLAppState *currentAppState;
-@property (strong, nonatomic, readonly) SDLAudioStreamState *currentAudioStreamState;
@property (strong, nonatomic, readonly) SDLVideoStreamState *currentVideoStreamState;
+@property (strong, nonatomic, readonly) SDLStateMachine *appStateMachine;
+@property (strong, nonatomic, readonly) SDLAppState *currentAppState;
@property (copy, nonatomic, nullable) SDLHMILevel hmiLevel;
-@property (assign, nonatomic, readonly, getter=shouldRestartVideoStream) BOOL restartVideoStream __deprecated_msg("This is now unused as the stream doesn't restart anymore. The video stream suspends and resumes if the app changed the state during active video stream");
-
/**
* Touch Manager responsible for providing touch event notifications.
*/
@property (nonatomic, strong, readonly) SDLTouchManager *touchManager;
-
-@property (nonatomic, strong, readonly) SDLAudioStreamManager *audioManager;
@property (nonatomic, strong) UIViewController *rootViewController;
@property (strong, nonatomic, readonly, nullable) SDLCarWindow *carWindow;
@@ -100,16 +73,6 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
@property (assign, nonatomic, readonly, getter=isVideoEncrypted) BOOL videoEncrypted;
/**
- * Whether or not the audio session is connected.
- */
-@property (assign, nonatomic, readonly, getter=isAudioConnected) BOOL audioConnected;
-
-/**
- * Whether or not the audio session is encrypted. This may be different than the requestedEncryptionType.
- */
-@property (assign, nonatomic, readonly, getter=isAudioEncrypted) BOOL audioEncrypted;
-
-/**
* Whether or not the video stream is paused due to either the application being backgrounded, the HMI state being either NONE or BACKGROUND, or the video stream not being ready.
*/
@property (assign, nonatomic, readonly, getter=isVideoStreamingPaused) BOOL videoStreamingPaused;
@@ -204,16 +167,6 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
*/
- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTime)presentationTimestamp;
-/**
- * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback
- *
- * @param audioData The data in PCM audio format, to be played
- *
- * @return Whether or not the data was successfully sent.
- */
-- (BOOL)sendAudioData:(NSData *)audioData;
-
-
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m
index f8e4ebe4f..ac7903407 100644
--- a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
+++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m
@@ -1,31 +1,31 @@
//
-// SDLStreamingMediaLifecycleManager.m
-// SmartDeviceLink-iOS
+// SDLStreamingVideoLifecycleManager.m
+// SmartDeviceLink
//
-// Created by Muller, Alexander (A.) on 2/16/17.
-// Copyright © 2017 smartdevicelink. All rights reserved.
+// Created by Joel Fischer on 6/19/18.
+// Copyright © 2018 smartdevicelink. All rights reserved.
//
-#import "SDLStreamingMediaLifecycleManager.h"
+#import "SDLStreamingVideoLifecycleManager.h"
-#import "SDLAudioStreamManager.h"
+#import "CVPixelBufferRef+SDLUtil.h"
#import "SDLCarWindow.h"
-#import "SDLControlFramePayloadAudioStartServiceAck.h"
+#import "SDLConnectionManagerType.h"
#import "SDLControlFramePayloadConstants.h"
#import "SDLControlFramePayloadNak.h"
#import "SDLControlFramePayloadVideoStartService.h"
#import "SDLControlFramePayloadVideoStartServiceAck.h"
#import "SDLDisplayCapabilities.h"
+#import "SDLFocusableItemLocator.h"
#import "SDLGenericResponse.h"
#import "SDLGetSystemCapability.h"
#import "SDLGetSystemCapabilityResponse.h"
#import "SDLGlobals.h"
-#import "SDLFocusableItemLocator.h"
#import "SDLH264VideoEncoder.h"
#import "SDLHMICapabilities.h"
+#import "SDLHMILevel.h"
#import "SDLImageResolution.h"
#import "SDLLogMacros.h"
-#import "SDLNotificationConstants.h"
#import "SDLOnHMIStatus.h"
#import "SDLProtocol.h"
#import "SDLProtocolMessage.h"
@@ -39,44 +39,26 @@
#import "SDLSystemCapability.h"
#import "SDLTouchManager.h"
#import "SDLVehicleType.h"
+#import "SDLVideoEncoderDelegate.h"
#import "SDLVideoStreamingCapability.h"
-#import "SDLVideoStreamingCodec.h"
-#import "SDLVideoStreamingFormat.h"
-#import "SDLVideoStreamingProtocol.h"
-
-#import "CVPixelBufferRef+SDLUtil.h"
+static NSUInteger const FramesToSendOnBackground = 30;
NS_ASSUME_NONNULL_BEGIN
-SDLAppState *const SDLAppStateInactive = @"AppInactive";
-SDLAppState *const SDLAppStateActive = @"AppActive";
-
-SDLVideoStreamState *const SDLVideoStreamStateStopped = @"VideoStreamStopped";
-SDLVideoStreamState *const SDLVideoStreamStateStarting = @"VideoStreamStarting";
-SDLVideoStreamState *const SDLVideoStreamStateReady = @"VideoStreamReady";
-SDLVideoStreamState *const SDLVideoStreamStateSuspended = @"VideoStreamSuspended";
-SDLVideoStreamState *const SDLVideoStreamStateShuttingDown = @"VideoStreamShuttingDown";
-
-SDLAudioStreamState *const SDLAudioStreamStateStopped = @"AudioStreamStopped";
-SDLAudioStreamState *const SDLAudioStreamStateStarting = @"AudioStreamStarting";
-SDLAudioStreamState *const SDLAudioStreamStateReady = @"AudioStreamReady";
-SDLAudioStreamState *const SDLAudioStreamStateShuttingDown = @"AudioStreamShuttingDown";
-
-static NSUInteger const FramesToSendOnBackground = 30;
-
typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_Nullable capability);
-
-@interface SDLStreamingMediaLifecycleManager () <SDLVideoEncoderDelegate>
+@interface SDLStreamingVideoLifecycleManager() <SDLVideoEncoderDelegate>
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) SDLProtocol *protocol;
@property (assign, nonatomic, readonly, getter=isAppStateVideoStreamCapable) BOOL appStateVideoStreamCapable;
-@property (assign, nonatomic, readonly, getter=isHmiStateAudioStreamCapable) BOOL hmiStateAudioStreamCapable;
@property (assign, nonatomic, readonly, getter=isHmiStateVideoStreamCapable) BOOL hmiStateVideoStreamCapable;
+@property (strong, nonatomic, readwrite) SDLStateMachine *videoStreamStateMachine;
+@property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine;
+
@property (strong, nonatomic, readwrite, nullable) SDLVideoStreamingFormat *videoFormat;
@property (strong, nonatomic, nullable) SDLH264VideoEncoder *videoEncoder;
@@ -84,10 +66,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
@property (copy, nonatomic) NSArray<NSString *> *secureMakes;
@property (copy, nonatomic) NSString *connectedVehicleMake;
-@property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine;
-@property (strong, nonatomic, readwrite) SDLStateMachine *videoStreamStateMachine;
-@property (strong, nonatomic, readwrite) SDLStateMachine *audioStreamStateMachine;
-
@property (assign, nonatomic) CV_NULLABLE CVPixelBufferRef backgroundingPixelBuffer;
@property (strong, nonatomic, nullable) CADisplayLink *displayLink;
@@ -97,11 +75,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
@end
-
-@implementation SDLStreamingMediaLifecycleManager
-
-#pragma mark - Public
-#pragma mark Lifecycle
+@implementation SDLStreamingVideoLifecycleManager
- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager configuration:(SDLStreamingMediaConfiguration *)configuration {
self = [super init];
@@ -127,7 +101,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
}
_touchManager = [[SDLTouchManager alloc] initWithHitTester:(id)_focusableItemManager];
- _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self];
_requestedEncryptionType = configuration.maximumDesiredEncryption;
_dataSource = configuration.dataSource;
@@ -157,7 +130,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
_appStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:initialState states:[self.class sdl_appStateTransitionDictionary]];
_videoStreamStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLVideoStreamStateStopped states:[self.class sdl_videoStreamStateTransitionDictionary]];
- _audioStreamStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLAudioStreamStateStopped states:[self.class sdl_audioStreamingStateTransitionDictionary]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_didReceiveRegisterAppInterfaceResponse:) name:SDLDidReceiveRegisterAppInterfaceResponse object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiLevelDidChange:) name:SDLDidChangeHMIStatusNotification object:nil];
@@ -180,12 +152,10 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
- (void)stop {
SDLLogD(@"Stopping manager");
- [self sdl_stopAudioSession];
[self sdl_stopVideoSession];
self.hmiLevel = SDLHMILevelNone;
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
}
@@ -221,24 +191,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
return [self.videoEncoder encodeFrame:imageBuffer presentationTimestamp:presentationTimestamp];
}
-- (BOOL)sendAudioData:(NSData*)audioData {
- if (!self.isAudioConnected) {
- return NO;
- }
-
- SDLLogV(@"Sending raw audio data");
- if (self.isAudioEncrypted) {
- [self.protocol sendEncryptedRawData:audioData onService:SDLServiceTypeAudio];
- } else {
- [self.protocol sendRawData:audioData withServiceType:SDLServiceTypeAudio];
- }
- return YES;
-}
-
#pragma mark Getters
-- (BOOL)isAudioConnected {
- return [self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateReady];
-}
- (BOOL)isVideoConnected {
return [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady];
@@ -256,10 +209,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
return self.appStateMachine.currentState;
}
-- (SDLAudioStreamState *)currentAudioStreamState {
- return self.audioStreamStateMachine.currentState;
-}
-
- (SDLVideoStreamState *)currentVideoStreamState {
return self.videoStreamStateMachine.currentState;
}
@@ -295,8 +244,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
} else {
[self sdl_stopVideoSession];
}
-
- [self sdl_stopAudioSession];
}
// Per Apple's guidelines: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html
@@ -310,8 +257,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
} else {
[self sdl_startVideoSession];
}
-
- [self sdl_startAudioSession];
}
#pragma mark Video Streaming
@@ -395,7 +340,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
[self.videoEncoder stop];
self.videoEncoder = nil;
}
-
+
if (self.videoEncoder == nil) {
NSError* error = nil;
NSAssert(self.videoFormat != nil, @"No video format is known, but it must be if we got a protocol start service response");
@@ -444,7 +389,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
- (void)didEnterStateVideoStreamSuspended {
SDLLogD(@"Video stream suspended");
-
+
[[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamSuspendedNotification object:nil];
}
@@ -453,55 +398,11 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
[self.protocol endServiceWithType:SDLServiceTypeVideo];
}
-#pragma mark Audio
-+ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_audioStreamingStateTransitionDictionary {
- return @{
- SDLAudioStreamStateStopped : @[SDLAudioStreamStateStarting],
- SDLAudioStreamStateStarting : @[SDLAudioStreamStateStopped, SDLAudioStreamStateReady],
- SDLAudioStreamStateReady : @[SDLAudioStreamStateShuttingDown, SDLAudioStreamStateStopped],
- SDLAudioStreamStateShuttingDown : @[SDLAudioStreamStateStopped]
- };
-}
-
-- (void)didEnterStateAudioStreamStopped {
- SDLLogD(@"Audio stream stopped");
- _audioEncrypted = NO;
-
- [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStopNotification object:nil];
-}
-
-- (void)didEnterStateAudioStreamStarting {
- SDLLogD(@"Audio stream starting");
- if ((self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) && ([self.secureMakes containsObject:self.connectedVehicleMake])) {
- [self.protocol startSecureServiceWithType:SDLServiceTypeAudio payload:nil completionHandler:^(BOOL success, NSError * _Nonnull error) {
- if (error) {
- SDLLogE(@"TLS setup error: %@", error);
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
- }
- }];
- } else {
- [self.protocol startServiceWithType:SDLServiceTypeAudio payload:nil];
- }
-}
-
-- (void)didEnterStateAudioStreamReady {
- SDLLogD(@"Audio stream ready");
- [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStartNotification object:nil];
-}
-
-- (void)didEnterStateAudioStreamShuttingDown {
- SDLLogD(@"Audio stream shutting down");
- [self.protocol endServiceWithType:SDLServiceTypeAudio];
-}
-
#pragma mark - SDLProtocolListener
#pragma mark Video / Audio Start Service ACK
- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
switch (startServiceACK.header.serviceType) {
- case SDLServiceTypeAudio: {
- [self sdl_handleAudioStartServiceAck:startServiceACK];
- } break;
case SDLServiceTypeVideo: {
[self sdl_handleVideoStartServiceAck:startServiceACK];
} break;
@@ -509,20 +410,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
}
}
-- (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAck {
- SDLLogD(@"Audio service started");
- _audioEncrypted = audioStartServiceAck.header.encrypted;
-
- SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:audioStartServiceAck.payload];
- SDLLogV(@"ACK: %@", audioAckPayload);
-
- if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) {
- [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio];
- }
-
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateReady];
-}
-
- (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAck {
SDLLogD(@"Video service started");
_videoEncrypted = videoStartServiceAck.header.encrypted;
@@ -559,9 +446,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK {
switch (startServiceNAK.header.serviceType) {
- case SDLServiceTypeAudio: {
- [self sdl_handleAudioStartServiceNak:startServiceNAK];
- } break;
case SDLServiceTypeVideo: {
[self sdl_handleVideoStartServiceNak:startServiceNAK];
}
@@ -594,11 +478,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
[self sdl_sendVideoStartService];
}
-- (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNak {
- SDLLogW(@"Audio service failed to start due to NAK");
- [self sdl_transitionToStoppedState:SDLServiceTypeAudio];
-}
-
#pragma mark Video / Audio End Service
- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK {
@@ -611,22 +490,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
[self sdl_transitionToStoppedState:endServiceNAK.header.serviceType];
}
-#pragma mark - SDLVideoEncoderDelegate
-
-- (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)encodedVideo {
- SDLLogV(@"Video encoder encoded frame, sending data");
- // Do we care about app state here? I don't think so…
- BOOL capableVideoStreamState = [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady];
-
- if (self.isHmiStateVideoStreamCapable && capableVideoStreamState) {
- if (self.isVideoEncrypted) {
- [self.protocol sendEncryptedRawData:encodedVideo onService:SDLServiceTypeVideo];
- } else {
- [self.protocol sendRawData:encodedVideo withServiceType:SDLServiceTypeVideo];
- }
- }
-}
-
#pragma mark - SDL RPC Notification callbacks
- (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification *)notification {
@@ -674,15 +537,24 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
} else {
[self sdl_stopVideoSession];
}
+}
- if (self.isHmiStateAudioStreamCapable) {
- [self sdl_startAudioSession];
- } else {
- [self sdl_stopAudioSession];
+#pragma mark - SDLVideoEncoderDelegate
+
+- (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)encodedVideo {
+ SDLLogV(@"Video encoder encoded frame, sending data");
+ // Do we care about app state here? I don't think so…
+ BOOL capableVideoStreamState = [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady];
+
+ if (self.isHmiStateVideoStreamCapable && capableVideoStreamState) {
+ if (self.isVideoEncrypted) {
+ [self.protocol sendEncryptedRawData:encodedVideo onService:SDLServiceTypeVideo];
+ } else {
+ [self.protocol sendRawData:encodedVideo withServiceType:SDLServiceTypeVideo];
+ }
}
}
-
#pragma mark - Streaming session helpers
- (void)sdl_startVideoSession {
@@ -708,18 +580,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
}
}
-- (void)sdl_startAudioSession {
- SDLLogV(@"Attempting to start audio session");
- if (!self.isStreamingSupported) {
- return;
- }
-
- if ([self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateStopped]
- && self.isHmiStateAudioStreamCapable) {
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStarting];
- }
-}
-
- (void)sdl_stopVideoSession {
SDLLogV(@"Attempting to stop video session");
if (!self.isStreamingSupported) {
@@ -731,22 +591,8 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
}
}
-- (void)sdl_stopAudioSession {
- SDLLogV(@"Attempting to stop audio session");
- if (!self.isStreamingSupported) {
- return;
- }
-
- if (self.isAudioConnected) {
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateShuttingDown];
- }
-}
-
- (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType {
switch (serviceType) {
- case SDLServiceTypeAudio:
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
- break;
case SDLServiceTypeVideo:
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
break;
@@ -849,7 +695,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
}
}
-
#pragma mark Setters / Getters
- (void)setRootViewController:(UIViewController *)rootViewController {
@@ -866,10 +711,6 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
return [self.appStateMachine isCurrentState:SDLAppStateActive];
}
-- (BOOL)isHmiStateAudioStreamCapable {
- return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull];
-}
-
- (BOOL)isHmiStateVideoStreamCapable {
return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull];
}
@@ -877,7 +718,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
- (NSArray<SDLVideoStreamingFormat *> *)supportedFormats {
SDLVideoStreamingFormat *h264raw = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRAW];
SDLVideoStreamingFormat *h264rtp = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP];
-
+
return @[h264raw, h264rtp];
}
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 6a9fc4da7..8f19b93fa 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -283,6 +283,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLVentilationMode.h"
#import "SDLVideoStreamingCodec.h"
#import "SDLVideoStreamingProtocol.h"
+#import "SDLVideoStreamingState.h"
#import "SDLVrCapabilities.h"
#import "SDLWarningLightStatus.h"
#import "SDLWayPointType.h"