summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2017-09-25 11:45:43 -0400
committerJoel Fischer <joeljfischer@gmail.com>2017-09-25 11:45:43 -0400
commitfb3b6a06f0943cf5e6687d6ea62c698ae11cbdd3 (patch)
treed3436d4c80d15edd5ded88cd329cc91b83631149
parente75038a5009681c8a64595b862889e9630a38dbd (diff)
parent968f628a8313bbab7ae6ca8e6895a57259ca7652 (diff)
downloadsdl_ios-bugfix/issue_679_remove_deprecations.tar.gz
Merge branch 'release/5.0.0' into bugfix/issue_679_remove_deprecationsbugfix/issue_679_remove_deprecations
# Conflicts: # SmartDeviceLink/SDLAbstractProtocol.h # SmartDeviceLink/SDLAbstractProtocol.m # SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj80
-rw-r--r--SmartDeviceLink.podspec1
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartService.h2
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadRPCStartService.m2
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h2
-rw-r--r--SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m2
-rw-r--r--SmartDeviceLink/SDLGlobals.m3
-rw-r--r--SmartDeviceLink/SDLH264VideoEncoder.h (renamed from SmartDeviceLink/SDLVideoEncoder.h)14
-rw-r--r--SmartDeviceLink/SDLH264VideoEncoder.m (renamed from SmartDeviceLink/SDLVideoEncoder.m)42
-rw-r--r--SmartDeviceLink/SDLHMICapabilities.h6
-rw-r--r--SmartDeviceLink/SDLImageResolution.h2
-rw-r--r--SmartDeviceLink/SDLImageResolution.m10
-rw-r--r--SmartDeviceLink/SDLLifecycleConfiguration.m1
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m34
-rw-r--r--SmartDeviceLink/SDLLogFileModuleMap.m2
-rw-r--r--SmartDeviceLink/SDLRAWH264Packetizer.h (renamed from SmartDeviceLink/SDLH264ByteStreamPacketizer.h)5
-rw-r--r--SmartDeviceLink/SDLRAWH264Packetizer.m (renamed from SmartDeviceLink/SDLH264ByteStreamPacketizer.m)9
-rw-r--r--SmartDeviceLink/SDLRPCStruct.m16
-rw-r--r--SmartDeviceLink/SDLStreamingMediaConfiguration.h30
-rw-r--r--SmartDeviceLink/SDLStreamingMediaConfiguration.m29
-rw-r--r--SmartDeviceLink/SDLStreamingMediaLifecycleManager.h67
-rw-r--r--SmartDeviceLink/SDLStreamingMediaLifecycleManager.m380
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManager.h40
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManager.m31
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManagerDataSource.h40
-rw-r--r--SmartDeviceLink/SDLVideoEncoderDelegate.h4
-rw-r--r--SmartDeviceLink/SDLVideoStreamingCapability.h3
-rw-r--r--SmartDeviceLink/SDLVideoStreamingCapability.m6
-rw-r--r--SmartDeviceLink/SDLVideoStreamingFormat.h2
-rw-r--r--SmartDeviceLink/SDLVideoStreamingFormat.m14
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m10
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.h17
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.m30
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m5
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLRAWH264PacketizerSpec.m (renamed from SmartDeviceLinkTests/DevAPISpecs/SDLH264ByteStreamPacketizerSpec.m)8
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m12
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLImageResolutionSpec.m46
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m4
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m6
-rw-r--r--SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m (renamed from SmartDeviceLinkTests/SDLVideoEncoderSpec.m)59
-rw-r--r--SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m689
-rw-r--r--SmartDeviceLink_Example/Classes/ProxyManager.m8
42 files changed, 1295 insertions, 478 deletions
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 69c8851a5..8d6a609d5 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -821,6 +821,7 @@
5D8204311BD001C700D0A41B /* SDLArtwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D82042F1BD001C700D0A41B /* SDLArtwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8204321BD001C700D0A41B /* SDLArtwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8204301BD001C700D0A41B /* SDLArtwork.m */; };
5D850AB01D4907C500E6E7EE /* TestLockScreenAppIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5D850AAF1D4907C500E6E7EE /* TestLockScreenAppIcon.png */; };
+ 5D8A09811F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8A09801F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h */; };
5D8B174F1AC9D266006A6E1C /* SDLDialNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8B174D1AC9D266006A6E1C /* SDLDialNumber.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8B17501AC9D266006A6E1C /* SDLDialNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8B174E1AC9D266006A6E1C /* SDLDialNumber.m */; };
5D8B17531AC9E11B006A6E1C /* SDLDialNumberResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8B17511AC9E11B006A6E1C /* SDLDialNumberResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -889,6 +890,8 @@
5DB1BCDF1D243DD3002FFC37 /* SDLLockScreenConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB1BCDE1D243DD3002FFC37 /* SDLLockScreenConfigurationSpec.m */; };
5DB1BCE11D243DDE002FFC37 /* SDLConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB1BCE01D243DDE002FFC37 /* SDLConfigurationSpec.m */; };
5DB1BCE71D245647002FFC37 /* TestStateMachineTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB1BCE61D245647002FFC37 /* TestStateMachineTarget.m */; };
+ 5DB202271F5F2D030061D189 /* SDLImageResolutionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB202261F5F2D030061D189 /* SDLImageResolutionSpec.m */; };
+ 5DB2022A1F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB202291F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.m */; };
5DB92D241AC47B2C00C15BB0 /* SDLHexUtilitySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB92D231AC47B2C00C15BB0 /* SDLHexUtilitySpec.m */; };
5DB92D2D1AC4A34F00C15BB0 /* SDLPrioritizedObjectCollectionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB92D2C1AC4A34F00C15BB0 /* SDLPrioritizedObjectCollectionSpec.m */; };
5DB92D2F1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB92D2E1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m */; };
@@ -1031,9 +1034,9 @@
DA9F7EB21DCC084300ACAE48 /* SDLDeliveryModeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB11DCC084300ACAE48 /* SDLDeliveryModeSpec.m */; };
DA9F7EB41DCC086400ACAE48 /* SDLDateTimeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB31DCC086400ACAE48 /* SDLDateTimeSpec.m */; };
DA9F7EB61DCC086A00ACAE48 /* SDLOasisAddressSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB51DCC086A00ACAE48 /* SDLOasisAddressSpec.m */; };
- DAA41D551DF66B2000BC7337 /* SDLVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */; };
- DAA41D561DF66B2000BC7337 /* SDLVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */; };
- DABB62171E4A900C0034C567 /* SDLVideoEncoderSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */; };
+ DAA41D551DF66B2000BC7337 /* SDLH264VideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA41D531DF66B2000BC7337 /* SDLH264VideoEncoder.h */; };
+ DAA41D561DF66B2000BC7337 /* SDLH264VideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA41D541DF66B2000BC7337 /* SDLH264VideoEncoder.m */; };
+ DABB62171E4A900C0034C567 /* SDLH264VideoEncoderSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DABB62161E4A900C0034C567 /* SDLH264VideoEncoderSpec.m */; };
DAC572571D1067270004288B /* SDLTouchManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572551D1067270004288B /* SDLTouchManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAC572581D1067270004288B /* SDLTouchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572561D1067270004288B /* SDLTouchManager.m */; };
DAC5725B1D10B81E0004288B /* SDLTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572591D10B81E0004288B /* SDLTouch.m */; };
@@ -1057,9 +1060,9 @@
E9C32B9E1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = E9C32B9A1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h */; };
E9C32B9F1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = E9C32B9B1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m */; };
EED5C9FE1F4D18D100F04000 /* SDLH264Packetizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EED5C9FD1F4D18D100F04000 /* SDLH264Packetizer.h */; };
- EED5CA001F4D18DC00F04000 /* SDLH264ByteStreamPacketizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EED5C9FF1F4D18DC00F04000 /* SDLH264ByteStreamPacketizer.h */; };
- EED5CA021F4D18EC00F04000 /* SDLH264ByteStreamPacketizer.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA011F4D18EC00F04000 /* SDLH264ByteStreamPacketizer.m */; };
- EED5CA041F4D1D5E00F04000 /* SDLH264ByteStreamPacketizerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA031F4D1D5E00F04000 /* SDLH264ByteStreamPacketizerSpec.m */; };
+ EED5CA001F4D18DC00F04000 /* SDLRAWH264Packetizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EED5C9FF1F4D18DC00F04000 /* SDLRAWH264Packetizer.h */; };
+ EED5CA021F4D18EC00F04000 /* SDLRAWH264Packetizer.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA011F4D18EC00F04000 /* SDLRAWH264Packetizer.m */; };
+ EED5CA041F4D1D5E00F04000 /* SDLRAWH264PacketizerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA031F4D1D5E00F04000 /* SDLRAWH264PacketizerSpec.m */; };
EED5CA061F4D1E2300F04000 /* SDLRTPH264Packetizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EED5CA051F4D1E2300F04000 /* SDLRTPH264Packetizer.h */; };
EED5CA081F4D1E2E00F04000 /* SDLRTPH264Packetizer.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA071F4D1E2E00F04000 /* SDLRTPH264Packetizer.m */; };
EED5CA0A1F4D206800F04000 /* SDLRTPH264PacketizerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EED5CA091F4D206800F04000 /* SDLRTPH264PacketizerSpec.m */; };
@@ -1331,7 +1334,6 @@
162E82B41A9BDE8A00906325 /* SDLVehicleDataResultSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVehicleDataResultSpec.m; sourceTree = "<group>"; };
162E82B51A9BDE8A00906325 /* SDLVehicleTypeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVehicleTypeSpec.m; sourceTree = "<group>"; };
162E82B61A9BDE8A00906325 /* SDLVrHelpItemSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVrHelpItemSpec.m; sourceTree = "<group>"; };
- 162E82B81A9BDE8A00906325 /* SDLEnumSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLEnumSpec.m; sourceTree = "<group>"; };
162E82B91A9BDE8A00906325 /* SDLRPCMessageSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCMessageSpec.m; sourceTree = "<group>"; };
162E82BA1A9BDE8A00906325 /* SDLRPCNotificationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCNotificationSpec.m; sourceTree = "<group>"; };
162E82BB1A9BDE8A00906325 /* SDLRPCRequestSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestSpec.m; sourceTree = "<group>"; };
@@ -1969,6 +1971,7 @@
5D82042F1BD001C700D0A41B /* SDLArtwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLArtwork.h; sourceTree = "<group>"; };
5D8204301BD001C700D0A41B /* SDLArtwork.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLArtwork.m; sourceTree = "<group>"; };
5D850AAF1D4907C500E6E7EE /* TestLockScreenAppIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestLockScreenAppIcon.png; sourceTree = "<group>"; };
+ 5D8A09801F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaManagerDataSource.h; sourceTree = "<group>"; };
5D8B174D1AC9D266006A6E1C /* SDLDialNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLDialNumber.h; sourceTree = "<group>"; };
5D8B174E1AC9D266006A6E1C /* SDLDialNumber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDialNumber.m; sourceTree = "<group>"; };
5D8B17511AC9E11B006A6E1C /* SDLDialNumberResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLDialNumberResponse.h; sourceTree = "<group>"; };
@@ -2032,6 +2035,9 @@
5DB1BCE01D243DDE002FFC37 /* SDLConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLConfigurationSpec.m; path = DevAPISpecs/SDLConfigurationSpec.m; sourceTree = "<group>"; };
5DB1BCE51D245647002FFC37 /* TestStateMachineTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestStateMachineTarget.h; path = TestUtilities/TestStateMachineTarget.h; sourceTree = "<group>"; };
5DB1BCE61D245647002FFC37 /* TestStateMachineTarget.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestStateMachineTarget.m; path = TestUtilities/TestStateMachineTarget.m; sourceTree = "<group>"; };
+ 5DB202261F5F2D030061D189 /* SDLImageResolutionSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLImageResolutionSpec.m; sourceTree = "<group>"; };
+ 5DB202281F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLFakeStreamingManagerDataSource.h; path = DevAPISpecs/SDLFakeStreamingManagerDataSource.h; sourceTree = "<group>"; };
+ 5DB202291F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFakeStreamingManagerDataSource.m; path = DevAPISpecs/SDLFakeStreamingManagerDataSource.m; sourceTree = "<group>"; };
5DB92D231AC47B2C00C15BB0 /* SDLHexUtilitySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLHexUtilitySpec.m; path = UtilitiesSpecs/SDLHexUtilitySpec.m; sourceTree = "<group>"; };
5DB92D2C1AC4A34F00C15BB0 /* SDLPrioritizedObjectCollectionSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLPrioritizedObjectCollectionSpec.m; path = "UtilitiesSpecs/Prioritized Objects/SDLPrioritizedObjectCollectionSpec.m"; sourceTree = "<group>"; };
5DB92D2E1AC59F0000C15BB0 /* SDLObjectWithPrioritySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLObjectWithPrioritySpec.m; path = "UtilitiesSpecs/Prioritized Objects/SDLObjectWithPrioritySpec.m"; sourceTree = "<group>"; };
@@ -2182,9 +2188,9 @@
DA9F7EB11DCC084300ACAE48 /* SDLDeliveryModeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDeliveryModeSpec.m; sourceTree = "<group>"; };
DA9F7EB31DCC086400ACAE48 /* SDLDateTimeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDateTimeSpec.m; sourceTree = "<group>"; };
DA9F7EB51DCC086A00ACAE48 /* SDLOasisAddressSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLOasisAddressSpec.m; sourceTree = "<group>"; };
- DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoEncoder.h; sourceTree = "<group>"; };
- DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoEncoder.m; sourceTree = "<group>"; };
- DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoEncoderSpec.m; sourceTree = "<group>"; };
+ DAA41D531DF66B2000BC7337 /* SDLH264VideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLH264VideoEncoder.h; sourceTree = "<group>"; };
+ DAA41D541DF66B2000BC7337 /* SDLH264VideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLH264VideoEncoder.m; sourceTree = "<group>"; };
+ DABB62161E4A900C0034C567 /* SDLH264VideoEncoderSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLH264VideoEncoderSpec.m; sourceTree = "<group>"; };
DAC572551D1067270004288B /* SDLTouchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLTouchManager.h; sourceTree = "<group>"; };
DAC572561D1067270004288B /* SDLTouchManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTouchManager.m; sourceTree = "<group>"; };
DAC572591D10B81E0004288B /* SDLTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTouch.m; sourceTree = "<group>"; };
@@ -2208,9 +2214,9 @@
E9C32B9A1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EAAccessoryManager+SDLProtocols.h"; sourceTree = "<group>"; };
E9C32B9B1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EAAccessoryManager+SDLProtocols.m"; sourceTree = "<group>"; };
EED5C9FD1F4D18D100F04000 /* SDLH264Packetizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLH264Packetizer.h; sourceTree = "<group>"; };
- EED5C9FF1F4D18DC00F04000 /* SDLH264ByteStreamPacketizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLH264ByteStreamPacketizer.h; sourceTree = "<group>"; };
- EED5CA011F4D18EC00F04000 /* SDLH264ByteStreamPacketizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLH264ByteStreamPacketizer.m; sourceTree = "<group>"; };
- EED5CA031F4D1D5E00F04000 /* SDLH264ByteStreamPacketizerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLH264ByteStreamPacketizerSpec.m; path = DevAPISpecs/SDLH264ByteStreamPacketizerSpec.m; sourceTree = "<group>"; };
+ EED5C9FF1F4D18DC00F04000 /* SDLRAWH264Packetizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLRAWH264Packetizer.h; sourceTree = "<group>"; };
+ EED5CA011F4D18EC00F04000 /* SDLRAWH264Packetizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRAWH264Packetizer.m; sourceTree = "<group>"; };
+ EED5CA031F4D1D5E00F04000 /* SDLRAWH264PacketizerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLRAWH264PacketizerSpec.m; path = DevAPISpecs/SDLRAWH264PacketizerSpec.m; sourceTree = "<group>"; };
EED5CA051F4D1E2300F04000 /* SDLRTPH264Packetizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLRTPH264Packetizer.h; sourceTree = "<group>"; };
EED5CA071F4D1E2E00F04000 /* SDLRTPH264Packetizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRTPH264Packetizer.m; sourceTree = "<group>"; };
EED5CA091F4D206800F04000 /* SDLRTPH264PacketizerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLRTPH264PacketizerSpec.m; path = DevAPISpecs/SDLRTPH264PacketizerSpec.m; sourceTree = "<group>"; };
@@ -2514,6 +2520,7 @@
5DE372A31ACB336600849FAA /* SDLHMICapabilitiesSpec.m */,
162E829E1A9BDE8A00906325 /* SDLHMIPermissionsSpec.m */,
162E829F1A9BDE8A00906325 /* SDLImageFieldSpec.m */,
+ 5DB202261F5F2D030061D189 /* SDLImageResolutionSpec.m */,
162E82A01A9BDE8A00906325 /* SDLImageSpec.m */,
162E82A11A9BDE8A00906325 /* SDLKeyboardPropertiesSpec.m */,
DA9F7EAD1DCC063400ACAE48 /* SDLLocationCoordinateSpec.m */,
@@ -2554,7 +2561,6 @@
162E82B71A9BDE8A00906325 /* SuperclassSpecs */ = {
isa = PBXGroup;
children = (
- 162E82B81A9BDE8A00906325 /* SDLEnumSpec.m */,
162E82B91A9BDE8A00906325 /* SDLRPCMessageSpec.m */,
162E82BA1A9BDE8A00906325 /* SDLRPCNotificationSpec.m */,
162E82BB1A9BDE8A00906325 /* SDLRPCRequestSpec.m */,
@@ -2861,7 +2867,7 @@
5D5934EE1A85160900687FB9 /* Protocol */ = {
isa = PBXGroup;
children = (
- 5DA49C8C1F1E549000E65FC5 /* BSON */,
+ 5DA49C8C1F1E549000E65FC5 /* BSON library */,
5D5934FA1A851AC900687FB9 /* @protocols */,
5D5935011A851D7E00687FB9 /* Header */,
5D5935021A851D8700687FB9 /* Message */,
@@ -3893,7 +3899,7 @@
name = Notifications;
sourceTree = "<group>";
};
- 5DA49C8C1F1E549000E65FC5 /* BSON */ = {
+ 5DA49C8C1F1E549000E65FC5 /* BSON library */ = {
isa = PBXGroup;
children = (
5D9FDA891F2A7D3400A495C8 /* bson_array.c */,
@@ -3904,7 +3910,7 @@
5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */,
5DA49CB51F1E64BB00E65FC5 /* emhashmap */,
);
- name = BSON;
+ name = "BSON library";
sourceTree = "<group>";
};
5DA49CB51F1E64BB00E65FC5 /* emhashmap */ = {
@@ -3996,8 +4002,6 @@
5DB92D201AC47AC400C15BB0 /* UtilitiesSpecs */ = {
isa = PBXGroup;
children = (
- DABB62151E4A8FF20034C567 /* Video Encoding */,
- DA1166D71D14601C00438CEA /* Touches */,
5DEE55BE1B8509A5004F0D0F /* HTTP Connection */,
5DB92D2B1AC4A32A00C15BB0 /* Prioritized Objects */,
5DB92D231AC47B2C00C15BB0 /* SDLHexUtilitySpec.m */,
@@ -4096,6 +4100,8 @@
children = (
5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */,
5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */,
+ 5DB202281F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.h */,
+ 5DB202291F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.m */,
);
name = Utilities;
sourceTree = "<group>";
@@ -4209,6 +4215,7 @@
DA8966E81E56938C00413EAB /* Lifecycle */,
5D53C46B1B7A99B9003526EA /* SDLStreamingMediaManager.h */,
5D53C46C1B7A99B9003526EA /* SDLStreamingMediaManager.m */,
+ 5D8A09801F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h */,
);
name = Streaming;
sourceTree = "<group>";
@@ -4225,8 +4232,10 @@
DA8966ED1E5693D100413EAB /* Streaming */ = {
isa = PBXGroup;
children = (
+ DA1166D71D14601C00438CEA /* Touches */,
DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */,
- EED5CA031F4D1D5E00F04000 /* SDLH264ByteStreamPacketizerSpec.m */,
+ DABB62161E4A900C0034C567 /* SDLH264VideoEncoderSpec.m */,
+ EED5CA031F4D1D5E00F04000 /* SDLRAWH264PacketizerSpec.m */,
EED5CA091F4D206800F04000 /* SDLRTPH264PacketizerSpec.m */,
);
name = Streaming;
@@ -4246,26 +4255,18 @@
DAA41D521DF66B1100BC7337 /* Video Encoding */ = {
isa = PBXGroup;
children = (
- DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */,
- DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */,
5DA23FFC1F312DBA009C0313 /* SDLVideoEncoderDelegate.h */,
+ DAA41D531DF66B2000BC7337 /* SDLH264VideoEncoder.h */,
+ DAA41D541DF66B2000BC7337 /* SDLH264VideoEncoder.m */,
EED5C9FD1F4D18D100F04000 /* SDLH264Packetizer.h */,
- EED5C9FF1F4D18DC00F04000 /* SDLH264ByteStreamPacketizer.h */,
- EED5CA011F4D18EC00F04000 /* SDLH264ByteStreamPacketizer.m */,
+ EED5C9FF1F4D18DC00F04000 /* SDLRAWH264Packetizer.h */,
+ EED5CA011F4D18EC00F04000 /* SDLRAWH264Packetizer.m */,
EED5CA051F4D1E2300F04000 /* SDLRTPH264Packetizer.h */,
EED5CA071F4D1E2E00F04000 /* SDLRTPH264Packetizer.m */,
);
name = "Video Encoding";
sourceTree = "<group>";
};
- DABB62151E4A8FF20034C567 /* Video Encoding */ = {
- isa = PBXGroup;
- children = (
- DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */,
- );
- name = "Video Encoding";
- sourceTree = "<group>";
- };
DAC5724C1D0FE3B60004288B /* Touches */ = {
isa = PBXGroup;
children = (
@@ -4349,6 +4350,7 @@
E9C32B941AB20BA200F283AF /* SDLStreamDelegate.h in Headers */,
DA9F7E871DCC049900ACAE48 /* SDLSubscribeWayPoints.h in Headers */,
5D61FDBB1A84238C00846EE7 /* SDLSystemAction.h in Headers */,
+ 5D8A09811F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h in Headers */,
5D61FC9C1A84238C00846EE7 /* SDLEmergencyEventType.h in Headers */,
5D61FD131A84238C00846EE7 /* SDLOnLanguageChange.h in Headers */,
5D61FDE71A84238C00846EE7 /* SDLUnsubscribeButton.h in Headers */,
@@ -4420,7 +4422,7 @@
5D61FDC71A84238C00846EE7 /* SDLTextAlignment.h in Headers */,
5D61FD051A84238C00846EE7 /* SDLOnButtonPress.h in Headers */,
5D61FCC51A84238C00846EE7 /* SDLHMIZoneCapabilities.h in Headers */,
- DAA41D551DF66B2000BC7337 /* SDLVideoEncoder.h in Headers */,
+ DAA41D551DF66B2000BC7337 /* SDLH264VideoEncoder.h in Headers */,
8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */,
5D61FCAF1A84238C00846EE7 /* SDLGenericResponse.h in Headers */,
5D61FC4F1A84238C00846EE7 /* SDLBodyInformation.h in Headers */,
@@ -4618,7 +4620,7 @@
5D61FC5B1A84238C00846EE7 /* SDLChangeRegistration.h in Headers */,
5D61FD5B1A84238C00846EE7 /* SDLReadDIDResponse.h in Headers */,
5D61FDEF1A84238C00846EE7 /* SDLUpdateMode.h in Headers */,
- EED5CA001F4D18DC00F04000 /* SDLH264ByteStreamPacketizer.h in Headers */,
+ EED5CA001F4D18DC00F04000 /* SDLRAWH264Packetizer.h in Headers */,
DA8966EB1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h in Headers */,
5D61FDDB1A84238C00846EE7 /* SDLTriggerSource.h in Headers */,
5D61FD8F1A84238C00846EE7 /* SDLShow.h in Headers */,
@@ -4903,7 +4905,7 @@
5D61FC441A84238C00846EE7 /* SDLAppInterfaceUnregisteredReason.m in Sources */,
5D61FD531A84238C00846EE7 /* SDLProxyFactory.m in Sources */,
5D61FDCA1A84238C00846EE7 /* SDLTextField.m in Sources */,
- DAA41D561DF66B2000BC7337 /* SDLVideoEncoder.m in Sources */,
+ DAA41D561DF66B2000BC7337 /* SDLH264VideoEncoder.m in Sources */,
5D61FC9D1A84238C00846EE7 /* SDLEmergencyEventType.m in Sources */,
5D61FCAC1A84238C00846EE7 /* SDLFuelCutoffStatus.m in Sources */,
5D61FC871A84238C00846EE7 /* SDLDeviceStatus.m in Sources */,
@@ -5131,7 +5133,7 @@
5D61FCA41A84238C00846EE7 /* SDLEndAudioPassThru.m in Sources */,
5D8B17541AC9E11B006A6E1C /* SDLDialNumberResponse.m in Sources */,
DA6223BE1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m in Sources */,
- EED5CA021F4D18EC00F04000 /* SDLH264ByteStreamPacketizer.m in Sources */,
+ EED5CA021F4D18EC00F04000 /* SDLRAWH264Packetizer.m in Sources */,
5D61FC851A84238C00846EE7 /* SDLDeviceLevelStatus.m in Sources */,
5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */,
5D61FD1E1A84238C00846EE7 /* SDLOnTBTClientState.m in Sources */,
@@ -5267,12 +5269,13 @@
88EED83B1F33BECB00E6C42E /* SDLHapticRectSpec.m in Sources */,
162E82EA1A9BDE8B00906325 /* SDLLanguageSpec.m in Sources */,
5D76E3291D3D0A8800647CFA /* SDLFakeViewControllerPresenter.m in Sources */,
+ 5DB2022A1F5F38B60061D189 /* SDLFakeStreamingManagerDataSource.m in Sources */,
162E83331A9BDE8B00906325 /* SDLPerformInteractionSpec.m in Sources */,
5D0A9F951F15585B00CC80DD /* SDLPhoneCapabilitySpec.m in Sources */,
1680B11A1A9CD7AD00DBD79E /* SDLAbstractProtocolSpec.m in Sources */,
1680B1151A9CD7AD00DBD79E /* SDLV2ProtocolHeaderSpec.m in Sources */,
162E83101A9BDE8B00906325 /* SDLOnAudioPassThruSpec.m in Sources */,
- DABB62171E4A900C0034C567 /* SDLVideoEncoderSpec.m in Sources */,
+ DABB62171E4A900C0034C567 /* SDLH264VideoEncoderSpec.m in Sources */,
5DBEFA581F436132009EE295 /* SDLFakeSecurityManager.m in Sources */,
162E82D91A9BDE8A00906325 /* SDLDisplayTypeSpec.m in Sources */,
162E83871A9BDE8B00906325 /* SDLPermissionItemSpec.m in Sources */,
@@ -5448,6 +5451,7 @@
162E83031A9BDE8B00906325 /* SDLTriggerSource.m in Sources */,
162E82D61A9BDE8A00906325 /* SDLComponentVolumeStatusSpec.m in Sources */,
162E835C1A9BDE8B00906325 /* SDLPutFileResponseSpec.m in Sources */,
+ 5DB202271F5F2D030061D189 /* SDLImageResolutionSpec.m in Sources */,
DA9F7EAA1DCC061A00ACAE48 /* SDLSubscribeWaypointsResponseSpec.m in Sources */,
162E835F1A9BDE8B00906325 /* SDLResetGlobalPropertiesResponseSpec.m in Sources */,
162E835E1A9BDE8B00906325 /* SDLRegisterAppInterfaceResponseSpec.m in Sources */,
@@ -5543,7 +5547,7 @@
5DB1BCD31D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m in Sources */,
5D0A9F971F1559EC00CC80DD /* SDLSystemCapabilitySpec.m in Sources */,
162E82F41A9BDE8B00906325 /* SDLPrimaryAudioSource.m in Sources */,
- EED5CA041F4D1D5E00F04000 /* SDLH264ByteStreamPacketizerSpec.m in Sources */,
+ EED5CA041F4D1D5E00F04000 /* SDLRAWH264PacketizerSpec.m in Sources */,
5DBAE0AB1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m in Sources */,
162E83461A9BDE8B00906325 /* SDLUnsubscribeButtonSpec.m in Sources */,
162E82EB1A9BDE8B00906325 /* SDLLayoutModeSpec.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index acd3dfcc4..796fccca2 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -205,6 +205,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLReadDID.h',
'SmartDeviceLink/SDLRectangle.h',
'SmartDeviceLink/SDLReadDIDResponse.h',
+'SmartDeviceLink/SDLRectangle.h',
'SmartDeviceLink/SDLRegisterAppInterface.h',
'SmartDeviceLink/SDLRegisterAppInterfaceResponse.h',
'SmartDeviceLink/SDLRequestType.h',
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h
index af3d97a12..2a1f7d674 100644
--- a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.h
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
/// The max version of protocol version supported by client requesting service to start. Must be in the format "Major.Minor.Patch"
@property (copy, nonatomic, readonly, nullable) NSString *protocolVersion;
-- (instancetype)initWithVersion:(NSString *)stringVersion;
+- (instancetype)initWithVersion:(nullable NSString *)stringVersion;
@end
diff --git a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m
index 95245e93e..d943d6a47 100644
--- a/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m
+++ b/SmartDeviceLink/SDLControlFramePayloadRPCStartService.m
@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLControlFramePayloadRPCStartService
-- (instancetype)initWithVersion:(NSString *)stringVersion {
+- (instancetype)initWithVersion:(nullable NSString *)stringVersion {
self = [super init];
if (!self) return nil;
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h
index 36ad5cfd6..58b6887f6 100644
--- a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.h
@@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
/// Accepted video codec to be used. See VideoStreamingCodec RPC
@property (copy, nonatomic, readonly, nullable) SDLVideoStreamingCodec videoCodec;
-- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(SDLVideoStreamingProtocol)protocol codec:(SDLVideoStreamingCodec)codec;
+- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(nullable SDLVideoStreamingProtocol)protocol codec:(nullable SDLVideoStreamingCodec)codec;
@end
diff --git a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m
index f16f4b108..d690d6690 100644
--- a/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m
+++ b/SmartDeviceLink/SDLControlFramePayloadVideoStartServiceAck.m
@@ -24,7 +24,7 @@
@implementation SDLControlFramePayloadVideoStartServiceAck
-- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(SDLVideoStreamingProtocol)protocol codec:(SDLVideoStreamingCodec)codec {
+- (instancetype)initWithMTU:(int64_t)mtu height:(int32_t)height width:(int32_t)width protocol:(nullable SDLVideoStreamingProtocol)protocol codec:(nullable SDLVideoStreamingCodec)codec {
self = [super init];
if (!self) return nil;
diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m
index 68f9c0378..7d63d606c 100644
--- a/SmartDeviceLink/SDLGlobals.m
+++ b/SmartDeviceLink/SDLGlobals.m
@@ -8,6 +8,8 @@
#import "SDLGlobals.h"
+#import "SDLLogMacros.h"
+
NS_ASSUME_NONNULL_BEGIN
// VERSION DEPENDENT CODE
@@ -69,6 +71,7 @@ typedef NSNumber* MTUBox;
}
- (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType {
+ SDLLogV(@"Setting dynamic MTU size: %lu for service %u", (unsigned long)maxMTUSize, serviceType);
self.dynamicMTUDict[@(serviceType)] = @(maxMTUSize);
}
diff --git a/SmartDeviceLink/SDLVideoEncoder.h b/SmartDeviceLink/SDLH264VideoEncoder.h
index 53816452b..cbeeb4f71 100644
--- a/SmartDeviceLink/SDLVideoEncoder.h
+++ b/SmartDeviceLink/SDLH264VideoEncoder.h
@@ -1,5 +1,5 @@
//
-// SDLVideoEncoder.h
+// SDLH264VideoEncoder
// SmartDeviceLink-iOS
//
// Created by Muller, Alexander (A.) on 12/5/16.
@@ -10,22 +10,24 @@
#import <VideoToolbox/VideoToolbox.h>
#import "SDLMacros.h"
+#import "SDLVideoStreamingProtocol.h"
#import "SDLVideoEncoderDelegate.h"
-@class SDLVideoEncoder;
+@protocol SDLH264Packetizer;
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, SDLVideoEncoderError) {
SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure = 0,
SDLVideoEncoderErrorConfigurationAllocationFailure = 1,
- SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure = 2
+ SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure = 2,
+ SDLVideoEncoderErrorProtocolUnknown = 3
};
extern NSString *const SDLErrorDomainVideoEncoder;
-@interface SDLVideoEncoder : NSObject
+@interface SDLH264VideoEncoder : NSObject
@property (nonatomic, weak, nullable) id<SDLVideoEncoderDelegate> delegate;
@@ -35,6 +37,8 @@ extern NSString *const SDLErrorDomainVideoEncoder;
*/
@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *videoEncoderSettings;
+@property (strong, nonatomic) id<SDLH264Packetizer> packetizer;
+
/**
* Provides default video encoder settings used.
*/
@@ -54,7 +58,7 @@ extern NSString *const SDLErrorDomainVideoEncoder;
- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithDimensions:(CGSize)dimensions properties:(NSDictionary<NSString *, id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError **)error NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions:(CGSize)dimensions properties:(NSDictionary<NSString *, id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError **)error NS_DESIGNATED_INITIALIZER;
- (void)stop;
diff --git a/SmartDeviceLink/SDLVideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m
index f3216d851..7929c3b11 100644
--- a/SmartDeviceLink/SDLVideoEncoder.m
+++ b/SmartDeviceLink/SDLH264VideoEncoder.m
@@ -1,15 +1,16 @@
//
-// SDLVideoEncoder.m
+// SDLH264VideoEncoder
// SmartDeviceLink-iOS
//
// Created by Muller, Alexander (A.) on 12/5/16.
// Copyright © 2016 smartdevicelink. All rights reserved.
//
-#import "SDLVideoEncoder.h"
+#import "SDLH264VideoEncoder.h"
-#import "SDLH264ByteStreamPacketizer.h"
#import "SDLLogMacros.h"
+#import "SDLRAWH264Packetizer.h"
+#import "SDLRTPH264Packetizer.h"
NS_ASSUME_NONNULL_BEGIN
@@ -18,31 +19,31 @@ NSString *const SDLErrorDomainVideoEncoder = @"com.sdl.videoEncoder";
static NSDictionary<NSString *, id>* _defaultVideoEncoderSettings;
-@interface SDLVideoEncoder ()
+@interface SDLH264VideoEncoder ()
@property (assign, nonatomic, nullable) VTCompressionSessionRef compressionSession;
@property (assign, nonatomic, nullable) CFDictionaryRef sdl_pixelBufferOptions;
@property (assign, nonatomic) NSUInteger currentFrameNumber;
-@property (nonatomic) id<SDLH264Packetizer> packetizer;
@property (assign, nonatomic) double timestampOffset;
@end
-@implementation SDLVideoEncoder
+@implementation SDLH264VideoEncoder
+ (void)initialize {
- if (self != [SDLVideoEncoder class]) {
+ if (self != [SDLH264VideoEncoder class]) {
return;
}
_defaultVideoEncoderSettings = @{
(__bridge NSString *)kVTCompressionPropertyKey_ProfileLevel: (__bridge NSString *)kVTProfileLevel_H264_Baseline_AutoLevel,
- (__bridge NSString *)kVTCompressionPropertyKey_RealTime: @YES
+ (__bridge NSString *)kVTCompressionPropertyKey_RealTime: @YES,
+ (__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate: @30,
};
}
-- (instancetype)initWithDimensions:(CGSize)dimensions properties:(NSDictionary<NSString *,id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError * _Nullable __autoreleasing *)error {
+- (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions:(CGSize)dimensions properties:(NSDictionary<NSString *, id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError **)error {
self = [super init];
if (!self) {
return nil;
@@ -83,7 +84,6 @@ static NSDictionary<NSString *, id>* _defaultVideoEncoderSettings;
}
NSArray* videoEncoderKeys = self.videoEncoderSettings.allKeys;
-
for (NSString *key in videoEncoderKeys) {
if (CFDictionaryContainsKey(supportedProperties, (__bridge CFStringRef)key) == false) {
if (!*error) {
@@ -105,12 +105,21 @@ static NSDictionary<NSString *, id>* _defaultVideoEncoderSettings;
if (!*error) {
*error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }];
}
-
return nil;
}
}
- _packetizer = [[SDLH264ByteStreamPacketizer alloc] init];
+ if ([protocol isEqualToEnum:SDLVideoStreamingProtocolRAW]) {
+ _packetizer = [[SDLRAWH264Packetizer alloc] init];
+ } else if ([protocol isEqualToEnum:SDLVideoStreamingProtocolRTP]) {
+ _packetizer = [[SDLRTPH264Packetizer alloc] init];
+ } else {
+ if (!*error) {
+ *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorProtocolUnknown userInfo:@{ @"encoder": protocol}];
+ }
+ return nil;
+ }
+
_timestampOffset = 0.0;
return self;
@@ -130,7 +139,12 @@ static NSDictionary<NSString *, id>* _defaultVideoEncoderSettings;
- (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTime)presentationTimestamp {
if (!CMTIME_IS_VALID(presentationTimestamp)) {
- presentationTimestamp = CMTimeMake(self.currentFrameNumber, 30);
+ int32_t timeRate = 30;
+ if (self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate] != nil) {
+ timeRate = ((NSNumber *)self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate]).intValue;
+ }
+
+ presentationTimestamp = CMTimeMake(self.currentFrameNumber, timeRate);
}
self.currentFrameNumber++;
@@ -175,7 +189,7 @@ void sdl_videoEncoderOutputCallback(void * CM_NULLABLE outputCallbackRefCon, voi
return;
}
- SDLVideoEncoder *encoder = (__bridge SDLVideoEncoder *)sourceFrameRefCon;
+ SDLH264VideoEncoder *encoder = (__bridge SDLH264VideoEncoder *)sourceFrameRefCon;
NSArray *nalUnits = [encoder.class sdl_extractNalUnitsFromSampleBuffer:sampleBuffer];
const CMTime presentationTimestampInCMTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
diff --git a/SmartDeviceLink/SDLHMICapabilities.h b/SmartDeviceLink/SDLHMICapabilities.h
index 6ab29741e..43ee2b810 100644
--- a/SmartDeviceLink/SDLHMICapabilities.h
+++ b/SmartDeviceLink/SDLHMICapabilities.h
@@ -9,21 +9,21 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLHMICapabilities : SDLRPCStruct
/**
- Availability of build in Nav. True: Available, False: Not Available
+ Availability of built in Nav. True: Available, False: Not Available
Boolean value. Optional.
*/
@property (nullable, copy, nonatomic) NSNumber<SDLBool> *navigation;
/**
- Availability of build in phone. True: Available, False: Not Available
+ Availability of built in phone. True: Available, False: Not Available
Boolean value. Optional.
*/
@property (nullable, copy, nonatomic) NSNumber<SDLBool> *phoneCall;
/**
- Availability of build in video streaming. True: Available, False: Not Available
+ Availability of built in video streaming. True: Available, False: Not Available
Boolean value. Optional.
*/
diff --git a/SmartDeviceLink/SDLImageResolution.h b/SmartDeviceLink/SDLImageResolution.h
index d9b25eec7..e6ec93ae9 100644
--- a/SmartDeviceLink/SDLImageResolution.h
+++ b/SmartDeviceLink/SDLImageResolution.h
@@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) NSNumber<SDLInt> *resolutionWidth;
@property (strong, nonatomic) NSNumber<SDLInt> *resolutionHeight;
+- (instancetype)initWithWidth:(uint16_t)width height:(uint16_t)height;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLImageResolution.m b/SmartDeviceLink/SDLImageResolution.m
index 18b69fe6e..f2f9c4566 100644
--- a/SmartDeviceLink/SDLImageResolution.m
+++ b/SmartDeviceLink/SDLImageResolution.m
@@ -11,6 +11,16 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLImageResolution
+- (instancetype)initWithWidth:(uint16_t)width height:(uint16_t)height {
+ self = [self init];
+ if (!self) { return nil; }
+
+ self.resolutionWidth = @(width);
+ self.resolutionHeight = @(height);
+
+ return self;
+}
+
- (void)setResolutionWidth:(NSNumber<SDLInt> *)resolutionWidth {
[store sdl_setObject:resolutionWidth forName:SDLNameResolutionWidth];
}
diff --git a/SmartDeviceLink/SDLLifecycleConfiguration.m b/SmartDeviceLink/SDLLifecycleConfiguration.m
index 1688246bd..c5b9e7071 100644
--- a/SmartDeviceLink/SDLLifecycleConfiguration.m
+++ b/SmartDeviceLink/SDLLifecycleConfiguration.m
@@ -9,7 +9,6 @@
#import "SDLLifecycleConfiguration.h"
#import "SDLFile.h"
-#import "SDLVideoEncoder.h"
static NSString *const DefaultTCPIPAddress = @"192.168.0.1";
static UInt16 const DefaultTCPIPPort = 12345;
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m
index e38e5084c..6c4cd41f9 100644
--- a/SmartDeviceLink/SDLLifecycleManager.m
+++ b/SmartDeviceLink/SDLLifecycleManager.m
@@ -71,6 +71,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
// Private properties
@property (copy, nonatomic) SDLManagerReadyBlock readyHandler;
+@property (assign, nonatomic) BOOL firstHMINonNoneOccurred;
@end
@@ -104,6 +105,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
_notificationDispatcher = [[SDLNotificationDispatcher alloc] init];
_responseDispatcher = [[SDLResponseDispatcher alloc] initWithNotificationDispatcher:_notificationDispatcher];
_registerResponse = nil;
+ _firstHMINonNoneOccurred = NO;
// Managers
_fileManager = [[SDLFileManager alloc] initWithConnectionManager:self];
@@ -112,8 +114,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation]
|| [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection]) {
- SDLLogV(@"Creating StreamingMediaManager for app type: %@", configuration.lifecycleConfig.appType);
- _streamManager = [[SDLStreamingMediaManager alloc] initWithEncryption:configuration.streamingMediaConfig.maximumDesiredEncryption videoEncoderSettings:configuration.streamingMediaConfig.customVideoEncoderSettings];
+ _streamManager = [[SDLStreamingMediaManager alloc] initWithConnectionManager:self configuration:configuration.streamingMediaConfig];
} else {
SDLLogV(@"Skipping StreamingMediaManager setup due to app type");
}
@@ -197,6 +198,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
[self.fileManager stop];
[self.permissionManager stop];
[self.lockScreenManager stop];
+ [self.streamManager stop];
[self.responseDispatcher clear];
self.registerResponse = nil;
@@ -274,19 +276,6 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
dispatch_group_leave(managerGroup);
}];
-
-
- if (self.streamManager != nil) {
- dispatch_group_enter(managerGroup);
- }
-
- [self.streamManager startWithProtocol:self.proxy.protocol completionHandler:^(BOOL success, NSError * _Nullable error) {
- if (!success) {
- SDLLogE(@"Streaming media manager was unable to start; error: %@", error);
- }
-
- dispatch_group_leave(managerGroup);
- }];
// We're done synchronously calling all startup methods, so we can now wait.
dispatch_group_leave(managerGroup);
@@ -311,6 +300,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
// If nil, return and wait until we get a notification
return;
}
+
// We are sure to have a HMIStatus, set state to ready
[self.lifecycleStateMachine transitionToState:SDLLifecycleStateReady];
}
@@ -452,6 +442,15 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
return YES;
}
+- (void)sdl_onFirstHMINonNone {
+ // If we are a nav / projection app and desire to stream, we need to be in HMI background, limited, or full and perform additional setup when that occurs
+ if (self.streamManager == nil) {
+ return;
+ }
+
+ [self.streamManager startWithProtocol:self.proxy.protocol];
+}
+
#pragma mark SDL notification observers
@@ -481,6 +480,11 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
SDLSystemContext oldSystemContext = self.systemContext;
self.systemContext = hmiStatusNotification.systemContext;
+
+ if (!self.firstHMINonNoneOccurred && ![self.hmiLevel isEqualToEnum:SDLHMILevelNone]) {
+ self.firstHMINonNoneOccurred = YES;
+ [self sdl_onFirstHMINonNone];
+ }
if ([self.lifecycleStateMachine isCurrentState:SDLLifecycleStateSettingUpHMI]) {
[self.lifecycleStateMachine transitionToState:SDLLifecycleStateReady];
diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m
index 6b5c6ac08..d3cc0c29e 100644
--- a/SmartDeviceLink/SDLLogFileModuleMap.m
+++ b/SmartDeviceLink/SDLLogFileModuleMap.m
@@ -60,7 +60,7 @@
}
+ (SDLLogFileModule *)sdl_streamingMediaManagerModule {
- return [SDLLogFileModule moduleWithName:@"Streaming" files:[NSSet setWithArray:@[@"SDLStreamingMediaManager", @"SDLTouchManager"]]];
+ return [SDLLogFileModule moduleWithName:@"Streaming" files:[NSSet setWithArray:@[@"SDLH264VideoEncoder", @"SDLRAWH264Packetizer", @"SDLRTPH264Packetizer", @"SDLStreamingMediaManager", @"SDLStreamingMediaLifecycleManager", @"SDLTouchManager"]]];
}
diff --git a/SmartDeviceLink/SDLH264ByteStreamPacketizer.h b/SmartDeviceLink/SDLRAWH264Packetizer.h
index 5b6d57928..df1a9baf7 100644
--- a/SmartDeviceLink/SDLH264ByteStreamPacketizer.h
+++ b/SmartDeviceLink/SDLRAWH264Packetizer.h
@@ -1,5 +1,5 @@
//
-// SDLH264ByteStreamPacketizer.h
+// SDLRAWH264Packetizer
// SmartDeviceLink-iOS
//
// Created by Sho Amano on 4/11/17.
@@ -7,11 +7,12 @@
//
#import <Foundation/Foundation.h>
+
#import "SDLH264Packetizer.h"
NS_ASSUME_NONNULL_BEGIN
-@interface SDLH264ByteStreamPacketizer : NSObject <SDLH264Packetizer>
+@interface SDLRAWH264Packetizer : NSObject <SDLH264Packetizer>
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLH264ByteStreamPacketizer.m b/SmartDeviceLink/SDLRAWH264Packetizer.m
index c229b0438..a40acd345 100644
--- a/SmartDeviceLink/SDLH264ByteStreamPacketizer.m
+++ b/SmartDeviceLink/SDLRAWH264Packetizer.m
@@ -1,5 +1,5 @@
//
-// SDLH264ByteStreamPacketizer.m
+// SDLRAWH264Packetizer
// SmartDeviceLink-iOS
//
// Created by Sho Amano on 4/11/17.
@@ -7,15 +7,16 @@
//
#import <Foundation/Foundation.h>
-#import "SDLH264ByteStreamPacketizer.h"
+#import "SDLRAWH264Packetizer.h"
+#import "SDLH264Packetizer.h"
NS_ASSUME_NONNULL_BEGIN
-@interface SDLH264ByteStreamPacketizer ()
+@interface SDLRAWH264Packetizer ()
@property (nonatomic) NSData *startCode;
@end
-@implementation SDLH264ByteStreamPacketizer
+@implementation SDLRAWH264Packetizer
- (instancetype)init {
self = [super init];
diff --git a/SmartDeviceLink/SDLRPCStruct.m b/SmartDeviceLink/SDLRPCStruct.m
index 01b514f24..b6a588823 100644
--- a/SmartDeviceLink/SDLRPCStruct.m
+++ b/SmartDeviceLink/SDLRPCStruct.m
@@ -82,6 +82,22 @@ NS_ASSUME_NONNULL_BEGIN
return newStruct;
}
+- (BOOL)isEqualToRPC:(SDLRPCStruct *)rpc {
+ return [rpc->store isEqualToDictionary:self->store];
+}
+
+- (BOOL)isEqual:(id)object {
+ if (self == object) {
+ return YES;
+ }
+
+ if (![object isMemberOfClass:self.class]) {
+ return NO;
+ }
+
+ return [self isEqualToRPC:(SDLRPCStruct *)object];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingMediaConfiguration.h b/SmartDeviceLink/SDLStreamingMediaConfiguration.h
index 033ce6ea3..e1bbb881a 100644
--- a/SmartDeviceLink/SDLStreamingMediaConfiguration.h
+++ b/SmartDeviceLink/SDLStreamingMediaConfiguration.h
@@ -11,6 +11,7 @@
#import "SDLStreamingMediaManagerConstants.h"
@protocol SDLSecurityType;
+@protocol SDLStreamingMediaManagerDataSource;
NS_ASSUME_NONNULL_BEGIN
@@ -28,11 +29,23 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) SDLStreamingEncryptionFlag maximumDesiredEncryption;
/**
- * Properties to use for applications that utilitze the video encoder for streaming.
+ * Properties to use for applications that utilitze the video encoder for streaming. See VTCompressionProperties.h for more details. For example, you can set kVTCompressionPropertyKey_ExpectedFrameRate to set your expected framerate.
*/
@property (copy, nonatomic, nullable) NSDictionary<NSString *, id> *customVideoEncoderSettings;
/**
+ Usable to change run time video stream setup behavior. Only use this and modify the results if you *really* know what you're doing. The head unit defaults are generally good.
+ */
+@property (weak, nonatomic, nullable) id<SDLStreamingMediaManagerDataSource> dataSource;
+
+/**
+ Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually.
+
+ @return The configuration
+ */
+- (instancetype)init;
+
+/**
Manually set all the properties to the streaming media configuration
@param securityManagers The security managers to use or nil for none.
@@ -40,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN
@param videoSettings Custom video encoder settings to be used in video streaming.
@return The configuration
*/
-- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings;
+- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource;
/**
Create a secure configuration for each of the security managers provided.
@@ -48,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
@param securityManagers The security managers to be used. The encryption flag will be set to AuthenticateAndEncrypt if any security managers are set.
@return The configuration
*/
-- (instancetype)initSecureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers;
+- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers;
/**
Create a secure configuration for each of the security managers provided.
@@ -59,18 +72,11 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers;
/**
- Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually.
-
- @return The configuration
- */
-- (instancetype)initInsecureConfiguration;
-
-/**
- Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually.
+ Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually. This is equivalent to `init`.
@return The configuration
*/
-+ (instancetype)insecureConfiguration;
++ (instancetype)insecureConfiguration NS_SWIFT_UNAVAILABLE("Use the standard initializer instead");
@end
diff --git a/SmartDeviceLink/SDLStreamingMediaConfiguration.m b/SmartDeviceLink/SDLStreamingMediaConfiguration.m
index 4eb6d81b8..93bcf7ebc 100644
--- a/SmartDeviceLink/SDLStreamingMediaConfiguration.m
+++ b/SmartDeviceLink/SDLStreamingMediaConfiguration.m
@@ -8,12 +8,22 @@
#import "SDLStreamingMediaConfiguration.h"
+#import "SDLStreamingMediaManagerDataSource.h"
+
NS_ASSUME_NONNULL_BEGIN
@implementation SDLStreamingMediaConfiguration
-- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings {
+- (instancetype)init {
+ return [self initWithSecurityManagers:nil encryptionFlag:SDLStreamingEncryptionFlagNone videoSettings:nil dataSource:nil];
+}
+
++ (instancetype)insecureConfiguration {
+ return [[self alloc] init];
+}
+
+- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource {
self = [super init];
if (!self) {
return nil;
@@ -22,33 +32,26 @@ NS_ASSUME_NONNULL_BEGIN
_securityManagers = securityManagers;
_maximumDesiredEncryption = encryptionFlag;
_customVideoEncoderSettings = videoSettings;
+ _dataSource = dataSource;
return self;
}
-- (instancetype)initSecureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers {
+- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers {
NSAssert(securityManagers.count > 0, @"A secure streaming media configuration requires security managers to be passed.");
SDLStreamingEncryptionFlag encryptionFlag = SDLStreamingEncryptionFlagAuthenticateAndEncrypt;
- return [self initWithSecurityManagers:securityManagers encryptionFlag:encryptionFlag videoSettings:nil];
+ return [self initWithSecurityManagers:securityManagers encryptionFlag:encryptionFlag videoSettings:nil dataSource:nil];
}
+ (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers {
- return [[self alloc] initSecureConfigurationWithSecurityManagers:securityManagers];
-}
-
-- (instancetype)initInsecureConfiguration {
- return [self initWithSecurityManagers:nil encryptionFlag:SDLStreamingEncryptionFlagNone videoSettings:nil];
-}
-
-+ (instancetype)insecureConfiguration {
- return [[self alloc] initInsecureConfiguration];
+ return [[self alloc] initWithSecurityManagers:securityManagers];
}
#pragma mark NSCopying
- (id)copyWithZone:(nullable NSZone *)zone {
- return [[self.class allocWithZone:zone] initWithSecurityManagers:_securityManagers encryptionFlag:_maximumDesiredEncryption videoSettings:_customVideoEncoderSettings];
+ return [[self.class allocWithZone:zone] initWithSecurityManagers:_securityManagers encryptionFlag:_maximumDesiredEncryption videoSettings:_customVideoEncoderSettings dataSource:_dataSource];
}
@end
diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h
index 1dcbcd09f..89da07993 100644
--- a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h
+++ b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h
@@ -9,13 +9,19 @@
#import <Foundation/Foundation.h>
#import <VideoToolbox/VideoToolbox.h>
+#import "SDLConnectionManagerType.h"
#import "SDLHMILevel.h"
#import "SDLProtocolListener.h"
#import "SDLStreamingMediaManagerConstants.h"
@class SDLAbstractProtocol;
+@class SDLImageResolution;
@class SDLStateMachine;
+@class SDLStreamingMediaConfiguration;
@class SDLTouchManager;
+@class SDLVideoStreamingFormat;
+
+@protocol SDLStreamingMediaManagerDataSource;
NS_ASSUME_NONNULL_BEGIN
@@ -58,16 +64,16 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
@property (nonatomic, strong, readonly) SDLTouchManager *touchManager;
/**
- * Whether or not video streaming is supported
- *
- * @see SDLRegisterAppInterface SDLDisplayCapabilities
+ A data source for the streaming manager's preferred resolutions and preferred formats.
*/
-@property (assign, nonatomic, readonly, getter=isVideoStreamingSupported) BOOL videoStreamingSupported;
+@property (weak, nonatomic, nullable) id<SDLStreamingMediaManagerDataSource> dataSource;
/**
- * Whether or not audio streaming is supported. Currently this is the same as videoStreamingSupported.
+ * Whether or not video streaming is supported
+ *
+ * @see SDLRegisterAppInterface SDLDisplayCapabilities
*/
-@property (assign, nonatomic, readonly, getter=isAudioStreamingSupported) BOOL audioStreamingSupported;
+@property (assign, nonatomic, readonly, getter=isStreamingSupported) BOOL streamingSupported;
/**
* Whether or not the video session is connected.
@@ -100,6 +106,36 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
@property (assign, nonatomic, readonly) CGSize screenSize;
/**
+ This is the agreed upon format of video encoder that is in use, or nil if not currently connected.
+ */
+@property (strong, nonatomic, readonly, nullable) SDLVideoStreamingFormat *videoFormat;
+
+/**
+ A list of all supported video formats by this manager
+ */
+@property (strong, nonatomic, readonly) NSArray<SDLVideoStreamingFormat *> *supportedFormats;
+
+/**
+ The decided upon preferred formats to try and connect with between the head unit and developer
+ */
+@property (strong, nonatomic) NSArray<SDLVideoStreamingFormat *> *preferredFormats;
+
+/**
+ The current attempt index for trying to connect with `preferredFormats`
+ */
+@property (assign, nonatomic) NSUInteger preferredFormatIndex;
+
+/**
+ The decided upon preferred resolutions to try and connect with between the head unit and the developer
+ */
+@property (strong, nonatomic) NSArray<SDLImageResolution *> *preferredResolutions;
+
+/**
+ The current attempt index for trying to connect with `preferredResolutions`
+ */
+@property (assign, nonatomic) NSUInteger preferredResolutionIndex;
+
+/**
* The pixel buffer pool reference returned back from an active VTCompressionSessionRef encoder.
*
* @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started).
@@ -114,22 +150,21 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
*/
@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType;
+- (instancetype)init NS_UNAVAILABLE;
+
/**
- * Creates a streaming manager with a specified encryption type.
- *
- * @param encryption The encryption type requested when starting to stream.
- * @param videoEncoderSettings The video encoder settings to use with SDLVideoEncoder.
- *
- * @return An instance of SDLStreamingMediaManager
+ 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)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings NS_DESIGNATED_INITIALIZER;
+- (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`.
- *
- * @param completionHandler The block to be called when the manager's setup is complete.
*/
-- (void)startWithProtocol:(SDLAbstractProtocol*)protocol completionHandler:(void (^)(BOOL success, NSError *__nullable error))completionHandler;
+- (void)startWithProtocol:(SDLAbstractProtocol *)protocol;
/**
* Stop the manager. This method is used internally.
diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
index 76489e012..ecbbf88d8 100644
--- a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
+++ b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
@@ -9,9 +9,17 @@
#import "SDLStreamingMediaLifecycleManager.h"
#import "SDLAbstractProtocol.h"
+#import "SDLControlFramePayloadAudioStartServiceAck.h"
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadNak.h"
+#import "SDLControlFramePayloadVideoStartService.h"
+#import "SDLControlFramePayloadVideoStartServiceAck.h"
#import "SDLDisplayCapabilities.h"
+#import "SDLGenericResponse.h"
+#import "SDLGetSystemCapability.h"
+#import "SDLGetSystemCapabilityResponse.h"
#import "SDLGlobals.h"
-#import "SDLHMILevel.h"
+#import "SDLHMICapabilities.h"
#import "SDLImageResolution.h"
#import "SDLLogMacros.h"
#import "SDLNotificationConstants.h"
@@ -22,8 +30,15 @@
#import "SDLRPCResponseNotification.h"
#import "SDLScreenParams.h"
#import "SDLStateMachine.h"
+#import "SDLStreamingMediaConfiguration.h"
+#import "SDLStreamingMediaManagerDataSource.h"
+#import "SDLSystemCapability.h"
#import "SDLTouchManager.h"
-#import "SDLVideoEncoder.h"
+#import "SDLH264VideoEncoder.h"
+#import "SDLVideoStreamingCapability.h"
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingFormat.h"
+#import "SDLVideoStreamingProtocol.h"
#import "CVPixelBufferRef+SDLUtil.h"
@@ -43,11 +58,14 @@ SDLAudioStreamState *const SDLAudioStreamStateStarting = @"AudioStreamStarting";
SDLAudioStreamState *const SDLAudioStreamStateReady = @"AudioStreamReady";
SDLAudioStreamState *const SDLAudioStreamStateShuttingDown = @"AudioStreamShuttingDown";
-static NSUInteger const SDLFramesToSendOnBackground = 30;
+static NSUInteger const FramesToSendOnBackground = 30;
+
+typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_Nullable capability);
@interface SDLStreamingMediaLifecycleManager () <SDLVideoEncoderDelegate>
+@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) SDLAbstractProtocol *protocol;
@property (assign, nonatomic, readonly, getter=isAppStateVideoStreamCapable) BOOL appStateVideoStreamCapable;
@@ -55,8 +73,9 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
@property (assign, nonatomic, readonly, getter=isHmiStateVideoStreamCapable) BOOL hmiStateVideoStreamCapable;
@property (assign, nonatomic, readwrite) BOOL restartVideoStream;
+@property (strong, nonatomic, readwrite, nullable) SDLVideoStreamingFormat *videoFormat;
-@property (strong, nonatomic, nullable) SDLVideoEncoder *videoEncoder;
+@property (strong, nonatomic, nullable) SDLH264VideoEncoder *videoEncoder;
@property (copy, nonatomic) NSDictionary<NSString *, id> *videoEncoderSettings;
@property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine;
@@ -75,24 +94,25 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
#pragma mark - Public
#pragma mark Lifecycle
-- (instancetype)init {
- return [self initWithEncryption:SDLStreamingEncryptionFlagAuthenticateAndEncrypt videoEncoderSettings:nil];
-}
-
-- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings {
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager configuration:(SDLStreamingMediaConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
SDLLogV(@"Creating StreamingLifecycleManager");
-
- _videoEncoderSettings = videoEncoderSettings ?: SDLVideoEncoder.defaultVideoEncoderSettings;
-
- _requestedEncryptionType = encryption;
+ _connectionManager = connectionManager;
+
+ _videoEncoderSettings = configuration.customVideoEncoderSettings ?: SDLH264VideoEncoder.defaultVideoEncoderSettings;
+ _requestedEncryptionType = configuration.maximumDesiredEncryption;
+ _dataSource = configuration.dataSource;
_screenSize = SDLDefaultScreenSize;
_backgroundingPixelBuffer = NULL;
-
+ _preferredFormatIndex = 0;
+ _preferredResolutionIndex = 0;
+
+ _touchManager = [[SDLTouchManager alloc] init];
+
SDLAppState *initialState = SDLAppStateInactive;
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive: {
@@ -104,38 +124,64 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
} break;
default: break;
}
-
- _touchManager = [[SDLTouchManager alloc] init];
-
+
_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];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationWillResignActiveNotification object:nil];
-
+
_lastPresentationTimestamp = kCMTimeInvalid;
return self;
}
-- (void)startWithProtocol:(SDLAbstractProtocol *)protocol completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler {
+- (void)startWithProtocol:(SDLAbstractProtocol *)protocol {
_protocol = protocol;
-
+
if (![self.protocol.protocolDelegateTable containsObject:self]) {
[self.protocol.protocolDelegateTable addObject:self];
}
-
- completionHandler(YES, nil);
+
+ SDLLogD(@"Requesting video capabilities");
+ __weak typeof(self) weakSelf = self;
+ [self sdl_requestVideoCapabilities:^(SDLVideoStreamingCapability * _Nullable capability) {
+ SDLLogD(@"Received video capability response");
+ SDLLogV(@"%@", capability);
+ if (capability != nil) {
+ // If we got a response, get our preferred formats and resolutions
+ weakSelf.preferredFormats = capability.supportedFormats;
+ weakSelf.preferredResolutions = @[capability.preferredResolution];
+
+ if (weakSelf.dataSource != nil) {
+ SDLLogV(@"Calling data source for modified preferred formats and resolutions");
+ weakSelf.preferredFormats = [weakSelf.dataSource preferredVideoFormatOrderFromHeadUnitPreferredOrder:weakSelf.preferredFormats];
+ weakSelf.preferredResolutions = [weakSelf.dataSource resolutionFromHeadUnitPreferredResolution:weakSelf.preferredResolutions.firstObject];
+ }
+
+ SDLLogD(@"Got specialized video capabilites, preferred formats: %@, resolutions: %@", weakSelf.preferredFormats, weakSelf.preferredResolutions);
+ } else {
+ // If we can't get capabilities, we're assuming it's H264 RAW at whatever the display capabilities said in the RAIR. We also aren't going to call the data source because they have no options.
+ SDLVideoStreamingFormat *format = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRAW];
+ SDLImageResolution *resolution = [[SDLImageResolution alloc] initWithWidth:weakSelf.screenSize.width height:weakSelf.screenSize.height];
+ weakSelf.preferredFormats = @[format];
+ weakSelf.preferredResolutions = @[resolution];
+ SDLLogD(@"Using generic video capabilites, preferred formats: %@, resolutions: %@", weakSelf.preferredFormats, weakSelf.preferredResolutions);
+ }
+
+ [weakSelf sdl_startVideoSession];
+ }];
}
- (void)stop {
+ SDLLogD(@"Stopping manager");
[self sdl_stopAudioSession];
[self sdl_stopVideoSession];
-
+
self.restartVideoStream = NO;
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
}
@@ -168,6 +214,7 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
self.lastPresentationTimestamp = presentationTimestamp;
+ SDLLogV(@"Sending data to video encoder");
return [self.videoEncoder encodeFrame:imageBuffer presentationTimestamp:presentationTimestamp];
}
@@ -175,7 +222,8 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
if (!self.isAudioConnected) {
return NO;
}
-
+
+ SDLLogV(@"Sending raw audio data");
if (self.isAudioEncrypted) {
[self.protocol sendEncryptedRawData:audioData onService:SDLServiceTypeAudio];
} else {
@@ -233,7 +281,7 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
- (void)didEnterStateAppInactive {
- SDLLogD(@"Manager became inactive");
+ SDLLogD(@"App became inactive");
if (!self.protocol) { return; }
[self sdl_sendBackgroundFrames];
@@ -244,7 +292,7 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
// 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(@"Manager became active");
+ SDLLogD(@"App became active");
if (!self.protocol) { return; }
[self sdl_startVideoSession];
@@ -264,14 +312,15 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
- (void)didEnterStateVideoStreamStopped {
SDLLogD(@"Video stream stopped");
_videoEncrypted = NO;
-
+ _videoFormat = nil;
+
if (_videoEncoder != nil) {
[_videoEncoder stop];
_videoEncoder = nil;
}
-
+
[[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStopNotification object:nil];
-
+
if (self.shouldRestartVideoStream) {
self.restartVideoStream = NO;
[self sdl_startVideoSession];
@@ -282,32 +331,25 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
SDLLogD(@"Video stream starting");
self.restartVideoStream = NO;
- // Decide if we need to start a secure service or not
- if (self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) {
- [self.protocol startSecureServiceWithType:SDLServiceTypeVideo payload:nil completionHandler:^(BOOL success, NSError *error) {
- // This only fires if we fail
- if (error) {
- SDLLogE(@"TLS setup error: %@", error);
- [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
- }
- }];
- } else {
- [self.protocol startServiceWithType:SDLServiceTypeVideo payload:nil];
- }
+ [self sdl_sendVideoStartService];
}
- (void)didEnterStateVideoStreamReady {
SDLLogD(@"Video stream ready");
+ // TODO: What if it isn't nil, is it even possible for it to not be nil?
if (self.videoEncoder == nil) {
NSError* error = nil;
- self.videoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:self.screenSize properties:self.videoEncoderSettings delegate:self error:&error];
-
- if (error) {
+ NSAssert(self.videoFormat != nil, @"No video format is known, but it must be if we got a protocol start service response");
+
+ SDLLogD(@"Attempting to create video encoder");
+ self.videoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:self.videoFormat.protocol dimensions:self.screenSize properties:self.videoEncoderSettings delegate:self error:&error];
+
+ if (error || self.videoEncoder == nil) {
SDLLogE(@"Could not create a video encoder: %@", error);
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
return;
}
-
+
if (!self.backgroundingPixelBuffer) {
CVPixelBufferRef backgroundingPixelBuffer = [self.videoEncoder newPixelBuffer];
if (CVPixelBufferAddText(backgroundingPixelBuffer, @"") == NO) {
@@ -315,12 +357,12 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
return;
}
-
+
self.backgroundingPixelBuffer = backgroundingPixelBuffer;
}
self.lastPresentationTimestamp = kCMTimeInvalid;
}
-
+
[[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil];
}
@@ -342,15 +384,14 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
- (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.protocol startSecureServiceWithType:SDLServiceTypeAudio payload:nil completionHandler:^(BOOL success, NSError *error) {
- // This only fires if we fail!!
+ [self.protocol startSecureServiceWithType:SDLServiceTypeAudio payload:nil completionHandler:^(BOOL success, NSError * _Nonnull error) {
if (error) {
SDLLogE(@"TLS setup error: %@", error);
[self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped];
@@ -372,40 +413,121 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
#pragma mark - SDLProtocolListener
+#pragma mark Video / Audio Start Service ACK
+
- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
switch (startServiceACK.header.serviceType) {
case SDLServiceTypeAudio: {
- _audioEncrypted = startServiceACK.header.encrypted;
-
- [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateReady];
+ [self sdl_handleAudioStartServiceAck:startServiceACK];
} break;
case SDLServiceTypeVideo: {
- _videoEncrypted = startServiceACK.header.encrypted;
-
- [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateReady];
+ [self sdl_handleVideoStartServiceAck: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:audioAckPayload.mtu forServiceType:SDLServiceTypeAudio];
+ }
+
+ [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateReady];
+}
+
+- (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAck {
+ SDLLogD(@"Video service started");
+ _videoEncrypted = videoStartServiceAck.header.encrypted;
+
+ SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:videoStartServiceAck.payload];
+ SDLLogV(@"ACK: %@", videoAckPayload);
+
+ if (videoAckPayload.mtu != SDLControlFrameInt64NotFound) {
+ [[SDLGlobals sharedGlobals] setDynamicMTUSize:videoAckPayload.mtu forServiceType:SDLServiceTypeVideo];
+ }
+
+ // This is the definitive screen size that will be used
+ if (videoAckPayload.height != SDLControlFrameInt32NotFound && videoAckPayload.width != SDLControlFrameInt32NotFound) {
+ _screenSize = CGSizeMake(videoAckPayload.width, videoAckPayload.height);
+ } // else we are using the screen size we got from the RAIR earlier
+
+ // Figure out the definitive format that will be used. If the protocol / codec weren't passed in the payload, it's probably a system that doesn't support those properties, which also means it's a system that requires H.264 RAW encoding
+ self.videoFormat = [[SDLVideoStreamingFormat alloc] init];
+ self.videoFormat.codec = videoAckPayload.videoCodec ?: SDLVideoStreamingCodecH264;
+ self.videoFormat.protocol = videoAckPayload.videoProtocol ?: SDLVideoStreamingProtocolRAW;
+
+ [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateReady];
+}
+
+#pragma mark Video / Audio Start Service NAK
+
- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK {
- [self sdl_transitionToStoppedState:startServiceNAK.header.serviceType];
+ switch (startServiceNAK.header.serviceType) {
+ case SDLServiceTypeAudio: {
+ [self sdl_handleAudioStartServiceNak:startServiceNAK];
+ } break;
+ case SDLServiceTypeVideo: {
+ [self sdl_handleVideoStartServiceNak:startServiceNAK];
+ }
+ default: break;
+ }
}
+- (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNak {
+ SDLLogW(@"Video service failed to start due to NAK");
+ SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:videoStartServiceNak.payload];
+ SDLLogD(@"NAK: %@", videoStartServiceNak);
+
+ // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry
+ if (nakPayload.rejectedParams.count == 0) {
+ [self sdl_transitionToStoppedState:SDLServiceTypeVideo];
+ return;
+ }
+
+ // If height and/or width was rejected, and we have another resolution to try, advance our counter to try another resolution
+ if (([nakPayload.rejectedParams containsObject:[NSString stringWithUTF8String:SDLControlFrameHeightKey]]
+ || [nakPayload.rejectedParams containsObject:[NSString stringWithUTF8String:SDLControlFrameWidthKey]])) {
+ self.preferredResolutionIndex++;
+ }
+
+ if (([nakPayload.rejectedParams containsObject:[NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]
+ || [nakPayload.rejectedParams containsObject:[NSString stringWithUTF8String:SDLControlFrameVideoProtocolKey]])) {
+ self.preferredFormatIndex++;
+ }
+
+ [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 {
+ 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 - SDLVideoEncoderDelegate
-- (void)videoEncoder:(SDLVideoEncoder *)encoder hasEncodedFrame:(NSData *)encodedVideo {
- SDLLogV(@"Video encoder encoded frame, sending");
+
+- (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];
@@ -416,22 +538,24 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
#pragma mark - SDL RPC Notification callbacks
-- (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification*)notification {
+
+- (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;
-
- _videoStreamingSupported = registerResponse.displayCapabilities.graphicSupported.boolValue;
- _audioStreamingSupported = registerResponse.displayCapabilities.graphicSupported.boolValue;
-
- if (!self.isVideoStreamingSupported) {
- SDLLogE(@"Graphics are not supported on this head unit. We are are assuming screen size is also unavailable.");
+
+ 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;
}
-
+
SDLImageResolution* resolution = registerResponse.displayCapabilities.screenParams.resolution;
if (resolution != nil) {
_screenSize = CGSizeMake(resolution.resolutionWidth.floatValue,
@@ -439,6 +563,8 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
} else {
_screenSize = SDLDefaultScreenSize;
}
+
+ SDLLogD(@"Determined base screen size on display capabilities: %@", NSStringFromCGSize(_screenSize));
}
- (void)sdl_hmiLevelDidChange:(SDLRPCNotificationNotification *)notification {
@@ -446,17 +572,17 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
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.isHmiStateVideoStreamCapable) {
[self sdl_startVideoSession];
} else {
[self sdl_stopVideoSession];
}
-
+
if (self.isHmiStateAudioStreamCapable) {
[self sdl_startAudioSession];
} else {
@@ -468,16 +594,16 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
#pragma mark - Streaming session helpers
- (void)sdl_startVideoSession {
- if (!self.isVideoStreamingSupported) {
+ SDLLogV(@"Attempting to start video session");
+ if (!self.isStreamingSupported) {
return;
}
-
- if (self.shouldRestartVideoStream
- && [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady]) {
+
+ if (self.shouldRestartVideoStream && [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady]) {
[self sdl_stopVideoSession];
return;
}
-
+
if ([self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateStopped]
&& self.isHmiStateVideoStreamCapable
&& self.isAppStateVideoStreamCapable) {
@@ -491,10 +617,11 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
- (void)sdl_startAudioSession {
- if (!self.isAudioStreamingSupported) {
+ SDLLogV(@"Attempting to start audio session");
+ if (!self.isStreamingSupported) {
return;
}
-
+
if ([self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateStopped]
&& self.isHmiStateAudioStreamCapable) {
[self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStarting];
@@ -502,20 +629,22 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
- (void)sdl_stopVideoSession {
- if (!self.isVideoStreamingSupported) {
+ SDLLogV(@"Attempting to stop video session");
+ if (!self.isStreamingSupported) {
return;
}
-
+
if (self.isVideoConnected) {
[self.videoStreamStateMachine transitionToState:SDLVideoStreamStateShuttingDown];
}
}
- (void)sdl_stopAudioSession {
- if (!self.isAudioStreamingSupported) {
+ SDLLogV(@"Attempting to stop audio session");
+ if (!self.isStreamingSupported) {
return;
}
-
+
if (self.isAudioConnected) {
[self.audioStreamStateMachine transitionToState:SDLAudioStreamStateShuttingDown];
}
@@ -535,12 +664,19 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
- (void)sdl_sendBackgroundFrames {
+ SDLLogV(@"Attempting to send background frames");
if (!self.backgroundingPixelBuffer) {
+ SDLLogW(@"No background pixel buffer, unable to send background frames");
return;
}
-
- const CMTime interval = CMTimeMake(1, 30);
- for (int frameCount = 0; frameCount < SDLFramesToSendOnBackground; frameCount++) {
+
+ int32_t timeRate = 30;
+ if (self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate] != nil) {
+ timeRate = ((NSNumber *)self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate]).intValue;
+ }
+
+ const CMTime interval = CMTimeMake(1, timeRate);
+ for (int frameCount = 0; frameCount < FramesToSendOnBackground; frameCount++) {
if (CMTIME_IS_VALID(self.lastPresentationTimestamp)) {
self.lastPresentationTimestamp = CMTimeAdd(self.lastPresentationTimestamp, interval);
[self.videoEncoder encodeFrame:self.backgroundingPixelBuffer presentationTimestamp:self.lastPresentationTimestamp];
@@ -550,7 +686,68 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
}
}
+- (void)sdl_requestVideoCapabilities:(SDLVideoCapabilityResponseHandler)responseHandler {
+ SDLLogD(@"Requesting video capabilities");
+ SDLGetSystemCapability *getVideoCapabilityRequest = [[SDLGetSystemCapability alloc] initWithType:SDLSystemCapabilityTypeVideoStreaming];
+
+ [self.connectionManager sendManagerRequest:getVideoCapabilityRequest withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (!response.success || [response isMemberOfClass:SDLGenericResponse.class]) {
+ SDLLogW(@"Video capabilities response failed: %@", error);
+ responseHandler(nil);
+ BLOCK_RETURN;
+ }
+
+ SDLVideoStreamingCapability *videoCapability = ((SDLGetSystemCapabilityResponse *)response).systemCapability.videoStreamingCapability;
+ SDLLogD(@"Video capabilities response received: %@", videoCapability);
+ responseHandler(videoCapability);
+ }];
+}
+
+/**
+ Pull the current format / resolution out of our preferred resolutions and craft a start video service payload out of it, then send a start service. If the format isn't one that we support, we're going to try the next format.
+ */
+- (void)sdl_sendVideoStartService {
+ SDLLogV(@"Attempting to find preferred format");
+ while (self.preferredFormatIndex < self.preferredFormats.count) {
+ if (![self.supportedFormats containsObject:self.preferredFormats[self.preferredFormatIndex]]) {
+ self.preferredFormatIndex++;
+ } else {
+ SDLLogV(@"Preferred format index found: %lu", self.preferredFormatIndex);
+ break;
+ }
+ }
+
+ // If this fails we have no known formats to use
+ if (self.preferredFormatIndex >= self.preferredFormats.count
+ || self.preferredResolutionIndex >= self.preferredResolutions.count) {
+ SDLLogE(@"No preferred format or no preferred resolution found that works: format index %lu, resolution index %lu", self.preferredFormatIndex, self.preferredResolutionIndex);
+ [self sdl_transitionToStoppedState:SDLServiceTypeVideo];
+ return;
+ }
+
+ SDLVideoStreamingFormat *preferredFormat = self.preferredFormats[self.preferredFormatIndex];
+ SDLImageResolution *preferredResolution = self.preferredResolutions[self.preferredResolutionIndex];
+
+ SDLControlFramePayloadVideoStartService *startVideoPayload = [[SDLControlFramePayloadVideoStartService alloc] initWithVideoHeight:preferredResolution.resolutionHeight.intValue width:preferredResolution.resolutionWidth.intValue protocol:preferredFormat.protocol codec:preferredFormat.codec];
+
+ // Decide if we need to start a secure service or not
+ if (self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) {
+ SDLLogD(@"Sending secure video start service with payload: %@", startVideoPayload);
+ [self.protocol startSecureServiceWithType:SDLServiceTypeVideo payload:startVideoPayload.data completionHandler:^(BOOL success, NSError *error) {
+ if (error) {
+ SDLLogE(@"TLS setup error: %@", error);
+ [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped];
+ }
+ }];
+ } else {
+ SDLLogD(@"Sending insecure video start service with payload: %@", startVideoPayload);
+ [self.protocol startServiceWithType:SDLServiceTypeVideo payload:startVideoPayload.data];
+ }
+}
+
+
#pragma mark Getters
+
- (BOOL)isAppStateVideoStreamCapable {
return [self.appStateMachine isCurrentState:SDLAppStateActive];
}
@@ -563,6 +760,13 @@ static NSUInteger const SDLFramesToSendOnBackground = 30;
return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull];
}
+- (NSArray<SDLVideoStreamingFormat *> *)supportedFormats {
+ SDLVideoStreamingFormat *h264raw = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRAW];
+ SDLVideoStreamingFormat *h264rtp = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP];
+
+ return @[h264raw, h264rtp];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h
index 46169484b..571d4320f 100644
--- a/SmartDeviceLink/SDLStreamingMediaManager.h
+++ b/SmartDeviceLink/SDLStreamingMediaManager.h
@@ -12,7 +12,11 @@
#import "SDLStreamingMediaManagerConstants.h"
@class SDLAbstractProtocol;
+@class SDLStreamingMediaConfiguration;
@class SDLTouchManager;
+@class SDLVideoStreamingFormat;
+
+@protocol SDLConnectionManagerType;
NS_ASSUME_NONNULL_BEGIN
@@ -30,12 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @see SDLRegisterAppInterface SDLDisplayCapabilities
*/
-@property (assign, nonatomic, readonly, getter=isVideoStreamingSupported) BOOL videoStreamingSupported;
-
-/**
- * Whether or not audio streaming is supported. Currently this is the same as videoStreamingSupported.
- */
-@property (assign, nonatomic, readonly, getter=isAudioStreamingSupported) BOOL audioStreamingSupported;
+@property (assign, nonatomic, readonly, getter=isStreamingSupported) BOOL streamingSupported;
/**
* Whether or not the video session is connected.
@@ -68,6 +67,16 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic, readonly) CGSize screenSize;
/**
+ This is the agreed upon format of video encoder that is in use, or nil if not currently connected.
+ */
+@property (strong, nonatomic, readonly, nullable) SDLVideoStreamingFormat *videoFormat;
+
+/**
+ A list of all supported video formats by this manager
+ */
+@property (strong, nonatomic, readonly) NSArray<SDLVideoStreamingFormat *> *supportedFormats;
+
+/**
* The pixel buffer pool reference returned back from an active VTCompressionSessionRef encoder.
*
* @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started).
@@ -82,22 +91,21 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType;
+- (instancetype)init NS_UNAVAILABLE;
+
/**
- * Creates a streaming manager with a specified encryption type.
- *
- * @param encryption The encryption type requested when starting to stream.
- * @param videoEncoderSettings The video encoder settings to use with SDLVideoEncoder.
- *
- * @return An instance of SDLStreamingMediaManager
+ 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)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings NS_DESIGNATED_INITIALIZER;
+- (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`.
- *
- * @param completionHandler The block to be called when the manager's setup is complete.
*/
-- (void)startWithProtocol:(SDLAbstractProtocol*)protocol completionHandler:(void (^)(BOOL success, NSError *__nullable error))completionHandler;
+- (void)startWithProtocol:(SDLAbstractProtocol *)protocol;
/**
* Stop the manager. This method is used internally.
diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m
index 72bbf9691..31f69946d 100644
--- a/SmartDeviceLink/SDLStreamingMediaManager.m
+++ b/SmartDeviceLink/SDLStreamingMediaManager.m
@@ -8,6 +8,9 @@
#import "SDLStreamingMediaManager.h"
+#import "SDLConnectionManagerType.h"
+#import "SDLStreamingMediaConfiguration.h"
+#import "SDLStreamingMediaManagerDataSource.h"
#import "SDLStreamingMediaLifecycleManager.h"
#import "SDLTouchManager.h"
@@ -26,23 +29,19 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Public
#pragma mark Lifecycle
-- (instancetype)init {
- return [self initWithEncryption:SDLStreamingEncryptionFlagAuthenticateAndEncrypt videoEncoderSettings:nil];
-}
-
-- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings {
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager configuration:(SDLStreamingMediaConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
- _lifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithEncryption:encryption videoEncoderSettings:videoEncoderSettings];
+ _lifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithConnectionManager:connectionManager configuration:configuration];
return self;
}
-- (void)startWithProtocol:(SDLAbstractProtocol *)protocol completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler {
- [self.lifecycleManager startWithProtocol:protocol completionHandler:completionHandler];
+- (void)startWithProtocol:(SDLAbstractProtocol *)protocol {
+ [self.lifecycleManager startWithProtocol:protocol];
}
- (void)stop {
@@ -68,12 +67,8 @@ NS_ASSUME_NONNULL_BEGIN
return self.lifecycleManager.touchManager;
}
-- (BOOL)isAudioStreamingSupported {
- return self.lifecycleManager.isAudioStreamingSupported;
-}
-
-- (BOOL)isVideoStreamingSupported {
- return self.lifecycleManager.isVideoStreamingSupported;
+- (BOOL)isStreamingSupported {
+ return self.lifecycleManager.isStreamingSupported;
}
- (BOOL)isAudioConnected {
@@ -100,6 +95,14 @@ NS_ASSUME_NONNULL_BEGIN
return self.lifecycleManager.screenSize;
}
+- (nullable SDLVideoStreamingFormat *)videoFormat {
+ return self.lifecycleManager.videoFormat;
+}
+
+- (NSArray<SDLVideoStreamingFormat *> *)supportedFormats {
+ return self.lifecycleManager.supportedFormats;
+}
+
- (CVPixelBufferPoolRef __nullable)pixelBufferPool {
return self.lifecycleManager.pixelBufferPool;
}
diff --git a/SmartDeviceLink/SDLStreamingMediaManagerDataSource.h b/SmartDeviceLink/SDLStreamingMediaManagerDataSource.h
new file mode 100644
index 000000000..7fdf13e38
--- /dev/null
+++ b/SmartDeviceLink/SDLStreamingMediaManagerDataSource.h
@@ -0,0 +1,40 @@
+//
+// SDLStreamingMediaManagerDataSource.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 8/28/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class SDLImageResolution;
+@class SDLVideoStreamingFormat;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol SDLStreamingMediaManagerDataSource <NSObject>
+
+/**
+ Implement to return a different preferred order of attempted format usage than the head unit's preferred order. In nearly all cases, it's best to simply return the head unit's preferred order, or not implement this method (which does the same thing).
+
+ @warning If you return a format that is not supported by the StreamingMediaManager, that format will be skipped.
+
+ @note If the head unit does not support the `GetSystemCapabilities` RPC, this method will not be called and H264 RAW will be used.
+
+ @param headUnitPreferredOrder The head unit's preferred order of format usage. The first item is the one that will be used unless this proxy does not support it, then the next item, etc.
+ @return Your preferred order of format usage.
+ */
+- (NSArray<SDLVideoStreamingFormat *> *)preferredVideoFormatOrderFromHeadUnitPreferredOrder:(NSArray<SDLVideoStreamingFormat *> *)headUnitPreferredOrder;
+
+/**
+ Implement to return a different resolution to use for video streaming than the head unit's requested resolution. If you return a resolution that the head unit does not like, the manager will fail to start up. In nearly all cases, it's best to simply return the head unit's preferred order, or not implement this method (which does the same thing), and adapt your UI to the head unit's preferred resolution instead.
+
+ @param headUnitPreferredResolution The resolution the head unit requested to use.
+ @return Your preferred order of image resolution usage. This system will not attempt more than 3 resolutions. It is strongly recommended that at least one resolution is the head unit's preferred resolution.
+ */
+- (NSArray<SDLImageResolution *> *)resolutionFromHeadUnitPreferredResolution:(SDLImageResolution *)headUnitPreferredResolution;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLVideoEncoderDelegate.h b/SmartDeviceLink/SDLVideoEncoderDelegate.h
index db4294106..a8bf27f22 100644
--- a/SmartDeviceLink/SDLVideoEncoderDelegate.h
+++ b/SmartDeviceLink/SDLVideoEncoderDelegate.h
@@ -8,10 +8,10 @@
#import <Foundation/Foundation.h>
-@class SDLVideoEncoder;
+@class SDLH264VideoEncoder;
@protocol SDLVideoEncoderDelegate <NSObject>
-- (void)videoEncoder:(SDLVideoEncoder *)encoder hasEncodedFrame:(NSData*)encodedVideo;
+- (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData*)encodedVideo;
@end
diff --git a/SmartDeviceLink/SDLVideoStreamingCapability.h b/SmartDeviceLink/SDLVideoStreamingCapability.h
index 86de1f1ac..c4e9c967e 100644
--- a/SmartDeviceLink/SDLVideoStreamingCapability.h
+++ b/SmartDeviceLink/SDLVideoStreamingCapability.h
@@ -15,7 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLVideoStreamingCapability : SDLRPCStruct
-- (instancetype)initWithVideoStreaming:(nullable SDLImageResolution *)preferredResolution maxBitrate:(nullable NSNumber<SDLInt> *)maxBitrate supportedFormats:(nullable NSArray<SDLVideoStreamingFormat *> *)supportedFormats hapticDataSupported:(nullable NSNumber<SDLBool> *)hapticDataSupported;
+- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray<SDLVideoStreamingFormat *> *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported;
+
/**
* @abstract The preferred resolution of a video stream for decoding and rendering on HMI, optional
*/
diff --git a/SmartDeviceLink/SDLVideoStreamingCapability.m b/SmartDeviceLink/SDLVideoStreamingCapability.m
index 75873a710..c5f5ae26c 100644
--- a/SmartDeviceLink/SDLVideoStreamingCapability.m
+++ b/SmartDeviceLink/SDLVideoStreamingCapability.m
@@ -17,16 +17,16 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLVideoStreamingCapability
-- (instancetype)initWithVideoStreaming:(nullable SDLImageResolution *)preferredResolution maxBitrate:(nullable NSNumber<SDLInt> *)maxBitrate supportedFormats:(nullable NSArray<SDLVideoStreamingFormat *> *)supportedFormats hapticDataSupported:(nullable NSNumber<SDLBool> *)hapticDataSupported {
+- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray<SDLVideoStreamingFormat *> *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported {
self = [self init];
if (!self) {
return self;
}
- self.maxBitrate = maxBitrate;
+ self.maxBitrate = @(maxBitrate);
self.preferredResolution = preferredResolution;
self.supportedFormats = supportedFormats;
- self.hapticSpatialDataSupported = hapticDataSupported;
+ self.hapticSpatialDataSupported = @(hapticDataSupported);
return self;
}
diff --git a/SmartDeviceLink/SDLVideoStreamingFormat.h b/SmartDeviceLink/SDLVideoStreamingFormat.h
index 75f0941ee..87657eb47 100644
--- a/SmartDeviceLink/SDLVideoStreamingFormat.h
+++ b/SmartDeviceLink/SDLVideoStreamingFormat.h
@@ -21,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic) SDLVideoStreamingCodec codec;
+- (instancetype)initWithCodec:(SDLVideoStreamingCodec)codec protocol:(SDLVideoStreamingProtocol)protocol;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLVideoStreamingFormat.m b/SmartDeviceLink/SDLVideoStreamingFormat.m
index d7f018b5d..35c639537 100644
--- a/SmartDeviceLink/SDLVideoStreamingFormat.m
+++ b/SmartDeviceLink/SDLVideoStreamingFormat.m
@@ -14,11 +14,21 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLVideoStreamingFormat
+- (instancetype)initWithCodec:(SDLVideoStreamingCodec)codec protocol:(SDLVideoStreamingProtocol)protocol {
+ self = [self init];
+ if (!self) { return nil; }
+
+ self.codec = codec;
+ self.protocol = protocol;
+
+ return self;
+}
+
- (SDLVideoStreamingProtocol)protocol {
return [store sdl_objectForName:SDLNameVideoProtocol];
}
-- (void)setVideoStreamingProtocol:(SDLVideoStreamingProtocol)protocol {
+- (void)setProtocol:(SDLVideoStreamingProtocol)protocol {
[store sdl_setObject:protocol forName:SDLNameVideoProtocol];
}
@@ -26,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
return [store sdl_objectForName:SDLNameVideoCodec];
}
-- (void)setVideoStreamingCodec:(SDLVideoStreamingCodec)codec {
+- (void)setCodec:(SDLVideoStreamingCodec)codec {
[store sdl_setObject:codec forName:SDLNameVideoCodec];
}
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m
index 5401af98a..6afb1f3cf 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m
@@ -9,7 +9,7 @@
QuickSpecBegin(SDLConfigurationSpec)
-fdescribe(@"a configuration", ^{
+describe(@"a configuration", ^{
__block SDLConfiguration *testConfig = nil;
context(@"created with custom configs", ^{
@@ -54,21 +54,21 @@ fdescribe(@"a configuration", ^{
});
it(@"should create correctly with initWithLifecycle:lockScreen:logging:streamingMedia:", ^{
- testConfig = [[SDLConfiguration alloc] initWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig logging:someLogConfig streamingMedia:someStreamingConfig];
+ testConfig = [[SDLConfiguration alloc] initWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig logging:someLogConfig streamingMedia:nil];
expect(testConfig.lifecycleConfig).to(equal(someLifecycleConfig));
expect(testConfig.lockScreenConfig).to(equal(someLockscreenConfig));
expect(testConfig.loggingConfig).to(equal(someLogConfig));
- expect(testConfig.streamingMediaConfig).to(equal(someStreamingConfig));
+ expect(testConfig.streamingMediaConfig).to(beNil());
});
it(@"should create correctly with configurationWithLifecycle:lockScreen:logging:streamingMedia:", ^{
- testConfig = [SDLConfiguration configurationWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig logging:someLogConfig streamingMedia:someStreamingConfig];
+ testConfig = [SDLConfiguration configurationWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig logging:someLogConfig streamingMedia:nil];
expect(testConfig.lifecycleConfig).to(equal(someLifecycleConfig));
expect(testConfig.lockScreenConfig).to(equal(someLockscreenConfig));
expect(testConfig.loggingConfig).to(equal(someLogConfig));
- expect(testConfig.streamingMediaConfig).to(equal(someStreamingConfig));
+ expect(testConfig.streamingMediaConfig).to(beNil());
});
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.h b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.h
new file mode 100644
index 000000000..7081bad29
--- /dev/null
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.h
@@ -0,0 +1,17 @@
+//
+// SDLFakeStreamingManagerDataSource.h
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 9/5/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLStreamingMediaManagerDataSource.h"
+
+@interface SDLFakeStreamingManagerDataSource : NSObject <SDLStreamingMediaManagerDataSource>
+
+@property (strong, nonatomic, readonly) SDLVideoStreamingFormat *extraFormat;
+
+@end
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.m
new file mode 100644
index 000000000..e8e58c04c
--- /dev/null
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeStreamingManagerDataSource.m
@@ -0,0 +1,30 @@
+//
+// SDLFakeStreamingManagerDataSource.m
+// SmartDeviceLink-iOS
+//
+// Created by Joel Fischer on 9/5/17.
+// Copyright © 2017 smartdevicelink. All rights reserved.
+//
+
+#import "SDLFakeStreamingManagerDataSource.h"
+
+#import "SDLImageResolution.h"
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingFormat.h"
+#import "SDLVideoStreamingProtocol.h"
+
+@implementation SDLFakeStreamingManagerDataSource
+
+- (SDLVideoStreamingFormat *)extraFormat {
+ return [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecVP8 protocol:SDLVideoStreamingProtocolRTMP];
+}
+
+- (NSArray<SDLVideoStreamingFormat *> *)preferredVideoFormatOrderFromHeadUnitPreferredOrder:(NSArray<SDLVideoStreamingFormat *> *)headUnitPreferredOrder {
+ return [@[self.extraFormat] arrayByAddingObjectsFromArray:headUnitPreferredOrder];
+}
+
+- (NSArray<SDLImageResolution *> *)resolutionFromHeadUnitPreferredResolution:(SDLImageResolution *)headUnitPreferredResolution {
+ return @[headUnitPreferredResolution];
+}
+
+@end
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
index 70e30f6b5..f858906d4 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
@@ -231,13 +231,12 @@ xdescribe(@"a lifecycle manager", ^{
describe(@"after receiving a register app interface response", ^{
__block NSError *fileManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil];
__block NSError *permissionManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil];
- __block NSError *streamingManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil];
beforeEach(^{
OCMStub([(SDLLockScreenManager *)lockScreenManagerMock start]);
OCMStub([fileManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), fileManagerStartError, nil])]);
OCMStub([permissionManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), permissionManagerStartError, nil])]);
- OCMStub([streamingManagerMock startWithProtocol:protocolMock completionHandler:([OCMArg invokeBlockWithArgs:@(YES), streamingManagerStartError, nil])]);
+ OCMStub([streamingManagerMock startWithProtocol:protocolMock]);
// Send an RAI response to move the lifecycle forward
[testManager.lifecycleStateMachine transitionToState:SDLLifecycleStateRegistered];
@@ -249,7 +248,7 @@ xdescribe(@"a lifecycle manager", ^{
OCMVerify([(SDLLockScreenManager *)lockScreenManagerMock start]);
OCMVerify([fileManagerMock startWithCompletionHandler:[OCMArg any]]);
OCMVerify([permissionManagerMock startWithCompletionHandler:[OCMArg any]]);
- OCMVerify([streamingManagerMock startWithProtocol:[OCMArg any] completionHandler:[OCMArg any]]);
+ OCMVerify([streamingManagerMock startWithProtocol:[OCMArg any]]);
});
itBehavesLike(@"unable to send an RPC", ^{ return @{ @"manager": testManager }; });
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLH264ByteStreamPacketizerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLRAWH264PacketizerSpec.m
index 59a3529bf..e55ecc1de 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLH264ByteStreamPacketizerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLRAWH264PacketizerSpec.m
@@ -9,9 +9,9 @@
#import <Foundation/Foundation.h>
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
-#import "SDLH264ByteStreamPacketizer.h"
+#import "SDLRAWH264Packetizer.h"
-QuickSpecBegin(SDLH264ByteStreamPacketizerSpec)
+QuickSpecBegin(SDLRAWH264PacketizerSpec)
describe(@"a H264 byte stream packetizer", ^{
// sample NAL units (SPS, PPS, I-frame, P-frame)
@@ -25,10 +25,10 @@ describe(@"a H264 byte stream packetizer", ^{
NSData *iframe = [NSData dataWithBytes:iframeData length:sizeof(iframeData)];
NSData *pframe = [NSData dataWithBytes:pframeData length:sizeof(pframeData)];
- __block SDLH264ByteStreamPacketizer *packetizer = nil;
+ __block SDLRAWH264Packetizer *packetizer = nil;
beforeEach(^{
- packetizer = [[SDLH264ByteStreamPacketizer alloc] init];
+ packetizer = [[SDLRAWH264Packetizer alloc] init];
});
describe(@"its output array", ^{
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m
index d9a166487..e4f54708d 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m
@@ -5,21 +5,25 @@
#import "SDLStreamingMediaConfiguration.h"
#import "SDLFakeSecurityManager.h"
+#import "SDLFakeStreamingManagerDataSource.h"
QuickSpecBegin(SDLStreamingMediaConfigurationSpec)
describe(@"a streaming media configuration", ^{
__block SDLStreamingMediaConfiguration *testConfig = nil;
+ __block SDLFakeStreamingManagerDataSource *testDataSource = nil;
context(@"that is created with insecure settings", ^{
beforeEach(^{
testConfig = [SDLStreamingMediaConfiguration insecureConfiguration];
+ testDataSource = [[SDLFakeStreamingManagerDataSource alloc] init];
});
it(@"should have properly set properties", ^{
expect(testConfig.securityManagers).to(beNil());
expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(SDLStreamingEncryptionFlagNone)));
expect(testConfig.customVideoEncoderSettings).to(beNil());
+ expect(testConfig.dataSource).to(beNil());
});
describe(@"after setting properties manually", ^{
@@ -33,12 +37,14 @@ describe(@"a streaming media configuration", ^{
testConfig.maximumDesiredEncryption = someEncryptionFlag;
testConfig.customVideoEncoderSettings = someVideoEncoderSettings;
+ testConfig.dataSource = testDataSource;
});
it(@"should have properly set properties", ^{
expect(testConfig.securityManagers).to(beNil());
expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(someEncryptionFlag)));
expect(testConfig.customVideoEncoderSettings).to(equal(someVideoEncoderSettings));
+ expect(testConfig.dataSource).toNot(beNil());
});
});
});
@@ -49,11 +55,11 @@ describe(@"a streaming media configuration", ^{
beforeEach(^{
testFakeSecurityManager = [[SDLFakeSecurityManager alloc] init];
- testConfig = [SDLStreamingMediaConfiguration secureConfigurationWithSecurityManagers:@[testFakeSecurityManager]];
+ testConfig = [SDLStreamingMediaConfiguration secureConfigurationWithSecurityManagers:@[testFakeSecurityManager.class]];
});
it(@"should have properly set properties", ^{
- expect(testConfig.securityManagers).to(contain(testFakeSecurityManager));
+ expect(testConfig.securityManagers).to(contain(testFakeSecurityManager.class));
expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(SDLStreamingEncryptionFlagAuthenticateAndEncrypt)));
expect(testConfig.customVideoEncoderSettings).to(beNil());
});
@@ -72,7 +78,7 @@ describe(@"a streaming media configuration", ^{
});
it(@"should have properly set properties", ^{
- expect(testConfig.securityManagers).to(contain(testFakeSecurityManager));
+ expect(testConfig.securityManagers).to(contain(testFakeSecurityManager.class));
expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(someEncryptionFlag)));
expect(testConfig.customVideoEncoderSettings).to(equal(someVideoEncoderSettings));
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLImageResolutionSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLImageResolutionSpec.m
new file mode 100644
index 000000000..c56008516
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLImageResolutionSpec.m
@@ -0,0 +1,46 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLImageResolution.h"
+#import "SDLNames.h"
+
+QuickSpecBegin(SDLImageResolutionSpec)
+
+describe(@"Getter/Setter Tests", ^ {
+ it(@"Should set and get correctly", ^ {
+ SDLImageResolution *testStruct = [[SDLImageResolution alloc] init];
+
+ testStruct.resolutionWidth = @245;
+ testStruct.resolutionHeight = @42;
+
+ expect(testStruct.resolutionHeight).to(equal(@42));
+ expect(testStruct.resolutionWidth).to(equal(@245));
+ });
+
+ it(@"should correct initialize", ^{
+ SDLImageResolution *testStruct = [[SDLImageResolution alloc] initWithWidth:1245 height:789];
+
+ expect(testStruct.resolutionHeight).to(equal(@789));
+ expect(testStruct.resolutionWidth).to(equal(@1245));
+ });
+
+ it(@"Should get correctly when initialized", ^ {
+ NSDictionary *dict = @{SDLNameResolutionHeight:@69,
+ SDLNameResolutionWidth:@869,
+ };
+ SDLImageResolution *testStruct = [[SDLImageResolution alloc] initWithDictionary:dict];
+
+ expect(testStruct.resolutionWidth).to(equal(@869));
+ expect(testStruct.resolutionHeight).to(equal(@69));
+ });
+
+ it(@"Should return nil if not set", ^ {
+ SDLImageResolution *testStruct = [[SDLImageResolution alloc] init];
+
+ expect(testStruct.resolutionHeight).to(beNil());
+ expect(testStruct.resolutionWidth).to(beNil());
+ });
+});
+
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
index 36f3c0e8e..05e5f4fa5 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
@@ -86,7 +86,7 @@ describe(@"Initialization tests", ^{
resolution.resolutionWidth = @600;
resolution.resolutionHeight = @500;
- NSNumber *maxBitrate = @100;
+ int32_t maxBitrate = 100;
NSNumber *hapticDataSupported = @YES;
SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init];
@@ -99,7 +99,7 @@ describe(@"Initialization tests", ^{
NSArray<SDLVideoStreamingFormat *> *formatArray = @[format1, format2];
- SDLVideoStreamingCapability *testVidStruct = [[SDLVideoStreamingCapability alloc] initWithVideoStreaming:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported];
+ SDLVideoStreamingCapability *testVidStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported];
SDLSystemCapability *testStruct = [[SDLSystemCapability alloc] initWithVideoStreamingCapability:testVidStruct];
expect(testStruct.systemCapabilityType).to(equal(SDLSystemCapabilityTypeVideoStreaming));
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m
index c977e0db7..ce42ce9d2 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m
@@ -60,12 +60,12 @@ describe(@"Initialization tests", ^{
expect(testStruct.supportedFormats).to(beNil());
});
- it(@"Should initialize correctly with initWithVideoStreaming:(SDLImageResolution *)preferredResolution (NSNumber *)maxBitrate (NSArray<SDLVideoStreamingFormat *> *)suportedFormats", ^ {
+ it(@"Should initialize correctly with initWithVideoStreaming:maxBitrate:suportedFormats", ^ {
SDLImageResolution* resolution = [[SDLImageResolution alloc] init];
resolution.resolutionWidth = @600;
resolution.resolutionHeight = @500;
- NSNumber *maxBitrate = @100;
+ int32_t maxBitrate = 100;
NSNumber *hapticDataSupported = @YES;
SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init];
@@ -78,7 +78,7 @@ describe(@"Initialization tests", ^{
NSArray<SDLVideoStreamingFormat *> *formatArray = @[format1, format2];
- SDLVideoStreamingCapability *testStruct = [[SDLVideoStreamingCapability alloc] initWithVideoStreaming:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported];
+ SDLVideoStreamingCapability *testStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported];
expect(testStruct.preferredResolution).to(equal(resolution));
expect(testStruct.maxBitrate).to(equal(maxBitrate));
diff --git a/SmartDeviceLinkTests/SDLVideoEncoderSpec.m b/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m
index c621f6a84..484b8b41a 100644
--- a/SmartDeviceLinkTests/SDLVideoEncoderSpec.m
+++ b/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m
@@ -7,33 +7,43 @@
//
#import <Foundation/Foundation.h>
+#import <AVFoundation/AVFoundation.h>
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
#import <OCMock/OCMock.h>
-#import "SDLVideoEncoder.h"
-#import <AVFoundation/AVFoundation.h>
+#import "SDLH264VideoEncoder.h"
+#import "SDLRAWH264Packetizer.h"
+#import "SDLRTPH264Packetizer.h"
+#import "SDLVideoStreamingProtocol.h"
-QuickSpecBegin(SDLVideoEncoderSpec)
+QuickSpecBegin(SDLH264VideoEncoderSpec)
describe(@"a video encoder", ^{
- __block SDLVideoEncoder *testVideoEncoder = nil;
- __block CGSize testSize = CGSizeMake(100, 200);
+ __block SDLH264VideoEncoder *testVideoEncoder = nil;
+ __block CGSize testSize = CGSizeZero;
__block id videoEncoderDelegateMock = OCMProtocolMock(@protocol(SDLVideoEncoderDelegate));
__block NSError *testError = nil;
+ __block SDLVideoStreamingProtocol testProtocol = nil;
+
+ beforeEach(^{
+ testSize = CGSizeMake(100, 200);
+ testProtocol = SDLVideoStreamingProtocolRAW;
+ testError = nil;
+ });
context(@"if using default video encoder settings", ^{
-
beforeEach(^{
- testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:SDLVideoEncoder.defaultVideoEncoderSettings delegate:videoEncoderDelegateMock error:&testError];
+ testVideoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:testProtocol dimensions:testSize properties:SDLH264VideoEncoder.defaultVideoEncoderSettings delegate:videoEncoderDelegateMock error:&testError];
});
it(@"should initialize properties", ^{
expect(testVideoEncoder).toNot(beNil());
- expect(testVideoEncoder.videoEncoderSettings).to(equal(SDLVideoEncoder.defaultVideoEncoderSettings));
+ expect(testVideoEncoder.videoEncoderSettings).to(equal(SDLH264VideoEncoder.defaultVideoEncoderSettings));
expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@NO));
expect(testError).to(beNil());
+ expect(testVideoEncoder.packetizer).to(beAnInstanceOf([SDLRAWH264Packetizer class]));
NSDictionary *pixelBufferProperties = (__bridge NSDictionary*)CVPixelBufferPoolGetPixelBufferAttributes(testVideoEncoder.pixelBufferPool);
expect(pixelBufferProperties[(__bridge NSString*)kCVPixelBufferWidthKey]).to(equal(@100));
@@ -51,7 +61,7 @@ describe(@"a video encoder", ^{
});
});
- context(@"is using custom video encoder settings", ^{
+ describe(@"is using custom video encoder settings", ^{
__block NSDictionary *testSettings = nil;
context(@"that is a valid setting", ^{
@@ -59,7 +69,8 @@ describe(@"a video encoder", ^{
testSettings = @{
(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1
};
- testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError];
+
+ testVideoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:testProtocol dimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError];
});
it(@"should initialize properties", ^{
@@ -79,17 +90,39 @@ describe(@"a video encoder", ^{
testSettings = @{
@"Bad" : @"Property"
};
- testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError];
+ testVideoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:testProtocol dimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError];
});
it(@"should not be initialized", ^{
expect(testVideoEncoder).to(beNil());
- expect(testVideoEncoder.videoEncoderSettings).to(beNil());
- expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@YES));
expect(testError).to(equal([NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ NSLocalizedDescriptionKey : @"\"Bad\" is not a supported key." }]));
});
});
});
+
+ context(@"using an unknown protocol", ^{
+ beforeEach(^{
+ testProtocol = SDLVideoStreamingProtocolRTSP;
+ testVideoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:testProtocol dimensions:testSize properties:SDLH264VideoEncoder.defaultVideoEncoderSettings delegate:videoEncoderDelegateMock error:&testError];
+ });
+
+ it(@"should not be initialized", ^{
+ expect(testVideoEncoder).to(beNil());
+ expect(testError.code).to(equal(SDLVideoEncoderErrorProtocolUnknown));
+ expect(testError.userInfo[@"encoder"]).to(equal(testProtocol));
+ });
+ });
+
+ context(@"creating with RTP H264 Protocol", ^{
+ beforeEach(^{
+ testProtocol = SDLVideoStreamingProtocolRTP;
+ testVideoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:testProtocol dimensions:testSize properties:SDLH264VideoEncoder.defaultVideoEncoderSettings delegate:videoEncoderDelegateMock error:&testError];
+ });
+
+ it(@"should create an RTP packetizer", ^{
+ expect(testVideoEncoder.packetizer).to(beAnInstanceOf([SDLRTPH264Packetizer class]));
+ });
+ });
});
QuickSpecEnd
diff --git a/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m
index 613313bcd..0c887f2d3 100644
--- a/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m
@@ -7,26 +7,46 @@
#import <Nimble/Nimble.h>
#import <OCMock/OCMock.h>
+#import "SDLConnectionManagerType.h"
+#import "SDLControlFramePayloadAudioStartServiceAck.h"
+#import "SDLControlFramePayloadConstants.h"
+#import "SDLControlFramePayloadNak.h"
+#import "SDLControlFramePayloadVideoStartServiceAck.h"
#import "SDLDisplayCapabilities.h"
+#import "SDLGenericResponse.h"
+#import "SDLGetSystemCapability.h"
+#import "SDLGetSystemCapabilityResponse.h"
+#import "SDLGlobals.h"
+#import "SDLHMILevel.h"
#import "SDLImageResolution.h"
#import "SDLNotificationConstants.h"
+#import "SDLOnHMIStatus.h"
+#import "SDLProtocol.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLRegisterAppInterfaceResponse.h"
#import "SDLRPCResponseNotification.h"
#import "SDLScreenParams.h"
#import "SDLStateMachine.h"
+#import "SDLStreamingMediaConfiguration.h"
#import "SDLStreamingMediaLifecycleManager.h"
-#import "SDLProtocol.h"
-#import "SDLOnHMIStatus.h"
-#import "SDLHMILevel.h"
+#import "SDLFakeStreamingManagerDataSource.h"
+#import "SDLSystemCapability.h"
+#import "SDLV2ProtocolHeader.h"
+#import "SDLV2ProtocolMessage.h"
+#import "SDLVideoStreamingCapability.h"
+#import "SDLVideoStreamingCodec.h"
+#import "SDLVideoStreamingFormat.h"
+#import "SDLVideoStreamingProtocol.h"
+#import "TestConnectionManager.h"
QuickSpecBegin(SDLStreamingMediaLifecycleManagerSpec)
describe(@"the streaming media manager", ^{
__block SDLStreamingMediaLifecycleManager *streamingLifecycleManager = nil;
- __block SDLStreamingEncryptionFlag streamingEncryptionFlag = SDLStreamingEncryptionFlagAuthenticateOnly;
- __block NSDictionary<NSString *, id> *someVideoEncoderSettings = nil;
+ __block SDLStreamingMediaConfiguration *testConfiguration = [SDLStreamingMediaConfiguration insecureConfiguration];
+ __block SDLFakeStreamingManagerDataSource *testDataSource = [[SDLFakeStreamingManagerDataSource alloc] init];
__block NSString *someBackgroundTitleString = nil;
+ __block TestConnectionManager *testConnectionManager = nil;
__block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILevel hmiLevel) {
SDLOnHMIStatus *hmiStatus = [[SDLOnHMIStatus alloc] init];
@@ -34,21 +54,22 @@ describe(@"the streaming media manager", ^{
SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:self rpcNotification:hmiStatus];
[[NSNotificationCenter defaultCenter] postNotification:notification];
- [NSThread sleepForTimeInterval:0.1];
+ [NSThread sleepForTimeInterval:0.3];
};
beforeEach(^{
- someVideoEncoderSettings = @{
+ testConfiguration.customVideoEncoderSettings = @{
(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1
};
+ testConfiguration.dataSource = testDataSource;
someBackgroundTitleString = @"Open Test App";
- streamingLifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithEncryption:streamingEncryptionFlag videoEncoderSettings:someVideoEncoderSettings];
+ testConnectionManager = [[TestConnectionManager alloc] init];
+ streamingLifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithConnectionManager:testConnectionManager configuration:testConfiguration];
});
it(@"should initialize properties", ^{
expect(streamingLifecycleManager.touchManager).toNot(beNil());
- expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO));
- expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO));
+ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO));
expect(@(streamingLifecycleManager.isVideoConnected)).to(equal(@NO));
expect(@(streamingLifecycleManager.isAudioConnected)).to(equal(@NO));
expect(@(streamingLifecycleManager.isVideoEncrypted)).to(equal(@NO));
@@ -56,10 +77,17 @@ describe(@"the streaming media manager", ^{
expect(@(streamingLifecycleManager.isVideoStreamingPaused)).to(equal(@YES));
expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero))).to(equal(@YES));
expect(@(streamingLifecycleManager.pixelBufferPool == NULL)).to(equal(@YES));
- expect(@(streamingLifecycleManager.requestedEncryptionType)).to(equal(@(streamingEncryptionFlag)));
+ expect(@(streamingLifecycleManager.requestedEncryptionType)).to(equal(@(SDLStreamingEncryptionFlagNone)));
expect(streamingLifecycleManager.currentAppState).to(equal(SDLAppStateActive));
expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStopped));
expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ expect(streamingLifecycleManager.videoFormat).to(beNil());
+ expect(streamingLifecycleManager.dataSource).to(equal(testDataSource));
+ expect(streamingLifecycleManager.supportedFormats).to(haveCount(2));
+ expect(streamingLifecycleManager.preferredFormats).to(beNil());
+ expect(streamingLifecycleManager.preferredResolutions).to(beNil());
+ expect(streamingLifecycleManager.preferredFormatIndex).to(equal(0));
+ expect(streamingLifecycleManager.preferredResolutionIndex).to(equal(0));
});
describe(@"when started", ^{
@@ -72,16 +100,11 @@ describe(@"the streaming media manager", ^{
readyHandlerSuccess = NO;
readyHandlerError = nil;
- [streamingLifecycleManager startWithProtocol:protocolMock completionHandler:^(BOOL success, NSError * _Nullable error) {
- readyHandlerSuccess = success;
- readyHandlerError = error;
- }];
+ [streamingLifecycleManager startWithProtocol:protocolMock];
});
-
it(@"should be ready to stream", ^{
- expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO));
- expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO));
+ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO));
expect(@(streamingLifecycleManager.isVideoConnected)).to(equal(@NO));
expect(@(streamingLifecycleManager.isAudioConnected)).to(equal(@NO));
expect(@(streamingLifecycleManager.isVideoEncrypted)).to(equal(@NO));
@@ -92,7 +115,13 @@ describe(@"the streaming media manager", ^{
expect(streamingLifecycleManager.currentAppState).to(equal(SDLAppStateActive));
expect(streamingLifecycleManager.currentAudioStreamState).to(match(SDLAudioStreamStateStopped));
expect(streamingLifecycleManager.currentVideoStreamState).to(match(SDLVideoStreamStateStopped));
-
+ });
+
+ it(@"should send out a video capabilities request", ^{
+ expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLGetSystemCapability class]));
+
+ SDLGetSystemCapability *getCapability = (SDLGetSystemCapability *)testConnectionManager.receivedRequests.lastObject;
+ expect(getCapability.systemCapabilityType).to(equal(SDLSystemCapabilityTypeVideoStreaming));
});
describe(@"after receiving a register app interface notification", ^{
@@ -110,7 +139,7 @@ describe(@"the streaming media manager", ^{
someScreenParams.resolution = someImageResolution;
});
- describe(@"that does not support graphics", ^{
+ context(@"that does not support graphics", ^{
beforeEach(^{
someDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
someDisplayCapabilities.graphicSupported = @NO;
@@ -126,12 +155,11 @@ describe(@"the streaming media manager", ^{
});
it(@"should not support streaming", ^{
- expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO));
- expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO));
+ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO));
});
});
- describe(@"that supports graphics", ^{
+ context(@"that supports graphics", ^{
beforeEach(^{
someDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
someDisplayCapabilities.graphicSupported = @YES;
@@ -147,203 +175,494 @@ describe(@"the streaming media manager", ^{
});
it(@"should support streaming", ^{
- expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@YES));
- expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@YES));
+ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@YES));
expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeMake(600, 100)))).to(equal(@YES));
});
});
});
-
- describe(@"if the app state is active", ^{
- __block id streamStub = nil;
-
- beforeEach(^{
- streamStub = OCMPartialMock(streamingLifecycleManager);
-
- OCMStub([streamStub isAudioStreamingSupported]).andReturn(YES);
- OCMStub([streamStub isVideoStreamingSupported]).andReturn(YES);
- [streamingLifecycleManager.appStateMachine setToState:SDLAppStateActive fromOldState:nil callEnterTransition:NO];
+ describe(@"after sending GetSystemCapabilities", ^{
+ context(@"and receiving an error response", ^{
+ // This happens if the HU doesn't understand GetSystemCapabilities
+ beforeEach(^{
+ SDLGenericResponse *genericResponse = [[SDLGenericResponse alloc] init];
+ genericResponse.resultCode = SDLResultInvalidData;
+
+ [testConnectionManager respondToLastRequestWithResponse:genericResponse];
+ });
+
+ it(@"should have correct format and resolution", ^{
+ expect(streamingLifecycleManager.preferredFormats).to(haveCount(1));
+ expect(streamingLifecycleManager.preferredFormats.firstObject.codec).to(equal(SDLVideoStreamingCodecH264));
+ expect(streamingLifecycleManager.preferredFormats.firstObject.protocol).to(equal(SDLVideoStreamingProtocolRAW));
+
+ expect(streamingLifecycleManager.preferredResolutions).to(haveCount(1));
+ expect(streamingLifecycleManager.preferredResolutions.firstObject.resolutionWidth).to(equal(0));
+ expect(streamingLifecycleManager.preferredResolutions.firstObject.resolutionHeight).to(equal(0));
+ });
});
-
- describe(@"and both streams are open", ^{
+
+ context(@"and receiving a response", ^{
+ __block SDLImageResolution *resolution = nil;
+ __block int32_t maxBitrate = 0;
+ __block NSArray<SDLVideoStreamingFormat *> *testFormats = nil;
+ __block BOOL testHapticsSupported = NO;
+
beforeEach(^{
- [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateReady fromOldState:nil callEnterTransition:NO];
- [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateReady fromOldState:nil callEnterTransition:NO];
+ SDLGetSystemCapabilityResponse *response = [[SDLGetSystemCapabilityResponse alloc] init];
+ response.success = @YES;
+ response.systemCapability = [[SDLSystemCapability alloc] init];
+ response.systemCapability.systemCapabilityType = SDLSystemCapabilityTypeVideoStreaming;
+
+ resolution = [[SDLImageResolution alloc] initWithWidth:42 height:69];
+ maxBitrate = 12345;
+ testFormats = @[[[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH265 protocol:SDLVideoStreamingProtocolRTMP], [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]];
+ testHapticsSupported = YES;
+ response.systemCapability.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:testFormats hapticDataSupported:testHapticsSupported];
+ [testConnectionManager respondToLastRequestWithResponse:response];
});
-
- describe(@"and the hmi state is limited", ^{
+
+ it(@"should have correct data from the data source", ^{
+ // Correct formats should be retrieved from the data source
+ expect(streamingLifecycleManager.preferredResolutions).to(haveCount(1));
+ expect(streamingLifecycleManager.preferredResolutions.firstObject.resolutionWidth).to(equal(resolution.resolutionWidth));
+ expect(streamingLifecycleManager.preferredResolutions.firstObject.resolutionHeight).to(equal(resolution.resolutionHeight));
+
+ expect(streamingLifecycleManager.preferredFormats).to(haveCount(streamingLifecycleManager.supportedFormats.count + 1));
+ expect(streamingLifecycleManager.preferredFormats.firstObject.codec).to(equal(testDataSource.extraFormat.codec));
+ expect(streamingLifecycleManager.preferredFormats.firstObject.protocol).to(equal(testDataSource.extraFormat.protocol));
+ });
+
+ describe(@"if the app state is active", ^{
+ __block id streamStub = nil;
+
beforeEach(^{
- streamingLifecycleManager.hmiLevel = SDLHMILevelLimited;
+ streamStub = OCMPartialMock(streamingLifecycleManager);
+
+ OCMStub([streamStub isStreamingSupported]).andReturn(YES);
+
+ [streamingLifecycleManager.appStateMachine setToState:SDLAppStateActive fromOldState:nil callEnterTransition:NO];
});
-
- describe(@"and the hmi state changes to", ^{
- context(@"none", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelNone);
- });
-
- it(@"should close only the video stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
- });
+
+ describe(@"and both streams are open", ^{
+ beforeEach(^{
+ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateReady fromOldState:nil callEnterTransition:NO];
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateReady fromOldState:nil callEnterTransition:NO];
});
-
- context(@"background", ^{
+
+ describe(@"and the hmi state is limited", ^{
beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelBackground);
+ streamingLifecycleManager.hmiLevel = SDLHMILevelLimited;
});
-
- it(@"should close only the video stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
+
+ describe(@"and the hmi state changes to", ^{
+ context(@"none", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelNone);
+ });
+
+ it(@"should close only the video stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
+ });
+ });
+
+ context(@"background", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelBackground);
+ });
+
+ it(@"should close only the video stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
+ });
+ });
+
+ context(@"limited", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelLimited);
+ });
+
+ it(@"should not close either stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
+ });
+
+ context(@"full", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelFull);
+ });
+
+ it(@"should not close either stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
+ });
+ });
+
+ describe(@"and the app state changes to", ^{
+ context(@"inactive", ^{
+ beforeEach(^{
+ [streamingLifecycleManager.appStateMachine setToState:SDLAppStateInactive fromOldState:nil callEnterTransition:YES];
+ });
+
+ it(@"should flag to restart the video stream", ^{
+ expect(@(streamingLifecycleManager.shouldRestartVideoStream)).to(equal(@YES));
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
+ });
});
});
-
- context(@"limited", ^{
+
+ describe(@"and the hmi state is full", ^{
beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelLimited);
+ streamingLifecycleManager.hmiLevel = SDLHMILevelFull;
});
-
- it(@"should not close either stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+
+ context(@"and hmi state changes to none", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelNone);
+ });
+
+ it(@"should close only the video stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
+ });
});
- });
-
- context(@"full", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelFull);
+
+ context(@"and hmi state changes to background", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelBackground);
+ });
+
+ it(@"should close only the video stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
+ });
});
-
- it(@"should not close either stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+
+ context(@"and hmi state changes to limited", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelLimited);
+ });
+
+ it(@"should not close either stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
+ });
+
+ context(@"and hmi state changes to full", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelFull);
+ });
+
+ it(@"should not close either stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
});
});
});
-
- describe(@"and the app state changes to", ^{
- context(@"inactive", ^{
+
+ describe(@"and both streams are closed", ^{
+ beforeEach(^{
+ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateStopped fromOldState:nil callEnterTransition:NO];
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStopped fromOldState:nil callEnterTransition:NO];
+ });
+
+ describe(@"and the hmi state is none", ^{
beforeEach(^{
- [streamingLifecycleManager.appStateMachine setToState:SDLAppStateInactive fromOldState:nil callEnterTransition:YES];
+ streamingLifecycleManager.hmiLevel = SDLHMILevelNone;
+ });
+
+ context(@"and hmi state changes to none", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelNone);
+ });
+
+ it(@"should only start the audio stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ });
+ });
+
+ context(@"and hmi state changes to background", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelBackground);
+ });
+
+ it(@"should only start the audio stream", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ });
});
- it(@"should flag to restart the video stream", ^{
- expect(@(streamingLifecycleManager.shouldRestartVideoStream)).to(equal(@YES));
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ context(@"and hmi state changes to limited", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelLimited);
+ });
+
+ it(@"should start both streams", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting));
+ });
+ });
+
+ context(@"and hmi state changes to full", ^{
+ beforeEach(^{
+ sendNotificationForHMILevel(SDLHMILevelFull);
+ });
+
+ it(@"should start both streams", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting));
+ });
+
+ it(@"should have decided upon the correct preferred format and resolution", ^{
+ SDLVideoStreamingFormat *preferredFormat = streamingLifecycleManager.preferredFormats[streamingLifecycleManager.preferredFormatIndex];
+ expect(preferredFormat.codec).to(equal(SDLVideoStreamingCodecH264));
+ expect(preferredFormat.protocol).to(equal(SDLVideoStreamingProtocolRTP));
+
+ SDLImageResolution *preferredResolution = streamingLifecycleManager.preferredResolutions[streamingLifecycleManager.preferredResolutionIndex];
+ expect(preferredResolution.resolutionHeight).to(equal(@69));
+ expect(preferredResolution.resolutionWidth).to(equal(@42));
+ });
});
});
});
});
-
- describe(@"and the hmi state is full", ^{
- beforeEach(^{
- streamingLifecycleManager.hmiLevel = SDLHMILevelFull;
- });
-
- context(@"and hmi state changes to none", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelNone);
- });
-
- it(@"should close only the video stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
- });
- });
-
- context(@"and hmi state changes to background", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelBackground);
- });
-
- it(@"should close only the video stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown));
- });
- });
-
- context(@"and hmi state changes to limited", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelLimited);
- });
-
- it(@"should not close either stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
- });
- });
+ });
+ });
- context(@"and hmi state changes to full", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelFull);
- });
-
- it(@"should not close either stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
- });
- });
+ describe(@"after receiving a Video Start ACK", ^{
+ __block SDLProtocolHeader *testVideoHeader = nil;
+ __block SDLProtocolMessage *testVideoMessage = nil;
+ __block SDLControlFramePayloadVideoStartServiceAck *testVideoStartServicePayload = nil;
+ __block int64_t testMTU = 789456;
+ __block int32_t testVideoHeight = 42;
+ __block int32_t testVideoWidth = 32;
+ __block SDLVideoStreamingCodec testVideoCodec = SDLVideoStreamingCodecH264;
+ __block SDLVideoStreamingProtocol testVideoProtocol = SDLVideoStreamingProtocolRTP;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testVideoHeader.frameType = SDLFrameTypeSingle;
+ testVideoHeader.frameData = SDLFrameInfoStartServiceACK;
+ testVideoHeader.encrypted = YES;
+ testVideoHeader.serviceType = SDLServiceTypeVideo;
+ });
+
+ context(@"with data", ^{
+ beforeEach(^{
+ testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testVideoHeight width:testVideoWidth protocol:testVideoProtocol codec:testVideoCodec];
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data];
+ [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect([[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeVideo]).to(equal(testMTU));
+ expect(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeMake(testVideoWidth, testVideoHeight))).to(equal(YES));
+ expect(streamingLifecycleManager.videoEncrypted).to(equal(YES));
+ expect(streamingLifecycleManager.videoFormat).to(equal([[SDLVideoStreamingFormat alloc] initWithCodec:testVideoCodec protocol:testVideoProtocol]));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
});
});
-
- describe(@"and both streams are closed", ^{
+
+ context(@"with missing data", ^{
beforeEach(^{
- [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateStopped fromOldState:nil callEnterTransition:NO];
- [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStopped fromOldState:nil callEnterTransition:NO];
+ testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testVideoHeight width:testVideoWidth protocol:nil codec:nil];
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data];
+ [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage];
});
-
- describe(@"and the hmi state is none", ^{
- beforeEach(^{
- streamingLifecycleManager.hmiLevel = SDLHMILevelNone;
- });
-
- context(@"and hmi state changes to none", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelNone);
- });
-
- it(@"should only start the audio stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
- });
- });
-
- context(@"and hmi state changes to background", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelBackground);
- });
-
- it(@"should only start the audio stream", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
- });
- });
-
- context(@"and hmi state changes to limited", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelLimited);
- });
-
- it(@"should start both streams", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting));
- });
- });
-
- context(@"and hmi state changes to full", ^{
- beforeEach(^{
- sendNotificationForHMILevel(SDLHMILevelFull);
- });
-
- it(@"should start both streams", ^{
- expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting));
- expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting));
- });
- });
+
+ it(@"should fall back correctly", ^{
+ expect(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeMake(testVideoWidth, testVideoHeight))).to(equal(YES));
+ expect(streamingLifecycleManager.videoFormat).to(equal([[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRAW]));
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
+ });
+ });
+ });
+
+ describe(@"after receiving a Video Start NAK", ^{
+ __block SDLProtocolHeader *testVideoHeader = nil;
+ __block SDLProtocolMessage *testVideoMessage = nil;
+ __block SDLControlFramePayloadNak *testVideoStartNakPayload = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testVideoHeader.frameType = SDLFrameTypeSingle;
+ testVideoHeader.frameData = SDLFrameInfoStartServiceACK;
+ testVideoHeader.encrypted = YES;
+ testVideoHeader.serviceType = SDLServiceTypeVideo;
+ });
+
+ context(@"with data", ^{
+ beforeEach(^{
+ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameHeightKey], [NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]];
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data];
+ [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage];
});
+
+ it(@"should have retried with new properties", ^{
+ expect(streamingLifecycleManager.preferredResolutionIndex).to(equal(1));
+ expect(streamingLifecycleManager.preferredFormatIndex).to(equal(1));
+ });
+ });
+
+ context(@"with missing data", ^{
+ beforeEach(^{
+ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:nil];
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data];
+ [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage];
+ });
+
+ it(@"should end the service", ^{
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ });
+ });
+ });
+
+ describe(@"after receiving a video end ACK", ^{
+ __block SDLProtocolHeader *testVideoHeader = nil;
+ __block SDLProtocolMessage *testVideoMessage = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testVideoHeader.frameType = SDLFrameTypeSingle;
+ testVideoHeader.frameData = SDLFrameInfoEndServiceACK;
+ testVideoHeader.encrypted = NO;
+ testVideoHeader.serviceType = SDLServiceTypeVideo;
+
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil];
+ [streamingLifecycleManager handleProtocolEndServiceACKMessage:testVideoMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ });
+ });
+
+ describe(@"after receiving a video end NAK", ^{
+ __block SDLProtocolHeader *testVideoHeader = nil;
+ __block SDLProtocolMessage *testVideoMessage = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testVideoHeader.frameType = SDLFrameTypeSingle;
+ testVideoHeader.frameData = SDLFrameInfoEndServiceNACK;
+ testVideoHeader.encrypted = NO;
+ testVideoHeader.serviceType = SDLServiceTypeVideo;
+
+ testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil];
+ [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testVideoMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped));
+ });
+ });
+
+ describe(@"after receiving an Audio Start ACK", ^{
+ __block SDLProtocolHeader *testAudioHeader = nil;
+ __block SDLProtocolMessage *testAudioMessage = nil;
+ __block SDLControlFramePayloadAudioStartServiceAck *testAudioStartServicePayload = nil;
+ __block int64_t testMTU = 786579;
+
+ beforeEach(^{
+ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testAudioHeader.frameType = SDLFrameTypeSingle;
+ testAudioHeader.frameData = SDLFrameInfoStartServiceACK;
+ testAudioHeader.encrypted = YES;
+ testAudioHeader.serviceType = SDLServiceTypeAudio;
+
+ testAudioStartServicePayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithMTU:testMTU];
+ testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:testAudioStartServicePayload.data];
+ [streamingLifecycleManager handleProtocolStartServiceACKMessage:testAudioMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect([[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeAudio]).to(equal(testMTU));
+ expect(streamingLifecycleManager.audioEncrypted).to(equal(YES));
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady));
+ });
+ });
+
+ describe(@"after receiving an Audio Start NAK", ^{
+ __block SDLProtocolHeader *testAudioHeader = nil;
+ __block SDLProtocolMessage *testAudioMessage = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLAudioStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testAudioHeader.frameType = SDLFrameTypeSingle;
+ testAudioHeader.frameData = SDLFrameInfoStartServiceNACK;
+ testAudioHeader.encrypted = NO;
+ testAudioHeader.serviceType = SDLServiceTypeAudio;
+
+ testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil];
+ [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStopped));
+ });
+ });
+
+ describe(@"after receiving a audio end ACK", ^{
+ __block SDLProtocolHeader *testAudioHeader = nil;
+ __block SDLProtocolMessage *testAudioMessage = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLAudioStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testAudioHeader.frameType = SDLFrameTypeSingle;
+ testAudioHeader.frameData = SDLFrameInfoEndServiceACK;
+ testAudioHeader.encrypted = NO;
+ testAudioHeader.serviceType = SDLServiceTypeAudio;
+
+ testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil];
+ [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStopped));
+ });
+ });
+
+ describe(@"after receiving a audio end NAK", ^{
+ __block SDLProtocolHeader *testAudioHeader = nil;
+ __block SDLProtocolMessage *testAudioMessage = nil;
+
+ beforeEach(^{
+ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLAudioStreamStateStarting fromOldState:nil callEnterTransition:NO];
+
+ testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5];
+ testAudioHeader.frameType = SDLFrameTypeSingle;
+ testAudioHeader.frameData = SDLFrameInfoEndServiceNACK;
+ testAudioHeader.encrypted = NO;
+ testAudioHeader.serviceType = SDLServiceTypeAudio;
+
+ testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil];
+ [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testAudioMessage];
+ });
+
+ it(@"should have set all the right properties", ^{
+ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStopped));
});
});
});
diff --git a/SmartDeviceLink_Example/Classes/ProxyManager.m b/SmartDeviceLink_Example/Classes/ProxyManager.m
index 4ac1216c7..478ae8296 100644
--- a/SmartDeviceLink_Example/Classes/ProxyManager.m
+++ b/SmartDeviceLink_Example/Classes/ProxyManager.m
@@ -77,7 +77,7 @@ NS_ASSUME_NONNULL_BEGIN
if (self.sdlManager) { return; }
SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration defaultConfigurationWithAppName:SDLAppName appId:SDLAppId]];
- SDLConfiguration *config = [SDLConfiguration configurationWithLifecycle:lifecycleConfig lockScreen:[SDLLockScreenConfiguration enabledConfiguration] logging:[SDLLogConfiguration defaultConfiguration]];
+ SDLConfiguration *config = [SDLConfiguration configurationWithLifecycle:lifecycleConfig lockScreen:[SDLLockScreenConfiguration enabledConfiguration] logging:[SDLLogConfiguration debugConfiguration]];
self.sdlManager = [[SDLManager alloc] initWithConfiguration:config delegate:self];
[self startManager];
@@ -88,11 +88,7 @@ NS_ASSUME_NONNULL_BEGIN
// Check for previous instance of sdlManager
if (self.sdlManager) { return; }
SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration debugConfigurationWithAppName:SDLAppName appId:SDLAppId ipAddress:[Preferences sharedPreferences].ipAddress port:[Preferences sharedPreferences].port]];
-
- SDLLogConfiguration *logConfiguration = [SDLLogConfiguration defaultConfiguration];
- logConfiguration.formatType = SDLLogFormatTypeSimple;
-
- SDLConfiguration *config = [SDLConfiguration configurationWithLifecycle:lifecycleConfig lockScreen:[SDLLockScreenConfiguration enabledConfiguration] logging:[SDLLogConfiguration defaultConfiguration]];
+ SDLConfiguration *config = [SDLConfiguration configurationWithLifecycle:lifecycleConfig lockScreen:[SDLLockScreenConfiguration enabledConfiguration] logging:[SDLLogConfiguration debugConfiguration]];
self.sdlManager = [[SDLManager alloc] initWithConfiguration:config delegate:self];
[self startManager];