From afa406c7ed88251842ee9fd23318e0cb4e2af747 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 18:27:26 +0800 Subject: [PATCH 01/28] Synchronize beauty code, synchronize tag: BeautyAPI project 1.0.7 --- .../APIExample.xcodeproj/project.pbxproj | 94 ++- .../ThirdBeautify/BeautyAPI/BeautyAPI.m | 72 +- .../Render/BytesRender/BytesBeautyRender.h | 13 +- .../Render/BytesRender/BytesBeautyRender.m | 170 ++-- .../Render/FURender/FUBeautyRender.h | 10 +- .../Render/FURender/FUBeautyRender.m | 110 ++- .../Render/SenseRender/SenseBeautyRender.m | 13 +- .../BeautyAPI/Report/APIReporter.h | 49 ++ .../BeautyAPI/Report/APIReporter.m | 143 ++++ .../ByteBeautify/BytedEffectVC.m | 2 +- .../ByteBeautify/Manager/BEEffectManager.h | 37 +- .../ByteBeautify/Manager/BEEffectManager.mm | 213 +++-- .../ByteBeautify/Manager/BEFrameProcessor.h | 165 ---- .../ByteBeautify/Manager/BEFrameProcessor.mm | 499 ----------- .../ByteBeautify/Manager/BEGLTexture.h | 111 +-- .../ByteBeautify/Manager/BEGLTexture.m | 191 ++++- .../ByteBeautify/Manager/BEGLUtils.h | 19 + .../ByteBeautify/Manager/BEGLUtils.m | 45 + .../Manager/BEHttpRequestProvider.h | 12 +- .../Manager/BEHttpRequestProvider.mm | 8 +- .../ByteBeautify/Manager/BEImageUtils.h | 202 +++-- .../ByteBeautify/Manager/BEImageUtils.m | 352 +++++++- .../ByteBeautify/Manager/BELicenseHelper.h | 10 +- .../ByteBeautify/Manager/BELicenseHelper.mm | 148 +++- .../ByteBeautify/Manager/BEPixelBufferInfo.h | 37 - .../ByteBeautify/Manager/BEPixelBufferInfo.m | 13 - .../ByteBeautify/Manager/BERender.h | 89 -- .../ByteBeautify/Manager/BERender.mm | 774 ------------------ .../ByteBeautify/Manager/BERenderHelper.h | 33 - .../ByteBeautify/Manager/BERenderHelper.m | 171 ---- .../ByteBeautify/Manager/BEResourceHelper.h | 50 -- .../ByteBeautify/Manager/BEResourceHelper.m | 110 --- .../ByteBeautify/Manager/BETimeRecoder.h | 31 + .../ByteBeautify/Manager/BETimeRecoder.m | 47 ++ .../ByteBeautify/Manager/ByteDanceFilter.h | 31 - .../ByteBeautify/Manager/ByteDanceFilter.m | 101 --- .../ByteBeautify/Manager/Config.h | 15 + .../ThirdBeautify/ByteBeautify/Manager/Core.h | 14 +- .../ByteBeautify/Manager/macro.h | 18 +- .../FUBeautify/Manager/FUManager.m | 52 +- .../SenseBeautify/Manager/EFGlobalSingleton.h | 28 + .../SenseBeautify/Manager/EFGlobalSingleton.m | 31 + .../SenseBeautify/Manager/EffectMacro.h | 12 +- .../SenseBeautify/Manager/Effects.h | 15 +- .../SenseBeautify/Manager/Effects.m | 115 ++- .../SenseBeautify/Manager/EffectsAnimal.h | 14 +- .../SenseBeautify/Manager/EffectsAnimal.m | 25 +- .../SenseBeautify/Manager/EffectsAttribute.h | 14 +- .../SenseBeautify/Manager/EffectsAttribute.m | 88 +- .../SenseBeautify/Manager/EffectsDetector.h | 7 +- .../SenseBeautify/Manager/EffectsDetector.m | 93 ++- .../SenseBeautify/Manager/EffectsLicense.m | 24 +- .../SenseBeautify/Manager/EffectsProcess.h | 25 +- .../SenseBeautify/Manager/EffectsProcess.m | 186 +++-- .../SenseBeautify/Manager/SENSEME.lic | 1 - .../Manager/VideoProcessingManager.m | 44 +- iOS/APIExample/beauty_build.sh | 17 + iOS/APIExample/bytedEffect.podspec | 9 +- iOS/APIExample/fu.podspec | 4 +- iOS/APIExample/sense.podspec | 6 +- 60 files changed, 2226 insertions(+), 2806 deletions(-) create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.h create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.m delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.h delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.mm create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.h create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.m delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.h delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.m delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.h delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.mm delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.h delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.m delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.h delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.m create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.h create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.m delete mode 100755 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.h delete mode 100755 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.m create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Config.h create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.h create mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.m delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/SENSEME.lic create mode 100755 iOS/APIExample/beauty_build.sh diff --git a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj index d7ea617d5..58ba1bdc3 100644 --- a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj +++ b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj @@ -214,22 +214,15 @@ E7A49D282907DDFF00F06DD4 /* EffectsDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D262907DDFE00F06DD4 /* EffectsDetector.m */; }; E7A49D2B2907DEE600F06DD4 /* EFMotionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D292907DEE600F06DD4 /* EFMotionManager.m */; }; E7A49D342907E74A00F06DD4 /* BundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D332907E74A00F06DD4 /* BundleUtil.m */; }; - E7A49D362907EB6000F06DD4 /* SENSEME.lic in Resources */ = {isa = PBXBuildFile; fileRef = E7A49D352907EB6000F06DD4 /* SENSEME.lic */; }; E7A49D40290907E200F06DD4 /* BytedEffect.strings in Resources */ = {isa = PBXBuildFile; fileRef = E7A49D39290907E200F06DD4 /* BytedEffect.strings */; }; E7A49D41290907E200F06DD4 /* BytedEffectVC.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D3B290907E200F06DD4 /* BytedEffectVC.m */; }; E7A49D42290907E200F06DD4 /* BytedEffect.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E7A49D3C290907E200F06DD4 /* BytedEffect.storyboard */; }; - E7A49D4529090F3C00F06DD4 /* ByteDanceFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D4429090F3C00F06DD4 /* ByteDanceFilter.m */; }; - E7A49D4829090F8000F06DD4 /* BEFrameProcessor.mm in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D4729090F8000F06DD4 /* BEFrameProcessor.mm */; }; - E7A49D4B29090FA000F06DD4 /* BERenderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D4929090FA000F06DD4 /* BERenderHelper.m */; }; - E7A49D4E29090FB800F06DD4 /* BEResourceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D4C29090FB800F06DD4 /* BEResourceHelper.m */; }; E7A49D5129090FCC00F06DD4 /* BEEffectManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D5029090FCC00F06DD4 /* BEEffectManager.mm */; }; E7A49D5429090FF500F06DD4 /* BELicenseHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D5329090FF500F06DD4 /* BELicenseHelper.mm */; }; E7A49D572909101D00F06DD4 /* BEImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D562909101D00F06DD4 /* BEImageUtils.m */; }; E7A49D5A2909103600F06DD4 /* BEGLTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D592909103500F06DD4 /* BEGLTexture.m */; }; - E7A49D5D2909105000F06DD4 /* BEPixelBufferInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D5C2909105000F06DD4 /* BEPixelBufferInfo.m */; }; E7A49D62290910FD00F06DD4 /* BEOpenGLRenderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D60290910FD00F06DD4 /* BEOpenGLRenderHelper.m */; }; E7A49D652909111400F06DD4 /* BEHttpRequestProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D642909111400F06DD4 /* BEHttpRequestProvider.mm */; }; - E7A49D682909113200F06DD4 /* BERender.mm in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D672909113200F06DD4 /* BERender.mm */; }; E7A49D6B2909115200F06DD4 /* BEEffectResourceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A49D6A2909115100F06DD4 /* BEEffectResourceHelper.m */; }; E7AD0DE129C85FFB00C9A4B0 /* sample.mov in Resources */ = {isa = PBXBuildFile; fileRef = E7AD0DE029C85FFB00C9A4B0 /* sample.mov */; }; E7AD0DE329C95EB500C9A4B0 /* PickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AD0DE229C95EB500C9A4B0 /* PickerView.swift */; }; @@ -242,6 +235,10 @@ F728B9DD2CA295D7007813BB /* PixelBufferPIPViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D42CA295D7007813BB /* PixelBufferPIPViewController.swift */; }; F728B9DE2CA295D7007813BB /* PixelBufferRenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D52CA295D7007813BB /* PixelBufferRenderView.swift */; }; F728B9E02CA29625007813BB /* PictureInPicture.strings in Resources */ = {isa = PBXBuildFile; fileRef = F728B9DF2CA29625007813BB /* PictureInPicture.strings */; }; + F73B01CE2CCB7E730077B7D2 /* BETimeRecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = F73B01C82CCB7E720077B7D2 /* BETimeRecoder.m */; }; + F73B01CF2CCB7E730077B7D2 /* BEGLUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F73B01CC2CCB7E730077B7D2 /* BEGLUtils.m */; }; + F73B01D52CCB84590077B7D2 /* APIReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = F73B01D32CCB84590077B7D2 /* APIReporter.m */; }; + F73B01D82CCB862A0077B7D2 /* EFGlobalSingleton.m in Sources */ = {isa = PBXBuildFile; fileRef = F73B01D72CCB862A0077B7D2 /* EFGlobalSingleton.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -567,19 +564,10 @@ E7A49D2E2907E68800F06DD4 /* libz.1.1.3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.1.1.3.tbd; path = usr/lib/libz.1.1.3.tbd; sourceTree = SDKROOT; }; E7A49D322907E74A00F06DD4 /* BundleUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BundleUtil.h; sourceTree = ""; }; E7A49D332907E74A00F06DD4 /* BundleUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BundleUtil.m; sourceTree = ""; }; - E7A49D352907EB6000F06DD4 /* SENSEME.lic */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SENSEME.lic; sourceTree = ""; }; E7A49D3A290907E200F06DD4 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/BytedEffect.strings"; sourceTree = ""; }; E7A49D3B290907E200F06DD4 /* BytedEffectVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BytedEffectVC.m; sourceTree = ""; }; E7A49D3D290907E200F06DD4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/BytedEffect.storyboard; sourceTree = ""; }; E7A49D3F290907E200F06DD4 /* BytedEffectVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytedEffectVC.h; sourceTree = ""; }; - E7A49D4329090F3B00F06DD4 /* ByteDanceFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteDanceFilter.h; sourceTree = ""; }; - E7A49D4429090F3C00F06DD4 /* ByteDanceFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ByteDanceFilter.m; sourceTree = ""; }; - E7A49D4629090F7F00F06DD4 /* BEFrameProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEFrameProcessor.h; sourceTree = ""; }; - E7A49D4729090F8000F06DD4 /* BEFrameProcessor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BEFrameProcessor.mm; sourceTree = ""; }; - E7A49D4929090FA000F06DD4 /* BERenderHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BERenderHelper.m; sourceTree = ""; }; - E7A49D4A29090FA000F06DD4 /* BERenderHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BERenderHelper.h; sourceTree = ""; }; - E7A49D4C29090FB800F06DD4 /* BEResourceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEResourceHelper.m; sourceTree = ""; }; - E7A49D4D29090FB800F06DD4 /* BEResourceHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEResourceHelper.h; sourceTree = ""; }; E7A49D4F29090FCC00F06DD4 /* BEEffectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEEffectManager.h; sourceTree = ""; }; E7A49D5029090FCC00F06DD4 /* BEEffectManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BEEffectManager.mm; sourceTree = ""; }; E7A49D5229090FF400F06DD4 /* BELicenseHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BELicenseHelper.h; sourceTree = ""; }; @@ -588,16 +576,12 @@ E7A49D562909101D00F06DD4 /* BEImageUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEImageUtils.m; sourceTree = ""; }; E7A49D582909103500F06DD4 /* BEGLTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEGLTexture.h; sourceTree = ""; }; E7A49D592909103500F06DD4 /* BEGLTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEGLTexture.m; sourceTree = ""; }; - E7A49D5B2909105000F06DD4 /* BEPixelBufferInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEPixelBufferInfo.h; sourceTree = ""; }; - E7A49D5C2909105000F06DD4 /* BEPixelBufferInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEPixelBufferInfo.m; sourceTree = ""; }; E7A49D5E290910A000F06DD4 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = ""; }; E7A49D5F290910A100F06DD4 /* macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macro.h; sourceTree = ""; }; E7A49D60290910FD00F06DD4 /* BEOpenGLRenderHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEOpenGLRenderHelper.m; sourceTree = ""; }; E7A49D61290910FD00F06DD4 /* BEOpenGLRenderHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEOpenGLRenderHelper.h; sourceTree = ""; }; E7A49D632909111300F06DD4 /* BEHttpRequestProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEHttpRequestProvider.h; sourceTree = ""; }; E7A49D642909111400F06DD4 /* BEHttpRequestProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BEHttpRequestProvider.mm; sourceTree = ""; }; - E7A49D662909113200F06DD4 /* BERender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BERender.h; sourceTree = ""; }; - E7A49D672909113200F06DD4 /* BERender.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BERender.mm; sourceTree = ""; }; E7A49D692909115100F06DD4 /* BEEffectResourceHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEEffectResourceHelper.h; sourceTree = ""; }; E7A49D6A2909115100F06DD4 /* BEEffectResourceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEEffectResourceHelper.m; sourceTree = ""; }; E7A49D6E290A744400F06DD4 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/ThirdBeautify.strings"; sourceTree = ""; }; @@ -614,6 +598,16 @@ F728B9D42CA295D7007813BB /* PixelBufferPIPViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferPIPViewController.swift; sourceTree = ""; }; F728B9D52CA295D7007813BB /* PixelBufferRenderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferRenderView.swift; sourceTree = ""; }; F728B9DF2CA29625007813BB /* PictureInPicture.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = PictureInPicture.strings; sourceTree = ""; }; + F73B01C82CCB7E720077B7D2 /* BETimeRecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BETimeRecoder.m; sourceTree = ""; }; + F73B01C92CCB7E720077B7D2 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; + F73B01CA2CCB7E720077B7D2 /* BETimeRecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BETimeRecoder.h; sourceTree = ""; }; + F73B01CC2CCB7E730077B7D2 /* BEGLUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BEGLUtils.m; sourceTree = ""; }; + F73B01CD2CCB7E730077B7D2 /* BEGLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BEGLUtils.h; sourceTree = ""; }; + F73B01D12CCB7EE20077B7D2 /* EffectMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectMacro.h; sourceTree = ""; }; + F73B01D22CCB84590077B7D2 /* APIReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIReporter.h; sourceTree = ""; }; + F73B01D32CCB84590077B7D2 /* APIReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APIReporter.m; sourceTree = ""; }; + F73B01D62CCB862A0077B7D2 /* EFGlobalSingleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EFGlobalSingleton.h; sourceTree = ""; }; + F73B01D72CCB862A0077B7D2 /* EFGlobalSingleton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EFGlobalSingleton.m; sourceTree = ""; }; FAAC2AEE355D103B9E8527B5 /* Pods-Agora-ScreenShare-Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Agora-ScreenShare-Extension.debug.xcconfig"; path = "Target Support Files/Pods-Agora-ScreenShare-Extension/Pods-Agora-ScreenShare-Extension.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1324,6 +1318,7 @@ E76347B62AAEF4AF005D130F /* BeautyAPI */ = { isa = PBXGroup; children = ( + F73B01D42CCB84590077B7D2 /* Report */, E76347B82AAEF4AF005D130F /* BeautyAPI.h */, E76347C72AAEF4AF005D130F /* BeautyAPI.m */, E76347BC2AAEF4AF005D130F /* Render */, @@ -1458,12 +1453,14 @@ E7A49D0729067F8300F06DD4 /* Manager */ = { isa = PBXGroup; children = ( - E7A49D352907EB6000F06DD4 /* SENSEME.lic */, E7A49D192907DD7800F06DD4 /* Effects.h */, E7A49D182907DD7800F06DD4 /* Effects.m */, E7A49D2A2907DEE600F06DD4 /* EFMotionManager.h */, E7A49D292907DEE600F06DD4 /* EFMotionManager.m */, + F73B01D62CCB862A0077B7D2 /* EFGlobalSingleton.h */, + F73B01D72CCB862A0077B7D2 /* EFGlobalSingleton.m */, E7A49D1B2907DD8400F06DD4 /* EffectsAnimal.h */, + F73B01D12CCB7EE20077B7D2 /* EffectMacro.h */, E7A49D1C2907DD8400F06DD4 /* EffectsAnimal.m */, E7A49D162907DD2600F06DD4 /* EffectsLicense.h */, E7A49D152907DD2600F06DD4 /* EffectsLicense.m */, @@ -1498,32 +1495,25 @@ children = ( E7A49D5E290910A000F06DD4 /* Core.h */, E7A49D5F290910A100F06DD4 /* macro.h */, - E7A49D662909113200F06DD4 /* BERender.h */, - E7A49D672909113200F06DD4 /* BERender.mm */, E7A49D692909115100F06DD4 /* BEEffectResourceHelper.h */, E7A49D6A2909115100F06DD4 /* BEEffectResourceHelper.m */, + F73B01CD2CCB7E730077B7D2 /* BEGLUtils.h */, + F73B01CC2CCB7E730077B7D2 /* BEGLUtils.m */, + F73B01CA2CCB7E720077B7D2 /* BETimeRecoder.h */, + F73B01C82CCB7E720077B7D2 /* BETimeRecoder.m */, + F73B01C92CCB7E720077B7D2 /* Config.h */, E7A49D632909111300F06DD4 /* BEHttpRequestProvider.h */, E7A49D642909111400F06DD4 /* BEHttpRequestProvider.mm */, E7A49D61290910FD00F06DD4 /* BEOpenGLRenderHelper.h */, E7A49D60290910FD00F06DD4 /* BEOpenGLRenderHelper.m */, - E7A49D5B2909105000F06DD4 /* BEPixelBufferInfo.h */, - E7A49D5C2909105000F06DD4 /* BEPixelBufferInfo.m */, E7A49D582909103500F06DD4 /* BEGLTexture.h */, E7A49D592909103500F06DD4 /* BEGLTexture.m */, E7A49D552909101D00F06DD4 /* BEImageUtils.h */, E7A49D562909101D00F06DD4 /* BEImageUtils.m */, E7A49D5229090FF400F06DD4 /* BELicenseHelper.h */, E7A49D5329090FF500F06DD4 /* BELicenseHelper.mm */, - E7A49D4D29090FB800F06DD4 /* BEResourceHelper.h */, - E7A49D4C29090FB800F06DD4 /* BEResourceHelper.m */, E7A49D4F29090FCC00F06DD4 /* BEEffectManager.h */, E7A49D5029090FCC00F06DD4 /* BEEffectManager.mm */, - E7A49D4A29090FA000F06DD4 /* BERenderHelper.h */, - E7A49D4929090FA000F06DD4 /* BERenderHelper.m */, - E7A49D4629090F7F00F06DD4 /* BEFrameProcessor.h */, - E7A49D4729090F8000F06DD4 /* BEFrameProcessor.mm */, - E7A49D4329090F3B00F06DD4 /* ByteDanceFilter.h */, - E7A49D4429090F3C00F06DD4 /* ByteDanceFilter.m */, ); path = Manager; sourceTree = ""; @@ -1547,6 +1537,15 @@ path = PixelBufferPIPViewController; sourceTree = ""; }; + F73B01D42CCB84590077B7D2 /* Report */ = { + isa = PBXGroup; + children = ( + F73B01D22CCB84590077B7D2 /* APIReporter.h */, + F73B01D32CCB84590077B7D2 /* APIReporter.m */, + ); + path = Report; + sourceTree = ""; + }; FD17F473C6A05604A44BDDDE /* Pods */ = { isa = PBXGroup; children = ( @@ -1616,6 +1615,7 @@ 1B6F6CF9B678035E221EAFDE /* [CP] Embed Pods Frameworks */, 0339BEBA25205B80007D4FDD /* Embed App Extensions */, E76F80122AF0A7A200CCB9D6 /* ShellScript */, + EA59815E58120166C6FD72B5 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1785,7 +1785,6 @@ 033A9F6B252D8B3500BC26E1 /* MediaChannelRelay.storyboard in Resources */, 671BD6B927E1DB2D0076D5E1 /* CustomAudioRender.storyboard in Resources */, E728B85128B60D5B00674A4A /* VideoViewSampleBufferDisplayView.xib in Resources */, - E7A49D362907EB6000F06DD4 /* SENSEME.lic in Resources */, 03D13BD72448758900B599B3 /* Main.storyboard in Resources */, F728B9D72CA295D7007813BB /* PictureInPicture.storyboard in Resources */, ); @@ -1901,6 +1900,23 @@ shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\" \n"; }; + EA59815E58120166C6FD72B5 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1923,7 +1939,6 @@ 8BA5459626AFEC8D00ED4295 /* SimpleFilter.swift in Sources */, 036CBA47251990B400D74FAD /* AgoraCustomEncryption.h in Sources */, E726BFFB2A949F70006870E2 /* AudioRouterPlayer.swift in Sources */, - E7A49D4E29090FB800F06DD4 /* BEResourceHelper.m in Sources */, E7A49D232907DD9A00F06DD4 /* EffectsCommonObject.m in Sources */, E7A49D652909111400F06DD4 /* BEHttpRequestProvider.mm in Sources */, E7A49CFB29029E0000F06DD4 /* ThirdBeautify.swift in Sources */, @@ -1933,7 +1948,6 @@ E76347D32AAEF4AF005D130F /* BeautyAPI.m in Sources */, 0339BE9625203293007D4FDD /* ScreenShare.swift in Sources */, 033A9F00252D61E200BC26E1 /* CustomAudioSource.swift in Sources */, - E7A49D682909113200F06DD4 /* BERender.mm in Sources */, 03DF1D9224CFC29700DF7151 /* UIView+CSshortFrame.m in Sources */, E7A49D1A2907DD7800F06DD4 /* Effects.m in Sources */, 671BD6BA27E1DB2D0076D5E1 /* CustomAudioRender.swift in Sources */, @@ -1945,13 +1959,10 @@ E77D54C928F55E9100D51C1E /* JoinChannelVideoToken.swift in Sources */, 0371D8AE250B4A2C00C0DD61 /* JoinChannelAudio.swift in Sources */, E726C0052A96FD3A006870E2 /* AudioWaveform.swift in Sources */, - E7A49D4529090F3C00F06DD4 /* ByteDanceFilter.m in Sources */, E7A49D5429090FF500F06DD4 /* BELicenseHelper.mm in Sources */, - E7A49D4B29090FA000F06DD4 /* BERenderHelper.m in Sources */, E7A49D172907DD2600F06DD4 /* EffectsLicense.m in Sources */, E728B84F28B601A300674A4A /* AgoraSampleBufferRender.m in Sources */, 8B333DA9267B4BC3002A3785 /* SettingsCells.swift in Sources */, - E7A49D4829090F8000F06DD4 /* BEFrameProcessor.mm in Sources */, 033A9EFC252D61E200BC26E1 /* CustomVideoRender.swift in Sources */, E76347D22AAEF4AF005D130F /* BytesBeautyRender.m in Sources */, 576EA59025AEDD3C000B3D79 /* (null) in Sources */, @@ -1999,8 +2010,10 @@ 0318857924CD667A00C699EB /* SettingsViewController.swift in Sources */, E726C0082A96FF15006870E2 /* ZSNBoxingView.m in Sources */, 033A9EFB252D61E200BC26E1 /* CustomVideoSourcePush.swift in Sources */, + F73B01D82CCB862A0077B7D2 /* EFGlobalSingleton.m in Sources */, 576CA80C25AA0FA90091520B /* AgoraPcmSourcePush.swift in Sources */, E7A49D62290910FD00F06DD4 /* BEOpenGLRenderHelper.m in Sources */, + F73B01D52CCB84590077B7D2 /* APIReporter.m in Sources */, A7BD7660247CC6920062A6B3 /* UITypeAlias.swift in Sources */, 8BE7ABC4279E065000DFBCEF /* FusionCDN.swift in Sources */, 57FE7C4B26B2D103002D9043 /* CircularBuffer.c in Sources */, @@ -2023,12 +2036,13 @@ 034C625E2524A06800296ECF /* VoiceChanger.swift in Sources */, E7A49D2B2907DEE600F06DD4 /* EFMotionManager.m in Sources */, 03D13BD02448758900B599B3 /* AppDelegate.swift in Sources */, + F73B01CE2CCB7E730077B7D2 /* BETimeRecoder.m in Sources */, 0385768225224A88003C369A /* JoinChannelVideo.swift in Sources */, A7847F922458062900469187 /* StatisticsInfo.swift in Sources */, - E7A49D5D2909105000F06DD4 /* BEPixelBufferInfo.m in Sources */, E7163F88296414F700EBBD55 /* ARVideoRenderer.swift in Sources */, 0339BE72251EF075007D4FDD /* MediaPlayer.swift in Sources */, E76347D02AAEF4AF005D130F /* FUBeautyRender.m in Sources */, + F73B01CF2CCB7E730077B7D2 /* BEGLUtils.m in Sources */, E7A49CFE29029E0000F06DD4 /* FUBeautifyVC.m in Sources */, E77902672A484A8A008791AD /* KFMP4Demuxer.m in Sources */, 0385767E2521E5A0003C369A /* MediaChannelRelay.swift in Sources */, diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/BeautyAPI.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/BeautyAPI.m index 844870bc9..ece43cc0d 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/BeautyAPI.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/BeautyAPI.m @@ -6,8 +6,9 @@ // #import "BeautyAPI.h" +#import "APIReporter.h" -static NSString *const beautyAPIVnersio = @"1.0.3"; +static NSString *const beautyAPIVersion = @"1.0.7"; @implementation BeautyStats @end @@ -24,6 +25,8 @@ @interface BeautyAPI () @property (nonatomic, assign) CFTimeInterval preTime; @property (nonatomic, strong) NSMutableArray *statsArray; @property (nonatomic, assign) AgoraVideoRenderMode renderMode; +@property (nonatomic, strong) APIReporter *reporter; +@property (nonatomic, assign) BOOL isFirstFrame; @end @@ -34,6 +37,13 @@ @interface BeautyAPI () @implementation BeautyAPI +- (instancetype)init { + if (self == [super init]) { + _isFrontCamera = YES; + } + return self; +} + - (NSMutableArray *)statsArray { if (_statsArray == nil) { _statsArray = [NSMutableArray new]; @@ -41,6 +51,15 @@ - (NSMutableArray *)statsArray { return _statsArray; } +- (APIReporter *)reporter { + if (_reporter == nil) { + _reporter = [[APIReporter alloc] initWithType:(APITypeBeauty) + version:beautyAPIVersion + engine:self.config.rtcEngine]; + } + return _reporter; +} + - (int)initialize:(BeautyConfig *)config { if (config.cameraConfig == nil) { CameraConfig *cameraConfig = [[CameraConfig alloc] init]; @@ -50,7 +69,6 @@ - (int)initialize:(BeautyConfig *)config { } [LogUtil log:[NSString stringWithFormat:@"RTC Version == %@", [AgoraRtcEngineKit getSdkVersion]]]; [LogUtil log:[NSString stringWithFormat:@"BeautyAPI Version == %@", [self getVersion]]]; - _isFrontCamera = YES; self.config = config; if (self.config.statsDuration <= 0) { self.config.statsDuration = 1; @@ -64,6 +82,7 @@ - (int)initialize:(BeautyConfig *)config { return -1; } [LogUtil log:[NSString stringWithFormat:@"beautyRender == %@", config.beautyRender.description]]; + [self.reporter startDurationEventWithName:@"initialize-release"]; self.beautyRender = config.beautyRender; if (config.captureMode == CaptureModeAgora) { #if __has_include() @@ -79,6 +98,7 @@ - (int)initialize:(BeautyConfig *)config { } }; [self rtcReportWithEvent:@"initialize" label:dict]; + [self setupMirror]; #else [LogUtil log:@"rtc 未导入" level:(LogLevelError)]; return -1; @@ -86,15 +106,17 @@ - (int)initialize:(BeautyConfig *)config { } else { [LogUtil log:@"captureMode == Custom"]; } + [self setupMirror]; return 0; } - (int)switchCamera { _isFrontCamera = !_isFrontCamera; - [self setupMirror]; NSDictionary *dict = @{ @"cameraPosition": @(_isFrontCamera) }; [self rtcReportWithEvent:@"cameraPosition" label:dict]; - return [self.config.rtcEngine switchCamera]; + int res = [self.config.rtcEngine switchCamera]; + [self setupMirror]; + return res; } - (AgoraVideoMirrorMode)setupMirror { @@ -190,6 +212,7 @@ - (int)destroy { [self.config.beautyRender destroy]; self.config = nil; [LogUtil log:@"destroy"]; + [self.reporter endDurationEventWithName:@"initialize-release" ext:@{}]; return 0; } @@ -198,39 +221,34 @@ - (void)rtcReportWithEvent: (NSString *)event label: (NSDictionary *)label { [LogUtil log:@"rtc 不能为空" level:(LogLevelError)]; return; } - NSString *jsonString = [self convertToJson:label]; - [self.config.rtcEngine sendCustomReportMessage:@"scenarioAPI" - category:[NSString stringWithFormat:@"beauty_iOS_%@",[self getVersion]] - event:event - label:jsonString - value:0]; -} - -- (NSString *)convertToJson: (NSDictionary *)object { - NSError *error = nil; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object - options:0 - error:&error]; - if (error) { - // 转换失败 - NSLog(@"Error: %@", error.localizedDescription); - return nil; - } - NSString *jsonString = [[NSString alloc] initWithData:jsonData - encoding:NSUTF8StringEncoding]; - return jsonString; + [self.reporter reportFuncEventWithName:event value:label ext:@{}]; } - (NSString *)getVersion { - return beautyAPIVnersio; + return beautyAPIVersion; } #pragma mark - VideoFrameDelegate #if __has_include() +- (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame *)videoFrame { + return [self onCaptureVideoFrame:videoFrame sourceType:(AgoraVideoSourceTypeCamera)]; +} - (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame *)videoFrame sourceType:(AgoraVideoSourceType)sourceType { if (!self.isEnable) { return YES; } CFTimeInterval startTime = CACurrentMediaTime(); + if (!self.isFirstFrame) { + [self.reporter startDurationEventWithName:@"first_beauty_frame"]; + } CVPixelBufferRef pixelBuffer = [self.config.beautyRender onCapture:videoFrame.pixelBuffer]; + if (!self.isFirstFrame) { + [self.reporter endDurationEventWithName:@"first_beauty_frame" ext:@{ + @"width": @(CVPixelBufferGetWidth(pixelBuffer)), + @"height": @(CVPixelBufferGetHeight(pixelBuffer)), + @"camera_facing": _isFrontCamera ? @"front" : @"back", + @"buffer_type": @"pixelbuffer" + }]; + self.isFirstFrame = YES; + } CFTimeInterval endTime = CACurrentMediaTime(); if (self.config.statsEnable) { [self.statsArray addObject:@(endTime - startTime)]; @@ -239,7 +257,7 @@ - (BOOL)onCaptureVideoFrame:(AgoraOutputVideoFrame *)videoFrame sourceType:(Agor if (self.config.eventCallback && self.preTime > 0 && self.config.statsEnable) { CFTimeInterval time = startTime - self.preTime; if (time > self.config.statsDuration && self.statsArray.count > 0) { - NSArray *sortArray = [self.statsArray sortedArrayUsingComparator:^NSComparisonResult(NSNumber * _Nonnull obj1, NSNumber * _Nonnull obj2) { + NSArray *sortArray = [self.statsArray sortedArrayUsingComparator:^NSComparisonResult(NSNumber * _Nonnull obj1, NSNumber * _Nonnull obj2) { return obj1.doubleValue > obj2.doubleValue; }]; double totalValue = 0; diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.h index bbe434af1..d9b637a5e 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.h @@ -5,13 +5,14 @@ // Created by zhaoyongqiang on 2023/6/30. // -#define BytesMoudle "bef_effect_ai_api.h" +#define BytesMoudle #import -#if __has_include("BEImageUtils.h") && __has_include("BEFrameProcessor.h") +#if __has_include("BEImageUtils.h") && __has_include("BEEffectManager.h") #import "BEImageUtils.h" -#import "BEFrameProcessor.h" +#import "BEEffectManager.h" +#import "BEEffectResourceHelper.h" #endif #import "BeautyAPI.h" @@ -19,11 +20,11 @@ NS_ASSUME_NONNULL_BEGIN @interface BytesBeautyRender : NSObject -#if __has_include("BEImageUtils.h") && __has_include("BEFrameProcessor.h") -@property (nonatomic, strong) BEFrameProcessor *frameProcessor; +#if __has_include("BEImageUtils.h") && __has_include("BEEffectManager.h") +@property (nonatomic, strong) BEEffectManager *effectManager; @property (nonatomic, strong) BEImageUtils *imageUtils; #endif - +- (BOOL)checkLicense; @end NS_ASSUME_NONNULL_END diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m index 645b31a3c..99f993e01 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m @@ -7,26 +7,30 @@ #import "BytesBeautyRender.h" + @interface BytesBeautyRender () @property (nonatomic, strong) NSMutableArray *bytesNodes; +@property (nonatomic, weak) BEPixelBufferGLTexture *outTexture; @end @implementation BytesBeautyRender -#if __has_include("BEImageUtils.h") && __has_include("BEFrameProcessor.h") -- (BEFrameProcessor *)frameProcessor { - if (_frameProcessor == nil) { - EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:context]; - _frameProcessor = [[BEFrameProcessor alloc]initWithContext:context resourceDelegate:nil]; - _frameProcessor.processorResult = BECVPixelBuffer; - [_frameProcessor setEffectOn:YES]; - [_frameProcessor updateComposerNodes:self.bytesNodes]; +#if __has_include("BEImageUtils.h") && __has_include("BEEffectManager.h") +- (BEEffectManager *)effectManager { + if (_effectManager == nil) { + _effectManager = [[BEEffectManager alloc] initWithResourceProvider:[BEEffectResourceHelper new] licenseProvider:[BELicenseHelper shareInstance]]; +#if __has_include(BytesMoudle) + int ret = [_effectManager initTask]; + if (ret == BEF_RESULT_SUC){ + [_effectManager updateComposerNodes:self.bytesNodes]; + } +#endif } - return _frameProcessor; + return _effectManager; } + - (BEImageUtils *)imageUtils { if (_imageUtils == nil) { _imageUtils = [[BEImageUtils alloc] init]; @@ -42,84 +46,150 @@ - (NSMutableArray *)bytesNodes { return _bytesNodes; } -- (void)destroy { +- (BOOL)checkLicense { +#if __has_include(BytesMoudle) + return [[BELicenseHelper shareInstance] checkLicense]; +#else + return NO; +#endif +} + +- (void)destroy { #if __has_include(BytesMoudle) - _frameProcessor = nil; + [_effectManager cleanPipeline]; + [_effectManager destroyTask]; + _effectManager = nil; _imageUtils = nil; + [self.outTexture destroy]; + self.outTexture = nil; #endif } -- (nonnull CVPixelBufferRef)onCapture:(nonnull CVPixelBufferRef)pixelBuffer { +- (nonnull CVPixelBufferRef)onCapture:(nonnull CVPixelBufferRef)pixelBuffer { #if __has_include(BytesMoudle) - pixelBuffer = [self.imageUtils transforCVPixelBufferToCVPixelBuffer:pixelBuffer outputFormat:BE_BGRA]; - CVPixelBufferRef px = [self.frameProcessor process: pixelBuffer - timeStamp: [NSDate date].timeIntervalSince1970].pixelBuffer; - return px; + double timeStamp = [[NSDate date] timeIntervalSince1970]; + BEPixelBufferInfo *pixelBufferInfo = [self.imageUtils getCVPixelBufferInfo:pixelBuffer]; + if (pixelBufferInfo.format != BE_BGRA) { + pixelBuffer = [self.imageUtils transforCVPixelBufferToCVPixelBuffer:pixelBuffer + outputFormat:pixelBufferInfo.format]; + } + + if ([self getDeviceOrientation] != BEF_AI_CLOCKWISE_ROTATE_0) { + pixelBuffer = [self.imageUtils rotateCVPixelBuffer:pixelBuffer rotation:BEF_AI_CLOCKWISE_ROTATE_0]; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if ([EAGLContext currentContext] != self.effectManager.glContext) { + [EAGLContext setCurrentContext: self.effectManager.glContext]; + } +#pragma clang diagnostic pop + id texture = [self.imageUtils transforCVPixelBufferToTexture:pixelBuffer]; + BEPixelBufferGLTexture *outTexture = nil; + + outTexture = [self.imageUtils getOutputPixelBufferGLTextureWithWidth:texture.width + height:texture.height + format:pixelBufferInfo.format + withPipeline:self.effectManager.usePipeline]; + self.outTexture = outTexture; + int ret = [self.effectManager processTexture:texture.texture + outputTexture:outTexture.texture + width:pixelBufferInfo.width + height:pixelBufferInfo.height + rotate:[self getDeviceOrientation] + timeStamp:timeStamp]; + if (ret != BEF_RESULT_SUC) { + outTexture = texture; + } + return [(BEPixelBufferGLTexture *)outTexture pixelBuffer]; +#else + return pixelBuffer; #endif - return nil; } + +#if __has_include(BytesMoudle) +- (bef_ai_rotate_type)getDeviceOrientation { + UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; + switch (orientation) { + case UIDeviceOrientationPortrait: + return BEF_AI_CLOCKWISE_ROTATE_0; + + case UIDeviceOrientationPortraitUpsideDown: + return BEF_AI_CLOCKWISE_ROTATE_180; + + case UIDeviceOrientationLandscapeLeft: + return BEF_AI_CLOCKWISE_ROTATE_270; + + case UIDeviceOrientationLandscapeRight: + return BEF_AI_CLOCKWISE_ROTATE_90; + + default: + return BEF_AI_CLOCKWISE_ROTATE_0; + } +} +#endif + #if __has_include() - (AgoraVideoFormat)getVideoFormatPreference { return AgoraVideoFormatCVPixelBGRA; } #endif -- (void)reset { +- (void)reset { #if __has_include(BytesMoudle) - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Overall" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Cheekbone" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Eye" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Nose" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Chin" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Jawbone" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Forehead" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_ZoomMouth" intensity:0]; - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_4Items" key:@"BEF_BEAUTY_WHITEN_TEETH" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Overall" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Cheekbone" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Eye" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Nose" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Chin" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Jawbone" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Forehead" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_ZoomMouth" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_4Items" key:@"BEF_BEAUTY_WHITEN_TEETH" intensity:0]; #endif } -- (void)setBeautyPreset { +- (void)setBeautyPreset { #if __has_include(BytesMoudle) - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0.2]; - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0.3]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Overall" intensity:0.15]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Cheekbone" intensity:0.3]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Eye" intensity:0.15]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Nose" intensity:0.15]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Chin" intensity:0.46]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Jawbone" intensity:0.46]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Forehead" intensity:0.4]; - [self.frameProcessor updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_ZoomMouth" intensity:0.16]; - [self.frameProcessor updateComposerNodeIntensity:@"/beauty_4Items" key:@"BEF_BEAUTY_WHITEN_TEETH" intensity:0.2]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0.2]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0.3]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Overall" intensity:0.15]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Cheekbone" intensity:0.3]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Eye" intensity:0.15]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Nose" intensity:0.15]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Chin" intensity:0.46]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Zoom_Jawbone" intensity:0.46]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_Forehead" intensity:0.4]; + [self.effectManager updateComposerNodeIntensity:@"/reshape_lite" key:@"Internal_Deform_ZoomMouth" intensity:0.16]; + [self.effectManager updateComposerNodeIntensity:@"/beauty_4Items" key:@"BEF_BEAUTY_WHITEN_TEETH" intensity:0.2]; #endif } -- (void)setMakeup:(BOOL)isSelected { +- (void)setMakeup:(BOOL)isSelected { #if __has_include(BytesMoudle) if (isSelected) { if (![self.bytesNodes containsObject:@"/style_makeup/qise"]) { [self.bytesNodes addObject:@"/style_makeup/qise"]; - [self.frameProcessor updateComposerNodes:self.bytesNodes]; + [self.effectManager updateComposerNodes:self.bytesNodes]; } - [self.frameProcessor updateComposerNodeIntensity:@"/style_makeup/qise" key:@"Makeup_ALL" intensity:0.6]; + [self.effectManager updateComposerNodeIntensity:@"/style_makeup/qise" key:@"Makeup_ALL" intensity:0.6]; } else { if ([self.bytesNodes containsObject:@"/style_makeup/qise"]) { [self.bytesNodes removeObject:@"/style_makeup/qise"]; - [self.frameProcessor updateComposerNodes:self.bytesNodes]; + [self.effectManager updateComposerNodes:self.bytesNodes]; } - [self.frameProcessor updateComposerNodeIntensity:@"/style_makeup/qise" key:@"Makeup_ALL" intensity:0]; + [self.effectManager updateComposerNodeIntensity:@"/style_makeup/qise" key:@"Makeup_ALL" intensity:0]; } #endif } -- (void)setSticker:(BOOL)isSelected { +- (void)setSticker:(BOOL)isSelected { #if __has_include(BytesMoudle) if (isSelected) { - [self.frameProcessor setStickerPath:@"matting_bg"]; + [self.effectManager setStickerPath:@"zhaocaimao"]; } else { - [self.frameProcessor setStickerPath:@""]; + [self.effectManager setStickerPath:@""]; } #endif } diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.h index daa31195b..a37bd6db7 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.h @@ -25,11 +25,13 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) FUManager *fuManager; #endif -- (void)setBeautyWithPath: (NSString *)path key: (NSString *)key value: (float)value; ++ (BOOL)checkLicense; -- (void)setStyleWithPath: (NSString *)path key: (NSString *)key value: (float)value; +- (void)setBeautyWithPath:(NSString *)path key:(NSString *)key value:(float)value; -- (void)setStickerWithPath: (NSString *)path; +- (void)setStyleWithPath:(NSString *)path key:(NSString *)key value:(float)value isCombined:(BOOL)isCombined; + +- (void)setStickerWithPath:(NSString *)path; - (void)reset; @@ -39,6 +41,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)destroy; + + @end NS_ASSUME_NONNULL_END diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m index 662529ef6..1be3981e4 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m @@ -7,6 +7,9 @@ #import "FUBeautyRender.h" #import "BundleUtil.h" +#if __has_include("FUManager.h") +#import "authpack.h" +#endif @interface FUBeautyRender () @@ -15,6 +18,7 @@ @interface FUBeautyRender () @property (nonatomic, strong) FUSticker *currentSticker; @property (nonatomic, strong) FUAnimoji *currentAnimoji; #endif +@property (nonatomic, copy) NSString *makeupKey; @end @@ -29,12 +33,27 @@ - (instancetype)init { return self; } ++ (BOOL)checkLicense { + BOOL success = NO; +#if __has_include(FURenderMoudle) + FUSetupConfig *setupConfig = [[FUSetupConfig alloc] init]; + setupConfig.authPack = FUAuthPackMake(g_auth_package, sizeof(g_auth_package)); + + // 初始化 FURenderKit + success = [FURenderKit setupWithSetupConfig:setupConfig]; +#endif + return success; +} + - (void)destroy { #if __has_include(FURenderMoudle) - [FURenderKit shareRenderKit].beauty = nil; - [FURenderKit shareRenderKit].makeup = nil; - [[FURenderKit shareRenderKit].stickerContainer removeAllSticks]; - [FURenderKit destroy]; + dispatch_queue_t referQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); + dispatch_async(referQueue, ^{ + [FURenderKit shareRenderKit].beauty = nil; + [FURenderKit shareRenderKit].makeup = nil; + [[FURenderKit shareRenderKit].stickerContainer removeAllSticks]; + [FURenderKit destroy]; + }); _fuManager = nil; #endif } @@ -55,8 +74,7 @@ - (void)setBeautyWithPath:(NSString *)path key:(NSString *)key value:(float)valu #if __has_include(FURenderMoudle) FUBeauty *beauty = [FURenderKit shareRenderKit].beauty; if (beauty == nil) { - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *faceAIPath = [bundle pathForResource:[NSString stringWithFormat:@"graphics/%@", path] ofType:@"bundle"]; + NSString *faceAIPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@", path] ofType:@"bundle"]; beauty = [[FUBeauty alloc] initWithPath:faceAIPath name:@"FUBeauty"]; beauty.heavyBlur = 0; } @@ -129,21 +147,46 @@ - (void)setBeautyWithPath:(NSString *)path key:(NSString *)key value:(float)valu } else if ([key isEqualToString:@"sharpen"]) { beauty.sharpen = value; } + beauty.enable = YES; [FURenderKit shareRenderKit].beauty = beauty; #endif } -- (void)setStyleWithPath:(NSString *)path key:(NSString *)key value:(float)value { +- (void)setStyleWithPath:(NSString *)path key:(NSString *)key value:(float)value isCombined:(BOOL)isCombined { #if __has_include(FURenderMoudle) - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *makeupPath = [bundle pathForResource:path ofType:@"bundle"]; + [self setupBeauty]; FUMakeup *makeup = [FURenderKit shareRenderKit].makeup; - if (makeup == nil) { - makeup = [[FUMakeup alloc] initWithPath:makeupPath name:@"face_makeup"]; - makeup.isMakeupOn = YES; - [FURenderKit shareRenderKit].makeup = makeup; - [FURenderKit shareRenderKit].makeup.enable = YES; + if (isCombined) { + if (makeup == nil || self.makeupKey != key) { + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; + NSString *stylePath = [bundle pathForResource:key ofType:@"bundle"]; + makeup = [[FUMakeup alloc] initWithPath:stylePath name:@"makeup"]; + makeup.isMakeupOn = YES; + dispatch_queue_t referQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); + dispatch_async(referQueue, ^{ + [FURenderKit shareRenderKit].makeup = makeup; + [FURenderKit shareRenderKit].makeup.intensity = value; + [FURenderKit shareRenderKit].makeup.enable = YES; + }); + } + [FURenderKit shareRenderKit].makeup.intensity = value; + self.makeupKey = key; + } else { + NSString *makeupPath = [[NSBundle mainBundle] pathForResource:path ofType:@"bundle"]; + if (makeup == nil || self.makeupKey != path) { + makeup = [[FUMakeup alloc] initWithPath:makeupPath name:@"face_makeup"]; + makeup.isMakeupOn = YES; + [FURenderKit shareRenderKit].makeup = makeup; + [FURenderKit shareRenderKit].makeup.enable = YES; + } + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; + NSString *stylePath = [bundle pathForResource:key ofType:@"bundle"]; + FUItem *makupItem = [[FUItem alloc] initWithPath:stylePath name:key]; + [makeup updateMakeupPackage:makupItem needCleanSubItem:NO]; + makeup.intensity = value; + self.makeupKey = path; } + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; NSString *stylePath = [bundle pathForResource:key ofType:@"bundle"]; FUItem *makupItem = [[FUItem alloc] initWithPath:stylePath name:key]; [makeup updateMakeupPackage:makupItem needCleanSubItem:NO]; @@ -153,6 +196,7 @@ - (void)setStyleWithPath:(NSString *)path key:(NSString *)key value:(float)value - (void)setAnimojiWithPath:(NSString *)path { #if __has_include(FURenderMoudle) + [self setupBeauty]; if (self.currentSticker) { [[FURenderKit shareRenderKit].stickerContainer removeSticker:self.currentSticker completion:nil]; self.currentSticker = nil; @@ -173,10 +217,15 @@ - (void)setAnimojiWithPath:(NSString *)path { } - (void)setStickerWithPath:(NSString *)path { +#if __has_include(FURenderMoudle) + [self setupBeauty]; NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; NSString *stickerPath = [bundle pathForResource:[NSString stringWithFormat:@"sticker/%@", path] ofType:@"bundle"]; -#if __has_include(FURenderMoudle) - FUSticker *sticker = [[FUSticker alloc] initWithPath:stickerPath name:@"sticker"]; + if (stickerPath == nil && self.currentSticker == nil) { + return; + } + FUSticker *sticker = [[FUSticker alloc] initWithPath:stickerPath + name:path]; if (self.currentAnimoji) { [[FURenderKit shareRenderKit].stickerContainer removeSticker:self.currentAnimoji completion:nil]; self.currentAnimoji = nil; @@ -192,15 +241,15 @@ - (void)setStickerWithPath:(NSString *)path { - (void)reset { #if __has_include(FURenderMoudle) - [FURenderKit shareRenderKit].beauty = nil; + [FURenderKit shareRenderKit].beauty.enable = NO; #endif } - (void)resetStyle { #if __has_include(FURenderMoudle) [FURenderKit shareRenderKit].makeup.enable = NO; - [FURenderKit shareRenderKit].makeup = nil; #endif + self.makeupKey = nil; } - (void)resetSticker { @@ -213,19 +262,31 @@ - (void)resetSticker { - (void)setBeautyPreset { #if __has_include(FURenderMoudle) - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *faceAIPath = [bundle pathForResource:@"graphics/face_beautification" ofType:@"bundle"]; - FUBeauty *beauty = [[FUBeauty alloc] initWithPath:faceAIPath name:@"FUBeauty"]; - [FURenderKit shareRenderKit].beauty = beauty; + dispatch_queue_t referQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); + dispatch_async(referQueue, ^{ + NSString *faceAIPath = [[NSBundle mainBundle] pathForResource:@"face_beautification" ofType:@"bundle"]; + FUBeauty *beauty = [[FUBeauty alloc] initWithPath:faceAIPath name:@"FUBeauty"]; + [FURenderKit shareRenderKit].beauty = beauty; + }); +#endif +} + +- (void)setupBeauty { +#if __has_include(FURenderMoudle) + if ([FURenderKit shareRenderKit].beauty == nil) { + NSString *faceAIPath = [[NSBundle mainBundle] pathForResource:@"face_beautification" ofType:@"bundle"]; + FUBeauty *beauty = [[FUBeauty alloc] initWithPath:faceAIPath name:@"FUBeauty"]; + [FURenderKit shareRenderKit].beauty = beauty; + } #endif } - (void)setMakeup:(BOOL)isSelected { #if __has_include(FURenderMoudle) if (isSelected) { - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *makeupPath = [bundle pathForResource:@"graphics/face_makeup" ofType:@"bundle"]; + NSString *makeupPath = [[NSBundle mainBundle] pathForResource:@"face_makeup" ofType:@"bundle"]; FUMakeup *makeup = [[FUMakeup alloc] initWithPath:makeupPath name:@"face_makeup"]; + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; NSString *path = [bundle pathForResource:@"makeup/ziyun" ofType:@"bundle"]; FUItem *makupItem = [[FUItem alloc] initWithPath:path name:@"ziyun"]; makeup.isMakeupOn = YES; @@ -235,7 +296,6 @@ - (void)setMakeup:(BOOL)isSelected { makeup.intensity = 0.7; } else { [FURenderKit shareRenderKit].makeup.enable = NO; - [FURenderKit shareRenderKit].makeup = nil; } #endif } diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/SenseRender/SenseBeautyRender.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/SenseRender/SenseBeautyRender.m index 323e32f87..52fba49ef 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/SenseRender/SenseBeautyRender.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/SenseRender/SenseBeautyRender.m @@ -61,10 +61,11 @@ - (void)checkSensetimeLicense { self.isSuccessLicense = [EffectsProcess authorizeWithLicensePath:licensePath]; __weak SenseBeautyRender *weakSelf = self; self.timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) { - weakSelf.isSuccessLicense = weakSelf.videoProcessing.effectsProcess.isAuthrized; if (weakSelf.isSuccessLicense) { [weakSelf.timer invalidate]; weakSelf.timer = nil; + } else { + weakSelf.isSuccessLicense = weakSelf.videoProcessing.effectsProcess.isAuthrized; } if (weakSelf.licenseEventCallback) { weakSelf.licenseEventCallback(weakSelf.isSuccessLicense); @@ -86,7 +87,7 @@ - (nonnull CVPixelBufferRef)onCapture:(nonnull CVPixelBufferRef)pixelBuffer { if (self.isSuccessLicense) { return [self.videoProcessing videoProcessHandler:pixelBuffer]; } - return nil; + return pixelBuffer; #endif return pixelBuffer; } @@ -134,14 +135,12 @@ - (void)setBeautyDefault { - (void)setMakeup:(BOOL)isSelected { #if __has_include(Sensetime) if (isSelected) { - NSString *path = [[NSBundle mainBundle] pathForResource:@"qise.zip" ofType:nil]; __weak SenseBeautyRender *weakself = self; - [self.videoProcessing.effectsProcess addStickerWithPath:path callBack:^(st_result_t state, int sticker, uint64_t action) { - [weakself.videoProcessing.effectsProcess setPackageId:sticker groupType:EFFECT_BEAUTY_GROUP_MAKEUP strength:0.5]; + [self.videoProcessing addStylePath:@"hunxue.zip" groupId:0 strength:0.5 callBack:^(int sticker) { weakself.stickerId = sticker; }]; } else { - [self.videoProcessing.effectsProcess removeSticker:self.stickerId]; + [self.videoProcessing removeStickerId:self.stickerId]; self.stickerId = 0; } #endif @@ -150,7 +149,7 @@ - (void)setMakeup:(BOOL)isSelected { - (void)setSticker:(BOOL)isSelected { #if __has_include(Sensetime) if (isSelected) { - NSString *path = [[NSBundle mainBundle] pathForResource:@"lianxingface.zip" ofType:nil]; + NSString *path = [[NSBundle mainBundle] pathForResource:@"ShangBanLe.zip" ofType:nil]; [self.videoProcessing.effectsProcess setStickerWithPath:path callBack:^(st_result_t state, int stickerId, uint64_t action) { }]; diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.h new file mode 100644 index 000000000..fe85201a1 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.h @@ -0,0 +1,49 @@ +// +// APIReporter.h +// BeautyAPi +// +// Created by zhaoyongqiang on 2024/4/17. +// + +#import +#import + +typedef NS_ENUM(NSInteger, APIType) { + APITypeKTV = 1, //K歌 + APITypeCall = 2, //呼叫 + APITypeBeauty = 3, //美颜 + APITypeVideoLoader = 4, //秒开/秒切 + APITypePK = 5, //团战 + APITypeVitualSpace = 6, + APITypeScreenSpace = 7, //屏幕共享 + APITypeAudioScenario = 8 //音频scenario +}; + +typedef NS_ENUM(NSInteger, APIEventType) { + APIEventTypeAPI = 0, //api事件 + APIEventTypeCost, //耗时事件 + APIEventTypeCustom //自定义事件 +}; + +typedef NS_ENUM(NSInteger, APICostEvent) { + APICostEventChannelUsage = 0, //频道使用耗时 + APICostEventFirstFrameActual, //首帧实际耗时 + APICostEventFirstFramePerceived //首帧感官耗时 +}; + +NS_ASSUME_NONNULL_BEGIN + +@interface APIReporter : NSObject + +- (instancetype)initWithType:(APIType)type version:(NSString *)version engine:(AgoraRtcEngineKit *)engine; +- (void)reportFuncEventWithName:(NSString *)name value:(NSDictionary *)value ext:(NSDictionary *)ext; +- (void)startDurationEventWithName:(NSString *)name; +- (void)endDurationEventWithName:(NSString *)name ext:(NSDictionary *)ext; +- (void)reportCostEventWithName:(APICostEvent)name cost:(NSInteger)cost ext:(NSDictionary *)ext; +- (void)reportCustomEventWithName:(NSString *)name ext:(NSDictionary *)ext; +- (void)writeLogWithContent:(NSString *)content level:(AgoraLogLevel)level; +- (void)cleanCache; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.m new file mode 100644 index 000000000..cb4ca73f1 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Report/APIReporter.m @@ -0,0 +1,143 @@ +// +// APIReporter.m +// BeautyAPi +// +// Created by zhaoyongqiang on 2024/4/17. +// + +#import "APIReporter.h" + +@interface APIReporter () + +@property (nonatomic, strong) AgoraRtcEngineKit *engine; +@property (nonatomic, copy) NSString *category; +@property (nonatomic, strong) NSMutableDictionary *durationEventStartMap; +@property (nonatomic, copy) NSString *messsageId; + +@end + +@implementation APIReporter + +- (NSString *)messsageId { + return @"agora:scenarioAPI"; +} + +- (instancetype)initWithType:(APIType)type version:(NSString *)version engine:(AgoraRtcEngineKit *)engine { + self = [super init]; + if (self) { + _category = [NSString stringWithFormat:@"%ld_iOS%@", (long)type, version]; + _engine = engine; + [self configParameters]; + } + return self; +} + +- (void)reportFuncEventWithName:(NSString *)name value:(NSDictionary *)value ext:(NSDictionary *)ext { + NSString *content = [NSString stringWithFormat:@"[APIReporter]reportFuncEvent: %@ value: %@ ext: %@", name, value, ext]; + [self debugApiPrint:content]; + + NSDictionary *eventMap = @{ @"type": @(APIEventTypeAPI), @"desc": name }; + NSDictionary *labelMap = @{ @"apiValue": value, @"ts": @([self getCurrentTs]), @"ext": ext}; + + NSString *event = [self convertToJSONString:eventMap]; + NSString *label = [self convertToJSONString:labelMap]; + + [self.engine sendCustomReportMessage:self.messsageId category:self.category event:event label:label value:0]; +} + +- (void)startDurationEventWithName:(NSString *)name { + self.durationEventStartMap[name] = @([self getCurrentTs]); +} + +- (void)endDurationEventWithName:(NSString *)name ext:(NSDictionary *)ext { + NSNumber *beginTs = self.durationEventStartMap[name]; + if (!beginTs) { + return; + } + [self.durationEventStartMap removeObjectForKey:name]; + + NSInteger ts = [self getCurrentTs]; + NSInteger cost = ts - beginTs.integerValue; + + [self reportCostEventWithTs:ts name:name cost:cost ext:ext]; +} + +- (void)reportCostEventWithName:(APICostEvent)name cost:(NSInteger)cost ext:(NSDictionary *)ext { [self.durationEventStartMap removeObjectForKey: [self getCostEventWithName:name]]; + + [self reportCostEventWithTs:[self getCurrentTs] name:[self getCostEventWithName:name] cost:cost ext:ext]; +} + +- (void)reportCustomEventWithName:(NSString *)name ext:(NSDictionary *)ext { + NSString *content = [NSString stringWithFormat:@"[APIReporter]reportCustomEvent: %@ ext: %@", name, ext]; + [self debugApiPrint:content]; + + NSDictionary *eventMap = @{ @"type": @(APIEventTypeCustom), @"desc": name }; + NSDictionary *labelMap = @{ @"ts": @([self getCurrentTs]), @"ext": ext }; + + NSString *event = [self convertToJSONString:eventMap]; + NSString *label = [self convertToJSONString:labelMap]; + + [self.engine sendCustomReportMessage:self.messsageId category:self.category event:event label:label value:0]; +} + +- (NSString *)getCostEventWithName:(APICostEvent)name { + switch (name) { + case APICostEventChannelUsage: return @"channelUsage"; + case APICostEventFirstFrameActual: return @"firstFrameActual"; + case APICostEventFirstFramePerceived: return @"firstFramePerceived"; + } +} + +- (void)writeLogWithContent:(NSString *)content level:(AgoraLogLevel)level { + [self.engine writeLog:level content:content]; +} + +- (void)cleanCache { + [self.durationEventStartMap removeAllObjects]; +} + +#pragma mark - Private Methods +- (void)reportCostEventWithTs:(NSInteger)ts name:(NSString *)name cost:(NSInteger)cost ext:(NSDictionary *)ext { + NSString *content = [NSString stringWithFormat:@"[APIReporter]reportCostEvent: %@ cost: %ld ms ext: %@", name, (long)cost, ext]; + [self debugApiPrint:content]; + [self writeLogWithContent:content level:AgoraLogLevelInfo]; + + NSDictionary *eventMap = @{ @"type": @(APIEventTypeCost), @"desc": name }; + NSDictionary *labelMap = @{ @"ts": @(ts), @"ext": ext }; + + NSString *event = [self convertToJSONString:eventMap]; + NSString *label = [self convertToJSONString:labelMap]; + + [self.engine sendCustomReportMessage:self.messsageId category:self.category event:event label:label value:cost]; +} + +- (void)configParameters { + [self.engine setParameters:@"{\"rtc.direct_send_custom_event\": true}"]; + [self.engine setParameters:@"{\"rtc.log_external_input\": true}"]; +} + +- (NSInteger)getCurrentTs { + return (NSInteger)([[NSDate date] timeIntervalSince1970] * 1000.0); +} + +- (NSString *)convertToJSONString:(NSDictionary *)dictionary { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; + if (!jsonData) { + [self writeLogWithContent:[NSString stringWithFormat:@"[APIReporter]convert to json fail: %@ dictionary: %@", error, dictionary] level:AgoraLogLevelWarn]; + return nil; + } + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + return jsonString; +} + +- (void)debugApiPrint:(NSString *)message { +#if DEBUG + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; + NSString *timeString = [formatter stringFromDate:[NSDate date]]; + NSLog(@"%@ %@", timeString, message); +#endif +} + +@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/BytedEffectVC.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/BytedEffectVC.m index 3e749aed9..1046954fd 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/BytedEffectVC.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/BytedEffectVC.m @@ -48,7 +48,7 @@ - (void)viewDidLoad { } - (void) initSDK { -#if __has_include("bef_effect_ai_api.h") +#if __has_include(BytesMoudle) [self.tipsLabel setHidden:YES]; [self.container setHidden:NO]; #else diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.h index ac48cee43..df5fc06af 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.h @@ -1,9 +1,6 @@ -// // BEEffectManager.h -// BytedEffectSDK -// -// Created by qun on 2021/5/17. -// +// EffectsARSDK + #ifndef BEEffectManager_h #define BEEffectManager_h @@ -12,9 +9,9 @@ #import #import #import "BELicenseHelper.h" -#if __has_include("bef_effect_ai_api.h") -#import "bef_effect_ai_api.h" -#import "bef_effect_ai_message_define.h" +#if __has_include() +#import +#import #endif #import "BEImageUtils.h" @@ -28,8 +25,8 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { BEEffectPart_2 = 2, BEEffectPart_3 = 3, BEEffectPart_4 = 4, - BEEffectPart_5 = 5, //全局染发 - BEEffectPart_6 = 6, //清除染发效果 + BEEffectPart_5 = 5, // {zh} 全局染发 {en} Global hair color + BEEffectPart_6 = 6, // {zh} 清除染发效果 {en} Clear hair color effect }; @protocol BEEffectManagerDelegate @@ -68,6 +65,10 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { @property (nonatomic, strong) id provider; @property (nonatomic, strong) id licenseProvider; @property (nonatomic, weak) id delegate; +@property (nonatomic, strong) NSString *resourcePath; +@property (atomic, weak) dispatch_queue_t renderQueue; +@property (nonatomic, strong) EAGLContext *glContext; +@property (nonatomic, assign, readonly) BOOL isSuccessLicense; // {zh} / @brief 构造函数 {en} /@brief constructor // {zh} / @details 需要传入一个 BEEffectResourceProvider 实现,用于提供各种素材的路径,和一个BELicenseProvider的实现,用于获取license {en} /@details need to pass in a BEEffectResourceProvider implementation to provide the path of various materials, and a BELicenseProvider implementation to get license @@ -75,7 +76,7 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { // {zh} / @param provider 特效资源文件获取类 {en} /@param provider effect resource file acquisition class - (instancetype)initWithResourceProvider:(id)resourceProvider licenseProvider:(id)licenseProvider; -#if __has_include("bef_effect_ai_api.h") +#if __has_include() // {zh} / @brief 初始化 SDK {en} /@brief initialization SDK - (bef_effect_result_t)initTask; @@ -94,15 +95,15 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { // {zh} / @brief 设置licenseProvider {en} /@Briefly set licenseProvider // {zh} / @param licenseProvider 传入一个licenseProvider的实现用于license的获取 {en} /@param licenseProvider is a BELicenseProvider implementation to provide the path of license, - +#endif // {zh} / @brief 设置滤镜路径 {en} /@Briefly set filter path // {zh} / @details 相对 FilterResource.bundle/Filter 路径,为 null 时关闭滤镜 {en} /@details Relative to FilterResource .bundle/Filter path, close filter when null // {zh} / @param path 相对路径 {en} /@param path relative path - (void)setFilterPath:(NSString *) path; -/// @brief 设置滤镜绝对路径 -/// @param path 滤镜素材的文件路径,绝对路径 +// {zh} / @brief 设置滤镜绝对路径 {en} /@Brief Set the absolute path of the filter +// {zh} / @param path 滤镜素材的文件路径,绝对路径 {en} /@Param path The file path of the filter material, absolute path - (void)setFilterAbsolutePath:(NSString *)path; // {zh} / @brief 设置滤镜强度 {en} /@Briefly set filter strength @@ -159,6 +160,7 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { // {zh} / @param majorRadius 触摸范围 {en} @param majorRadius touch range // {zh} / @param pointerId 触摸点 id {en} /@param pointerId touch point id // {zh} / @param pointerCount 触摸点数量 {en} @param pointerCount number of touch points +#if __has_include() - (BOOL)processTouchEvent:(bef_ai_touch_event_code)eventCode x:(float)x y:(float)y force:(float)force majorRadius:(float)majorRadius pointerId:(int)pointerId pointerCount:(int)pointerCount; // {zh} / @brief 处理手势事件 {en} Handle gesture events briefly @@ -188,6 +190,7 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { // {zh} / @brief 获取特效 SDK 中的人脸 mask 结果 {en} /@Brief Get the face mask results in the special effects SDK - (bef_ai_face_mask_info *)getFaceMaskInfo; #endif + // {zh} / @brief 是否开启并行渲染 {en} /@Brief whether to turn on parallel rendering // {zh} / @details 特效 SDK 内部工作分为两部分,算法检测和特效渲染,当开启并行渲染之后, {en} /@Details The internal work of the special effects SDK is divided into two parts, algorithm detection and special effects rendering. When parallel rendering is turned on, // {zh} / 算法检测和特效渲染将在不同线程执行,以充分利用多多线程进行加速, {en} /Algorithm detection and effects rendering will be performed on different threads to make full use of multi-threads for acceleration, @@ -223,7 +226,9 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { // {zh} / @details 传入一个固定名字的纹理给到 SDK,传入 BEBuffer,SDK 会将其解析成纹理 {en} /@details pass a texture with a fixed name to the SDK, pass BEBuffer, and the SDK will parse it into a texture // {zh} / @param key 纹理名称 {en} /@param key texture name // {zh} / @param buffer BEBuffer, 仅支持 RGBA 格式 {en} /@param buffer BEBuffer, only supports RGBA format +#if __has_include() - (BOOL)setRenderCacheTexture:(NSString *)key buffer:(BEBuffer *)buffer; +#endif - (void)loadResource:(int)timeout; @@ -240,6 +245,10 @@ typedef NS_ENUM(NSInteger, BEEffectPart) { - (UIImage*)getCapturedImageWithKey:(const char*) key; +// {zh} / @brief 开启或关闭强制人脸检测 {en} /@brief Enable or disable forced face detection +// {zh} /detection YES 开启人脸检测 NO关闭人脸检测 {en} /detection YES on face detection NO off face detection +- (void)forcedFaceDetection:(BOOL)detection; + @end #endif /* BEEffectManager_h */ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.mm b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.mm index f0fd890a8..d2ad46298 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.mm +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEEffectManager.mm @@ -1,18 +1,18 @@ -// // BEEffectManager.m // Core -// -// Created by qun on 2021/5/17. -// + #import "BEEffectManager.h" -#if __has_include("bef_effect_ai_api.h") -#import "bef_effect_ai_api.h" -#import "bef_effect_ai_message_define.h" -#import "bef_effect_ai_error_code_format.h" -#import "bef_effect_ai_version.h" +#if __has_include() +#import +#import +#import +#import #endif +#import "BETimeRecoder.h" #import "Core.h" +#import "BEImageUtils.h" +#import "BEGLUtils.h" #ifdef EFFECT_LOG_ENABLED typedef enum { @@ -26,11 +26,12 @@ BEF_LOG_LEVEL_FATAL = 7, BEF_LOG_LEVEL_SILENT = 8, }bef_log_level; -#if __has_include("bef_effect_ai_api.h") +#if __has_include() BEF_SDK_API void bef_effect_set_log_level(bef_effect_handle_t handle, bef_log_level logLevel); BEF_SDK_API typedef int(*logFileFuncPointer)(int logLevel, const char* msg); BEF_SDK_API bef_effect_result_t bef_effect_set_log_to_local_func(logFileFuncPointer pfunc); #endif + int effectLogCallback(int logLevel, const char* msg) { printf("[EffectSDK] %s\n", msg); return 0; @@ -41,9 +42,8 @@ int effectLogCallback(int logLevel, const char* msg) { #define BE_LOAD_RESOURCE_TIMEOUT true -#if __has_include("bef_effect_ai_api.h") +#if __has_include() @interface BEEffectManager () { -#if __has_include("bef_effect_ai_api.h") bef_effect_handle_t _handle; BOOL _effectOn; @@ -54,12 +54,16 @@ @interface BEEffectManager () { bef_ai_face_mask_info *_faceMaskInfo; bef_ai_mouth_mask_info *_mouthMaskInfo; bef_ai_teeth_mask_info *_teethMaskInfo; -#endif +// EAGLContext *_glContext; + #if BE_LOAD_RESOURCE_TIMEOUT NSMutableSet *_existResourcePathes; BOOL _needLoadResource; -#endif + BOOL _isInitSuccess; } +#else +} +#endif @end #endif @@ -71,8 +75,8 @@ @implementation BEEffectManager - (instancetype)initWithResourceProvider:(id)resourceProvider licenseProvider:(id)licenseProvider { self = [super init]; +#if __has_include() if (self) { -#if __has_include("bef_effect_ai_api.h") _faceInfo = nil; _handInfo = nil; _skeletonInfo = nil; @@ -83,17 +87,26 @@ - (instancetype)initWithResourceProvider:(id)resourceP #if BE_LOAD_RESOURCE_TIMEOUT _existResourcePathes = [NSMutableSet set]; _needLoadResource = NO; + _renderQueue = nil; #endif self.provider = resourceProvider; self.licenseProvider = licenseProvider; -#endif } +#endif return self; } - (int)initTask { -#if __has_include("bef_effect_ai_api.h") +#if __has_include() _effectOn = true; + _glContext = [EAGLContext currentContext]; // 运行在主线程,使用的是self.glView.context + if (_glContext == nil) { + NSLog(@"initTask is not run in thread with glContext!!!"); + _glContext = [BEGLUtils createContextWithDefaultAPI:kEAGLRenderingAPIOpenGLES3]; + } + if ([EAGLContext currentContext] != _glContext) { + [EAGLContext setCurrentContext: _glContext]; + } int ret = 0; ret = bef_effect_ai_create(&_handle); CHECK_RET_AND_RETURN(bef_effect_ai_create, ret) @@ -104,6 +117,7 @@ - (int)initTask { if (self.licenseProvider.licenseMode == OFFLINE_LICENSE) { ret = bef_effect_ai_check_license(_handle, self.licenseProvider.licensePath); CHECK_RET_AND_RETURN(bef_effect_ai_check_license, ret) + _isSuccessLicense = ret == 0; } else if (self.licenseProvider.licenseMode == ONLINE_LICENSE){ if (![self.licenseProvider checkLicenseResult: @"getLicensePath"]) @@ -121,8 +135,13 @@ - (int)initTask { CHECK_RET_AND_RETURN(bef_effect_ai_use_builtin_sensor, ret) ret = bef_effect_ai_init(_handle, 10, 10, self.provider.modelDirPath, ""); CHECK_RET_AND_RETURN(bef_effect_ai_init, ret) + + ret = bef_effect_ai_use_3buffer(_handle, false); + CHECK_RET_AND_RETURN(bef_effect_ai_use_3buffer, ret); + _msgDelegateManager = [[IRenderMsgDelegateManager alloc] init]; [self addMsgHandler:self]; + _isInitSuccess = ret == 0; return ret; #else return -1; @@ -130,40 +149,66 @@ - (int)initTask { } - (int)destroyTask { -#if __has_include("bef_effect_ai_api.h") +#if __has_include() + if ([EAGLContext currentContext] != _glContext) { + NSLog(@"effectsar init and destroy are not run in the same glContext"); + [EAGLContext setCurrentContext:_glContext]; + } [self removeMsgHandler:self]; bef_effect_ai_destroy(_handle); + [_msgDelegateManager destoryDelegate]; + _msgDelegateManager = nil; free(_faceInfo); free(_handInfo); free(_skeletonInfo); free(_faceMaskInfo); free(_mouthMaskInfo); free(_teethMaskInfo); -#endif + _isInitSuccess = NO; return 0; +#else + return -1; +#endif } -#if __has_include("bef_effect_ai_api.h") + #pragma mark - public +#if __has_include() - (bef_effect_result_t)processTexture:(GLuint)texture outputTexture:(GLuint)outputTexture width:(int)width height:(int)height rotate:(bef_ai_rotate_type)rotate timeStamp:(double)timeStamp { + if (!_isInitSuccess) { + return BEF_RESULT_FAIL; + } #if BE_LOAD_RESOURCE_TIMEOUT - if (_needLoadResource) { - _needLoadResource = NO; - [self loadResource:-1]; + if (_renderQueue) { + if (_needLoadResource) { + _needLoadResource = NO; + [self loadResource:-1]; + } } #endif + if ([EAGLContext currentContext] != _glContext) { + NSLog(@"effectsar init and process are not run in the same glContext"); + [EAGLContext setCurrentContext:_glContext]; + } + + RECORD_TIME(totalProcess) bef_effect_result_t ret = bef_effect_ai_set_width_height(_handle, width, height); - CHECK_RET_AND_RETURN(bef_effect_ai_set_width_height, ret); + CHECK_RET_AND_RETURN(bef_effect_ai_set_width_height, ret) ret = bef_effect_ai_set_orientation(_handle, rotate); - CHECK_RET_AND_RETURN(bef_effect_ai_set_orientation, ret); + CHECK_RET_AND_RETURN(bef_effect_ai_set_orientation, ret) + RECORD_TIME(algorithmProcess) ret = bef_effect_ai_algorithm_texture(_handle, texture, timeStamp); - CHECK_RET_AND_RETURN(bef_effect_ai_algorithm_texture, ret); + STOP_TIME(algorithmProcess) + CHECK_RET_AND_RETURN(bef_effect_ai_algorithm_texture, ret) + RECORD_TIME(effectProcess) ret = bef_effect_ai_process_texture(_handle, texture, outputTexture, timeStamp); - CHECK_RET_AND_RETURN(bef_effect_ai_process_texture, ret); + STOP_TIME(effectProcess) + CHECK_RET_AND_RETURN(bef_effect_ai_process_texture, ret) + STOP_TIME(totalProcess) return ret; } - (void) setFilterPath:(NSString *)path { - if ([self be_empty:path]) { + if (![self be_empty:path]) { path = [self.provider filterPath:path]; } @@ -186,9 +231,11 @@ -(void)setFilterIntensity:(float)intensity { CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_set_intensity, status, ;) } +#endif - (void)setStickerPath:(NSString *)path { - if ([self be_empty:path]) { +#if __has_include() + if (![self be_empty:path]) { path = [self.provider stickerPath:path]; } @@ -196,24 +243,29 @@ - (void)setStickerPath:(NSString *)path { status = bef_effect_ai_set_effect(_handle, [path UTF8String]); CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_set_effect, status, ;) +#endif } - (void)setStickerAbsolutePath:(NSString*)path { +#if __has_include() bef_effect_result_t status = BEF_RESULT_SUC; status = bef_effect_ai_set_effect(_handle, [path UTF8String]); CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_set_effect, status, ;) +#endif } - (void)setAvatarPath:(NSString*) path { +#if __has_include() bef_effect_result_t status = BEF_RESULT_SUC; status = bef_effect_ai_set_effect(_handle, [path UTF8String]); CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_set_effect, status, ;) - +#endif } +#if __has_include() - (void)releaseEffectManager { bef_effect_ai_destroy(_handle); } @@ -224,11 +276,12 @@ - (void)updateComposerNodes:(NSArray *)nodes { } - (void)updateComposerNodes:(NSArray *)nodes withTags:(NSArray *)tags { +#if __has_include() if (tags != nil && nodes.count != tags.count) { NSLog(@"bef_effect_ai_composer_set_nodes error: count of tags must equal to nodes"); return; } -#if __has_include("bef_effect_ai_api.h") + #if BE_LOAD_RESOURCE_TIMEOUT for (NSString *node in nodes) { if (![_existResourcePathes containsObject:node]) { @@ -238,7 +291,6 @@ - (void)updateComposerNodes:(NSArray *)nodes withTags:(NSArray *paths = [NSMutableArray arrayWithCapacity:nodes.count]; @@ -279,7 +331,7 @@ - (void)updateComposerNodes:(NSArray *)nodes withTags:(NSArray *)nodes withTags:(NSArray *)nodes withTags:(NSArray_needLoadResource) { + [self loadResource:-1]; + self->_needLoadResource = NO; + } + }); } #endif #endif @@ -321,7 +376,7 @@ - (void)appendComposerNodes:(NSArray *)nodes withTags:(NSArray) #if BE_LOAD_RESOURCE_TIMEOUT for (NSString *node in nodes) { if (![_existResourcePathes containsObject:node]) { @@ -332,10 +387,15 @@ - (void)appendComposerNodes:(NSArray *)nodes withTags:(NSArray *paths = [NSMutableArray arrayWithCapacity:nodes.count]; for (int i = 0; i < nodes.count; i++) { - [paths addObject:[self.provider composerNodePath:nodes[i]]]; + if ([self.resourcePath isEqualToString:@"sticker"]) { + [paths addObject:[self.provider stickerPath:nodes[i]]]; + } + else { + [paths addObject:[self.provider composerNodePath:nodes[i]]]; + } + } nodes = paths; @@ -371,7 +431,7 @@ - (void)appendComposerNodes:(NSArray *)nodes withTags:(NSArray) bef_effect_result_t result = BEF_RESULT_SUC; if (tags == nil) { result = bef_effect_ai_composer_append_nodes(_handle, (const char **)nodesPath, count); @@ -381,7 +441,6 @@ - (void)appendComposerNodes:(NSArray *)nodes withTags:(NSArray *)nodes withTags:(NSArray_needLoadResource) { + [self loadResource:-1]; + self->_needLoadResource = NO; + } + }); } #endif #endif } - (void)removeComposerNodes:(NSArray *)nodes { -#if __has_include("bef_effect_ai_api.h") +#if __has_include() #if BE_LOAD_RESOURCE_TIMEOUT for (NSString *node in nodes) { [_existResourcePathes removeObject:node]; } -#endif #endif NSMutableArray *paths = [NSMutableArray arrayWithCapacity:nodes.count]; for (int i = 0; i < nodes.count; i++) { - [paths addObject:[self.provider composerNodePath:nodes[i]]]; + if ([self.resourcePath isEqualToString:@"sticker"]) { + [paths addObject:[self.provider stickerPath:nodes[i]]]; + } + else { + [paths addObject:[self.provider composerNodePath:nodes[i]]]; + } } nodes = paths; @@ -439,30 +505,37 @@ - (void)removeComposerNodes:(NSArray *)nodes { count++; } -#if __has_include("bef_effect_ai_api.h") + bef_effect_result_t result = BEF_RESULT_SUC; result = bef_effect_ai_composer_remove_nodes(_handle, (const char **)nodesPath, count); if (result != BEF_RESULT_SUC) { NSLog(@"bef_effect_ai_composer_set_nodes error: %d", result); } -#endif + for (int i = 0; i < count; i++) { free(nodesPath[i]); } free(nodesPath); +#endif } - (void)updateComposerNodeIntensity:(NSString *)node key:(NSString *)key intensity:(float)intensity { -// node = [self.provider composerNodePath:node]; -#if __has_include("bef_effect_ai_api.h") + + if ([self.resourcePath isEqualToString:@"sticker"]) { + node = [self.provider stickerPath:node]; + } + else { + node = [self.provider composerNodePath:node]; + } +#if __has_include() bef_effect_result_t result = bef_effect_ai_composer_update_node(_handle, (const char *)[node UTF8String], (const char *)[key UTF8String], intensity); CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_composer_update_node, result, ;) #endif } +#if __has_include() - (NSArray *)availableFeatures { //Dynamic lookup feature availability -#if __has_include("bef_effect_ai_api.h") int feature_len = 60; char features[feature_len][BEF_EFFECT_FEATURE_LEN]; int *pf = &feature_len; @@ -483,21 +556,14 @@ - (void)updateComposerNodeIntensity:(NSString *)node key:(NSString *)key intensi } return @[]; } -#else - return @[]; -#endif } - (NSString *)sdkVersion { -#if __has_include("bef_effect_ai_api.h") char version[20]; bef_effect_ai_get_version(version, 20); return [NSString stringWithUTF8String:version]; -#else - return @""; -#endif } -#if __has_include("bef_effect_ai_api.h") + - (void)setFrontCamera:(BOOL)frontCamera { _frontCamera = frontCamera; bef_effect_result_t ret = bef_effect_ai_set_camera_device_position(_handle, frontCamera ? bef_ai_camera_position_front : bef_ai_camera_position_back); @@ -681,13 +747,13 @@ - (UIImage*)getCapturedImageWithKey:(const char*) key buf.format = BE_RGBA; BEImageUtils* imageUtils = [BEImageUtils new]; UIImage* img = [imageUtils transforBufferToUIImage:buf]; - //由于img的数据地址与buffer一样,需要深拷贝结果图 + // {zh} 由于img的数据地址与buffer一样,需要深拷贝结果图 {en} Since the data address of img is the same as that of buffer, deep copy of the result graph is required UIGraphicsBeginImageContext(img.size); [img drawInRect:CGRectMake(0, 0, img.size.width, img.size.height)]; UIImage *copiedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); - //释放贴纸内部buffer + // {zh} 释放贴纸内部buffer {en} Release sticker internal buffer bef_effect_ai_release_captured_image(_handle, pImage); return copiedImage; } @@ -715,7 +781,6 @@ - (bef_ai_render_api_type)renderAPI { } return bef_ai_render_api_gles30; } -#endif - (BOOL)sethairColorByPart:(BEEffectPart)partIndex r:(CGFloat)r g:(CGFloat)g b:(CGFloat)b a:(CGFloat)a { NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys: @@ -725,19 +790,19 @@ - (BOOL)sethairColorByPart:(BEEffectPart)partIndex r:(CGFloat)r g:(CGFloat)g b:( [NSString stringWithFormat:@"%.3f",a],@"a", nil]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; -#if __has_include("bef_effect_ai_api.h") return [self sendMsg:BEEffectHairColor arg1:0 arg2:partIndex arg3:[jsonString UTF8String]]; -#else - return NO; -#endif } - (BOOL)sendCaptureMessage { -#if __has_include("bef_effect_ai_api.h") return [self sendMsg:BEEffectTakingPictures arg1:1 arg2:0 arg3:0]; -#else - return NO; -#endif } +// {zh} / @brief 开启或关闭强制人脸检测 {en} /@brief Enable or disable forced face detection +// {zh} /detection YES 开启人脸检测 NO关闭人脸检测 {en} /detection YES on face detection NO off face detection +- (void)forcedFaceDetection:(BOOL)detection +{ + bef_effect_result_t ret = bef_effect_ai_set_algorithm_force_detect(_handle,detection); + CHECK_RET_AND_RETURN_RESULT(bef_effect_ai_set_algorithm_force_detect, ret, ;) +} +#endif @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.h deleted file mode 100644 index a9a2d3cee..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2018 Beijing Bytedance Network Technology Co., Ltd. -#import -#import "BEResourceHelper.h" -#import "BEEffectManager.h" - -@class BEFrameProcessor; - -/// result type of process -/// can be composite -typedef NS_ENUM(NSInteger, BEProcessorResult) { - BETexture = 1 << 0, - BERawData = 1 << 1, - BECVPixelBuffer = 1 << 2, - BEImage = 1 << 3 -}; - -/// represent buffer result -@interface BEProcessResultBuffer : NSObject -/// raw data pointer -@property (nonatomic, assign) unsigned char *buffer; -/// with of buffer -@property (nonatomic, assign) int width; -/// height of buffer -@property (nonatomic, assign) int height; -/// bytes per row of buffer -@property (nonatomic, assign) int bytesPerRow; -/// format of buffer -@property (nonatomic, assign) BEFormatType format; - -@end - -/// output of (BEProcessResult *)process:(CVPixelBufferRef)pixelBuffer timeStamp:(double)timeStamp and (BEProcessResult *)process:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow timeStamp:(double)timeStamp -@interface BEProcessResult : NSObject -/// always set -@property (nonatomic, assign) GLuint texture; -/// avaliable when set BERawData/BECVPixelBuffer/BEImage to BEFrameProcessor's processorResult -@property (nonatomic, strong) BEProcessResultBuffer *buffer; -/// available when set BECVPixelBuffer to BEFrameProcessor's processorResult -@property (nonatomic, assign) CVPixelBufferRef pixelBuffer; -/// available when set BEImage to BEFrameProcessor's processResult -@property (nonatomic, assign) UIImage *image; -/// size of result -@property (nonatomic, assign) CGSize size; -@end - - -/// capture image delegate, will be invoked when set BEFrameProcessor's captureNextFrame YES -@protocol BECaptureDelegate - -- (void)onImageCapture:(UIImage *)image; - -@end - -@interface BEFrameProcessor : NSObject - -/// bind texture and CVPixelBuffer, accelerate pixel reading -@property (nonatomic, assign) BOOL pixelBufferAccelerate; - -/// dispath algorithm and effect render to different thread -@property (nonatomic, assign) BOOL usePipeline; - -/// process result type, buffer/CVPixelBuffer -@property (nonatomic, assign) NSInteger processorResult; - -/// process result format, if not set, will be the same to inputFormat -/// such as for processorResult BECVPixelBuffer and BERawData, BE_RGBA BE_BGRA BE_YUV420P BEYUV420V are available -/// for BEImage and BETexture, no available -@property (nonatomic, assign) BEFormatType outputFormat; - -/// get composer Mode, 0/1 -@property (nonatomic, readonly) int composerMode; - -/// capture next frame when set YES -@property (nonatomic, assign) BOOL captureNextFrame; - -/// capture frame delegate -@property (nonatomic, weak) id captureDelegate; - -/// init function -/// @param context gl context -/// @param delegate resource delegate, nullable -- (instancetype)initWithContext:(EAGLContext *)context resourceDelegate:(id)delegate; - -/// process CVPixelBuffer -/// @param pixelBuffer original pixelBuffer -/// @param timeStamp current time -- (BEProcessResult *)process:(CVPixelBufferRef)pixelBuffer timeStamp:(double)timeStamp; - -/// process buffer -/// @param buffer original buffer -/// @param width with of buffer -/// @param height height of buffer -/// @param bytesPerRow bytesPerRow of buffer -/// @param timeStamp current time -/// @param format pixel format, see BEFormatType -- (BEProcessResult *)process:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow timeStamp:(double)timeStamp format:(BEFormatType)format; - -/// process texture -/// @param texture original texture -/// @param width width of texture -/// @param height height of texture -/// @param timeStamp current time -- (BEProcessResult *)process:(GLuint)texture width:(int)width height:(int)height timeStamp:(double)timeStamp; - -/// set filter path -/// @param path relative path -- (void)setFilterPath:(NSString *)path; - -/// set filter intensity -/// @param intensity 0-1 -- (void)setFilterIntensity:(float)intensity; - -/// set sticker path -/// @param path relative path -- (void)setStickerPath:(NSString *)path; - -/// set composer mode -/// @param mode 0: exclusive between composer and sticker, 1: not exclusive between composer and sticker -- (void)setComposerMode:(int)mode; - -/// update composer nodes -/// @param nodes relative path of nodes -- (void)updateComposerNodes:(NSArray *)nodes; - -/// update composer node intensity -/// @param node relative path of node -/// @param key key of feature, such as smooth,white... -/// @param intensity 0-1 -- (void)updateComposerNodeIntensity:(NSString *)node key:(NSString *)key intensity:(CGFloat)intensity; - -/// set if effect is on -/// @param on YES: do render NO: not do render, just return origin texture/buffer/CVPixelBuffer -- (void)setEffectOn:(BOOL)on; - -/// get available features in sdk -- (NSArray *)availableFeatures; - -/// get sdk version -- (NSString *)sdkVersion; - -/// set camera position -/// @param isFront YES: texture/buffer/CVPxielBuffer is from front camera -- (BOOL)setCameraPosition:(BOOL)isFront; - -/// set image mode -/// @param imageMode YES for image process when reuse texture -- (BOOL)setImageMode:(BOOL)imageMode; - -/// process touch event -/// @param x x -/// @param y y -- (BOOL)processTouchEvent:(float)x y:(float)y; - -#if __has_include("bef_effect_ai_api.h") -/// get face detect result -- (bef_ai_face_info *)getFaceInfo; - -/// get hand detect result -- (bef_ai_hand_info *)getHandInfo; - -/// get skeleton detect result -- (bef_ai_skeleton_result *)getSkeletonInfo; -#endif - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.mm b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.mm deleted file mode 100644 index 24320bf41..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEFrameProcessor.mm +++ /dev/null @@ -1,499 +0,0 @@ -// Copyright (C) 2018 Beijing Bytedance Network Technology Co., Ltd. -#import "BEFrameProcessor.h" - -#import -#if __has_include("bef_effect_ai_api.h") -#import "RenderMsgDelegate.h" -#endif - -#import "BERender.h" -#import "BEEffectManager.h" -#import "BEResourceHelper.h" -#import "BEEffectResourceHelper.h" - - -@implementation BEProcessResultBuffer -@end - -@implementation BEProcessResult -@end - -#if __has_include("bef_effect_ai_api.h") -@interface BEFrameProcessor() { - - EAGLContext *_glContext; - - BOOL _effectOn; - BEEffectManager *_effectManager; - BERender *_render; - BEResourceHelper *_resourceHelper; - IRenderMsgDelegateManager *_manager; - BEFormatType _inputFormat; - - BOOL _shouldResetComposer; -#if __has_include("bef_effect_ai_api.h") - bef_ai_face_info *_faceInfo; - bef_ai_hand_info *_handInfo; - bef_ai_skeleton_result *_skeletonInfo; -#endif -} - -@end -#endif - -@implementation BEFrameProcessor - -/** - * license有效时间2019-03-01到2019-04-30 - * license只是为了追踪使用情况,可以随时申请无任何限制license - */ - -- (instancetype)initWithContext:(EAGLContext *)context resourceDelegate:(id)delegate { - self = [super init]; -#if __has_include("bef_effect_ai_api.h") - if (self) { - _glContext = context; - [EAGLContext setCurrentContext:context]; - - _effectOn = YES; - _shouldResetComposer = YES; - _pixelBufferAccelerate = YES; - _processorResult = BECVPixelBuffer; - _faceInfo = NULL; - _handInfo = NULL; - _skeletonInfo = NULL; - BEEffectResourceHelper *resourceHelper = [BEEffectResourceHelper new]; - _effectManager = [[BEEffectManager alloc] initWithResourceProvider:resourceHelper licenseProvider:[BELicenseHelper shareInstance]]; - int ret = [_effectManager initTask]; - NSLog(@"ret == %d", ret); - if (ret == BEF_RESULT_SUC) { - [self setEffectOn:true]; - } - _render = [[BERender alloc] init]; - _resourceHelper = [[BEResourceHelper alloc] init]; - _resourceHelper.delegate = delegate; - self.usePipeline = YES; - } -#endif - return self; -} - -- (void)dealloc { - NSLog(@"BEFrameProcessor dealloc %@", NSStringFromSelector(_cmd)); -#if __has_include("bef_effect_ai_api.h") - free(_faceInfo); - free(_handInfo); - free(_skeletonInfo); - [EAGLContext setCurrentContext:_glContext]; -#endif - [self be_releaseSDK]; -} - -/* - * 帧处理流程 - */ -- (BEProcessResult *)process:(CVPixelBufferRef)pixelBuffer timeStamp:(double)timeStamp{ - CVPixelBufferLockBaseAddress(pixelBuffer, 0); -#if __has_include("bef_effect_ai_api.h") - BEPixelBufferInfo *info = [_render getCVPixelBufferInfo:pixelBuffer]; - if (info.format == BE_UNKNOW) { - NSLog(@"unknow pixelBuffer format, use format show in BEFormatType..."); - return nil; - } - _inputFormat = info.format; -#endif -#if __has_include("bef_effect_ai_api.h") - // 设置 OpenGL 环境 , 需要与初始化 SDK 时一致 - if ([EAGLContext currentContext] != _glContext) { - [EAGLContext setCurrentContext:_glContext]; - } -#endif - - BEProcessResult *result; - if (_pixelBufferAccelerate) { -#if __has_include("bef_effect_ai_api.h") - GLuint inputTexture = [_render transforCVPixelBufferToTexture:pixelBuffer]; - [_render initOutputTextureAndCVPixelBufferWithWidth:info.width height:info.height format:info.format]; - result = [self process:inputTexture width:info.width height:info.height timeStamp:timeStamp fromPixelBuffer:YES]; -#endif - } else { -#if __has_include("bef_effect_ai_api.h") - int bytesPerRow = info.width * 4; - unsigned char *baseAddress = [_render transforCVPixelBufferToBuffer:pixelBuffer outputFormat:info.format]; - if (baseAddress == nil) { - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - return nil; - } - result = [self process:baseAddress width:info.width height:info.height bytesPerRow:bytesPerRow timeStamp:timeStamp format:info.format fromPixelBuffer:YES]; -#endif - } - - if ((_processorResult & BECVPixelBuffer)) { - if (_pixelBufferAccelerate) { -#if __has_include("bef_effect_ai_api.h") - result.pixelBuffer = [_render getOutputPixelBuffer]; -#endif - } else { - BEProcessResultBuffer *buffer = result.buffer; - if (buffer) { -#if __has_include("bef_effect_ai_api.h") - result.pixelBuffer = [_render transforBufferToCVPixelBuffer:buffer.buffer pixelBuffer:pixelBuffer width:buffer.width height:buffer.height bytesPerRow:buffer.bytesPerRow inputFormat:buffer.format outputFormat:[self be_outputFormat]]; -#endif - } - } - } - - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - return result; -} - -- (BEProcessResult *)process:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow timeStamp:(double)timeStamp format:(BEFormatType)format { - // 设置 OpenGL 环境 , 需要与初始化 SDK 时一致 -#if __has_include("bef_effect_ai_api.h") - if ([EAGLContext currentContext] != _glContext) { - [EAGLContext setCurrentContext:_glContext]; - } - _inputFormat = format; -#endif - return [self process:buffer width:width height:height bytesPerRow:bytesPerRow timeStamp:timeStamp format:format fromPixelBuffer:NO]; -} - -- (BEProcessResult *)process:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow timeStamp:(double)timeStamp format:(BEFormatType)format fromPixelBuffer:(BOOL)fromPixelBuffer { -#if __has_include("bef_effect_ai_api.h") - // transfor buffer to texture - GLuint inputTexture = [_render transforBufferToTexture:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:format]; - - return [self process:inputTexture width:width height:height timeStamp:timeStamp fromPixelBuffer:fromPixelBuffer]; -#else - return nil; -#endif -} - -- (BEProcessResult *)process:(GLuint)texture width:(int)width height:(int)height timeStamp:(double)timeStamp { - // 设置 OpenGL 环境 , 需要与初始化 SDK 时一致 -#if __has_include("bef_effect_ai_api.h") - if ([EAGLContext currentContext] != _glContext) { - [EAGLContext setCurrentContext:_glContext]; - } - - _inputFormat = BE_RGBA; - return [self process:texture width:width height:height timeStamp:timeStamp fromPixelBuffer:NO]; -#else - return nil; -#endif -} - -- (BEProcessResult *)process:(GLuint)texture width:(int)width height:(int)height timeStamp:(double)timeStamp fromPixelBuffer:(BOOL)fromPixelBuffer { - //设置后续美颜以及其他识别功能的基本参数 - // [_effectManager setWidth:width height:height orientation:[self getDeviceOrientation]]; -#if __has_include("bef_effect_ai_api.h") - GLuint textureResult; - if (_effectOn) { - GLuint outputTexutre = [_render getOutputTexture:width height:height]; - textureResult = [_effectManager processTexture:texture outputTexture:outputTexutre width:width height:height rotate:BEF_AI_CLOCKWISE_ROTATE_0 timeStamp:timeStamp]; - } else { - textureResult = texture; - } - - // transfor texture to buffer/CVPxielbuffer/UIImage with format be_outputFormat - BEProcessResult *result = [self be_transforTextureToResult:textureResult width:width height:height fromPixelBuffer:fromPixelBuffer]; - - // check and capture current frame, for taking photo - [self be_checkAndCaptureFrame:result]; - - return result; -#else - return nil; -#endif -} - -/* - * 设置滤镜强度 - */ --(void)setFilterIntensity:(float)intensity{ -#if __has_include("bef_effect_ai_api.h") - [_effectManager setFilterIntensity:intensity]; -#endif -} - -/* - * 设置贴纸资源 - */ -- (void)setStickerPath:(NSString *)path { -#if __has_include("bef_effect_ai_api.h") - if (path != nil && ![path isEqualToString:@""]) { - _shouldResetComposer = true; - path = [_resourceHelper stickerPath:path]; - } - [_effectManager setStickerPath:path]; -#endif -} - -- (void)setComposerMode:(int)mode { - _composerMode = mode; - // [_effectManager setComposerMode:mode]; -} - -- (void)updateComposerNodes:(NSArray *)nodes { - [self be_checkAndSetComposer]; - -#if __has_include("bef_effect_ai_api.h") - NSMutableArray *paths = [NSMutableArray arrayWithCapacity:nodes.count]; - for (int i = 0; i < nodes.count; i++) { - NSString *path = [_resourceHelper composerNodePath:nodes[i]]; - if (path) { - [paths addObject:path]; - } - } - [_effectManager updateComposerNodes:paths]; -#endif -} - -- (void)updateComposerNodeIntensity:(NSString *)node key:(NSString *)key intensity:(CGFloat)intensity { -#if __has_include("bef_effect_ai_api.h") - [_effectManager updateComposerNodeIntensity:[_resourceHelper composerNodePath:node] key:key intensity:intensity]; -#endif -} - -/* - * 设置滤镜资源路径和系数 - */ -- (void)setFilterPath:(NSString *)path { -#if __has_include("bef_effect_ai_api.h") - if (path != nil && ![path isEqualToString:@""]) { - path = [_resourceHelper filterPath:path]; - } - [_effectManager setFilterPath:path]; -#endif -} - -- (void)setEffectOn:(BOOL)on -{ -#if __has_include("bef_effect_ai_api.h") - _effectOn = on; -#endif -} - -- (NSArray *)availableFeatures { -#if __has_include("bef_effect_ai_api.h") - return [_effectManager availableFeatures]; -#else - return nil; -#endif -} - -- (NSString *)sdkVersion { -#if __has_include("bef_effect_ai_api.h") - return [_effectManager sdkVersion]; -#else - return nil; -#endif -} - -- (BOOL)setCameraPosition:(BOOL)isFront { -#if __has_include("bef_effect_ai_api.h") - [_effectManager setFrontCamera:isFront]; -#endif - return YES; -} - -- (BOOL)setImageMode:(BOOL)imageMode { - // return [_effectManager setImageMode:imageMode]; - return YES; -} - -- (BOOL)processTouchEvent:(float)x y:(float)y { - // return [_effectManager processTouchEvent:x y:y]; - return YES; -} - -#if __has_include("bef_effect_ai_api.h") -- (bef_ai_face_info *)getFaceInfo { - return [_effectManager getFaceInfo]; -} - -- (bef_ai_hand_info *)getHandInfo { - return [_effectManager getHandInfo]; -} - -- (bef_ai_skeleton_result *)getSkeletonInfo { - return [_effectManager getSkeletonInfo]; -} -#endif - -#pragma mark - RenderMsgDelegate -- (BOOL)msgProc:(unsigned int)unMsgID arg1:(int)nArg1 arg2:(int)nArg2 arg3:(const char *)cArg3 { -#ifdef DEBUG_LOG - NSLog(@"msg proc: %d, arg: %d in processor: %lu", unMsgID, nArg1, self.hash); -#endif - return NO; -} - -#pragma mark - setter -- (void)setUsePipeline:(BOOL)usePipeline { - _usePipeline = usePipeline; -#if __has_include("bef_effect_ai_api.h") - if (_effectManager != nil) { - [_effectManager setUsePipeline:usePipeline]; - } - if (_render != nil) { - _render.useCacheTexture = usePipeline; - } -#endif -} - -#pragma mark - private - -- (void)be_releaseSDK { - // 要在opengl上下文中调用 -#if __has_include("bef_effect_ai_api.h") - [_effectManager destroyTask]; -#endif -} - -- (void)be_checkAndSetComposer { - if ([self be_shouldResetComposer]) { - // [_effectManager initEffectCompose:[_resourceHelper composerPath]]; -#if __has_include("bef_effect_ai_api.h") - _shouldResetComposer = false; -#endif - } -} - -- (BOOL)be_shouldResetComposer { -#if __has_include("bef_effect_ai_api.h") - return _shouldResetComposer && _composerMode == 0; -#else - return NO; -#endif -} - -- (BEFormatType)be_outputFormat { - if (_outputFormat) { - return _outputFormat; - } -#if __has_include("bef_effect_ai_api.h") - return _inputFormat; -#else - return _outputFormat; -#endif -} - -- (BEProcessResult *)be_transforTextureToResult:(GLuint)texture width:(int)width height:(int)height fromPixelBuffer:(BOOL)fromPixelBuffer { - BEProcessResult *result = [BEProcessResult new]; - result.texture = texture; - result.size = CGSizeMake(width, height); - - BEProcessResultBuffer *buffer; - if (_processorResult & (BERawData | (BECVPixelBuffer & !_pixelBufferAccelerate) | BEImage)) { - buffer = [BEProcessResultBuffer new]; - buffer.format = [self be_outputFormat]; - buffer.width = width; - buffer.height = height; - int bytesPerRow = 0; -#if __has_include("bef_effect_ai_api.h") - buffer.buffer = [_render transforTextureToBuffer:texture width:width height:height outputFormat:[self be_outputFormat] bytesPerRowPointer:&bytesPerRow]; -#endif - buffer.bytesPerRow = bytesPerRow; - result.buffer = buffer; - } - if (!fromPixelBuffer && (_processorResult & BECVPixelBuffer)) { - if (buffer) { -#if __has_include("bef_effect_ai_api.h") - result.pixelBuffer = [_render transforBufferToCVPixelBuffer:buffer.buffer width:buffer.width height:buffer.height bytesPerRow:buffer.bytesPerRow inputFormat:buffer.format outputFormat:[self be_outputFormat]]; -#endif - } else { - NSLog(@"getCVPixelBuffer error: no buffer"); - } - } - if ((_processorResult & BEImage)) { - if (buffer) { -#if __has_include("bef_effect_ai_api.h") - result.image = [_render transforBufferToUIImage:buffer.buffer - width:buffer.width - height:buffer.height - bytesPerRow:buffer.bytesPerRow - inputFormat:buffer.format]; -#endif - } else { - NSLog(@"getImage error: no buffer"); - } - } - return result; -} - -- (void)be_checkAndCaptureFrame:(BEProcessResult *)result { - if (_captureNextFrame) { - - int width = result.size.width; - int height = result.size.height; - UIImage *image; - if (result.image) { - image = result.image; - } else if (result.buffer) { - - BEProcessResultBuffer *buffer = result.buffer; -#if __has_include("bef_effect_ai_api.h") - image = [_render transforBufferToUIImage:buffer.buffer - width:buffer.width - height:buffer.height - bytesPerRow:buffer.bytesPerRow - inputFormat:buffer.format]; -#endif - } else { - - int bytesPerRow; - BEFormatType format = BE_RGBA; -#if __has_include("bef_effect_ai_api.h") - unsigned char *buffer = [_render transforTextureToBuffer:result.texture - width:width - height:height - outputFormat:format - bytesPerRowPointer:&bytesPerRow]; - image = [_render transforBufferToUIImage:buffer - width:width - height:height - bytesPerRow:bytesPerRow - inputFormat:format]; -#endif - } - if (self.captureDelegate) { - if (image) { - [self.captureDelegate onImageCapture:image]; - } else { - NSLog(@"captureNextFrame error: no image"); - } - } - _captureNextFrame = NO; - } -} - -/* - * 获取设备旋转角度 - */ -- (int)getDeviceOrientation { -#if __has_include("bef_effect_ai_api.h") - UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; - switch (orientation) { - case UIDeviceOrientationPortrait: - return BEF_AI_CLOCKWISE_ROTATE_0; - - case UIDeviceOrientationPortraitUpsideDown: - return BEF_AI_CLOCKWISE_ROTATE_180; - - case UIDeviceOrientationLandscapeLeft: - return BEF_AI_CLOCKWISE_ROTATE_270; - - case UIDeviceOrientationLandscapeRight: - return BEF_AI_CLOCKWISE_ROTATE_90; - - default: - return BEF_AI_CLOCKWISE_ROTATE_0; - } -#else - return -1; -#endif -} - -@end - diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.h index 16d309314..bd570a7a0 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.h @@ -1,116 +1,127 @@ -// // BEGLTexture.h -// BytedEffects -// -// Created by qun on 2021/1/19. -// Copyright © 2021 ailab. All rights reserved. -// +// EffectsARSDK + #ifndef BEGLTexture_h #define BEGLTexture_h #import #import +#import typedef NS_ENUM(NSInteger, BEGLTextureType) { - // {zh} / 通过 glGenTextures 创建的纹理 {en} /Textures created by glGenTextures + // {zh} / 通过 glGenTextures 创建的纹理 {en} /Textures created by glGenTextures BE_NORMAL_TEXTURE, - // {zh} / 与 CVPixelBuffer 绑定的纹理 {en} /Textures bound to CVPixelBuffer + // {zh} / 与 CVPixelBuffer 绑定的纹理 {en} /Textures bound to CVPixelBuffer BE_PIXEL_BUFFER_TEXTURE }; -// {zh} / OpenGL 纹理的封装,它可以是直接通过 glGenTextures 创建的纹理, {en} /OpenGL texture encapsulation, it can be a texture created directly through glGenTextures, -// {zh} / 也可以是通过 CVPixelBufferRef 创建并与之绑定的纹理, {en} /It can also be a texture created and bound with CVPixelBufferRef, -// {zh} / 当使用 CVPixelBufferRef 创建时,仅支持 kCVPixelFormatType_32BGRA 格式的 CVPixelBufferRef {en} /When created with CVPixelBufferRef, only CVPixelBufferRef in kCVPixelFormatType_32BGRA format is supported +// {zh} / OpenGL 纹理的封装,它可以是直接通过 glGenTextures 创建的纹理, {en} /OpenGL texture encapsulation, it can be a texture created directly through glGenTextures, +// {zh} / 也可以是通过 CVPixelBufferRef 创建并与之绑定的纹理, {en} /It can also be a texture created and bound with CVPixelBufferRef, +// {zh} / 当使用 CVPixelBufferRef 创建时,仅支持 kCVPixelFormatType_32BGRA 格式的 CVPixelBufferRef {en} /When created with CVPixelBufferRef, only CVPixelBufferRef in kCVPixelFormatType_32BGRA format is supported @protocol BEGLTexture -// {zh} / 纹理 ID {en} /Texture ID +// {zh} / 纹理 ID {en} /Texture ID @property (nonatomic) GLuint texture; -// {zh} / 纹理类型 {en} /Texture type +// uv纹理ID,在绑定的pixelbuffer是yuv格式时该纹理号有效 +@property (nonatomic) GLuint uvTexture; + +// {zh} / 纹理类型 {en} /Texture type @property (nonatomic) BEGLTextureType type; -// {zh} / 是否有效 {en} /Is it effective +// {zh} / 是否有效 {en} /Is it effective @property (nonatomic) BOOL available; -// {zh} / 宽 {en} /Width +// {zh} / 宽 {en} /Width @property (nonatomic, readonly) int width; -// {zh} / 高 {en} /High +// {zh} / 高 {en} /High @property (nonatomic, readonly) int height; -// {zh} / @brief 初始化 {en} /@brief initialization -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 初始化 {en} /@brief initialization +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height - (instancetype)initWithWidth:(int)width height:(int)height; -// {zh} / @brief 更新宽高 {en} /@Brief update width and height -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 更新宽高 {en} /@Brief update width and height +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height - (void)updateWidth:(int)width height:(int)height; -// {zh} / @brief 销毁纹理 {en} /@Briefly destroy texture +// {zh} / @brief 销毁纹理 {en} /@Briefly destroy texture - (void)destroy; @end -// {zh} / 普通 gl 纹理的封装 {en} /Ordinary gl texture encapsulation +// {zh} / 普通 gl 纹理的封装 {en} /Ordinary gl texture encapsulation @interface BENormalGLTexture : NSObject -// {zh} / @brief 根据纹理号、宽、高初始化 {en} /@Brief initializes according to texture number, width, and height -// {zh} / @param texture 纹理 ID {en} /@param texture texture ID -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 根据纹理号、宽、高初始化 {en} /@Brief initializes according to texture number, width, and height +// {zh} / @param texture 纹理 ID {en} /@param texture texture ID +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height - (instancetype)initWithTexture:(GLuint)texture width:(int)width height:(int)height; -// {zh} / @brief 根据 buffer 初始化 {en} /@Brief initialization based on buffer +// {zh} / @brief 根据 buffer 初始化 {en} /@Brief initialization based on buffer /// @param buffer buffer -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height -// {zh} / @param format buffer 格式,GL_RGBA/GL_BGRA {en} /@param format buffer format, GL_RGBA/GL_BGRA +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height +// {zh} / @param format buffer 格式,GL_RGBA/GL_BGRA {en} /@param format buffer format, GL_RGBA/GL_BGRA - (instancetype)initWithBuffer:(unsigned char *)buffer width:(int)width height:(int)height format:(GLenum)format; -// {zh} / @brief 根据 buffer 更新纹理内容 {en} /@BriefUpdate texture content according to buffer +// {zh} / @brief 根据 buffer 更新纹理内容 {en} /@BriefUpdate texture content according to buffer /// @param buffer buffer -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height -// {zh} / @param format buffer 格式,GL_RGBA/GL_BGRA {en} /@param format buffer format, GL_RGBA/GL_BGRA +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height +// {zh} / @param format buffer 格式,GL_RGBA/GL_BGRA {en} /@param format buffer format, GL_RGBA/GL_BGRA - (void)update:(unsigned char *)buffer width:(int)width height:(int)height format:(GLenum)format; -// {zh} / @brief 根据纹理号、宽、高更新纹理 {en} Update texture according to texture number, width, and height -// {zh} / @param texture 纹理 ID {en} /@param texture texture ID -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 根据纹理号、宽、高更新纹理 {en} Update texture according to texture number, width, and height +// {zh} / @param texture 纹理 ID {en} /@param texture texture ID +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height - (void)updateTexture:(GLuint)texture width:(int)width height:(int)height; @end -// {zh} / 根据 CVPixelBuffer 生成的 gl 纹理封装 {en} /Gl texture package generated according to CVPixelBuffer -// {zh} / 内部完成了 CVPixelBuffer 与 gl 纹理的绑定,当完成对纹理的处理之后, {en} /Internally completed the binding of CVPixelBuffer and gl texture. After the texture is processed, -// {zh} / 直接调用 pixelBuffer 就可以得到处理之后的 CVPixelBuffer {en} /Call pixelBuffer directly to get the processed CVPixelBuffer +// {zh} / 根据 CVPixelBuffer 生成的 gl 纹理封装 {en} /Gl texture package generated according to CVPixelBuffer +// {zh} / 内部完成了 CVPixelBuffer 与 gl 纹理及 mtl 纹理的绑定,当完成对纹理的处理之后, {en} /Internally completed the binding of CVPixelBuffer to gl texture and mtl texture. After the texture is processed, +// {zh} / 直接调用 pixelBuffer 就可以得到处理之后的 CVPixelBuffer {en} /Call pixelBuffer directly to get the processed CVPixelBuffer @interface BEPixelBufferGLTexture : NSObject -// {zh} / @brief 根据 CVOpenGLESTextureCacheRef 初始化 {en} CVOpenGLESTextureCacheRef initialization +@property (nonatomic) id mtlTexture; + +// {zh} / @brief 根据 CVOpenGLESTextureCacheRef 初始化 {en} CVOpenGLESTextureCacheRef initialization /// @param textureCache cache - (instancetype)initWithTextureCache:(CVOpenGLESTextureCacheRef)textureCache; -// {zh} / @brief 根据宽、高、CVOpenGLESTextureCacheRef 初始化 {en} CVOpenGLESTextureCacheRef initialization based on width, height -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 根据 CVMetalTextureCacheRef 初始化 {en} CVMetalTextureCacheRef initialization +- (instancetype)initWithMTKTextureCache:(CVMetalTextureCacheRef)textureCache; + +// {zh} / @brief 根据宽、高、CVOpenGLESTextureCacheRef 初始化 {en} CVOpenGLESTextureCacheRef initialization based on width, height +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height /// @param textureCache cache - (instancetype)initWithWidth:(int)width height:(int)height textureCache:(CVOpenGLESTextureCacheRef)textureCache; -// {zh} / @brief 根据 CVPixelBuffer 初始化 {en} /@Briefing initialization based on CVPixelBuffer +// {zh} / @brief 根据宽、高、CVMetalTextureCacheRef 初始化 {en} CVMetalTextureCacheRef initialization based on width, height +- (instancetype)initWithWidth:(int)width height:(int)height mtlTextureCache:(CVMetalTextureCacheRef)textureCache; + +// {zh} / @brief 根据 CVPixelBuffer 初始化 {en} /@Briefing initialization based on CVPixelBuffer /// @param pixelBuffer CVPixelBuffer /// @param textureCache cache - (instancetype)initWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer textureCache:(CVOpenGLESTextureCacheRef)textureCache; -// {zh} / @brief 更新 CVPixelBuffer {en} /@brief update CVPixelBuffer +// {zh} / @brief 根据 CVPixelBuffer 初始化 {en} /@Briefing initialization based on CVPixelBuffer +- (instancetype)initWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer mtlTextureCache:(CVMetalTextureCacheRef)textureCache; + +// {zh} / @brief 更新 CVPixelBuffer {en} /@brief update CVPixelBuffer /// @param pixelBuffer CVPixelBuffer - (void)update:(CVPixelBufferRef)pixelBuffer; -// {zh} / @brief 获取与之绑定的 CVPixelBuffer {en} /@BriefGet the CVPixelBuffer bound with it +// {zh} / @brief 获取与之绑定的 CVPixelBuffer {en} /@BriefGet the CVPixelBuffer bound with it - (CVPixelBufferRef)pixelBuffer; @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.m index 4dc0d24b4..da3db0db0 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLTexture.m @@ -1,14 +1,17 @@ -// // BEGLTexture.m -// BytedEffects -// -// Created by qun on 2021/1/19. -// Copyright © 2021 ailab. All rights reserved. -// +// EffectsARSDK + #import "BEGLTexture.h" #import +#define GL_TEXTURE_SETTING(texture) glBindTexture(GL_TEXTURE_2D, texture); \ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); \ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); \ + glBindTexture(GL_TEXTURE_2D, 0); + @implementation BENormalGLTexture { } @@ -100,14 +103,22 @@ - (void)destroy { @end @implementation BEPixelBufferGLTexture { - CVOpenGLESTextureRef _cvTexture; CVPixelBufferRef _pixelBuffer; BOOL _needReleasePixelBuffer; + + CVOpenGLESTextureRef _cvTexture; + CVOpenGLESTextureRef _yuvTexture; CVOpenGLESTextureCacheRef _textureCache; + + CVMetalTextureRef _cvMTLTexture; + CVMetalTextureCacheRef _mtlTextureCache; + BOOL _needReleaseTextureCache; + BOOL _needReleaseMTLTextureCache; } @synthesize texture = _texture; +@synthesize uvTexture = _uvTexture; @synthesize type = _type; @synthesize available = _available; @synthesize width = _width; @@ -132,6 +143,16 @@ - (instancetype)initWithTextureCache:(CVOpenGLESTextureCacheRef)textureCache { return self; } +- (instancetype)initWithMTKTextureCache:(CVMetalTextureCacheRef)textureCache { + self = [super init]; + if (self) { + _type = BE_PIXEL_BUFFER_TEXTURE; + _mtlTextureCache = textureCache; + _needReleaseMTLTextureCache = NO; + } + return self; +} + - (instancetype)initWithWidth:(int)width height:(int)height { if (self = [super init]) { _type = BE_PIXEL_BUFFER_TEXTURE; @@ -150,6 +171,16 @@ - (instancetype)initWithWidth:(int)width height:(int)height textureCache:(CVOpen return self; } +- (instancetype)initWithWidth:(int)width height:(int)height mtlTextureCache:(CVMetalTextureCacheRef)textureCache { + if (self = [super init]) { + _mtlTextureCache = textureCache; + _needReleaseMTLTextureCache = NO; + _type = BE_PIXEL_BUFFER_TEXTURE; + [self update:[self createPxielBuffer:width height:height]]; + } + return self; +} + - (instancetype)initWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer textureCache:(CVOpenGLESTextureCacheRef)textureCache { if (self = [super init]) { _textureCache = textureCache; @@ -160,18 +191,43 @@ - (instancetype)initWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer textureCache return self; } +- (instancetype)initWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer mtlTextureCache:(CVMetalTextureCacheRef)textureCache { + if (self = [super init]) { + _mtlTextureCache = textureCache; + _needReleaseMTLTextureCache = NO; + _type = BE_PIXEL_BUFFER_TEXTURE; + [self update:pixelBuffer]; + } + return self; +} + - (CVPixelBufferRef)createPxielBuffer:(int)width height:(int)height { CVPixelBufferRef pixelBuffer; - const void *keys[] = { - kCVPixelBufferOpenGLCompatibilityKey, - kCVPixelBufferIOSurfacePropertiesKey - }; - const void *values[] = { - (__bridge const void *)([NSNumber numberWithBool:YES]), - (__bridge const void *)([NSDictionary dictionary]) - }; - - CFDictionaryRef optionsDicitionary = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, NULL, NULL); + CFDictionaryRef optionsDicitionary = nil; + // judge whether the device support metal + if (MTLCreateSystemDefaultDevice()) { + const void *keys[] = { + kCVPixelBufferOpenGLCompatibilityKey, + kCVPixelBufferMetalCompatibilityKey, + kCVPixelBufferIOSurfacePropertiesKey + }; + const void *values[] = { + (__bridge const void *)([NSNumber numberWithBool:YES]), + (__bridge const void *)([NSNumber numberWithBool:YES]), + (__bridge const void *)([NSDictionary dictionary]) + }; + optionsDicitionary = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, NULL, NULL); + } else { + const void *keys[] = { + kCVPixelBufferOpenGLCompatibilityKey, + kCVPixelBufferIOSurfacePropertiesKey + }; + const void *values[] = { + (__bridge const void *)([NSNumber numberWithBool:YES]), + (__bridge const void *)([NSDictionary dictionary]) + }; + optionsDicitionary = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, NULL, NULL); + } CVReturn res = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, optionsDicitionary, &pixelBuffer); CFRelease(optionsDicitionary); @@ -204,6 +260,8 @@ - (void)update:(CVPixelBufferRef)pixelBuffer { _available = NO; return; } + + // gl texture if (!_textureCache) { _needReleaseTextureCache = YES; EAGLContext *context = [EAGLContext currentContext]; @@ -220,6 +278,12 @@ - (void)update:(CVPixelBufferRef)pixelBuffer { _cvTexture = nil; } + if (_yuvTexture) { + CFRelease(_yuvTexture); + _yuvTexture = nil; + } + + OSType pbType = CVPixelBufferGetPixelFormatType(pixelBuffer); CVPixelBufferLockBaseAddress(pixelBuffer, 0); int bytesPerRow = (int) CVPixelBufferGetBytesPerRow(pixelBuffer); int width = (int) CVPixelBufferGetWidth(pixelBuffer); @@ -230,23 +294,76 @@ - (void)update:(CVPixelBufferRef)pixelBuffer { width = width + (int) iLeft + (int) iRight; height = height + (int) iTop + (int) iBottom; bytesPerRow = bytesPerRow + (int) iLeft + (int) iRight; - CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0, &_cvTexture); - if (ret != kCVReturnSuccess || !_cvTexture) { - NSLog(@"create CVOpenGLESTextureRef fail: %d", ret); - _available = NO; - return; + CVReturn ret = kCVReturnSuccess; + + if (pbType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange || pbType == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) { + // yuv + size_t planeCount = CVPixelBufferGetPlaneCount(pixelBuffer); + assert(planeCount == 2); + + CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_LUMINANCE, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &_cvTexture); + if (ret != kCVReturnSuccess || !_cvTexture) { + NSLog(@"create CVOpenGLESTextureRef fail: %d", ret); + _available = NO; + return; + } + + _width = width; + _height = height; + _pixelBuffer = pixelBuffer; + _texture = CVOpenGLESTextureGetName(_cvTexture); + GL_TEXTURE_SETTING(_texture); + + ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, width/2, height/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &_yuvTexture); + if (ret != kCVReturnSuccess || !_yuvTexture) { + NSLog(@"create CVOpenGLESTextureRef fail: %d", ret); + _available = NO; + return; + } + _uvTexture = CVOpenGLESTextureGetName(_yuvTexture); + GL_TEXTURE_SETTING(_uvTexture); + } else { + // bgra + ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0, &_cvTexture); + if (ret != kCVReturnSuccess || !_cvTexture) { + NSLog(@"create CVOpenGLESTextureRef fail: %d", ret); + _available = NO; + return; + } + + _width = width; + _height = height; + _pixelBuffer = pixelBuffer; + _texture = CVOpenGLESTextureGetName(_cvTexture); + GL_TEXTURE_SETTING(_texture); + } + + // metal texture + id device = MTLCreateSystemDefaultDevice(); + if (device) { + if(!_mtlTextureCache) { + _needReleaseMTLTextureCache = YES; + ret = CVMetalTextureCacheCreate(kCFAllocatorDefault, NULL, device, NULL, &_mtlTextureCache); + if (ret != kCVReturnSuccess) { + NSLog(@"create CVMetalTextureCacheRef fail: %d", ret); + _available = NO; + return; + } + } + + ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _mtlTextureCache, pixelBuffer, NULL, MTLPixelFormatBGRA8Unorm, width, height, 0, &_cvMTLTexture); + if (ret != kCVReturnSuccess || !_cvMTLTexture) { + NSLog(@"create CVMetalTextureRef fail: %d", ret); + _available = NO; + return; + } + _mtlTexture = CVMetalTextureGetTexture(_cvMTLTexture); + if (_cvMTLTexture) { + CFRelease(_cvMTLTexture); + _cvMTLTexture = nil; + } } - _width = width; - _height = height; - _pixelBuffer = pixelBuffer; - _texture = CVOpenGLESTextureGetName(_cvTexture); - glBindTexture(GL_TEXTURE_2D, _texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); _available = YES; } @@ -259,6 +376,10 @@ - (void)destroy { CFRelease(_cvTexture); _cvTexture = nil; } + if (_cvMTLTexture) { + CFRelease(_cvMTLTexture); + _cvMTLTexture = nil; + } if (_pixelBuffer && _needReleasePixelBuffer) { NSLog(@"release pixelBuffer %@", _pixelBuffer); _needReleasePixelBuffer = NO; @@ -271,6 +392,12 @@ - (void)destroy { CFRelease(_textureCache); _textureCache = nil; } + if (_mtlTextureCache && _needReleaseMTLTextureCache) { + NSLog(@"release CVMetalTextureCache %@", _mtlTextureCache); + CVMetalTextureCacheFlush(_mtlTextureCache, 0); + CFRelease(_mtlTextureCache); + _mtlTextureCache = nil; + } _available = NO; } diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.h new file mode 100644 index 000000000..f56563556 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.h @@ -0,0 +1,19 @@ +// BEGLUtils.h +// EffectsARSDK + + +#ifndef BEGLUtils_h +#define BEGLUtils_h + +#import + +@interface BEGLUtils : NSObject + ++ (EAGLContext *)createContextWithDefaultAPI:(EAGLRenderingAPI)api; + ++ (EAGLContext *)createContextWithDefaultAPI:(EAGLRenderingAPI)api sharegroup:(EAGLSharegroup *)sharegroup; + +@end + + +#endif /* BEGLUtils_h */ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.m new file mode 100644 index 000000000..40e9d6f48 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEGLUtils.m @@ -0,0 +1,45 @@ +// BEGLUtils.m +// EffectsARSDK + + +#import "BEGLUtils.h" + +@implementation BEGLUtils + ++ (EAGLContext *)createContextWithDefaultAPI:(EAGLRenderingAPI)api { + while (api != 0) { + EAGLContext *context = [[EAGLContext alloc] initWithAPI:api]; + if (context != nil) { + return context; + } + NSLog(@"not support api %lu, use lower api %lu", (unsigned long)api, [self be_lowerAPI:api]); + api = [self be_lowerAPI:api]; + } + return nil; +} + ++ (EAGLContext *)createContextWithDefaultAPI:(EAGLRenderingAPI)api sharegroup:(EAGLSharegroup *)sharegroup { + while (api != 0) { + EAGLContext *context = [[EAGLContext alloc] initWithAPI:api sharegroup:sharegroup]; + if (context != nil) { + return context; + } + NSLog(@"not support api %lu, use lower api %lu", (unsigned long)api, [self be_lowerAPI:api]); + api = [self be_lowerAPI:api]; + } + return nil; +} + ++ (EAGLRenderingAPI)be_lowerAPI:(EAGLRenderingAPI)api { + switch (api) { + case kEAGLRenderingAPIOpenGLES3: + return kEAGLRenderingAPIOpenGLES2; + case kEAGLRenderingAPIOpenGLES2: + return kEAGLRenderingAPIOpenGLES1; + case kEAGLRenderingAPIOpenGLES1: + return 0; + } + return 0; +} + +@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.h index 53dd39d60..579ebc3dd 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.h @@ -1,18 +1,18 @@ #ifndef BEHttpRequestProvider_h #define BEHttpRequestProvider_h -#if __has_include("bef_effect_ai_api.h") -#include "BytedLicenseDefine.h" +#if __has_include() +#include #endif -#if __has_include("bef_effect_ai_api.h") -class BEHttpRequestProvider: public HttpRequestProvider +#if __has_include() +class BEHttpRequestProvider: public EffectsSDK::HttpRequestProvider { public: - bool getRequest(const RequestInfo* requestInfo, ResponseInfo& responseInfo) override; + bool getRequest(const EffectsSDK::RequestInfo* requestInfo, EffectsSDK::ResponseInfo& responseInfo) override; - bool postRequest(const RequestInfo* requestInfo, ResponseInfo& responseInfo) override; + bool postRequest(const EffectsSDK::RequestInfo* requestInfo, EffectsSDK::ResponseInfo& responseInfo) override; }; #endif diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.mm b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.mm index d58975ecc..20ee60748 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.mm +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEHttpRequestProvider.mm @@ -1,14 +1,14 @@ #import "BEHttpRequestProvider.h" #import -#if __has_include("bef_effect_ai_api.h") -//post请求暂时不需要实现 -bool BEHttpRequestProvider::getRequest(const RequestInfo* requestInfo, ResponseInfo& responseInfo) +#if __has_include() +// {zh} post请求暂时不需要实现 {en} The post request does not need to be implemented for the time being +bool BEHttpRequestProvider::getRequest(const EffectsSDK::RequestInfo* requestInfo, EffectsSDK::ResponseInfo& responseInfo) { return false; } -bool BEHttpRequestProvider::postRequest(const RequestInfo* requestInfo, ResponseInfo& responseInfo) +bool BEHttpRequestProvider::postRequest(const EffectsSDK::RequestInfo* requestInfo, EffectsSDK::ResponseInfo& responseInfo) { NSString* nsUrl = [[NSString alloc] initWithCString:requestInfo->url.c_str() encoding:NSUTF8StringEncoding]; NSURL *URL = [NSURL URLWithString:nsUrl]; diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.h index 0d5dec9df..e96533272 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.h @@ -1,60 +1,101 @@ -// // BEImageUtils.h -// BytedEffects -// -// Created by qun on 2021/2/2. -// Copyright © 2021 ailab. All rights reserved. -// +// EffectsARSDK + #ifndef BEImageUtils_h #define BEImageUtils_h #import #import +#import #import #import "BEGLTexture.h" -#import "BEPixelBufferInfo.h" +// {zh} / 数据格式 {en} /Data format +typedef NS_ENUM(NSInteger, BEFormatType) { + // {zh} 未知格式 {en} Unknown format + BE_UNKNOW, + // 8bit R G B A + BE_RGBA, + // 8bit B G R A + BE_BGRA, + // video range, 8bit Y1 Y2 Y3 Y4... U1 V1... + BE_YUV420V, + // full range, 8bit Y1 Y2 Y3 Y4... U1 V1... + BE_YUV420F, + // 8bit Y1 Y2 Y3 Y4... U1... V1... + BE_YUVY420, + BE_RGB, + BE_BGR +}; + + +typedef NS_ENUM(NSInteger, BEFlipOrientation) { + BE_FlipHorizontal, + + BE_FlipVertical +}; + +@interface BEPixelBufferInfo : NSObject + +@property (nonatomic, assign) BEFormatType format; +@property (nonatomic, assign) int width; +@property (nonatomic, assign) int height; +@property (nonatomic, assign) int bytesPerRow; + +@end @interface BEBuffer : NSObject -// {zh} / buffer 指针,用于 RGBA 格式 {en} /Buffer pointer for RGBA format +// {zh} / buffer 指针,用于 RGBA 格式 {en} /Buffer pointer for RGBA format @property (nonatomic, assign) unsigned char *buffer; -// {zh} / y buffer 指针,只用于 YUV 格式 {en} /Y buffer pointer, only for YUV format +// {zh} / y buffer 指针,只用于 YUV 格式 {en} /Y buffer pointer, only for YUV format @property (nonatomic, assign) unsigned char *yBuffer; -// {zh} / uv buffer 指针,只用于 YUV 格式 {en} /UV buffer pointer, only for YUV format +// {zh} / uv buffer 指针,只用于 YUV 格式 {en} /UV buffer pointer, only for YUV format @property (nonatomic, assign) unsigned char *uvBuffer; -// {zh} / 宽,用于 RGBA 格式 {en} /Wide for RGBA format +// {zh} / u buffer 指针,只用于 YUV 格式(y420) {en} /U buffer pointer, only for YUV format(y420) +@property (nonatomic, assign) unsigned char *uBuffer; + +// {zh} / v buffer 指针,只用于 YUV 格式(y420) {en} /v buffer pointer, only for YUV format(y420) +@property (nonatomic, assign) unsigned char *vBuffer; + +// {zh} / 宽,用于 RGBA 格式 {en} /Wide for RGBA format @property (nonatomic, assign) int width; -// {zh} / 高,用于 RGBA 格式 {en} /High, for RGBA format +// {zh} / 高,用于 RGBA 格式 {en} /High, for RGBA format @property (nonatomic, assign) int height; -// {zh} / y buffer 宽,用于 YUV 格式 {en} /Y buffer width for YUV format +// {zh} / y buffer 宽,用于 YUV 格式 {en} /Y buffer width for YUV format @property (nonatomic, assign) int yWidth; -// {zh} / y buffer 高,用于 YUV 格式 {en} High/y buffer for YUV format +// {zh} / y buffer 高,用于 YUV 格式 {en} High/y buffer for YUV format @property (nonatomic, assign) int yHeight; -// {zh} / uv buffer 宽,用于 YUV 格式 {en} Wide/uv buffer for YUV format +// {zh} / uv buffer 宽,用于 YUV 格式 {en} Wide/uv buffer for YUV format @property (nonatomic, assign) int uvWidth; -// {zh} / uv buffer 高,用于 YUV 格式 {en} High/uv buffer for YUV format +// {zh} / uv buffer 高,用于 YUV 格式 {en} High/uv buffer for YUV format @property (nonatomic, assign) int uvHeight; -// {zh} / 行宽,用于 RGBA 格式 {en} /Line width for RGBA format +// {zh} / 行宽,用于 RGBA 格式 {en} /Line width for RGBA format @property (nonatomic, assign) int bytesPerRow; -// {zh} / y buffer 行宽,用于 YUV 格式 {en} /Y buffer line width for YUV format +// {zh} / y buffer 行宽,用于 YUV 格式 {en} /Y buffer line width for YUV format @property (nonatomic, assign) int yBytesPerRow; -// {zh} / uv buffer 行宽,用于 YUV 格式 {en} /UV buffer line width for YUV format +// {zh} / uv buffer 行宽,用于 YUV 格式 {en} /UV buffer line width for YUV format @property (nonatomic, assign) int uvBytesPerRow; -// {zh} / 格式 {en} /Format +// {zh} / u buffer 行宽,用于 YUV 格式 {en} /U buffer line width for YUV format +@property (nonatomic, assign) int uBytesPerRow; + +// {zh} / v buffer 行宽,用于 YUV 格式 {en} /V buffer line width for YUV format +@property (nonatomic, assign) int vBytesPerRow; + +// {zh} / 格式 {en} /Format @property (nonatomic, assign) BEFormatType format; @end @@ -63,124 +104,141 @@ #pragma mark - Init output texture and get -// {zh} / @brief 初始化一个与 CVPixelBufferRef 绑定的纹理 {en} /@brief initializes a texture bound to CVPixelBufferRef -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height -// {zh} / @param format 格式,仅支持 BE_BGRA/BE_YUV420F/BE_YUV420V {en} /@param format, only support BE_BGRA/BE_YUV420F/BE_YUV420V -- (BEPixelBufferGLTexture *)getOutputPixelBufferGLTextureWithWidth:(int)width height:(int)height format:(BEFormatType)format; +// {zh} / @brief 初始化一个与 CVPixelBufferRef 绑定的纹理 {en} /@brief initializes a texture bound to CVPixelBufferRef +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height +// {zh} / @param format 格式,仅支持 BE_BGRA/BE_YUV420F/BE_YUV420V {en} /@param format, only support BE_BGRA/BE_YUV420F/BE_YUV420V +- (BEPixelBufferGLTexture *)getOutputPixelBufferGLTextureWithWidth:(int)width height:(int)height format:(BEFormatType)format withPipeline:(BOOL)usepipeline; -// {zh} / @brief 开启纹理缓存 {en} /@brief open texture cache -// {zh} / @details 当开启之后,调用 getOutputPixelBufferGLTextureWithWidth:height:format: {en} /@details When turned on, call getOutputPixelBufferGLTextureWithWidth: height: format: -// {zh} / 时,会循环输出三个不同的纹理,保证任意连续的 3 帧纹理不会重复,用于 SDK 的并行渲染 {en} /Hour, three different textures will be output in a loop to ensure that any consecutive 3 frames of textures will not be repeated, which is used for parallel rendering of SDK -// {zh} / @param useCache 是否开启纹理缓存 {en} /@param useCache whether to open texture cache +// {zh} / @brief 开启纹理缓存 {en} /@brief open texture cache +// {zh} / @details 当开启之后,调用 getOutputPixelBufferGLTextureWithWidth:height:format: {en} /@details When turned on, call getOutputPixelBufferGLTextureWithWidth: height: format: +// {zh} / 时,会循环输出三个不同的纹理,保证任意连续的 3 帧纹理不会重复,用于 SDK 的并行渲染 {en} /Hour, three different textures will be output in a loop to ensure that any consecutive 3 frames of textures will not be repeated, which is used for parallel rendering of SDK +// {zh} / @param useCache 是否开启纹理缓存 {en} /@param useCache whether to open texture cache - (void)setUseCachedTexture:(BOOL)useCache; #pragma mark - CVPixelBuffer to others -// {zh} / @brief CVPixelBuffer 转 BEBuffer {en} /@Briefing CVPixelBuffer to BEBuffer +// {zh} / @brief CVPixelBuffer 转 BEBuffer {en} /@Briefing CVPixelBuffer to BEBuffer /// @param pixelBuffer CVPixelBuffer -// {zh} / @param outputFormat 输出 BEBuffer 格式 {en} /@param outputFormat output BEBuffer format +// {zh} / @param outputFormat 输出 BEBuffer 格式 {en} /@param outputFormat output BEBuffer format - (BEBuffer *)transforCVPixelBufferToBuffer:(CVPixelBufferRef)pixelBuffer outputFormat:(BEFormatType)outputFormat; -// {zh} / @brief CVPixelBuffer 转 纹理 {en} /@Briefing CVPixelBuffer, texture +// {zh} / @brief CVPixelBuffer 转 纹理 {en} /@Briefing CVPixelBuffer, texture /// @param pixelBuffer CVPixelBuffer - (BEPixelBufferGLTexture *)transforCVPixelBufferToTexture:(CVPixelBufferRef)pixelBuffer; -// {zh} / @brief CVPixelBuffer 转 CVPixelBuffer {en} /@Briefing CVPixelBuffer to CVPixelBuffer -// {zh} / @param pixelBuffer 输入 CVPixelBuffer {en} /@param pixelBuffer Enter CVPixelBuffer -// {zh} / @param outputFormat 输出 CVPixelBuffer 格式 {en} /@param outputFormat output CVPixelBuffer format +// {zh} / @brief CVPixelBuffer 转 metal纹理 {en} /@Briefing CVPixelBuffer to metal texture +/// @param pixelBuffer CVPixelBuffer +- (id)transformCVPixelBufferToMTLTexture:(CVPixelBufferRef)pixelBuffer; + +// {zh} / @brief CVPixelBuffer 转 CVPixelBuffer {en} /@Briefing CVPixelBuffer to CVPixelBuffer +// {zh} / @param pixelBuffer 输入 CVPixelBuffer {en} /@param pixelBuffer Enter CVPixelBuffer +// {zh} / @param outputFormat 输出 CVPixelBuffer 格式 {en} /@param outputFormat output CVPixelBuffer format - (CVPixelBufferRef)transforCVPixelBufferToCVPixelBuffer:(CVPixelBufferRef)pixelBuffer outputFormat:(BEFormatType)outputFormat; -// {zh} / @brief 旋转 CVPixelBuffer {en} /@Briefing Rotate CVPixelBuffer -// {zh} / @details 输出的 CVPixelBuffer 需要手动调用 CVPixelBufferRelease 释放 {en} /@details The output CVPixelBuffer needs to be released manually by calling CVPixelBufferRelease +// {zh} / @brief 旋转 CVPixelBuffer {en} /@Briefing Rotate CVPixelBuffer +// {zh} / @details 输出的 CVPixelBuffer 需要手动调用 CVPixelBufferRelease 释放 {en} /@details The output CVPixelBuffer needs to be released manually by calling CVPixelBufferRelease /// @param pixelBuffer CVPixelBuffer -// {zh} / @param rotation 旋转角度,90/180/270 {en} /@param rotation angle, 90/180/270 +// {zh} / @param rotation 旋转角度,90/180/270 {en} /@param rotation angle, 90/180/270 - (CVPixelBufferRef)rotateCVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotation:(int)rotation; + +- (CVPixelBufferRef)reflectCVPixelBuffer:(CVPixelBufferRef)pixelBuffer orientation:(BEFlipOrientation)orient; + #pragma mark - BEBuffer to others -// {zh} / @brief BEBuffer 转 CVPixelBuffer {en} @Briefing BEBuffer to CVPixelBuffer +// {zh} / @brief BEBuffer 转 CVPixelBuffer {en} @Briefing BEBuffer to CVPixelBuffer /// @param buffer BEBuffer -// {zh} / @param outputFormat 输出格式 {en} /@param outputFormat output format +// {zh} / @param outputFormat 输出格式 {en} /@param outputFormat output format - (CVPixelBufferRef)transforBufferToCVPixelBuffer:(BEBuffer *)buffer outputFormat:(BEFormatType)outputFormat; -// {zh} / @brief BEBuffer 转 CVPixelBuffer {en} @Briefing BEBuffer to CVPixelBuffer -// {zh} / @details 将 BEBuffer 的内容复制到已存在的目标 CVPixleBuffer 中,可以同时进行格式转换 {en} /@details Copy the contents of the BEBuffer to the existing target CVPixleBuffer, which can be formatted at the same time +// {zh} / @brief BEBuffer 转 CVPixelBuffer {en} @Briefing BEBuffer to CVPixelBuffer +// {zh} / @details 将 BEBuffer 的内容复制到已存在的目标 CVPixleBuffer 中,可以同时进行格式转换 {en} /@details Copy the contents of the BEBuffer to the existing target CVPixleBuffer, which can be formatted at the same time /// @param buffer BEBuffer -// {zh} / @param pixelBuffer 目标 CVPixelBuffer {en} /@param pixelBuffer Target CVPixelBuffer +// {zh} / @param pixelBuffer 目标 CVPixelBuffer {en} /@param pixelBuffer Target CVPixelBuffer - (BOOL)transforBufferToCVPixelBuffer:(BEBuffer *)buffer pixelBuffer:(CVPixelBufferRef)pixelBuffer; -// {zh} / @brief BEBuffer 转 BEBuffer {en} /@Briefing BEBuffer to BEBuffer -// {zh} / @param inputBuffer 输入BEBuffer {en} /@param inputBuffer Enter BEBuffer -// {zh} / @param outputFormat 输出格式 {en} /@param outputFormat output format +// {zh} / @brief BEBuffer 转 BEBuffer {en} /@Briefing BEBuffer to BEBuffer +// {zh} / @param inputBuffer 输入BEBuffer {en} /@param inputBuffer Enter BEBuffer +// {zh} / @param outputFormat 输出格式 {en} /@param outputFormat output format - (BEBuffer *)transforBufferToBuffer:(BEBuffer *)inputBuffer outputFormat:(BEFormatType)outputFormat; -// {zh} / @brief BEBuffer 转 BEBuffer {en} /@Briefing BEBuffer to BEBuffer -// {zh} / @details 将 BEBuffer 的内容复制到已存在的目标 BEBuffer 中,可以同时进行格式转换 {en} /@details Copy the contents of the BEBuffer to the existing target BEBuffer, and format conversion can be performed at the same time -// {zh} / @param inputBuffer 输入 BEBuffer {en} /@param inputBuffer Enter BEBuffer -// {zh} / @param outputBuffer 输出 BEBuffer {en} /@param outputBuffer output BEBuffer +// {zh} / @brief BEBuffer 转 BEBuffer {en} /@Briefing BEBuffer to BEBuffer +// {zh} / @details 将 BEBuffer 的内容复制到已存在的目标 BEBuffer 中,可以同时进行格式转换 {en} /@details Copy the contents of the BEBuffer to the existing target BEBuffer, and format conversion can be performed at the same time +// {zh} / @param inputBuffer 输入 BEBuffer {en} /@param inputBuffer Enter BEBuffer +// {zh} / @param outputBuffer 输出 BEBuffer {en} /@param outputBuffer output BEBuffer - (BOOL)transforBufferToBuffer:(BEBuffer *)inputBuffer outputBuffer:(BEBuffer *)outputBuffer; -// {zh} / @brief 旋转 BEBuffer {en} @Briefing BEBuffer -// {zh} / @param inputBuffer 输入 BEBuffer {en} /@param inputBuffer Enter BEBuffer -// {zh} / @param outputBuffer 输出 BEBuffer {en} /@param outputBuffer output BEBuffer -// {zh} / @param rotation 旋转角度,90/180/270 {en} /@param rotation angle, 90/180/270 +// {zh} / @brief 旋转 BEBuffer {en} @Briefing BEBuffer +// {zh} / @param inputBuffer 输入 BEBuffer {en} /@param inputBuffer Enter BEBuffer +// {zh} / @param outputBuffer 输出 BEBuffer {en} /@param outputBuffer output BEBuffer +// {zh} / @param rotation 旋转角度,90/180/270 {en} /@param rotation angle, 90/180/270 - (BOOL)rotateBufferToBuffer:(BEBuffer *)inputBuffer outputBuffer:(BEBuffer *)outputBuffer rotation:(int)rotation; -// {zh} / @brief BEBuffer 转 纹理 {en} /@Brief BEBuffer, texture +// {zh} / @brief BEBuffer 转 纹理 {en} /@Brief BEBuffer, texture /// @param buffer BEBuffer - (id)transforBufferToTexture:(BEBuffer *)buffer; -// {zh} / @brief BEBuffer 转 UIImage {en} @Briefing BEBuffer to UIImage +// {zh} / @brief BEBuffer 转 UIImage {en} @Briefing BEBuffer to UIImage /// @param buffer BEBuffer - (UIImage *)transforBufferToUIImage:(BEBuffer *)buffer; #pragma mark - Texture to others -// {zh} / @brief 纹理转 BEBuffer {en} /@brief texture to BEBuffer -// {zh} / @param texture 纹理 ID {en} /@param texture texture ID -// {zh} / @param widht 宽 {en} /@param widht -// {zh} / @param height 高 {en} /@param height -// {zh} / @param outputFormat 输出 BEBuffer 格式,仅支持 RGBA/BGRA {en} /@param outputFormat output BEBuffer format, only supports RGBA/BGRA +// {zh} / @brief 纹理转 BEBuffer {en} /@brief texture to BEBuffer +// {zh} / @param texture 纹理 ID {en} /@param texture texture ID +// {zh} / @param widht 宽 {en} /@param widht +// {zh} / @param height 高 {en} /@param height +// {zh} / @param outputFormat 输出 BEBuffer 格式,仅支持 RGBA/BGRA {en} /@param outputFormat output BEBuffer format, only supports RGBA/BGRA - (BEBuffer *)transforTextureToBEBuffer:(GLuint)texture width:(int)widht height:(int)height outputFormat:(BEFormatType)outputFormat; #pragma mark - UIImage to others -// {zh} / @brief UIImage 转 BEBuffer {en} @Briefing UIImage to BEBuffer +// {zh} / @brief UIImage 转 BEBuffer {en} @Briefing UIImage to BEBuffer /// @param image UIImage - (BEBuffer *)transforUIImageToBEBuffer:(UIImage *)image; #pragma mark - Utils -// {zh} / @brief 获取 CVPxielBuffer 格式 {en} /@Briefing Get the CVPxielBuffer format +// {zh} / @brief 获取 CVPxielBuffer 格式 {en} /@Briefing Get the CVPxielBuffer format /// @param pixelBuffer CVPixelBuffer - (BEFormatType)getCVPixelBufferFormat:(CVPixelBufferRef)pixelBuffer; -// {zh} / @brief OSType 转 BEFormatType {en} @Briefing OSType to BEFormatType +// {zh} / @brief OSType 转 BEFormatType {en} @Briefing OSType to BEFormatType /// @param type OSType - (BEFormatType)getFormatForOSType:(OSType)type; -// {zh} / @brief BEFormatType 转 OSType {en} @Briefing BEFormatType to OSType +// {zh} / @brief BEFormatType 转 OSType {en} @Briefing BEFormatType to OSType /// @param format BEFormatType - (OSType)getOsType:(BEFormatType)format; -// {zh} / @brief BEFormatType 转 Glenum {en} @Briefing BEFormatType to Glenum +// {zh} / @brief BEFormatType 转 Glenum {en} @Briefing BEFormatType to Glenum /// @param format BEFormatType - (GLenum)getGlFormat:(BEFormatType)format; -// {zh} / @brief 获取 CVPixelBuffer 信息 {en} /@Briefing for CVPixelBuffer information +// {zh} / @brief 获取 CVPixelBuffer 信息 {en} /@Briefing for CVPixelBuffer information /// @param pixelBuffer CVPixelBuffer - (BEPixelBufferInfo *)getCVPixelBufferInfo:(CVPixelBufferRef)pixelBuffer; -// {zh} / @brief 创建 BEBuffer {en} /@Briefing Create BEBuffer -// {zh} / @details 可以根据宽、高、bytesPerRow、格式等信息计算出所需的大小, {en} /@Details can calculate the required size based on information such as width, height, bytesPerRow, format, etc. -// {zh} / 外部无需考虑内存释放 {en} /External no need to consider memory release -// {zh} / @param width 宽 {en} /@param width -// {zh} / @param height 高 {en} /@param height +// {zh} / @brief 创建 BEBuffer {en} /@Briefing Create BEBuffer +// {zh} / @details 可以根据宽、高、bytesPerRow、格式等信息计算出所需的大小, {en} /@Details can calculate the required size based on information such as width, height, bytesPerRow, format, etc. +// {zh} / 外部无需考虑内存释放 {en} /External no need to consider memory release +// {zh} / @param width 宽 {en} /@param width +// {zh} / @param height 高 {en} /@param height /// @param bytesPerRow bytesPerRow /// @param format BEFormatType - (BEBuffer *)allocBufferWithWidth:(int)width height:(int)height bytesPerRow:(int)bytesPerRow format:(BEFormatType)format; +// {zh} / @brief 拷贝pixelbuffer,调用者需要管理返回buffer的生命周期 {en} /@Briefing Copy CVPixelBuffer, revoker should be resposible for the life cycle. +// {zh} / @param pixelBuffer 源buffer {en} /@param src pixelBuffer +- (CVPixelBufferRef)copyCVPixelBuffer:(CVPixelBufferRef)pixelBuffer; + +// change default settings ++ (void)setTextureCacheNum:(int)num; ++ (void)setUseCachedPixelBuffer:(bool)use; ++ (int)textureCacheNum; ++ (bool)useCachedPixelBuffer; + @end #endif /* BEImageUtils_h */ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.m index 56a19eb13..77b0718be 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEImageUtils.m @@ -1,17 +1,19 @@ -// // BEImageUtils.m -// BytedEffects -// -// Created by qun on 2021/2/2. -// Copyright © 2021 ailab. All rights reserved. -// +// EffectsARSDK + #import "BEImageUtils.h" #import +#import "BEGLTexture.h" #import "BEOpenGLRenderHelper.h" -static const int TEXTURE_CACHE_NUM = 3; -static const int MAX_MALLOC_CACHE = 3; +static int TEXTURE_CACHE_NUM = 3; +static int MAX_MALLOC_CACHE = 3; + +static bool USE_CACHE_PIXEL_BUFFER = true; + +@implementation BEPixelBufferInfo +@end @implementation BEBuffer @end @@ -52,11 +54,6 @@ - (instancetype)init - (void)dealloc { // release input/output texture - if (_textureCache) { - CVOpenGLESTextureCacheFlush(_textureCache, 0); - CFRelease(_textureCache); - _textureCache = nil; - } for (id texture in _inputTextures) { [texture destroy]; } @@ -65,6 +62,11 @@ - (void)dealloc [texture destroy]; } [_outputTextures removeAllObjects]; + if (_textureCache) { + CVOpenGLESTextureCacheFlush(_textureCache, 0); + CFRelease(_textureCache); + _textureCache = nil; + } // release malloced memory for (NSValue *value in _mallocDict.allValues) { unsigned char *pointer = [value pointerValue]; @@ -78,11 +80,14 @@ - (void)dealloc } for (NSValue *value in self.pixelBufferPoolDict.allValues) { CVPixelBufferPoolRef pool = [value pointerValue]; + CVPixelBufferPoolFlush(pool, kCVPixelBufferPoolFlushExcessBuffers); CVPixelBufferPoolRelease(pool); } + [self.pixelBufferPoolDict removeAllObjects]; + self.pixelBufferPoolDict = nil; } -- (BEPixelBufferGLTexture *)getOutputPixelBufferGLTextureWithWidth:(int)width height:(int)height format:(BEFormatType)format { +- (BEPixelBufferGLTexture *)getOutputPixelBufferGLTextureWithWidth:(int)width height:(int)height format:(BEFormatType)format withPipeline:(BOOL)usepipeline { if (format != BE_BGRA) { NSLog(@"this method only supports BE_BRGA format, please use BE_BGRA"); return nil; @@ -102,7 +107,7 @@ - (BEPixelBufferGLTexture *)getOutputPixelBufferGLTextureWithWidth:(int)width he [_outputTexture updateWidth:width height:height]; - if (_useCacheTexture) { + if (_useCacheTexture && usepipeline) { // If use pipeline, return last output texture if we can. // To resolve problems like size changed between two continuous frames int lastTextureIndex = (_textureIndex + TEXTURE_CACHE_NUM - 1) % TEXTURE_CACHE_NUM; @@ -169,13 +174,47 @@ - (CVPixelBufferRef)rotateCVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotation:( return outputPixelBuffer; } -- (id)transforCVPixelBufferToTexture:(CVPixelBufferRef)pixelBuffer { +- (CVPixelBufferRef)reflectCVPixelBuffer:(CVPixelBufferRef)pixelBuffer orientation:(BEFlipOrientation)orient +{ BEPixelBufferInfo *info = [self getCVPixelBufferInfo:pixelBuffer]; - if (info.format != BE_BGRA) { - pixelBuffer = [self transforCVPixelBufferToCVPixelBuffer:pixelBuffer outputFormat:BE_BGRA]; - NSLog(@"this method only supports BRGA format CVPixelBuffer, convert it to BGRA CVPixelBuffer internal"); + + int outputWidth = info.width; + int outputHeight = info.height; + + CVPixelBufferRef outputPixelBuffer = [self be_createPixelBufferFromPool:[self getOsType:info.format] heigth:outputHeight width:outputWidth]; + + + BEBuffer *inputBuffer = [self be_getBufferFromCVPixelBuffer:pixelBuffer]; + BEBuffer *outputBuffer = [self be_getBufferFromCVPixelBuffer:outputPixelBuffer]; + + vImage_Buffer src, dest; + { + src.width = inputBuffer.width; + src.height = inputBuffer.height; + src.data = inputBuffer.buffer; + src.rowBytes = inputBuffer.bytesPerRow; + dest.width = outputBuffer.width; + dest.height = outputBuffer.height; + dest.data = outputBuffer.buffer; + dest.rowBytes = outputBuffer.bytesPerRow; } + if (orient == BE_FlipVertical) { + vImageVerticalReflect_ARGB8888(&src, &dest, kvImageNoFlags); + } else { + vImageHorizontalReflect_ARGB8888(&src, &dest, kvImageNoFlags); + } + return outputPixelBuffer; +} + + +- (id)transforCVPixelBufferToTexture:(CVPixelBufferRef)pixelBuffer { + BEPixelBufferInfo *info = [self getCVPixelBufferInfo:pixelBuffer]; +// if (info.format != BE_BGRA) { +// pixelBuffer = [self transforCVPixelBufferToCVPixelBuffer:pixelBuffer outputFormat:BE_BGRA]; +//// NSLog(@"this method only supports BRGA format CVPixelBuffer, convert it to BGRA CVPixelBuffer internal"); +// } + if (_useCacheTexture) { _textureIndex = (_textureIndex + 1) % TEXTURE_CACHE_NUM; } else { @@ -226,7 +265,7 @@ - (BEBuffer *)transforBufferToBuffer:(BEBuffer *)inputBuffer outputFormat:(BEFor BEBuffer *buffer = nil; if ([self be_isRgba:outputFormat]) { if ([self be_isRgba:inputBuffer.format]) { - buffer = [self allocBufferWithWidth:inputBuffer.width height:inputBuffer.height bytesPerRow:inputBuffer.bytesPerRow format:outputFormat]; + buffer = [self allocBufferWithWidth:inputBuffer.width height:inputBuffer.height bytesPerRow:inputBuffer.width * 4 format:outputFormat]; } else { buffer = [self allocBufferWithWidth:inputBuffer.width height:inputBuffer.height bytesPerRow:inputBuffer.width * 4 format:outputFormat]; } @@ -236,6 +275,10 @@ - (BEBuffer *)transforBufferToBuffer:(BEBuffer *)inputBuffer outputFormat:(BEFor } else { buffer = [self allocBufferWithWidth:inputBuffer.width height:inputBuffer.height bytesPerRow:inputBuffer.bytesPerRow format:outputFormat]; } + } else if ([self be_isRgb:outputFormat]) { + if ([self be_isRgba:inputBuffer.format]) { + buffer = [self allocBufferWithWidth:inputBuffer.width height:inputBuffer.height bytesPerRow:inputBuffer.width * 3 format:outputFormat]; + } } if (buffer == nil) { return nil; @@ -312,8 +355,73 @@ - (BOOL)transforBufferToBuffer:(BEBuffer *)inputBuffer outputBuffer:(BEBuffer *) bgraBuffer.rowBytes = outputBuffer.bytesPerRow; BOOL result = [self be_convertYuvToRgba:&yBuffer yvBuffer:&uvBuffer rgbaBuffer:&bgraBuffer inputFormat:inputBuffer.format outputFormat:outputBuffer.format]; return result; + } else if ([self be_isYuv420Planar:inputBuffer.format]) { + vImage_Buffer yBuffer; + yBuffer.data = inputBuffer.yBuffer; + yBuffer.width = inputBuffer.yWidth; + yBuffer.height = inputBuffer.yHeight; + yBuffer.rowBytes = inputBuffer.yBytesPerRow; + vImage_Buffer uBuffer; + uBuffer.data = inputBuffer.uBuffer; + uBuffer.width = inputBuffer.uvWidth; + uBuffer.height = inputBuffer.uvHeight; + uBuffer.rowBytes = inputBuffer.uBytesPerRow; + vImage_Buffer vBuffer; + vBuffer.data = inputBuffer.vBuffer; + vBuffer.width = inputBuffer.uvWidth; + vBuffer.height = inputBuffer.uvHeight; + vBuffer.rowBytes = inputBuffer.vBytesPerRow; + vImage_Buffer bgraBuffer; + bgraBuffer.data = outputBuffer.buffer; + bgraBuffer.width = outputBuffer.width; + bgraBuffer.height = outputBuffer.height; + bgraBuffer.rowBytes = outputBuffer.bytesPerRow; + BOOL result = [self be_convertYuvToRgba:&yBuffer uBuffer:&uBuffer vBuffer:&vBuffer rgbaBuffer:&bgraBuffer inputFormat:inputBuffer.format outputFormat:outputBuffer.format]; + return result; + } + } else if ([self be_isYuv420Planar:outputBuffer.format]) { + if ([self be_isRgba:inputBuffer.format]) { + vImage_Buffer rgbaBuffer; + rgbaBuffer.data = inputBuffer.buffer; + rgbaBuffer.width = inputBuffer.width; + rgbaBuffer.height = inputBuffer.height; + rgbaBuffer.rowBytes = inputBuffer.bytesPerRow; + vImage_Buffer yBuffer; + yBuffer.data = outputBuffer.yBuffer; + yBuffer.width = outputBuffer.yWidth; + yBuffer.height = outputBuffer.yHeight; + yBuffer.rowBytes = outputBuffer.yBytesPerRow; + vImage_Buffer uBuffer; + uBuffer.data = outputBuffer.uBuffer; + uBuffer.width = outputBuffer.uvWidth; + uBuffer.height = outputBuffer.uvHeight; + uBuffer.rowBytes = outputBuffer.uBytesPerRow; + vImage_Buffer vBuffer; + vBuffer.data = outputBuffer.vBuffer; + vBuffer.width = outputBuffer.uvWidth; + vBuffer.height = outputBuffer.uvHeight; + vBuffer.rowBytes = outputBuffer.vBytesPerRow; + + BOOL result = [self be_convertRgbaToYuv:&rgbaBuffer yBuffer:&yBuffer uBuffer:&uBuffer vBuffer:&vBuffer inputFormat:inputBuffer.format outputFormat:outputBuffer.format]; + return result; + } + } else if ([self be_isRgb:outputBuffer.format]) { + if ([self be_isRgba:inputBuffer.format]) { + vImage_Buffer bgraBuffer; + bgraBuffer.data = inputBuffer.buffer; + bgraBuffer.width = inputBuffer.width; + bgraBuffer.height = inputBuffer.height; + bgraBuffer.rowBytes = inputBuffer.bytesPerRow; + vImage_Buffer bgrBuffer; + bgrBuffer.data = outputBuffer.buffer; + bgrBuffer.width = outputBuffer.width; + bgrBuffer.height = outputBuffer.height; + bgrBuffer.rowBytes = outputBuffer.bytesPerRow; + BOOL result = [self be_convertBgraToBgr:&bgraBuffer outputBuffer:&bgrBuffer inputFormat:inputBuffer.format outputFormat:outputBuffer.format]; + return result; } } + return NO; } @@ -368,6 +476,26 @@ - (BOOL)rotateBufferToBuffer:(BEBuffer *)inputBuffer outputBuffer:(BEBuffer *)ou return texture; } +- (id)transformCVPixelBufferToMTLTexture:(CVPixelBufferRef)pixelBuffer{ + size_t width = CVPixelBufferGetWidth(pixelBuffer); + size_t height = CVPixelBufferGetHeight(pixelBuffer); + id device = MTLCreateSystemDefaultDevice(); + CVMetalTextureCacheRef _textureCache; + CVMetalTextureCacheCreate(NULL, NULL, device, NULL, &_textureCache); + + CVMetalTextureRef tmpTexture = NULL; + CVReturn ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, MTLPixelFormatBGRA8Unorm, width, height, 0, &tmpTexture); + if (ret != kCVReturnSuccess) { + NSLog(@"MetalTextureCreate error: %d", ret); + return nil; + } + id mtlTexture = CVMetalTextureGetTexture(tmpTexture); + CFRelease(tmpTexture); + + return mtlTexture; +} + + - (UIImage *)transforBufferToUIImage:(BEBuffer *)buffer { if (![self be_isRgba:buffer.format]) { buffer = [self transforBufferToBuffer:buffer outputFormat:BE_BGRA]; @@ -388,7 +516,7 @@ - (UIImage *)transforBufferToUIImage:(BEBuffer *)buffer { if (buffer.format == BE_RGBA) { bitmapInfo = kCGBitmapByteOrderDefault|kCGImageAlphaLast; } else { - bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaFirst; + bitmapInfo = kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst; } CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; @@ -408,6 +536,8 @@ - (UIImage *)transforBufferToUIImage:(BEBuffer *)buffer { CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpaceRef); CGImageRelease(imageRef); + NSData *data = UIImageJPEGRepresentation(uiImage, 1); + uiImage = [UIImage imageWithData:data]; return uiImage; } @@ -426,6 +556,8 @@ - (BEFormatType)getFormatForOSType:(OSType)type { return BE_YUV420F; case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: return BE_YUV420V; + case kCVPixelFormatType_420YpCbCr8Planar: + return BE_YUVY420; default: return BE_UNKNOW; break; @@ -480,7 +612,7 @@ - (BEBuffer *)allocBufferWithWidth:(int)width height:(int)height bytesPerRow:(in buffer.bytesPerRow = bytesPerRow; buffer.format = format; if ([self be_isRgba:format]) { - buffer.buffer = [self be_mallocBufferWithSize:bytesPerRow * height * 4]; + buffer.buffer = [self be_mallocBufferWithSize:bytesPerRow * height]; return buffer; } else if ([self be_isYuv420:format]) { buffer.yBuffer = [self be_mallocBufferWithSize:bytesPerRow * height]; @@ -492,6 +624,9 @@ - (BEBuffer *)allocBufferWithWidth:(int)width height:(int)height bytesPerRow:(in buffer.uvHeight = height / 2; buffer.uvBytesPerRow = bytesPerRow; return buffer; + } else if ([self be_isRgb:format]) { + buffer.buffer = [self be_mallocBufferWithSize:bytesPerRow * height * 3]; + return buffer; } return nil; } @@ -526,8 +661,45 @@ - (BEBuffer *)transforTextureToBEBuffer:(GLuint)texture width:(int)widht height: return buffer; } +- (CVPixelBufferRef)copyCVPixelBuffer:(CVPixelBufferRef)pixelBuffer { + CVPixelBufferLockBaseAddress(pixelBuffer, 0); + int bufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer); + int bufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer); + size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer); + uint8_t *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer); + OSType format = CVPixelBufferGetPixelFormatType(pixelBuffer); + CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); + + CVPixelBufferRef pixelBufferCopy = [self be_createPixelBufferFromPool:format heigth:bufferHeight width:bufferWidth]; + CVPixelBufferLockBaseAddress(pixelBufferCopy, 0); + uint8_t *copyBaseAddress = CVPixelBufferGetBaseAddress(pixelBufferCopy); + memcpy(copyBaseAddress, baseAddress, bufferHeight * bytesPerRow); + CVPixelBufferUnlockBaseAddress(pixelBufferCopy, 0); + return pixelBufferCopy; +} + #pragma mark - private +- (BOOL)be_convertBgraToBgr:(vImage_Buffer *)inputBuffer outputBuffer:(vImage_Buffer *)outputBuffer inputFormat:(BEFormatType)inputFormat + outputFormat:(BEFormatType)outputFormat { + if (![self be_isRgba:inputFormat] || ![self be_isRgb:outputFormat]) { + return NO; + } + vImage_Error error = kvImageNoError; + if (inputFormat == BE_BGRA && outputFormat == BE_BGR) + error = vImageConvert_BGRA8888toBGR888(inputBuffer, outputBuffer, kvImageNoFlags); + else if (inputFormat == BE_BGRA && outputFormat == BE_RGB) + error = vImageConvert_BGRA8888toRGB888(inputBuffer, outputBuffer, kvImageNoFlags); + else if (inputFormat == BE_RGBA && outputFormat == BE_BGR) + error = vImageConvert_RGBA8888toBGR888(inputBuffer, outputBuffer, kvImageNoFlags); + else if (inputFormat == BE_RGBA && outputFormat == BE_RGB) + error = vImageConvert_RGBA8888toRGB888(inputBuffer, outputBuffer, kvImageNoFlags); + if (error != kvImageNoError) { + NSLog(@"be_convertBgraToBgr error: %ld", error); + } + return error == kvImageNoError; +} + - (BOOL)be_convertRgbaToBgra:(vImage_Buffer *)inputBuffer outputBuffer:(vImage_Buffer *)outputBuffer inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { if (![self be_isRgba:inputFormat] || ![self be_isRgba:outputFormat]) { return NO; @@ -584,6 +756,41 @@ - (BOOL)be_convertRgbaToYuv:(vImage_Buffer *)inputBuffer yBuffer:(vImage_Buffer return YES; } +- (BOOL)be_convertRgbaToYuv:(vImage_Buffer *)inputBuffer + yBuffer:(vImage_Buffer *)yBuffer + uBuffer:(vImage_Buffer *)uBuffer + vBuffer:(vImage_Buffer *)vBuffer + inputFormat:(BEFormatType)inputFormat + outputFormat:(BEFormatType)outputFormat { + if (![self be_isRgba:inputFormat] || ![self be_isYuv420Planar:outputFormat]) { + return NO; + } + uint8_t map[4] = {1, 2, 3, 0}; + [self be_permuteMap:map format:inputFormat]; + vImage_YpCbCrPixelRange pixelRange; + [self be_yuvPixelRange:&pixelRange format:outputFormat]; + + vImageARGBType argbType = kvImageARGB8888; + vImageYpCbCrType yuvType = kvImage420Yp8_Cb8_Cr8; + vImage_ARGBToYpCbCr conversionInfo; + vImage_Flags flags = kvImageNoFlags; + + vImage_Error error = vImageConvert_ARGBToYpCbCr_GenerateConversion(kvImage_ARGBToYpCbCrMatrix_ITU_R_601_4, &pixelRange, &conversionInfo, argbType, yuvType, flags); + if (error != kvImageNoError) { + NSLog(@"vImageConvert_ARGBToYpCbCr_GenerateConversion error: %ld", error); + return NO; + } + + error = vImageConvert_ARGB8888To420Yp8_Cb8_Cr8(inputBuffer, yBuffer, uBuffer, vBuffer, &conversionInfo, map, flags); + if (error != kvImageNoError) { + NSLog(@"vImageConvert_ARGB8888To420Yp8_Cb8_Cr8 error: %ld", error); + return NO; + } + + return YES; +} + + - (BOOL)be_convertYuvToRgba:(vImage_Buffer *)yBuffer yvBuffer:(vImage_Buffer *)uvBuffer rgbaBuffer:(vImage_Buffer *)rgbaBuffer inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { if (![self be_isYuv420:inputFormat] || ![self be_isRgba:outputFormat]) { return NO; @@ -614,6 +821,36 @@ - (BOOL)be_convertYuvToRgba:(vImage_Buffer *)yBuffer yvBuffer:(vImage_Buffer *)u return YES; } +- (BOOL)be_convertYuvToRgba:(vImage_Buffer *)yBuffer uBuffer:(vImage_Buffer *)uBuffer vBuffer:(vImage_Buffer *)vBuffer rgbaBuffer:(vImage_Buffer *)rgbaBuffer inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { + if (![self be_isYuv420Planar:inputFormat] || ![self be_isRgba:outputFormat]) { + return NO; + } + + uint8_t map[4] = {1, 2, 3, 0}; + [self be_permuteMap:map format:outputFormat]; + vImage_YpCbCrPixelRange pixelRange; + [self be_yuvPixelRange:&pixelRange format:inputFormat]; + + vImageARGBType argbType = kvImageARGB8888; + vImageYpCbCrType yuvType = kvImage420Yp8_Cb8_Cr8; + vImage_YpCbCrToARGB conversionInfo; + vImage_Flags flags = kvImageNoFlags; + + vImage_Error error = vImageConvert_YpCbCrToARGB_GenerateConversion(kvImage_YpCbCrToARGBMatrix_ITU_R_601_4, &pixelRange, &conversionInfo, yuvType, argbType, flags); + if (error != kvImageNoError) { + NSLog(@"vImageConvert_YpCbCrToARGB_GenerateConversion error: %ld", error); + return NO; + } + + error = vImageConvert_420Yp8_Cb8_Cr8ToARGB8888(yBuffer, uBuffer, vBuffer, rgbaBuffer, &conversionInfo, map, 255, flags); + if (error != kvImageNoError) { + NSLog(@"vImageConvert_420Yp8_Cb8_Cr8ToARGB8888 error: %ld", error); + return NO; + } + + return YES; +} + - (BEBuffer *)be_getBufferFromCVPixelBuffer:(CVPixelBufferRef)pixelBuffer { BEBuffer *buffer = [[BEBuffer alloc] init]; BEPixelBufferInfo *info = [self getCVPixelBufferInfo:pixelBuffer]; @@ -635,16 +872,37 @@ - (BEBuffer *)be_getBufferFromCVPixelBuffer:(CVPixelBufferRef)pixelBuffer { buffer.yHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); buffer.uvWidth = (int)CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); buffer.uvHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); + } else if ([self be_isYuv420Planar:info.format]) { + buffer.yBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); + buffer.yBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); + buffer.uBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); + buffer.uBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); + buffer.vBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 2); + buffer.vBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 2); + + buffer.yWidth = (int)CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); + buffer.yHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); + buffer.uvWidth = (int)CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); + buffer.uvHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); + } CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); return buffer; } +- (BOOL)be_isRgb:(BEFormatType)format { + return format == BE_RGB || format == BE_BGR; +} + - (BOOL)be_isRgba:(BEFormatType)format { return format == BE_RGBA || format == BE_BGRA; } +- (BOOL)be_isYuv420Planar:(BEFormatType)format { + return format == BE_YUVY420; +} + - (BOOL)be_isYuv420:(BEFormatType)format { return format == BE_YUV420F || format == BE_YUV420V; } @@ -690,6 +948,16 @@ - (void)be_yuvPixelRange:(vImage_YpCbCrPixelRange *)pixelRange format:(BEFormatT pixelRange->CbCrMax = 240; pixelRange->CbCrMin = 16; break; + case BE_YUVY420: + pixelRange->Yp_bias = 16; + pixelRange->CbCr_bias = 128; + pixelRange->YpRangeMax = 235; + pixelRange->CbCrRangeMax = 240; + pixelRange->YpMax = 235; + pixelRange->YpMin = 16; + pixelRange->CbCrMax = 240; + pixelRange->CbCrMin = 16; + break; default: break; } @@ -710,7 +978,7 @@ - (unsigned char *)be_mallocBufferWithSize:(int)size { } - (CVPixelBufferRef)be_createCVPixelBufferWithWidth:(int)width height:(int)height format:(BEFormatType)format { - if (_cachedPixelBuffer != nil) { + if (_cachedPixelBuffer != nil && USE_CACHE_PIXEL_BUFFER) { BEPixelBufferInfo *info = [self getCVPixelBufferInfo:_cachedPixelBuffer]; if (info.format == format && info.width == width && info.height == height) { return _cachedPixelBuffer; @@ -720,7 +988,9 @@ - (CVPixelBufferRef)be_createCVPixelBufferWithWidth:(int)width height:(int)heigh } NSLog(@"create CVPixelBuffer"); CVPixelBufferRef pixelBuffer = [self be_createPixelBufferFromPool:[self getOsType:format] heigth:height width:width]; - _cachedPixelBuffer = pixelBuffer; + if (USE_CACHE_PIXEL_BUFFER) { + _cachedPixelBuffer = pixelBuffer; + } return pixelBuffer; } @@ -754,27 +1024,24 @@ - (CVPixelBufferPoolRef)be_createPixelBufferPool:(OSType)type heigth:(int)height NSMutableDictionary* attributes = [NSMutableDictionary dictionary]; - [attributes setObject:[NSNumber numberWithBool:YES] forKey:(NSString*)kCVPixelBufferOpenGLCompatibilityKey]; + [attributes setObject:CFBridgingRelease((__bridge_retained CFNumberRef)[NSNumber numberWithBool:YES]) forKey:(NSString*)kCVPixelBufferOpenGLCompatibilityKey]; + if (MTLCreateSystemDefaultDevice()) { + [attributes setObject:CFBridgingRelease((__bridge_retained CFNumberRef)[NSNumber numberWithBool:YES]) forKey:(NSString*)kCVPixelBufferMetalCompatibilityKey]; + } [attributes setObject:[NSNumber numberWithInt:type] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; [attributes setObject:[NSNumber numberWithInt:width] forKey: (NSString*)kCVPixelBufferWidthKey]; [attributes setObject:[NSNumber numberWithInt:height] forKey: (NSString*)kCVPixelBufferHeightKey]; [attributes setObject:@(16) forKey:(NSString*)kCVPixelBufferBytesPerRowAlignmentKey]; [attributes setObject:[NSDictionary dictionary] forKey:(NSString*)kCVPixelBufferIOSurfacePropertiesKey]; - + CVReturn ret = CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (__bridge CFDictionaryRef)attributes, &pool); + [attributes removeAllObjects]; if (ret != kCVReturnSuccess){ NSLog(@"Create pixbuffer pool failed %d", ret); return NULL; } - - CVPixelBufferRef buffer; - ret = CVPixelBufferPoolCreatePixelBuffer(NULL, pool, &buffer); - if (ret != kCVReturnSuccess){ - NSLog(@"Create pixbuffer from pixelbuffer pool failed %d", ret); - return NULL; - } - + return pool; } @@ -806,4 +1073,21 @@ - (BEOpenGLRenderHelper *)renderHelper { return _renderHelper; } ++ (void)setTextureCacheNum:(int)num { + TEXTURE_CACHE_NUM = num; + MAX_MALLOC_CACHE = num; +} + ++ (void)setUseCachedPixelBuffer:(bool)use { + USE_CACHE_PIXEL_BUFFER = use; +} + ++ (int)textureCacheNum { + return TEXTURE_CACHE_NUM; +} + ++ (bool)useCachedPixelBuffer { + return USE_CACHE_PIXEL_BUFFER; +} + @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.h index 1316cde30..4497b628e 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.h @@ -1,9 +1,6 @@ -// // BEEffectResourceHelper.h // Effect -// -// Created by qun on 2021/5/18. -// + #ifndef BELicenseHelper_h #define BELicenseHelper_h @@ -29,6 +26,9 @@ typedef NS_ENUM(NSInteger, LICENSE_MODE_ENUM) { - (bool)checkLicenseOK:(const char *) filePath; +- (bool)deleteCacheFile; + +- (bool)checkLicense; @end @interface BELicenseHelper : NSObject @@ -39,6 +39,8 @@ typedef NS_ENUM(NSInteger, LICENSE_MODE_ENUM) { +(instancetype) shareInstance; +- (void)setParam:(NSString*)key value:(NSString*) value; + @end #endif /* BELicenseHelper_h */ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.mm b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.mm index 56306038b..3476c94f1 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.mm +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BELicenseHelper.mm @@ -1,29 +1,34 @@ -// // BELicenseHelper.m // BECore -// -// Created by bytedance on 2021/9/2. -// + #import "BELicenseHelper.h" +#if __has_include() +#import +#import +#endif #import "BEHttpRequestProvider.h" -#import "Core.h" #import #import -#if __has_include("bef_effect_ai_api.h") -#import "bef_effect_ai_license_wrapper.h" -#import "bef_effect_ai_api.h" -#import "BytedLicenseDefine.h" -#endif +#import "BundleUtil.h" +#import "Config.h" using namespace std; +static NSString *OFFLIN_LICENSE_PATH = @"LicenseBag"; +static NSString *OFFLIN_BUNDLE = @"bundle"; +static NSString *LICENSE_URL = @"https://cv.iccvlog.com/cv_tob/v1/api/sdk/tob_license/getlicense"; +static NSString *KEY = @"cv_test_online1"; +static NSString *SECRET = @"e479f002-4018-11eb-a1e0-b8599f494dc4"; +static LICENSE_MODE_ENUM LICENSE_MODE = OFFLINE_LICENSE; +BOOL overSeasVersion = NO; + @interface BELicenseHelper() { std::string _licenseFilePath; LICENSE_MODE_ENUM _licenseMode; -#if __has_include("bef_effect_ai_api.h") - IBytedLicenseProvider* _licenseProvider; - BEHttpRequestProvider* _requestProvider; +#if __has_include() + EffectsSDK::LicenseProvider* _licenseProvider; + EffectsSDK::HttpRequestProvider* _requestProvider; #endif } @end @@ -53,9 +58,18 @@ -(id) copyWithZone:(struct _NSZone *)zone return [BELicenseHelper shareInstance] ; } +- (void)setParam:(NSString*)key value:(NSString*) value{ +#if __has_include() + if (_licenseProvider == nil) + return; + + _licenseProvider->setParam([key UTF8String], [value UTF8String]); +#endif +} + - (id)init { self = [super init]; -#if __has_include("bef_effect_ai_api.h") +#if __has_include() if (self) { _errorCode = 0; _licenseMode = LICENSE_MODE; @@ -63,10 +77,10 @@ - (id)init { if (_licenseMode == ONLINE_LICENSE) { _licenseProvider->setParam("mode", "ONLINE"); - _licenseProvider->setParam("url", "https://cv-tob.bytedance.com/v1/api/sdk/tob_license/getlicense"); - _licenseProvider->setParam("key", ONLINE_LICENSE_KEY); - _licenseProvider->setParam("secret", ONLINE_LICENSE_SECRET); - NSString *licenseName = [NSString stringWithFormat:@"/%s", LICENSE_NAME]; + _licenseProvider->setParam("url", [[self licenseUrl] UTF8String]); + _licenseProvider->setParam("key", [[self licenseKey] UTF8String]); + _licenseProvider->setParam("secret", [[self licenseSecret] UTF8String]); + NSString *licenseName = [NSString stringWithFormat:@"/%s", "license.bag"]; NSString *licensePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; licensePath = [licensePath stringByAppendingString:licenseName]; _licenseProvider->setParam("licensePath", [licensePath UTF8String]); @@ -75,7 +89,8 @@ - (id)init { { _licenseProvider->setParam("mode", "OFFLINE"); NSString *licenseName = [NSString stringWithFormat:@"/%s", LICENSE_NAME]; - NSString* licensePath = [[NSBundle mainBundle] pathForResource:OFFLIN_LICENSE_PATH ofType:OFFLIN_BUNDLE]; + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; + NSString* licensePath = [bundle pathForResource:OFFLIN_LICENSE_PATH ofType:OFFLIN_BUNDLE]; licensePath = [licensePath stringByAppendingString:licenseName]; _licenseProvider->setParam("licensePath", [licensePath UTF8String]); } @@ -83,42 +98,88 @@ - (id)init { _licenseProvider->registerHttpProvider(_requestProvider); } #endif + return self; } +- (NSString *)licenseUrl { + NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; + if ([[def objectForKey:@"licenseUrl"] isEqual: @""] || [def objectForKey:@"licenseUrl"] == nil) { + [def synchronize]; + if (overSeasVersion) + LICENSE_URL = @"https://cv-tob.byteintl.com/v1/api/sdk/tob_license/getlicense"; + return LICENSE_URL; + } + else { + NSString *licenseUrl = [def objectForKey:@"licenseUrl"]; + [def synchronize]; + return licenseUrl; + } +} + +- (NSString *)licenseKey { + NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; + if ([[def objectForKey:@"licenseKey"] isEqual: @""] || [def objectForKey:@"licenseKey"] == nil) { + [def synchronize]; + if (overSeasVersion) + KEY = @"biz_license_tool_test_key6f4411ef1eb14a858e51bfcdfbe68a60"; + return KEY; + } + else { + NSString *licenseKey = [def objectForKey:@"licenseKey"]; + [def synchronize]; + return licenseKey; + } +} + +- (NSString *)licenseSecret { + NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; + if ([[def objectForKey:@"licenseSecret"] isEqual: @""] || [def objectForKey:@"licenseSecret"] == nil) { + [def synchronize]; + + if (overSeasVersion) + SECRET = @"969f0a51ae465c4b21f30c59bcb08ea4"; + return SECRET; + } + else { + NSString *licenseSecret = [def objectForKey:@"licenseSecret"]; + [def synchronize]; + return licenseSecret; + } +} + -(void)dealloc { -#if __has_include("bef_effect_ai_api.h") +#if __has_include() delete _licenseProvider; delete _requestProvider; #endif } +#if __has_include() - (const char *)licensePath { _errorCode = 0; _errorMsg = @""; -#if __has_include("bef_effect_ai_api.h") std::map params; - _licenseProvider->getLicenseWithParams(params, false, [](const char* retmsg, int retSize, ErrorInfo error, void* userdata){ + _licenseProvider->getLicenseWithParams(params, false, [](const char* retmsg, int retSize, EffectsSDK::ErrorInfo error, void* userdata){ BELicenseHelper* pThis = CFBridgingRelease(userdata); pThis.errorCode = error.errorCode; pThis.errorMsg = [[NSString alloc] initWithCString:error.errorMsg.c_str() encoding:NSUTF8StringEncoding]; }, (void*)CFBridgingRetain(self)); + if (![self checkLicenseResult: @"getLicensePath"]) return ""; _licenseFilePath = _licenseProvider->getParam("licensePath"); return _licenseFilePath.c_str(); -#else - return ""; -#endif } +#endif +#if __has_include() - (const char *)updateLicensePath { _errorCode = 0; _errorMsg = @""; -#if __has_include("bef_effect_ai_api.h") std::map params; - _licenseProvider->updateLicenseWithParams(params, false, [](const char* retmsg, int retSize, ErrorInfo error, void* userdata){ + _licenseProvider->updateLicenseWithParams(params, false, [](const char* retmsg, int retSize, EffectsSDK::ErrorInfo error, void* userdata){ BELicenseHelper* pThis = CFBridgingRelease(userdata); pThis.errorCode = error.errorCode; pThis.errorMsg = [[NSString alloc] initWithCString:error.errorMsg.c_str() encoding:NSUTF8StringEncoding]; @@ -129,15 +190,21 @@ - (const char *)updateLicensePath { _licenseFilePath = _licenseProvider->getParam("licensePath"); return _licenseFilePath.c_str(); -#else - return ""; -#endif } +#endif - (LICENSE_MODE_ENUM) licenseMode{ return _licenseMode; } +- (bool)checkLicense { + NSString *licenseName = [NSString stringWithFormat:@"/%s", LICENSE_NAME]; + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; + NSString* licensePath = [bundle pathForResource:OFFLIN_LICENSE_PATH ofType:OFFLIN_BUNDLE]; + licensePath = [licensePath stringByAppendingString:licenseName]; + return [self checkLicenseOK:[licensePath UTF8String]]; +} + - (bool)checkLicenseResult:(NSString*) msg { if (_errorCode != 0) { if ([_errorMsg length] > 0) { @@ -155,7 +222,7 @@ - (bool)checkLicenseResult:(NSString*) msg { } - (bool)checkLicenseOK:(const char *) filePath { -#if __has_include("bef_effect_ai_api.h") +#if __has_include() bef_effect_handle_t effectHandle = 0; int ret = bef_effect_ai_create(&effectHandle); // this property will be held by a singleton, and only got once, @@ -169,10 +236,23 @@ - (bool)checkLicenseOK:(const char *) filePath { { return false; } - +#endif return true; -#else - return false; +} + +- (bool)deleteCacheFile { +#if __has_include() + std::string filePath = _licenseProvider->getParam("licensePath"); + if (!filePath.empty()) { + NSString *path = [[NSString alloc] initWithUTF8String:filePath.c_str()]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL isDelete = [fileManager removeItemAtPath:path error:nil]; + if (!isDelete) { + return false; + } + } #endif + return true; } + @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.h deleted file mode 100644 index aa7f6aabe..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// BEPixelBufferInfo.h -// BeautifyExample -// -// Created by zhaoyongqiang on 2022/8/19. -// Copyright © 2022 Agora. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -// {zh} / 数据格式 {en} /Data format -typedef NS_ENUM(NSInteger, BEFormatType) { - // {zh} 未知格式 {en} Unknown format - BE_UNKNOW, - // 8bit R G B A - BE_RGBA, - // 8bit B G R A - BE_BGRA, - // video range, 8bit Y1 Y2 Y3 Y4... U1 V1... - BE_YUV420V, - // full range, 8bit Y1 Y2 Y3 Y4... U1 V1... - BE_YUV420F -}; - - -@interface BEPixelBufferInfo : NSObject - -@property (nonatomic, assign) BEFormatType format; -@property (nonatomic, assign) int width; -@property (nonatomic, assign) int height; -@property (nonatomic, assign) int bytesPerRow; - -@end - -NS_ASSUME_NONNULL_END diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.m deleted file mode 100644 index 1a1be1e9a..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEPixelBufferInfo.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// BEPixelBufferInfo.m -// BeautifyExample -// -// Created by zhaoyongqiang on 2022/8/19. -// Copyright © 2022 Agora. All rights reserved. -// - -#import "BEPixelBufferInfo.h" - -@implementation BEPixelBufferInfo - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.h deleted file mode 100644 index 4709a9cd9..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2019 Beijing Bytedance Network Technology Co., Ltd. -#import -#import -#import -#import "BEPixelBufferInfo.h" - -@interface BERender : NSObject - -/// use several cached texture -@property(nonatomic, assign) bool useCacheTexture; - -/// init output texture binding CVPixelBuffer -/// @param width with -/// @param height height -/// @param format format -- (BOOL)initOutputTextureAndCVPixelBufferWithWidth:(int)width height:(int)height format:(BEFormatType)format; - -/// get output CVPixelBuffer binding output texture -- (CVPixelBufferRef)getOutputPixelBuffer; - -/// transfor CVPixelBuffer to buffer -/// @param pixelBuffer CVPixelBuffer -/// @param outputFormat format of buffer -- (unsigned char *)transforCVPixelBufferToBuffer:(CVPixelBufferRef)pixelBuffer outputFormat:(BEFormatType)outputFormat; - -/// transfor CVPixelBuffer to texture -/// @param pixelBuffer original CVPixelBuffer -- (GLuint)transforCVPixelBufferToTexture:(CVPixelBufferRef)pixelBuffer; - -/// transfor texture to buffer -/// @param texture texture -/// @param width with of texture -/// @param height height of texture -/// @param outputFormat format of buffer -/// @param bytesPerRowPointer pointer of bytesPerRow, would be changed according to outputFormat -- (unsigned char *)transforTextureToBuffer:(GLuint)texture width:(int)width height:(int)height outputFormat:(BEFormatType)outputFormat bytesPerRowPointer:(int *)bytesPerRowPointer; - -/// transfor buffer to texture -/// @param buffer buffer -/// @param width with of buffer -/// @param height height of buffer -/// @param bytesPerRow bytesPerRow of buffer -/// @param inputFormat format of buffer -- (GLuint)transforBufferToTexture:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat; - -/// transfor buffer to CVPixelBuffer without CVPixelBuffer -/// @param buffer buffer -/// @param width with of buffer -/// @param height height of buffer -/// @param bytesPerRow bytesPerRow of buffer -/// @param inputFormat format of buffer -/// @param outputFormat format of CVPixelBuffer -- (CVPixelBufferRef)transforBufferToCVPixelBuffer:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat; - -/// transfor buffer to CVPixelBuffer with exsiting CVPixelBuffer -/// @param buffer buffer -/// @param pixelBuffer CVPixelBuffer -/// @param width wiht of buffer -/// @param height height of buffer -/// @param bytesPerRow bytesPerRow of buffer -/// @param inputFormat format of buffer -/// @param outputFormat format of CVPixelBuffer -- (CVPixelBufferRef)transforBufferToCVPixelBuffer:(unsigned char *)buffer pixelBuffer:(CVPixelBufferRef)pixelBuffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat; - -/// transfor buffer to UIImage -/// @param buffer buffer -/// @param width width of buffer -/// @param height height of buffer -/// @param bytesPerRow bytesPerRow of buffer -/// @param inputFormat format of buffer -- (UIImage *)transforBufferToUIImage:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat; - -/// generate output texture -/// @param width with of texture -/// @param height height of texture -- (GLuint)getOutputTexture:(int)width height:(int)height; - -/// get format of CVPixelBuffer -/// @param pixelBuffer CVPixelBuffer -- (BEFormatType)getCVPixelBufferFormat:(CVPixelBufferRef)pixelBuffer; - -/// get glFormat from BEFormatType -/// @param format BEFormatType -- (GLenum)getGlFormat:(BEFormatType)format; - -/// get CVPixelBuffer info -/// @param pixelBuffer pixelBuffer -- (BEPixelBufferInfo *)getCVPixelBufferInfo:(CVPixelBufferRef)pixelBuffer; -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.mm b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.mm deleted file mode 100644 index f4d10aa14..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERender.mm +++ /dev/null @@ -1,774 +0,0 @@ -// Copyright (C) 2019 Beijing Bytedance Network Technology Co., Ltd. -#import "BERender.h" - -#if __has_include("bef_effect_ai_api.h") -#import "bef_effect_ai_yuv_process.h" -#endif - -#import "BERenderHelper.h" - -static const int TEXTURE_CACHE_NUM = 3; - -@interface BERender () { - BERenderHelper *_renderHelper; - GLuint _frameBuffer; - GLuint _textureInputs[TEXTURE_CACHE_NUM]; - GLuint _textureOutputs[TEXTURE_CACHE_NUM]; - int _textureIndex; - - CIContext *_ciContext; - CVPixelBufferRef _cachedPixelBuffer; - unsigned char *_buffOutPointer; - unsigned int _buffOutPointerLength; - unsigned char *_yuvBufferOutPointer; - unsigned int _yuvBufferOutPointerLength; - - // for CVPixelBuffer/Texture binding - CVOpenGLESTextureCacheRef _cvTextureCaches[TEXTURE_CACHE_NUM]; - CVOpenGLESTextureRef _cvTextureInputs[TEXTURE_CACHE_NUM]; - CVOpenGLESTextureRef _cvTextureOutputs[TEXTURE_CACHE_NUM]; - CVPixelBufferRef _outputPixelBuffers[TEXTURE_CACHE_NUM]; -} - -@property (nonatomic, readwrite) NSString *triggerAction; -@property (nonatomic, assign) BOOL effectEnable; - -@property (nonatomic, assign) GLuint currentTexture; -@end - -@implementation BERender - -static NSString* LICENSE_PATH; - -- (instancetype)init { - self = [super init]; - if (self){ - _renderHelper = [[BERenderHelper alloc] init]; - glGenFramebuffers(1, &_frameBuffer); - - _cachedPixelBuffer = NULL; - _buffOutPointer = NULL; - _textureIndex = 0; - _useCacheTexture = NO; - } - return self; -} - -- (void)dealloc { - free(_buffOutPointer); - free(_yuvBufferOutPointer); - if (_cachedPixelBuffer) { - CVPixelBufferRelease(_cachedPixelBuffer); - _cachedPixelBuffer = NULL; - } - for (int i = 0; i < TEXTURE_CACHE_NUM; i++) { - if (_cvTextureInputs[i] != NULL) { - CFRelease(_cvTextureInputs[i]); - _cvTextureInputs[i] = NULL; - } - - if (_cvTextureCaches[i] != NULL) { - CFRelease(_cvTextureCaches[i]); - _cvTextureCaches[i] = NULL; - } - - if (_outputPixelBuffers[i]) { - CVPixelBufferRelease(_outputPixelBuffers[i]); - _outputPixelBuffers[i] = NULL; - } - - if (_cvTextureOutputs[i]) { - CFRelease(_cvTextureOutputs[i]); - _cvTextureOutputs[i] = NULL; - } - } - glDeleteFramebuffers(1, &_frameBuffer); - glDeleteTextures(TEXTURE_CACHE_NUM, _textureInputs); - glDeleteTextures(TEXTURE_CACHE_NUM, _textureOutputs); -} - -- (unsigned char *)transforCVPixelBufferToBuffer:(CVPixelBufferRef)pixelBuffer outputFormat:(BEFormatType)outputFormat { - BEFormatType inputFormat = [self getCVPixelBufferFormat:pixelBuffer]; - if (inputFormat == BE_UNKNOW) { - return nil; - } - - unsigned char *result = nil; - CVPixelBufferLockBaseAddress(pixelBuffer, 0); - if ([self be_isYuv420:inputFormat]) { - if ([self be_isRgba:outputFormat]) { - result = [self be_CVPixelBufferYuvToRgba:pixelBuffer inputFormat:inputFormat outputFormat:outputFormat]; - } else { - [self be_notSupportNow]; - } - } else if ([self be_isRgba:inputFormat]) { - BEPixelBufferInfo *info = [self getCVPixelBufferInfo:pixelBuffer]; - if ([self be_isRgba:outputFormat]) { - result = [self be_transforRgbaToRgba:(unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer) inputFormat:inputFormat outputFormat:outputFormat width:info.width height:info.height bytesPerRow:info.bytesPerRow]; - } else if ([self be_isYuv420:outputFormat]) { - result = [self be_transforRgbaToYuv:(unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer) width:info.width height:info.height bytesPerRow:info.bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - } - else { - [self be_notSupportNow]; - } - } else { - [self be_notSupportNow]; - } - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - return result; -} - -- (CVPixelBufferRef)getOutputPixelBuffer { - if (_cvTextureCaches[_textureIndex] == NULL || _cvTextureOutputs[_textureIndex] == NULL || _outputPixelBuffers[_textureIndex] == NULL) { - return NULL; - } - CVOpenGLESTextureCacheFlush(_cvTextureCaches[_textureIndex], 0); - return _outputPixelBuffers[_textureIndex]; -} - -- (BOOL)initOutputTextureAndCVPixelBufferWithWidth:(int)width height:(int)height format:(BEFormatType)format { - if (_outputPixelBuffers[_textureIndex] != NULL) { - BEPixelBufferInfo *info = [self getCVPixelBufferInfo:_outputPixelBuffers[_textureIndex]]; - if (info.width == width && info.height == height && info.format == format) { - return YES; - } else { - CVPixelBufferRelease(_outputPixelBuffers[_textureIndex]); - _outputPixelBuffers[_textureIndex] = NULL; - } - } - - if (![self be_isRgba:format]) { - [self be_notSupportNow]; - return NO; - } - - // create texture cache - if (!_cvTextureCaches[_textureIndex]) { - EAGLContext *glContext = [EAGLContext currentContext]; - CVReturn ret = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, glContext, NULL, &_cvTextureCaches[_textureIndex]); - if (ret != kCVReturnSuccess) { - NSLog(@"create texture cache error"); - return NO; - } - } - - if (_cvTextureOutputs[_textureIndex]) { - CFRelease(_cvTextureOutputs[_textureIndex]); - _cvTextureOutputs[_textureIndex] = NULL; - } - - CVPixelBufferRef pixelBuffer = [self be_createCVPixelBufferWithWidth:width height:height format:format]; - if (pixelBuffer == NULL) { - NSLog(@"create pxiel buffer error"); - return NO; - } - _outputPixelBuffers[_textureIndex] = pixelBuffer; - CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _cvTextureCaches[_textureIndex], pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width, height, [self getGlFormat:format], GL_UNSIGNED_BYTE, 0, &_cvTextureOutputs[_textureIndex]); - if (ret != kCVReturnSuccess) { - NSLog(@"create texture from image error"); - return NO; - } - - _textureOutputs[_textureIndex] = CVOpenGLESTextureGetName(_cvTextureOutputs[_textureIndex]); - if (!glIsTexture(_textureOutputs[_textureIndex])) { - NSLog(@"get glTexture error"); - return NO; - } - glBindTexture(CVOpenGLESTextureGetTarget(_cvTextureOutputs[_textureIndex]), _textureOutputs[_textureIndex]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - return YES; -} - -- (GLuint)transforCVPixelBufferToTexture:(CVPixelBufferRef)pixelBuffer { - BEPixelBufferInfo *info = [self getCVPixelBufferInfo:pixelBuffer]; - if (![self be_isRgba:info.format]) { - [self be_notSupportNow]; - return -1; - } - - if (_useCacheTexture) { - _textureIndex = (_textureIndex + 1) % TEXTURE_CACHE_NUM; - } else { - _textureIndex = 0; - } - - if (!_cvTextureCaches[_textureIndex]) { - EAGLContext *glContext = [EAGLContext currentContext]; - CVReturn ret = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, glContext, NULL, &_cvTextureCaches[_textureIndex]); - if (ret != kCVReturnSuccess) { - NSLog(@"create texture cache error"); - return NO; - } - } - if (_cvTextureInputs[_textureIndex]) { - CFRelease(_cvTextureInputs[_textureIndex]); - _cvTextureInputs[_textureIndex] = NULL; - } - - CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, - _cvTextureCaches[_textureIndex], - pixelBuffer, - NULL, - GL_TEXTURE_2D, - GL_RGBA, - info.width, - info.height, - [self getGlFormat:info.format], - GL_UNSIGNED_BYTE, - 0, - &_cvTextureInputs[_textureIndex]); - if (!_cvTextureInputs[_textureIndex] || ret != kCVReturnSuccess) { - return -1; - } - _textureInputs[_textureIndex] = CVOpenGLESTextureGetName(_cvTextureInputs[_textureIndex]); - glBindTexture(GL_TEXTURE_2D , _textureInputs[_textureIndex]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - return _textureInputs[_textureIndex]; -} - -- (unsigned char *)transforTextureToBuffer:(GLuint)texture width:(int)width height:(int)height outputFormat:(BEFormatType)outputFormat bytesPerRowPointer:(int *)bytesPerRowPointer { - GLenum glFormat = [self getGlFormat:outputFormat]; - unsigned char *buffer = [self be_transforTextureToRgbaBuffer:texture width:width height:height format:glFormat]; - if ([self be_isRgba:outputFormat]) { - *bytesPerRowPointer = width * 4; - return buffer; - } - if ([self be_isYuv420:outputFormat]) { - *bytesPerRowPointer = width; - return [self be_transforRgbaToYuv:buffer width:width height:height bytesPerRow:width * 4 inputFormat:BE_RGBA outputFormat:outputFormat]; - } - - [self be_notSupportNow]; - return nil; -} - -- (GLuint)transforBufferToTexture:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat { - if (_useCacheTexture) { - _textureIndex = (_textureIndex + 1) % TEXTURE_CACHE_NUM; - } else { - _useCacheTexture = 0; - } - -// NSLog(@"use texture index: %d", _textureIndex); - unsigned char *rgbaBuffer = nullptr; - GLenum glFormat = GL_RGBA; - if ([self be_isRgba:inputFormat]) { - rgbaBuffer = buffer; - glFormat = [self getGlFormat:inputFormat]; - } else if ([self be_isYuv420:inputFormat]) { - rgbaBuffer = [self be_transforYuvToRgba:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:BE_RGBA]; - glFormat = GL_RGBA; - } else { - [self be_notSupportNow]; - } - return [self be_transforRgbaBufferToTexture:rgbaBuffer width:width height:height format:glFormat]; -} - -- (CVPixelBufferRef)transforBufferToCVPixelBuffer:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - if (_cachedPixelBuffer != NULL) { - BEPixelBufferInfo *info = [self getCVPixelBufferInfo:_cachedPixelBuffer]; - if (info.width != width || info.height != height || info.format != outputFormat) { - CVPixelBufferRelease(_cachedPixelBuffer); - _cachedPixelBuffer = NULL; - } - } - if (_cachedPixelBuffer == NULL) { - _cachedPixelBuffer = [self be_createCVPixelBufferWithWidth:width height:height format:outputFormat]; - } - CVPixelBufferRef pixelBuffer = _cachedPixelBuffer; - if (!pixelBuffer) { - return nil; - } - return [self transforBufferToCVPixelBuffer:buffer pixelBuffer:pixelBuffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; -} - -- (CVPixelBufferRef)transforBufferToCVPixelBuffer:(unsigned char *)buffer pixelBuffer:(CVPixelBufferRef)pixelBuffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - CVPixelBufferLockBaseAddress(pixelBuffer, 0); - if ([self be_isRgba:inputFormat]) { - [self be_transforRgbaToCVPixelBuffer:pixelBuffer buffer:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - } else if ([self be_isYuv420:inputFormat]) { - [self be_transforYuvToCVPixelBuffer:pixelBuffer buffer:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - } else { - [self be_notSupportNow]; - } - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - return pixelBuffer; -} - -- (UIImage *)transforBufferToUIImage:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat { - if ([self be_isRgba:inputFormat]) { - return [self be_transforRgbaBufferToUIImage:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat]; - } else if ([self be_isYuv420:inputFormat]) { - unsigned char *rgbaBuffer = [self be_transforYuvToRgba:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:BE_RGBA]; - bytesPerRow = width * 4; - return [self be_transforRgbaBufferToUIImage:rgbaBuffer width:width height:height bytesPerRow:bytesPerRow inputFormat:BE_RGBA]; - } - [self be_notSupportNow]; - return nil; -} - -- (GLuint)be_transforRgbaBufferToTexture:(unsigned char *)buffer width:(int)width height:(int)height format:(GLenum)format { - GLuint textureInput = _textureInputs[_textureIndex]; - - if (glIsTexture(textureInput)) { - glBindTexture(GL_TEXTURE_2D, textureInput); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, GL_UNSIGNED_BYTE, buffer); - glBindTexture(GL_TEXTURE_2D, 0); - return textureInput; - } - - NSLog(@"gen input texture"); - glGenTextures(1, &textureInput); - glBindTexture(GL_TEXTURE_2D, textureInput); - - // 加载相机数据到纹理 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, buffer); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - _textureInputs[_textureIndex] = textureInput; - return textureInput; -} - -- (GLuint)getOutputTexture:(int)width height:(int)height { - GLuint textureOutput = _textureOutputs[_textureIndex]; - - if (glIsTexture(textureOutput)) { - return textureOutput; - } - - NSLog(@"gen output texture"); - glGenTextures(1, &textureOutput); - glBindTexture(GL_TEXTURE_2D, textureOutput); - - // 为输出纹理开辟空间 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - _textureOutputs[_textureIndex] = textureOutput; - return textureOutput; -} - -- (BEFormatType)getCVPixelBufferFormat:(CVPixelBufferRef)pixelBuffer { - OSType type = CVPixelBufferGetPixelFormatType(pixelBuffer); - switch (type) { - case kCVPixelFormatType_32BGRA: - return BE_BGRA; - case kCVPixelFormatType_32RGBA: - return BE_RGBA; - case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: - return BE_YUV420F; - case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: - return BE_YUV420V; - default: - return BE_UNKNOW; - break; - } -} - -- (OSType)getOsType:(BEFormatType)format { - switch (format) { - case BE_RGBA: - return kCVPixelFormatType_32RGBA; - case BE_BGRA: - return kCVPixelFormatType_32BGRA; - case BE_YUV420F: - return kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; - case BE_YUV420V: - return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; - default: - return kCVPixelFormatType_32BGRA; - break; - } -} - -- (GLenum)getGlFormat:(BEFormatType)format { - switch (format) { - case BE_RGBA: - return GL_RGBA; - case BE_BGRA: - return GL_BGRA; - default: - return GL_RGBA; - break; - } -} - -- (BEPixelBufferInfo *)getCVPixelBufferInfo:(CVPixelBufferRef)pixelBuffer { - int bytesPerRow = (int) CVPixelBufferGetBytesPerRow(pixelBuffer); - int width = (int) CVPixelBufferGetWidth(pixelBuffer); - int height = (int) CVPixelBufferGetHeight(pixelBuffer); - size_t iTop, iBottom, iLeft, iRight; - CVPixelBufferGetExtendedPixels(pixelBuffer, &iLeft, &iRight, &iTop, &iBottom); - width = width + (int) iLeft + (int) iRight; - height = height + (int) iTop + (int) iBottom; - bytesPerRow = bytesPerRow + (int) iLeft + (int) iRight; - - BEPixelBufferInfo *info = [BEPixelBufferInfo new]; - info.format = [self getCVPixelBufferFormat:pixelBuffer]; - info.width = width; - info.height = height; - info.bytesPerRow = bytesPerRow; - return info; -} - -#pragma mark - setter -- (void)setUseCacheTexture:(bool)useCacheTexture { - _useCacheTexture = useCacheTexture; - if (!useCacheTexture) { - _textureIndex = 0; - } -} - -#pragma mark - private - -- (unsigned char *)be_mallocBufferWithWidth:(int)width height:(int)height { - if (_buffOutPointer == NULL || _buffOutPointerLength != width * height) { - if (_buffOutPointer != NULL) { - free(_buffOutPointer); - } - _buffOutPointer = (unsigned char *)malloc(width * height * 4 * sizeof(unsigned char)); - _buffOutPointerLength = width * height; - NSLog(@"malloc size %d", width * height * 4); - } - return _buffOutPointer; -} - -- (unsigned char *)be_mallocYuvBuffer:(int)size { - if (_yuvBufferOutPointer == NULL || _yuvBufferOutPointerLength != size) { - if (_yuvBufferOutPointer != NULL) { - free(_yuvBufferOutPointer); - } - _yuvBufferOutPointer = (unsigned char *)malloc(size * sizeof(unsigned char)); - _yuvBufferOutPointerLength = size; - NSLog(@"malloc size %d", size); - } - return _yuvBufferOutPointer; -} - -- (CVPixelBufferRef)be_createCVPixelBufferWithWidth:(int)width height:(int)height format:(BEFormatType)format { - CVPixelBufferRef pixelBuffer; - const void *keys[] = { - kCVPixelBufferOpenGLCompatibilityKey, - kCVPixelBufferIOSurfacePropertiesKey - }; - const void *values[] = { - (__bridge const void *)([NSNumber numberWithBool:YES]), - (__bridge const void *)([NSDictionary dictionary]) - }; - - CFDictionaryRef optionsDicitionary = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, NULL, NULL); - - CVReturn res = CVPixelBufferCreate(kCFAllocatorDefault, width, height, [self getOsType:format], optionsDicitionary, &pixelBuffer); - CFRelease(optionsDicitionary); - if (res != kCVReturnSuccess) { - NSLog(@"CVPixelBufferCreate error: %d", res); - } - return pixelBuffer; -} - -- (unsigned char *)be_CVPixelBufferYuvToRgba:(CVPixelBufferRef)pixelBuffer inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - if (([self be_isYuv420:inputFormat]) && ([self be_isRgba:outputFormat])) { - unsigned int width = (unsigned int)CVPixelBufferGetWidth(pixelBuffer); - unsigned int height = (unsigned int)CVPixelBufferGetHeight(pixelBuffer); - - uint8_t *yBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - unsigned int yPitch = (unsigned int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - uint8_t *uvBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - unsigned int uvPitch = (unsigned int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); - - return [self be_transforYuvToRgba:yBuffer uvBuffer:uvBuffer width:width height:height yBytesPerRow:yPitch uvBytesPerRow:uvPitch inputFormat:inputFormat outputFormat:outputFormat]; - } else { - [self be_notSupportNow]; - } - return nil; -} - -- (unsigned char *)be_transforRgbaToRgba:(unsigned char *)buffer inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow { - int realBytesPerRow = width * 4; - BOOL aligned = bytesPerRow != realBytesPerRow; - if (inputFormat == outputFormat && !aligned) { - return buffer; - } - if ([self be_isRgba:inputFormat] && [self be_isRgba:outputFormat]) { - unsigned char *result = [self be_mallocBufferWithWidth:width height:height]; - if (aligned) { - [self be_copyBufferFrom:buffer to:result bytesPerRowFrom:bytesPerRow bytesPerRowTo:realBytesPerRow height:height]; - } else { - memcpy(result, buffer, width * height * 4); - } - if (inputFormat != outputFormat) { - for (int i = 0; i < bytesPerRow * height; i += 4) { - int16_t r = result[i]; - int16_t b = result[i+2]; - result[i] = b; - result[i+2] = r; - } - } - return result; - } else { - [self be_notSupportNow]; - } - return nil; -} - -- (unsigned char *)be_transforTextureToRgbaBuffer:(GLuint)texture width:(int)width height:(int)height format:(GLenum)format { - unsigned char *buffer = [self be_mallocBufferWithWidth:width height:height]; - [_renderHelper textureToImage:texture withBuffer:buffer Width:width height:height format:format rotation:0]; - return buffer; -} - -- (unsigned char *)be_transforRgbaToYuv:(unsigned char *)rgbaBuffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - if ([self be_isRgba:inputFormat] && [self be_isYuv420:outputFormat]) { - unsigned char *yBuffer = [self be_mallocYuvBuffer:width * height * 3/2]; - if (inputFormat == BE_RGBA) { -#if __has_include("bef_effect_ai_api.h") - cvt_rgba2yuv(rgbaBuffer, yBuffer, BEF_AI_PIX_FMT_NV12, width, height); -#endif - return yBuffer; - } - - unsigned char *uvBuffer = &yBuffer[width * height]; - - for (int j = 0; j < height; j++) { - unsigned char *rgbaLine = &rgbaBuffer[bytesPerRow * j]; - unsigned char *yBufferLine = &yBuffer[width * j]; - unsigned char *uvBufferLine = &uvBuffer[width * (j >> 1)]; - for (int i = 0; i < width; i++) { - int p = i * 4; - int16_t r = rgbaLine[p + 0]; - int16_t g = rgbaLine[p + 1]; - int16_t b = rgbaLine[p + 2]; - - if (inputFormat == BE_BGRA) { - int16_t tmp = r; - r = b; - b = tmp; - } - - yBufferLine[i] = (int16_t)(0.299 * r + 0.587 * g + 0.114 * b); - if (outputFormat == BE_YUV420V) { - yBufferLine[i] = yBufferLine[i] * 0.875 + 16; - } - if ((j & 1) == 0 && (i & 1) == 0) { - uvBufferLine[i & ~1] = (int16_t)(-0.169 * r - 0.331 * g + 0.5 * b + 128); - uvBufferLine[i | 1] = (int16_t)(0.5 * r - 0.419 * g - 0.081 * b + 128); - } - } - } - return yBuffer; - } - - [self be_notSupportNow]; - return nil; -} - -- (unsigned char *)be_transforYuvToRgba:(unsigned char *)yBuffer uvBuffer:(unsigned char *)uvBuffer width:(int)width height:(int)height yBytesPerRow:(int)yBytesPerRow uvBytesPerRow:(int)uvBytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - if ([self be_isYuv420:inputFormat] && [self be_isRgba:outputFormat]) { - int bytesPerPixel = 4; - unsigned char *rgbaOut = [self be_mallocBufferWithWidth:width height:height]; - - unsigned int yPitch = yBytesPerRow; - unsigned int uvPitch = uvBytesPerRow; - - for (int j = 0; j < height; j++) { - uint8_t *rgbaBufferLine = &rgbaOut[j * width * bytesPerPixel]; - uint8_t *yBufferLine = &yBuffer[j * yPitch]; - uint8_t *uvBufferLine = &uvBuffer[(j >> 1) * uvPitch]; - - for (int i = 0; i < width; i++) { - int16_t y = yBufferLine[i]; - // transfor 420f to 420v - if (inputFormat == BE_YUV420F) { - y = y * 0.875 + 16; - } - int16_t u = uvBufferLine[i & ~1] - 128; - int16_t v = uvBufferLine[i | 1] - 128; - - uint8_t *rgba = &rgbaBufferLine[i * bytesPerPixel]; - int16_t r = (int16_t)roundf( y + v * 1.4 ); - int16_t g = (int16_t)roundf( y + u * -0.343 + v * -0.711 ); - int16_t b = (int16_t)roundf( y + u * 1.765); - - if (outputFormat == BE_BGRA) { - int16_t tmp = r; - r = b; - b = tmp; - } - - rgba[0] = r; - rgba[1] = g; - rgba[2] = b; - rgba[3] = 0xff; - } - } - return rgbaOut; - } - [self be_notSupportNow]; - return nil; -} - -- (unsigned char *)be_transforYuvToRgba:(unsigned char *)yuvBuffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - if ([self be_isYuv420:inputFormat] && [self be_isRgba:outputFormat]) { - if (outputFormat == BE_RGBA) { - unsigned char *rgbaBuffer = [self be_mallocBufferWithWidth:width height:height]; -#if __has_include("bef_effect_ai_api.h") - cvt_yuv2rgba(yuvBuffer, rgbaBuffer, BEF_AI_PIX_FMT_NV12, width, height, width, height, BEF_AI_CLOCKWISE_ROTATE_0, false); -#endif - return rgbaBuffer; - } - - unsigned char *yBuffer = yuvBuffer; - unsigned char *uvBuffer = yuvBuffer + bytesPerRow * height; - return [self be_transforYuvToRgba:yBuffer uvBuffer:uvBuffer width:width height:height yBytesPerRow:bytesPerRow uvBytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - } - [self be_notSupportNow]; - return nil; -} - -- (void)be_transforRgbaToCVPixelBuffer:(CVPixelBufferRef)pixelBuffer buffer:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - int pixelBufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer); - int pixelBufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer); - if (width != pixelBufferWidth || height != pixelBufferHeight) { - NSLog(@"wrong state: width %d height: %d pixelBufferWidth %d pixelBufferHeight %d", width, height, pixelBufferWidth, pixelBufferHeight); - } - if ([self be_isRgba:outputFormat]) { - int pixelBufferBytesPerRow = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); - unsigned char *baseAddress = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer); - buffer = [self be_transforRgbaToRgba:buffer inputFormat:inputFormat outputFormat:outputFormat width:width height:height bytesPerRow:bytesPerRow]; - if (pixelBufferBytesPerRow != bytesPerRow) { - unsigned char *from = buffer; - unsigned char *to = baseAddress; - for (int i = 0; i < height; i++) { - memcpy(to, from, bytesPerRow); - from += bytesPerRow; - to += pixelBufferBytesPerRow; - } - } else { - memcpy(baseAddress, buffer, height * bytesPerRow); - } - } else if ([self be_isYuv420:outputFormat]) { - unsigned char *yuvBuffer = [self be_transforRgbaToYuv:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - bytesPerRow = width; - unsigned char *yBaseAddress = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - int yBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - [self be_copyBufferFrom:yuvBuffer to:yBaseAddress bytesPerRowFrom:bytesPerRow bytesPerRowTo:yBytesPerRow height:height]; - unsigned char *uvBaseAddress = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - int uvBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); - [self be_copyBufferFrom:yuvBuffer + bytesPerRow * height to:uvBaseAddress bytesPerRowFrom:bytesPerRow bytesPerRowTo:uvBytesPerRow height:height/2]; - - } else { - [self be_notSupportNow]; - } -} - -- (void)be_transforYuvToCVPixelBuffer:(CVPixelBufferRef)pixelBuffer buffer:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat outputFormat:(BEFormatType)outputFormat { - int pixelBufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer); - int pixelBufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer); - if (width != pixelBufferWidth || height != pixelBufferHeight) { - NSLog(@"wrong state: width %d height: %d pixelBufferWidth %d pixelBufferHeight %d", width, height, pixelBufferWidth, pixelBufferHeight); - } - if ([self be_isYuv420:inputFormat] && [self be_isRgba:outputFormat]) { - unsigned char *rgbaBuffer = [self be_transforYuvToRgba:buffer width:width height:height bytesPerRow:bytesPerRow inputFormat:inputFormat outputFormat:outputFormat]; - unsigned char *baseAddress = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer); - int pixelBufferBytesPerRow = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); - if (pixelBufferBytesPerRow != width * 4) { - [self be_copyBufferFrom:rgbaBuffer to:baseAddress bytesPerRowFrom:width * 4 bytesPerRowTo:pixelBufferBytesPerRow height:height]; - } else { - memcpy(baseAddress, rgbaBuffer, width * 4 * height); - } - - } else if ([self be_isYuv420:inputFormat] && [self be_isYuv420:outputFormat]) { - unsigned char *yBuffer = buffer; - unsigned char *uvBuffer = buffer + bytesPerRow * height; - unsigned char *yPixelBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - int yPixelBufferBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - unsigned char *uvPixelBuffer = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - int uvPixelBufferBytesPerRow = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); - [self be_copyBufferFrom:yBuffer to:yPixelBuffer bytesPerRowFrom:bytesPerRow bytesPerRowTo:yPixelBufferBytesPerRow height:height]; - [self be_copyBufferFrom:uvBuffer to:uvPixelBuffer bytesPerRowFrom:bytesPerRow bytesPerRowTo:uvPixelBufferBytesPerRow height:height/2]; - } -} - -- (UIImage *)be_transforRgbaBufferToUIImage:(unsigned char *)buffer width:(int)width height:(int)height bytesPerRow:(int)bytesPerRow inputFormat:(BEFormatType)inputFormat { - if ([self be_isRgba:inputFormat]) { - CGDataProviderRef provider = CGDataProviderCreateWithData( - NULL, - buffer, - height * bytesPerRow, - NULL); - - CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); - CGBitmapInfo bitmapInfo; - if (inputFormat == BE_RGBA) { - bitmapInfo = kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast; - } else { - bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst; - } - CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; - - CGImageRef imageRef = CGImageCreate(width, - height, - 8, - 4 * 8, - bytesPerRow, - colorSpaceRef, - bitmapInfo, - provider, - NULL, - NO, - renderingIntent); - - UIImage *uiImage = [UIImage imageWithCGImage:imageRef]; - CGDataProviderRelease(provider); - CGColorSpaceRelease(colorSpaceRef); - CGImageRelease(imageRef); - return uiImage; - } - [self be_notSupportNow]; - return nil; -} - -- (void)be_notSupportNow { - NSLog(@"not support now"); -} - -- (BOOL)be_isRgba:(BEFormatType)format { - return format == BE_RGBA || format == BE_BGRA; -} - -- (BOOL)be_isYuv420:(BEFormatType)format { - return format == BE_YUV420F || format == BE_YUV420V; -} - -- (void)be_copyBufferFrom:(unsigned char *)from to:(unsigned char *)to bytesPerRowFrom:(int)bytesPerRowFrom bytesPerRowTo:(int)bytesPserRowTo height:(int)height { - int copyLength = bytesPserRowTo > bytesPerRowFrom ? bytesPerRowFrom : bytesPserRowTo; - for (int i = 0; i < height; i++) { - memcpy(to, from, copyLength); - from += bytesPerRowFrom; - to += bytesPserRowTo; - } -} - -- (BERenderHelper*)renderHelper { - if (!_renderHelper){ - _renderHelper = [[BERenderHelper alloc] init]; - } - return _renderHelper; -} - -@end - diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.h deleted file mode 100644 index d383a0eee..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019 Beijing Bytedance Network Technology Co., Ltd. - -#import -#import - -@interface BERenderHelper : NSObject - -/// transfor texture to buffer -/// @param texture texture -/// @param buffer buffer -/// @param rWidth width of buffer -/// @param rHeight height of buffer -- (void)textureToImage:(GLuint)texture withBuffer:(unsigned char*)buffer Width:(int)rWidth height:(int)rHeight; - -/// transfor texture to buffer -/// @param texture texture -/// @param buffer buffer -/// @param rWidth width of buffer -/// @param rHeight height of buffer -/// @param format pixel format, such as GL_RGBA,GL_BGRA... -- (void)textureToImage:(GLuint)texture withBuffer:(unsigned char*)buffer Width:(int)rWidth height:(int)rHeight format:(GLenum)format; - -/// transfor texture to buffer -/// @param texture texture -/// @param buffer buffer -/// @param rWidth width of buffer -/// @param rHeight height of buffer -/// @param format pixel format, such as GL_RGBA,GL_BGRA... -/// @param rotation rotation of buffer, 0: 0˚, 1: 90˚, 2: 180˚, 3: 270˚ -- (void)textureToImage:(GLuint)texture withBuffer:(unsigned char*)buffer Width:(int)rWidth height:(int)rHeight format:(GLenum)format rotation:(int)rotation; -+ (int) compileShader:(NSString *)shaderString withType:(GLenum)shaderType; -@end - diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.m deleted file mode 100644 index 2ea6aee7f..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BERenderHelper.m +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2019 Beijing Bytedance Network Technology Co., Ltd. -#import "BERenderHelper.h" - -#define TTF_STRINGIZE(x) #x -#define TTF_STRINGIZE2(x) TTF_STRINGIZE(x) -#define TTF_SHADER_STRING(text) @ TTF_STRINGIZE2(text) - -static NSString *const CAMREA_RESIZE_VERTEX = TTF_SHADER_STRING -( -attribute vec4 position; -attribute vec4 inputTextureCoordinate; -varying vec2 textureCoordinate; -void main(){ - textureCoordinate = inputTextureCoordinate.xy; - gl_Position = position; -} -); - -static NSString *const CAMREA_RESIZE_FRAGMENT = TTF_SHADER_STRING -( - precision mediump float; - varying highp vec2 textureCoordinate; - uniform sampler2D inputImageTexture; - void main() - { - gl_FragColor = texture2D(inputImageTexture, textureCoordinate); - } -); - -@interface BERenderHelper (){ - GLuint _resizeProgram; - GLuint _resizeLocation; - GLuint _resizeInputImageTexture; - GLuint _resizeTextureCoordinate; - GLuint _resizeTexture; - - //为了resize buffer - GLuint _frameBuffer; -} - -@end - -static float TEXTURE_RORATION_0[] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,}; -static float TEXTURE_ROTATED_90[] = {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,}; -static float TEXTURE_ROTATED_180[] = {1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f,}; -static float TEXTURE_ROTATED_270[] = {1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,}; -static float CUBE[] = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,}; - -@implementation BERenderHelper - -- (instancetype) init -{ - self = [super init]; - if (self) { - [self loadResizeShader]; - glGenFramebuffers(1, &_frameBuffer); - glGenTextures(1, &_resizeTexture); - } - - return self; -} - --(void)dealloc{ - glDeleteFramebuffers(1, &_frameBuffer); - glDeleteTextures(1, &_resizeTexture); -} - -+ (int) compileShader:(NSString *)shaderString withType:(GLenum)shaderType { - GLuint shaderHandle = glCreateShader(shaderType); - const char * shaderStringUTF8 = [shaderString UTF8String]; - - int shaderStringLength = (int) [shaderString length]; - glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength); - glCompileShader(shaderHandle); - GLint success; - glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &success); - - if (success == GL_FALSE){ - NSLog(@"BErenderHelper compiler shader error: %s", shaderStringUTF8); - return 0; - } - return shaderHandle; -} - -/* - * load resize shader - */ -- (void) loadResizeShader{ - GLuint vertexShader = [BERenderHelper compileShader:CAMREA_RESIZE_VERTEX withType:GL_VERTEX_SHADER]; - GLuint fragmentShader = [BERenderHelper compileShader:CAMREA_RESIZE_FRAGMENT withType:GL_FRAGMENT_SHADER]; - - _resizeProgram = glCreateProgram(); - glAttachShader(_resizeProgram, vertexShader); - glAttachShader(_resizeProgram, fragmentShader); - glLinkProgram(_resizeProgram); - - GLint linkSuccess; - glGetProgramiv(_resizeProgram, GL_LINK_STATUS, &linkSuccess); - if (linkSuccess == GL_FALSE){ - NSLog(@"BERenderHelper link shader error"); - } - - glUseProgram(_resizeProgram); - _resizeLocation = glGetAttribLocation(_resizeProgram, "position"); - _resizeTextureCoordinate = glGetAttribLocation(_resizeProgram, "inputTextureCoordinate"); - _resizeInputImageTexture = glGetUniformLocation(_resizeProgram, "inputImageTexture"); - - if (vertexShader) - glDeleteShader(vertexShader); - - if (fragmentShader) - glDeleteShader(fragmentShader); -} - -/* - * transfer a image th buffer - */ -- (void)textureToImage:(GLuint)texture withBuffer:(unsigned char*)buffer Width:(int)rWidth height:(int)rHeight { - [self textureToImage:texture withBuffer:buffer Width:rWidth height:rHeight format:GL_RGBA]; -} - -- (void) textureToImage:(GLuint)texture withBuffer:(unsigned char*)buffer Width:(int)rWidth height:(int)rHeight format:(GLenum)format { - [self textureToImage:texture withBuffer:buffer Width:rWidth height:rHeight format:format rotation:0]; -} - -- (void)textureToImage:(GLuint)texture withBuffer:(unsigned char *)buffer Width:(int)rWidth height:(int)rHeight format:(GLenum)format rotation:(int)rotation { - glBindTexture(GL_TEXTURE_2D, _resizeTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rWidth, rHeight, 0, format, GL_UNSIGNED_BYTE, NULL); - - glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _resizeTexture, 0); - - glUseProgram(_resizeProgram); - glVertexAttribPointer(_resizeLocation, 2, GL_FLOAT, false, 0, CUBE); - glEnableVertexAttribArray(_resizeLocation); - float *rota = TEXTURE_RORATION_0; - if (rotation == 1) { - rota = TEXTURE_ROTATED_90; - } else if (rotation == 2) { - rota = TEXTURE_ROTATED_180; - } else if (rotation == 3) { - rota = TEXTURE_ROTATED_270; - } - glVertexAttribPointer(_resizeTextureCoordinate, 2, GL_FLOAT, false, 0, rota); - glEnableVertexAttribArray(_resizeTextureCoordinate); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(_resizeInputImageTexture, 0); - glViewport(0, 0, rWidth, rHeight); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glDisableVertexAttribArray(_resizeLocation); - glDisableVertexAttribArray(_resizeTextureCoordinate); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - - glReadPixels(0, 0, rWidth, rHeight, format, GL_UNSIGNED_BYTE, buffer); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - [self checkGLError]; -} - -- (void)checkGLError { - int error = glGetError(); - if (error != GL_NO_ERROR) { - NSLog(@"checkGLError %d", error); - @throw [NSException exceptionWithName:@"GLError" reason:@"error " userInfo:nil]; - } -} - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.h deleted file mode 100644 index a0a06b284..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// BEResourceHelper.h -// BytedEffects -// -// Created by QunZhang on 2019/10/22. -// Copyright © 2019 ailab. All rights reserved. -// - -#import - -@protocol BEResourceHelperDelegate - -@optional - -/// path of license dir -- (NSString *)licenseDirPath; - -/// path of composer node -- (NSString *)composerNodeDirPath; - -/// path of filter dir -- (NSString *)filterDirPath; - -/// path of sticker dir -- (NSString *)stickerDirPath; - -/// path of composer -- (NSString *)composerDirPath; - -/// path of model dir -- (NSString *)modelDirPath; - -/// license name -- (NSString *)licenseName; - -@end - -@interface BEResourceHelper : NSObject - -@property (nonatomic, weak) id delegate; - -- (NSString *)licensePath; -- (NSString *)composerNodePath:(NSString *)nodeName; -- (NSString *)filterPath:(NSString *)filterName; -- (NSString *)stickerPath:(NSString *)stickerName; -- (NSString *)modelPath:(NSString *)modelName; -- (NSString *)composerPath; -- (NSString *)modelDirPath; - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.m deleted file mode 100644 index 3cde465d5..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BEResourceHelper.m +++ /dev/null @@ -1,110 +0,0 @@ -// -// BEResourceHelper.m -// BytedEffects -// -// Created by QunZhang on 2019/10/22. -// Copyright © 2019 ailab. All rights reserved. -// - -#import "BEResourceHelper.h" -#import "BELicenseHelper.h" -#import "BundleUtil.h" -#import "Core.h" - -static NSString *LICENSE_PATH = @"LicenseBag"; -static NSString *COMPOSER_PATH = @"ComposeMakeup"; -static NSString *FILTER_PATH = @"FilterResource"; -static NSString *STICKER_PATH = @"StickerResource"; -static NSString *MODEL_PATH = @"ModelResource"; - -static NSString *BUNDLE = @"bundle"; - -@interface BEResourceHelper () { - NSString *_licensePrefix; - NSString *_composerPrefix; - NSString *_filterPrefix; - NSString *_stickerPrefix; -} - -@end - -@implementation BEResourceHelper - -- (NSString *)licensePath { -// const char *license = [BELicenseHelper shareInstance].licensePath; -// return [[NSString alloc]initWithCString:license encoding:(NSUTF8StringEncoding)]; - NSString *licenseName; - if ([self.delegate respondsToSelector:@selector(licenseName)]) { - licenseName = [self.delegate licenseName]; - } else { - licenseName = [[NSString alloc] initWithCString:LICENSE_NAME encoding:NSUTF8StringEncoding]; - } - if ([self.delegate respondsToSelector:@selector(licenseDirPath)]) { - return [[self.delegate licenseDirPath] stringByAppendingString:licenseName]; - } - if (!_licensePrefix) { - _licensePrefix = [[NSBundle mainBundle] pathForResource:LICENSE_PATH ofType:BUNDLE]; - } - return [_licensePrefix stringByAppendingString:licenseName]; -} - -- (NSString *)composerNodePath:(NSString *)nodeName { - if ([self.delegate respondsToSelector:@selector(composerNodeDirPath)]) { - return [self.delegate composerNodeDirPath]; - } - if (!_composerPrefix) { - NSBundle *budle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; - _composerPrefix = [[budle pathForResource:COMPOSER_PATH ofType:BUNDLE] stringByAppendingString:@"/ComposeMakeup/"]; - } - if ([nodeName containsString:_composerPrefix]) { - return nodeName; - } - return [_composerPrefix stringByAppendingString:nodeName]; -} - -- (NSString *)filterPath:(NSString *)filterName { - if ([self.delegate respondsToSelector:@selector(filterDirPath)]) { - return [[self.delegate filterDirPath] stringByAppendingString:filterName]; - } - if (!_filterPrefix) { - NSBundle *budle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; - _filterPrefix = [[budle pathForResource:FILTER_PATH ofType:BUNDLE] stringByAppendingFormat:@"/Filter/"]; - } - return [_filterPrefix stringByAppendingString:filterName]; -} - -- (NSString *)stickerPath:(NSString *)stickerName { - if ([self.delegate respondsToSelector:@selector(stickerDirPath)]) { - return [[self.delegate stickerDirPath] stringByAppendingString:stickerName]; - } - if (!_stickerPrefix) { - NSBundle *budle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; - _stickerPrefix = [[budle pathForResource:STICKER_PATH ofType:BUNDLE] stringByAppendingString:@"/stickers/"]; - } - return [_stickerPrefix stringByAppendingString:stickerName]; -} - -- (NSString *)modelPath:(NSString *)modelName { - return [[self modelDirPath] stringByAppendingString:modelName]; -} - -- (NSString *)composerPath { - if ([self.delegate respondsToSelector:@selector(composerDirPath)]) { - return [self.delegate composerDirPath]; - } - if (!_composerPrefix) { - NSBundle *budle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; - _composerPrefix = [[budle pathForResource:COMPOSER_PATH ofType:BUNDLE] stringByAppendingString:@"/ComposeMakeup/"]; - } - return [_composerPrefix stringByAppendingString:@"/composer"]; -} - -- (NSString *)modelDirPath { - if ([self.delegate respondsToSelector:@selector(modelDirPath)]) { - return [self.delegate modelDirPath]; - } - NSBundle *budle = [BundleUtil bundleWithBundleName:@"ByteEffectLib" podName:@"bytedEffect"]; - return [budle pathForResource:MODEL_PATH ofType:BUNDLE]; -} - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.h new file mode 100644 index 000000000..4e4f75a2c --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.h @@ -0,0 +1,31 @@ +// BETimeRecoder.h +// EffectsARSDK + + +#import + +#if TIME_LOG +#define RECORD_TIME(NAME) double _##NAME = [NSDate date].timeIntervalSince1970; +#else +#define RECORD_TIME(NAME) +#endif + +#if TIME_LOG +#define STOP_TIME(NAME) NSLog(@"TimeRecoder %s %f", #NAME, ([NSDate date].timeIntervalSince1970 - _##NAME) * 1000); +#else +#define STOP_TIME(NAME) +#endif + +@interface BETimeRecoder : NSObject + +// {zh} / @brief 开始记录耗时 {en} /@Brief start recording time +// {zh} / @param tag 标签 {en} /@param tag ++ (void)record:(NSString *)tag; + +// {zh} / @brief 停止记录耗时 {en} /@Briefing Stop Recording Time-consuming +// {zh} / @param tag 标签 {en} /@param tag ++ (void)stop:(NSString *)tag; + ++ (void)be_recordOnce:(NSString *)tag interval:(double)interval; + +@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.m new file mode 100644 index 000000000..bad367ecf --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/BETimeRecoder.m @@ -0,0 +1,47 @@ +// BETimeRecoder.m +// EffectsARSDK + + +#import "BETimeRecoder.h" + +static NSMutableDictionary *be_startTime; + +@interface BETimeRecoder () + +@end + +@implementation BETimeRecoder + ++ (void)initialize +{ + if (self == [BETimeRecoder class]) { + be_startTime = [NSMutableDictionary dictionary]; + } +} + ++ (void)record:(NSString *)tag { + [be_startTime setObject:[NSNumber numberWithDouble:[NSDate date].timeIntervalSince1970] forKey:tag]; +} + ++ (void)stop:(NSString *)tag { + NSNumber *start = [be_startTime objectForKey:tag]; + if (start == nil) { + [self be_startNotFound:tag]; + return; + } + [be_startTime removeObjectForKey:tag]; + double s = [start doubleValue]; + double e = [NSDate date].timeIntervalSince1970; + [self be_recordOnce:tag interval:e - s]; +} + +#pragma mark - private ++ (void)be_startNotFound:(NSString *)tag { + NSLog(@"call record with tag %@ first", tag); +} + ++ (void)be_recordOnce:(NSString *)tag interval:(double)interval { + NSLog(@"TimeRecoder %@ %f", tag, interval * 1000); +} + +@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.h deleted file mode 100755 index 51b548b2a..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// ByteDanceFilter.h -// FULiveDemo -// -// Created by 刘洋 on 2017/8/18. -// Copyright © 2017年 刘洋. All rights reserved. -// - -#import -#import -#import - - -@protocol VideoFilterDelegate - -- (CVPixelBufferRef)processFrame:(CVPixelBufferRef)frame timeStamp:(double)timeStamp; - -@end - -@interface ByteDanceFilter : NSObject - -@property (nonatomic, assign) BOOL enabled; - -+ (ByteDanceFilter *)shareManager; - -- (void)setBuauty: (BOOL)isSelected; -- (void)setMakeup: (BOOL)isSelected; -- (void)setSticker: (BOOL)isSelected; -- (void)setFilter: (BOOL)isSelected; - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.m deleted file mode 100755 index 328190ef3..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/ByteDanceFilter.m +++ /dev/null @@ -1,101 +0,0 @@ -// -// ByteDanceFilter.m -// FULiveDemo -// -// Created by 刘洋 on 2017/8/18. -// Copyright © 2017年 刘洋. All rights reserved. -// - -#import "ByteDanceFilter.h" -#import "BEFrameProcessor.h" - -@interface ByteDanceFilter(){ - BEFrameProcessor *_processor; -} - -@end - -static ByteDanceFilter *shareManager = NULL; - -@implementation ByteDanceFilter - -+ (ByteDanceFilter *)shareManager -{ - __block ByteDanceFilter *shareManager; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - shareManager = [[ByteDanceFilter alloc] init]; - }); - return shareManager; -} - -- (instancetype)init -{ - if (self = [super init]) { - EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:context]; - _processor = [[BEFrameProcessor alloc] initWithContext:context resourceDelegate:nil]; - _processor.processorResult = BECVPixelBuffer; - - [_processor setEffectOn:YES]; -// [_processor setFilterPath:@"Filter_32_Po10"]; -// [_processor setStickerPath:@"test_sticker"]; - [_processor updateComposerNodes:@[@"/beauty_IOS_lite"]]; - } - - return self; -} - -- (void)setBuauty: (BOOL)isSelected { -#if __has_include("bef_effect_ai_api.h") - if (isSelected) { - [_processor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0.6]; - [_processor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0.6]; - } else { - [_processor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"whiten" intensity:0]; - [_processor updateComposerNodeIntensity:@"/beauty_IOS_lite" key:@"smooth" intensity:0]; - } -#endif -} -- (void)setMakeup: (BOOL)isSelected { -#if __has_include("bef_effect_ai_api.h") - if (isSelected) { - [_processor updateComposerNodeIntensity:@"/style_makeup/tianmei" key:@"Makeup_ALL" intensity:0.6]; - } else { - [_processor updateComposerNodeIntensity:@"/style_makeup/tianmei" key:@"Makeup_ALL" intensity:0]; - } -#endif -} -- (void)setSticker: (BOOL)isSelected { -#if __has_include("bef_effect_ai_api.h") - if (isSelected) { - [_processor setStickerPath:@"wochaotian"]; - } else { - [_processor setStickerPath:@""]; - } -#endif -} -- (void)setFilter: (BOOL)isSelected { -#if __has_include("bef_effect_ai_api.h") - if (isSelected) { - [_processor setFilterPath:@"Filter_02_14"]; - [_processor setFilterIntensity:0.4]; - } else { - [_processor setFilterIntensity:0]; - } -#endif -} - - -#pragma mark - VideoFilterDelegate -/// process your video frame here -- (CVPixelBufferRef)processFrame:(CVPixelBufferRef)frame timeStamp:(double)timeStamp{ - if(self.enabled) { - BEProcessResult *result = [_processor process:frame timeStamp:timeStamp]; - return result.pixelBuffer; - } - return frame; -} - - -@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Config.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Config.h new file mode 100644 index 000000000..5d0a43ae5 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Config.h @@ -0,0 +1,15 @@ +// Config.h +// BECore + + +#ifndef Config_h +#define Config_h + +#define LICENSE_NAME ((const char *)"Agora_test_20241014_20241214_io.agora.entfull_4.5.0_2060.licbag") + +#define DEBUG_LOG false +#define TIME_LOG false +#define BEF_AUTO_TEST false +#define ENABLE_STICKER_TEST true + +#endif /* Config_h */ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Core.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Core.h index 069aafd07..3bc4b0031 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Core.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/Core.h @@ -1,12 +1,5 @@ #import "macro.h" - -#define LICENSE_NAME ((const char *)"agora_test_20220805_20230208_io.agora.entfull_4.2.3.licbag") -#define ONLINE_LICENSE_KEY ((const char *)"jiaoyang_test") -#define ONLINE_LICENSE_SECRET ((const char *)"04273924-9a77-11eb-94da-0c42a1b32a30") - -static NSString *OFFLIN_LICENSE_PATH = @"LicenseBag"; -static NSString *OFFLIN_BUNDLE = @"bundle"; -static LICENSE_MODE_ENUM LICENSE_MODE = ONLINE_LICENSE; +#import "Config.h" #define CHECK_RET_AND_RETURN(MSG, ret) \ if (ret != 0 && ret != -11 && ret != 1) {\ @@ -64,8 +57,3 @@ if (ret != 0 && ret != -11 && ret != 1) {\ #else #define BELog(fmt, ...) #endif - - -#define BEColorWithARGBHex(hex) [UIColor colorWithRed:((hex&0xFF0000)>>16)/255.0 green:((hex&0x00FF00)>>8)/255.0 blue:((hex&0x0000FF))/255.0 alpha:((hex&0xFF000000)>>24)/255.0] -#define BEColorWithRGBAHex(hex,alpha) [UIColor colorWithRed:((hex&0xFF0000)>>16)/255.0 green:((hex&0x00FF00)>>8)/255.0 blue:((hex&0x0000FF))/255.0 alpha:alpha] -#define BEColorWithRGBHex(hex) [UIColor colorWithRed:((hex&0xFF0000)>>16)/255.0 green:((hex&0x00FF00)>>8)/255.0 blue:((hex&0x0000FF))/255.0 alpha:1] diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/macro.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/macro.h index 0ab9c0368..8f02ffdce 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/macro.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Manager/macro.h @@ -1,11 +1,13 @@ // writen by update_ios_core_macro.py, don't edit it manually +#define BEF_CONFUSION_TOB TRUE #define BEF_EFFECT_TOB TRUE #define BEF_HAND_TOB TRUE #define BEF_FACE_TOB TRUE #define BEF_SKELETON_TOB TRUE #define BEF_PET_FACE_TOB TRUE #define BEF_PORTRAIT_MATTING_TOB TRUE +#define BEF_SALIENCY_MATTING_TOB TRUE #define BEF_HEAD_SEG_TOB TRUE #define BEF_HAIR_PARSE_TOB TRUE #define BEF_SKY_SEG_TOB TRUE @@ -24,7 +26,21 @@ #define BEF_SKIN_SEGMENTATION_TOB TRUE #define BEF_CHROMA_KEYING_TOB TRUE #define BEF_BACH_SKELETON_TOB TRUE +#define BEF_SLAM_TOB TRUE +#define BEF_FACEFITTING_TOB TRUE +#define BEF_LICENSE_CAKE_TOB TRUE +#define BEF_AVABOOST_TOB TRUE +#define BEF_OBJECT_TRACKING_TOB TRUE +#define BEF_AVATAR_SKELETON_3D_TOB TRUE #define BEF_LENS_TOB TRUE +#define BEF_LENS_PHOTO_NIGHT_SCENE_TOB TRUE #define BEF_LENS_VIDEO_SR_TOB TRUE #define BEF_LENS_NIGHT_SCENE_TOB TRUE -#define BEF_LENS_ADAPTIVE_SHARPEN_TOB TRUE \ No newline at end of file +#define BEF_LENS_ADAPTIVE_SHARPEN_TOB TRUE +#define BEF_LENS_ONEKEY_ENHANCE_TOB TRUE +#define BEF_LENS_VIDEO_VIF_TOB TRUE +#define BEF_LENS_VIDA_TOB TRUE +#define BEF_LENS_TAINT_DETECT_TOB TRUE +#define BEF_LENS_CINE_MOVE_TOB TRUE +#define BEF_LENS_VIDEO_DEFLICKER_TOB TRUE +#define BEF_LENS_VIDEO_HDR_TOB TRUE diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m index b108bdb6a..9cdb90e87 100755 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m @@ -32,40 +32,36 @@ + (FUManager *)shareManager dispatch_once(&onceToken, ^{ shareManager = [[FUManager alloc] init]; }); - + return shareManager; } - (instancetype)init { if (self = [super init]) { - #if __has_include() - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; -// [[NSBundle mainBundle] pathForResource:@"controller_cpp" ofType:@"bundle" inDirectory:@"Frameworks"] - NSString *controllerPath = [bundle pathForResource:@"graphics/controller_cpp" ofType:@"bundle"]; -// NSString *controllerPath = [[NSBundle mainBundle] pathForResource:@"controller_cpp" ofType:@"bundle"]; - NSString *controllerConfigPath = [bundle pathForResource:@"graphics/controller_config" ofType:@"bundle"]; - FUSetupConfig *setupConfig = [[FUSetupConfig alloc] init]; - setupConfig.authPack = FUAuthPackMake(g_auth_package, sizeof(g_auth_package)); - setupConfig.controllerPath = controllerPath; - setupConfig.controllerConfigPath = controllerConfigPath; - - // 初始化 FURenderKit - [FURenderKit setupWithSetupConfig:setupConfig]; - - [FURenderKit setLogLevel:FU_LOG_LEVEL_ERROR]; - dispatch_async(dispatch_get_global_queue(0, 0), ^{ + NSString *controllerPath = [[NSBundle mainBundle] pathForResource:@"controller_cpp" ofType:@"bundle"]; + NSString *controllerConfigPath = [[NSBundle mainBundle] pathForResource:@"controller_config" ofType:@"bundle"]; + FUSetupConfig *setupConfig = [[FUSetupConfig alloc] init]; + setupConfig.authPack = FUAuthPackMake(g_auth_package, sizeof(g_auth_package)); + setupConfig.controllerPath = controllerPath; + setupConfig.controllerConfigPath = controllerConfigPath; + + // 初始化 FURenderKit + [FURenderKit setupWithSetupConfig:setupConfig]; + + [FURenderKit setLogLevel:FU_LOG_LEVEL_ERROR]; + // 加载人脸 AI 模型 - NSString *faceAIPath = [bundle pathForResource:@"model/ai_face_processor" ofType:@"bundle"];//[[NSBundle mainBundle] pathForResource:@"ai_face_processor" ofType:@"bundle"]; + NSString *faceAIPath = [[NSBundle mainBundle] pathForResource:@"ai_face_processor" ofType:@"bundle"]; [FUAIKit loadAIModeWithAIType:FUAITYPE_FACEPROCESSOR dataPath:faceAIPath]; // 加载身体 AI 模型 - NSString *bodyAIPath = [bundle pathForResource:@"model/ai_human_processor" ofType:@"bundle"];//[[NSBundle mainBundle] pathForResource:@"ai_human_processor" ofType:@"bundle"]; + NSString *bodyAIPath = [[NSBundle mainBundle] pathForResource:@"ai_human_processor" ofType:@"bundle"]; [FUAIKit loadAIModeWithAIType:FUAITYPE_HUMAN_PROCESSOR dataPath:bodyAIPath]; - NSString *path = [bundle pathForResource:@"graphics/tongue" ofType:@"bundle"];//[[NSBundle mainBundle] pathForResource:@"tongue" ofType:@"bundle"]; + NSString *path = [[NSBundle mainBundle] pathForResource:@"tongue" ofType:@"bundle"]; [FUAIKit loadTongueMode:path]; /* 设置嘴巴灵活度 默认= 0*/ // @@ -74,6 +70,9 @@ - (instancetype)init // 设置人脸算法质量 [FUAIKit shareKit].faceProcessorFaceLandmarkQuality = [FURenderKit devicePerformanceLevel] == FUDevicePerformanceLevelHigh ? FUFaceProcessorFaceLandmarkQualityHigh : FUFaceProcessorFaceLandmarkQualityMedium; + + // 设置小脸检测 + [FUAIKit shareKit].faceProcessorDetectSmallFace = [FURenderKit devicePerformanceLevel] == FUDevicePerformanceLevelHigh; }); [FUAIKit shareKit].maxTrackFaces = 4; @@ -95,8 +94,7 @@ - (void)destoryItems { - (void)setBuauty: (BOOL)isSelected { #if __has_include() if (isSelected) { - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *beautyPath = [bundle pathForResource:@"graphics/face_beautification" ofType:@"bundle"]; + NSString *beautyPath = [[NSBundle mainBundle] pathForResource:@"face_beautification" ofType:@"bundle"]; FUBeauty *beauty = [[FUBeauty alloc] initWithPath:beautyPath name:@"FUBeauty"]; // 默认均匀磨皮 beauty.heavyBlur = 0; @@ -110,8 +108,7 @@ - (void)setBuauty: (BOOL)isSelected { - (void)setMakeup: (BOOL)isSelected { #if __has_include() if (isSelected) { - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *beautyPath = [bundle pathForResource:@"graphics/face_makeup" ofType:@"bundle"]; + NSString *beautyPath = [[NSBundle mainBundle] pathForResource:@"face_makeup" ofType:@"bundle"]; FUMakeup *makeup = [[FUMakeup alloc] initWithPath:beautyPath name:@"face_makeup"]; makeup.isMakeupOn = YES; [FURenderKit setLogLevel:FU_LOG_LEVEL_DEBUG]; @@ -119,6 +116,7 @@ - (void)setMakeup: (BOOL)isSelected { [FURenderKit shareRenderKit].makeup = makeup; [FURenderKit shareRenderKit].makeup.enable = isSelected; + NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; NSString *makeupPath = [bundle pathForResource:@"美妆/ziyun" ofType:@"bundle"]; FUItem *makeupItem = [[FUItem alloc] initWithPath:makeupPath name:@"ziyun"]; [makeup updateMakeupPackage:makeupItem needCleanSubItem:NO]; @@ -141,8 +139,7 @@ - (void)setSticker: (BOOL)isSelected { - (void)setFilter: (BOOL)isSelected { #if __has_include() if (isSelected) { - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"FURenderKit" podName:@"fuLib"]; - NSString *beautyPath = [bundle pathForResource:@"graphics/face_beautification" ofType:@"bundle"]; + NSString *beautyPath = [[NSBundle mainBundle] pathForResource:@"face_beautification" ofType:@"bundle"]; FUBeauty *beauty = [[FUBeauty alloc] initWithPath:beautyPath name:@"FUBeauty"]; beauty.filterName = FUFilterMiTao1; beauty.filterLevel = 0.8; @@ -204,6 +201,9 @@ - (CVPixelBufferRef)processFrame:(CVPixelBufferRef)frame { [self.delegate faceUnityManagerCheckAI]; } #if __has_include() + if ([FURenderKit shareRenderKit].beauty == nil) { + return frame; + } FURenderInput *input = [[FURenderInput alloc] init]; input.pixelBuffer = frame; //默认图片内部的人脸始终是朝上,旋转屏幕也无需修改该属性。 diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.h new file mode 100644 index 000000000..cfc697279 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.h @@ -0,0 +1,28 @@ +// +// EFGlobalSingleton.h +// SenseMeEffects +// +// Created by 马浩萌 on 2021/11/30. +// Copyright © 2021 SoftSugar. All rights reserved. +// + +#import + +static NSString * const EFGlobalSingletonMaleKey = @"EFGlobalSingletonMaleKey"; + +@interface EFGlobalSingleton : NSObject + +@property (nonatomic, assign) int efTouchTriggerAction; // 点击屏幕触发事件保存 +@property (nonatomic, assign) BOOL efHasSegmentCapability; // 标识是否有皮肤分割capability +@property (nonatomic, assign) BOOL isMale; // 标识当前用户性别(不同默认参数) +@property (nonatomic, assign) BOOL needDelay; // 是否是tryon试鞋/试表需要开启未来帧 +@property (nonatomic, assign) BOOL isTryonShoes; // 是否是tryon试鞋(光脚提示) +@property (nonatomic, assign) BOOL isPortraitOnly; // 是否是gan image(只支持横屏) + ++(instancetype)sharedInstance; +-(instancetype)init NS_UNAVAILABLE; ++(instancetype)new NS_UNAVAILABLE; ++(instancetype)alloc NS_UNAVAILABLE; + +@end + diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.m new file mode 100644 index 000000000..dd6b6bd41 --- /dev/null +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EFGlobalSingleton.m @@ -0,0 +1,31 @@ +// +// EFGlobalSingleton.m +// SenseMeEffects +// +// Created by 马浩萌 on 2021/11/30. +// Copyright © 2021 SoftSugar. All rights reserved. +// + +#import "EFGlobalSingleton.h" + +@implementation EFGlobalSingleton + ++(instancetype)sharedInstance { + static EFGlobalSingleton * _shared = nil; + static dispatch_once_t sharedOnceToken; + dispatch_once(&sharedOnceToken, ^{ + _shared = [[self alloc] init]; + }); + return _shared; +} + +-(BOOL)isMale { + NSNumber *isMaleNumberValue = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:EFGlobalSingletonMaleKey]; + return isMaleNumberValue.boolValue; +} + +-(void)setIsMale:(BOOL)isMale { + [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:isMale] forKey:EFGlobalSingletonMaleKey]; +} + +@end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectMacro.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectMacro.h index 1326bdfec..d93b20da6 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectMacro.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectMacro.h @@ -17,8 +17,12 @@ typedef NS_ENUM(NSUInteger, EffectsType){ EffectsTypeVideo, }; +typedef enum : NSUInteger { + EFDetectConfigModeOther = 0, + EFDetectConfigModeItsMe, +} EFDetectConfigMode; -#define EFFECTS_LOG 0 +#define EFFECTS_LOG 1 #ifdef DEBUG #if EFFECTS_LOG #define EFFECTSLog(format , ...) NSLog((format) , ##__VA_ARGS__); @@ -29,6 +33,12 @@ typedef NS_ENUM(NSUInteger, EffectsType){ #define EFFECTSLog(format , ...) #endif +#ifdef DEBUG +#if EFFECTS_LOG +#define NSLog(format , ...) NSLog((format) , ##__VA_ARGS__); +#endif +#endif + #if EFFECTS_LOG #define EFFECTSTIMELOG(key) double key = CFAbsoluteTimeGetCurrent(); #define EFFECTSTIMEPRINT(key , dsc) printf("%s\t%.1f \n" , dsc , (CFAbsoluteTimeGetCurrent() - key) * 1000); diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.h index 919fe8fe8..cead3ed4a 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.h @@ -9,7 +9,6 @@ #if __has_include("st_mobile_common.h") #import "st_mobile_common.h" #import "st_mobile_effect.h" -#import "st_mobile_color_convert.h" #endif #import "EffectMacro.h" @@ -92,6 +91,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)addStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback; +-(void)changeStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback; + /// 获取获取素材的贴纸信息 /// @param package_id package_id /// @param modules 贴纸信息 @@ -120,10 +121,8 @@ NS_ASSUME_NONNULL_BEGIN /// 清空贴纸 - (st_result_t)cleareStickers; -///// 移除美妆 -///// @param stickerId 美妆Id -//- (st_result_t)removeMakeup:(int)stickerId; - (uint64_t)getDetectConfig; +- (uint64_t)getDetectConfigWithMode:(EFDetectConfigMode)configMode; - (uint64_t)getAnimalDetectConfig; @@ -136,8 +135,7 @@ NS_ASSUME_NONNULL_BEGIN stride:(int)stride rotate:(st_rotate_type)rotate detectResult:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t const *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outDetectResult:(st_mobile_human_action_t)outDetectResult withCache:(CVOpenGLESTextureCacheRef)cache outPixelFormat:(st_pixel_format)fmt_out @@ -152,8 +150,7 @@ NS_ASSUME_NONNULL_BEGIN stride:(int)stride rotate:(st_rotate_type)rotate detectResult:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t const *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outDetectResult:(st_mobile_human_action_t)outDetectResult withCache:(CVOpenGLESTextureCacheRef)cache outPixelFormat:(st_pixel_format)fmt_out @@ -164,6 +161,8 @@ NS_ASSUME_NONNULL_BEGIN rgba:(GLuint)texture size:(CGSize)size; +-(st_result_t)setParam:(st_effect_param_t)param andValue:(float)value; + -(st_result_t)setFaceMeshList:(st_mobile_face_mesh_list_t)mesh_list; #endif diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.m index 466aba6a9..4c248db04 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/Effects.m @@ -6,9 +6,14 @@ // #import "Effects.h" +#if __has_include("st_mobile_common.h") +#import "st_mobile_effect.h" +#import "st_mobile_color_convert.h" +#endif #import #import #import +#import "EFGlobalSingleton.h" @interface EffectsMotionManager () { @@ -62,7 +67,6 @@ @interface Effects () { EffectsType _type; } -//@property (nonatomic, strong) EffectsAudioPlayerManager *audioManager; @end @implementation Effects @@ -115,25 +119,28 @@ - (void)createHandleWithType:(EffectsType)type context:(EAGLContext *)glContext{ NSLog(@"st_mobile_effect_create_handle error %d", ret); return; } -// self.audioManager = [[EffectsAudioPlayerManager alloc] init]; -// self.audioManager.delegate = self; -// st_result_t setRet = ST_OK; -// setRet = st_mobile_effect_set_module_state_change_callback(handle, _modul_state_change_callback); -// if (setRet != ST_OK) { -// NSLog(@"st_mobile_effect_set_module_state_change_callback error %d", setRet); -// } -// setRet = st_mobile_effect_set_packaged_state_change_callback(handle, _package_state_change_callback); -// if (setRet != ST_OK) { -// NSLog(@"st_mobile_effect_set_packaged_state_change_callback error %d", setRet); -// } + st_result_t setRet = ST_OK; + setRet = st_mobile_effect_set_module_state_change_callback(handle, _modul_state_change_callback); + if (setRet != ST_OK) { + NSLog(@"st_mobile_effect_set_module_state_change_callback error %d", setRet); + } self.glContext = glContext; } break; case EffectsTypeVideo: ret = st_mobile_effect_create_handle(EFFECT_CONFIG_IMAGE_MODE, &handle); + st_result_t setRet = ST_OK; + setRet = st_mobile_effect_set_module_state_change_callback(handle, _modul_state_change_callback); + if (setRet != ST_OK) { + NSLog(@"st_mobile_effect_set_module_state_change_callback error %d", setRet); + } break; case EffectsTypePhoto: ret = st_mobile_effect_create_handle(EFFECT_CONFIG_IMAGE_MODE, &handle); + ret = st_mobile_effect_set_module_state_change_callback(handle, _modul_state_change_callback); + if (setRet != ST_OK) { + NSLog(@"st_mobile_effect_set_module_state_change_callback error %d", setRet); + } break; } st_mobile_effect_set_param(handle, EFFECT_PARAM_MAX_MEMORY_BUDGET_MB, 1000.0); @@ -349,6 +356,27 @@ - (void)addStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:( } } +-(void)changeStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback { + if (!stickerPath) { + return ; + } + int packageId = 0; + st_result_t iRet = st_mobile_effect_change_package(self.handle, stickerPath.UTF8String, &packageId); + if (ST_OK != iRet) { + NSLog(@"st_mobile_effect_add_package error %d", iRet); + return; + } + uint64_t action = 0; + st_mobile_effect_get_detect_config(self.handle, &action); + + uint64_t customAciton = 0; + st_mobile_effect_get_custom_event_config(self.handle, &customAciton); + + if (callback) { + callback(iRet, packageId, action, customAciton); + } +} + -(st_result_t)getModulesInPackage:(int)package_id modules:(st_effect_module_info_t*)modules { st_effect_package_info_t *p_package_info = malloc(sizeof(st_effect_package_info_t)); st_result_t iRet = st_mobile_effect_get_package_info(self.handle, package_id, p_package_info); @@ -424,14 +452,13 @@ - (GLuint)processTexture:(GLuint)inputTexture stride:(int)stride rotate:(st_rotate_type)rotate detectResult:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t const *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outDetectResult:(st_mobile_human_action_t)outDetectResult withCache:(CVOpenGLESTextureCacheRef)cache outPixelFormat:(st_pixel_format)fmt_out outBuffer:(unsigned char *)img_out { st_mobile_face_mesh_list_t tmp = {}; - return [self processTexture:inputTexture inputData:inputData inputFormat:inputFormat outputTexture:outputTexture width:width height:height stride:stride rotate:rotate detectResult:detectResult animalResult:animalResult animalCount:animalCount outDetectResult:outDetectResult withCache:cache outPixelFormat:fmt_out outBuffer:img_out meshList:tmp]; + return [self processTexture:inputTexture inputData:inputData inputFormat:inputFormat outputTexture:outputTexture width:width height:height stride:stride rotate:rotate detectResult:detectResult animalResult:animalResult outDetectResult:outDetectResult withCache:cache outPixelFormat:fmt_out outBuffer:img_out meshList:tmp]; } - (GLuint)processTexture:(GLuint)inputTexture @@ -443,8 +470,7 @@ - (GLuint)processTexture:(GLuint)inputTexture stride:(int)stride rotate:(st_rotate_type)rotate detectResult:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t const *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outDetectResult:(st_mobile_human_action_t)outDetectResult withCache:(CVOpenGLESTextureCacheRef)cache outPixelFormat:(st_pixel_format)fmt_out @@ -486,18 +512,17 @@ - (GLuint)processTexture:(GLuint)inputTexture inputEvent.front_camera = self.cameraPosition == AVCaptureDevicePositionFront; } -// EFGlobalSingleton *globalSingleton = [EFGlobalSingleton sharedInstance]; -// if (globalSingleton.efTouchTriggerAction > 0) { -// inputEvent.event = globalSingleton.efTouchTriggerAction; -// globalSingleton.efTouchTriggerAction = 0; -// } + EFGlobalSingleton *globalSingleton = [EFGlobalSingleton sharedInstance]; + if (globalSingleton.efTouchTriggerAction > 0) { + inputEvent.event = globalSingleton.efTouchTriggerAction; + globalSingleton.efTouchTriggerAction = 0; + } - st_effect_texture_t input_texture = {inputTexture, width, height, ST_PIX_FMT_BGRA8888}; + st_mobile_texture_t input_texture = {inputTexture, width, height, ST_PIX_FMT_BGRA8888}; st_effect_render_in_param_t input_param ={}; input_param.p_custom_param = &inputEvent; input_param.p_human = &detectResult; - input_param.animal_face_count = animalCount; - input_param.p_animal_face = animalResult; + input_param.p_animal = animalResult; input_param.rotate = rotate; input_param.front_rotate = rotate; input_param.need_mirror = false; @@ -506,7 +531,7 @@ - (GLuint)processTexture:(GLuint)inputTexture st_image_t inputImage = {.data = inputData, .pixel_format = inputFormat, .width = width, .height = height, .stride = stride, .time_stamp= 0.0}; st_effect_in_image_t effectImag = {.image = inputImage, .rotate = ST_CLOCKWISE_ROTATE_0, .b_mirror = GL_FALSE}; input_param.p_image = &effectImag; - st_effect_texture_t output_texture = {outputTexture, width, height, ST_PIX_FMT_BGRA8888}; + st_mobile_texture_t output_texture = {outputTexture, width, height, ST_PIX_FMT_BGRA8888}; st_effect_render_out_param_t output_param = {}; output_param.p_tex = &output_texture; st_mobile_human_action_t human_out_param; @@ -538,6 +563,14 @@ - (uint64_t)getDetectConfig{ return config; } +- (uint64_t)getDetectConfigWithMode:(EFDetectConfigMode)configMode { + uint64_t config = [self getDetectConfig]; + if (configMode == EFDetectConfigModeItsMe) { + config |= ST_MOBILE_FACE_DETECT; + } + return config; +} + - (uint64_t)getAnimalDetectConfig{ uint64_t config; st_handle_t handle = self.handle; @@ -559,20 +592,12 @@ - (void)convertYUVBuffer:(unsigned char *)buffer } -#pragma mark - EffectsAudioPlayerManagerDelegate -- (void)audioPlayerDidFinishPlayingWithAudioName:(NSString *)audioName{ - if (self.handle) { - st_result_t iRet = ST_OK; - st_effect_module_info_t module_info; - memset(&module_info, 0, sizeof(st_effect_module_info_t)); - module_info.type = EFFECT_MODULE_SOUND; - module_info.state = EFFECT_MODULE_PAUSED_LAST_FRAME; - memcpy(module_info.name, audioName.UTF8String, audioName.length); - iRet = st_mobile_effect_set_module_info(self.handle, &module_info); - if (iRet != ST_OK) { - NSLog(@"st mobile set sound complete str failed: %d", iRet); - } +-(st_result_t)setParam:(st_effect_param_t)param andValue:(float)value { + st_result_t iRet = st_mobile_effect_set_param(self.handle, param, value); + if (iRet != ST_OK) { + NSLog(@"st_mobile_effect_set_param error %d", iRet); } + return iRet; } -(st_result_t)setFaceMeshList:(st_mobile_face_mesh_list_t)mesh_list { @@ -583,11 +608,21 @@ -(st_result_t)setFaceMeshList:(st_mobile_face_mesh_list_t)mesh_list { } return iRet; } -#endif - (void)setCurrentEAGLContext:(EAGLContext*)glContext{ if ([EAGLContext currentContext] != glContext) { [EAGLContext setCurrentContext:glContext]; } } + +st_result_t _modul_state_change_callback(st_handle_t handle, const st_effect_module_info_t* p_module_info) { + if (p_module_info->type == EFFECT_MODULE_GAN_IMAGE) { // GAN +// _gan_modul_state_change_callback(handle, p_module_info); + } else if (p_module_info->type == EFFECT_MODULE_SEGMENT) { // 绿幕分割 +// _segment_modul_state_change_callback(handle, p_module_info); + } + return ST_OK; +} +#endif + @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.h index 6e59928f3..e47d11d7a 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.h @@ -3,11 +3,11 @@ // SenseMeEffects // // Created by sunjian on 2021/7/16. -// Copyright © 2021 SenseTime. All rights reserved. +// Copyright © 2021 SoftSugar. All rights reserved. // #import -#if __has_include("st_mobile_common.h") +#if __has_include("st_mobile_effect.h") #import "st_mobile_common.h" #import "st_mobile_animal.h" #endif @@ -17,7 +17,8 @@ NS_ASSUME_NONNULL_BEGIN @interface EffectsAnimal : NSObject - (instancetype)initWithType:(EffectsType)type; -#if __has_include("st_mobile_common.h") + +#if __has_include("st_mobile_effect.h") /// 动物检测函数 /// @param pixelBuffer 每帧图像数据 /// @param rotate 手机旋转方向 @@ -25,8 +26,7 @@ NS_ASSUME_NONNULL_BEGIN - (st_result_t)detectAnimalWithPixelbuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate config:(st_mobile_animal_type)config - detectResult:(st_mobile_animal_face_t **)detectResult - animalCount:(int *)animalCount; + detectResult:(st_mobile_animal_result_t *)detectResult; /// 动物检测函数 /// @param buffer 每帧图像数据 @@ -43,11 +43,9 @@ NS_ASSUME_NONNULL_BEGIN height:(int)height stride:(int)stride config:(st_mobile_animal_type)config - detectResult:(st_mobile_animal_face_t **)detectResult - animalCount:(int *)animalCount; + detectResult:(st_mobile_animal_result_t *)detectResult; -(st_result_t)resetAnimalFaceTracker; - #endif @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.m index 8b3e403a1..34e87335e 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAnimal.m @@ -3,7 +3,7 @@ // SenseMeEffects // // Created by sunjian on 2021/7/16. -// Copyright © 2021 SenseTime. All rights reserved. +// Copyright © 2021 SoftSugar. All rights reserved. // #import "EffectsAnimal.h" @@ -11,11 +11,10 @@ #import "st_mobile_effect.h" #endif #import -#import "BundleUtil.h" @interface EffectsAnimal () { -#if __has_include("st_mobile_common.h") +#if __has_include("st_mobile_effect.h") st_handle_t _hAnimalHandle; #endif } @@ -42,10 +41,9 @@ - (instancetype)initWithType:(EffectsType)type{ } - (void)createHandlerWithType:(EffectsType)type{ -#if __has_include("st_mobile_common.h") - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"SenseLib" podName:@"senseLib"]; - NSString *catFaceModelPath = [bundle pathForResource:@"M_SenseME_CatFace_3.0.0" ofType:@"model"]; - NSString *dogFaceModelPath = [bundle pathForResource:@"M_SenseME_DogFace_2.0.0" ofType:@"model"]; + NSString *catFaceModelPath = [[NSBundle mainBundle] pathForResource:@"M_SenseME_CatFace_p_3.2.0.1" ofType:@"model"]; + NSString *dogFaceModelPath = [[NSBundle mainBundle] pathForResource:@"M_SenseME_DogFace_p_2.0.0.1" ofType:@"model"]; +#if __has_include("st_mobile_effect.h") int config = ST_MOBILE_TRACKING_MULTI_THREAD; switch (type) { case EffectsTypePhoto: @@ -80,8 +78,7 @@ - (void)createHandlerWithType:(EffectsType)type{ - (st_result_t)detectAnimalWithPixelbuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate config:(st_mobile_animal_type)config - detectResult:(st_mobile_animal_face_t **)detectResult - animalCount:(int *)animalCount{ + detectResult:(nonnull st_mobile_animal_result_t *)detectResult{ CVPixelBufferLockBaseAddress(pixelBuffer, 0); unsigned char* pixelData = (unsigned char*)CVPixelBufferGetBaseAddress(pixelBuffer); int iBytesPerRow = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); @@ -95,7 +92,7 @@ - (st_result_t)detectAnimalWithPixelbuffer:(CVPixelBufferRef)pixelBuffer stride:iBytesPerRow config:config detectResult:detectResult - animalCount:animalCount]; + ]; CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); return state; } @@ -107,9 +104,7 @@ - (st_result_t)detectAnimalWithBuffer:(unsigned char *)buffer height:(int)height stride:(int)stride config:(st_mobile_animal_type)config - detectResult:(st_mobile_animal_face_t **)detectResult - animalCount:(int *)animalCount{ - + detectResult:(st_mobile_animal_result_t *)detectResult { EFFECTSTIMELOG(key) st_result_t iRet = st_mobile_tracker_animal_face_track(_hAnimalHandle, buffer, @@ -119,8 +114,7 @@ - (st_result_t)detectAnimalWithBuffer:(unsigned char *)buffer stride, rotate, config, - detectResult, - animalCount); + detectResult); EFFECTSTIMEPRINT(key, "st_mobile_tracker_animal_face_track"); return iRet; } @@ -133,5 +127,4 @@ -(st_result_t)resetAnimalFaceTracker { return iRet; } #endif - @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.h index 42b4e1e47..8b5131c92 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.h @@ -3,7 +3,7 @@ // SenseMeEffects // // Created by sunjian on 2021/7/16. -// Copyright © 2021 SenseTime. All rights reserved. +// Copyright © 2021 SoftSugar. All rights reserved. // #import @@ -23,6 +23,10 @@ NS_ASSUME_NONNULL_BEGIN detectResult:(st_mobile_human_action_t)detectResult attrArray:(st_mobile_attributes_t *)pAttrArray; +- (st_result_t)detectAttributeWithPixelbuffer:(CVPixelBufferRef)pixelBuffer + detectResult:(st_mobile_human_action_t)detectResult + attrArray:(st_mobile_attributes_t *)pAttrArray withGenderCallback:(void(^)(BOOL isMale))callback; + - (st_result_t)detectAttributeWithBuffer:(unsigned char *)buffer pixelFormat:(st_pixel_format)pixelFormat width:(int)width @@ -30,6 +34,14 @@ NS_ASSUME_NONNULL_BEGIN stride:(int)stride faces:(st_mobile_106_t *)faces attrArray:(st_mobile_attributes_t *)pAttrArray; + +- (st_result_t)detectAttributeWithBuffer:(unsigned char *)buffer + pixelFormat:(st_pixel_format)pixelFormat + width:(int)width + height:(int)height + stride:(int)stride + faces:(st_mobile_106_t *)faces + attrArray:(st_mobile_attributes_t *)pAttrArray withGenderCallback:(void(^)(BOOL isMale))callback; #endif @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.m index 5d0e42d7b..d27096db3 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsAttribute.m @@ -3,11 +3,10 @@ // SenseMeEffects // // Created by sunjian on 2021/7/16. -// Copyright © 2021 SenseTime. All rights reserved. +// Copyright © 2021 SoftSugar. All rights reserved. // #import "EffectsAttribute.h" -#import "BundleUtil.h" #import @interface EffectsAttribute () @@ -35,23 +34,21 @@ - (instancetype)init{ } - (void)createHandler{ + NSString *strAttriModelPath = [[NSBundle mainBundle] pathForResource:@"M_SenseME_Attribute_p_1.2.8.1" ofType:@"model"]; #if __has_include("st_mobile_common.h") - NSBundle *bundle = [BundleUtil bundleWithBundleName:@"SenseLib" podName:@"senseLib"]; - NSString *strAttriModelPath = [bundle pathForResource:@"M_SenseME_Attribute_1.0.1" ofType:@"model"]; - st_result_t ret = st_mobile_face_attribute_create(strAttriModelPath.UTF8String, &_hAttributeHandle); if (ret != ST_OK) { NSLog(@"st_mobile_face_attribute_create error %d", ret); } #endif } + #if __has_include("st_mobile_common.h") - (st_result_t)detectAttributeWithPixelbuffer:(CVPixelBufferRef)pixelBuffer detectResult:(st_mobile_human_action_t)detectResult attrArray:(st_mobile_attributes_t *)pAttrArray{ if (detectResult.face_count == 0) return ST_E_INVALIDARG; - st_mobile_106_t *faces = (st_mobile_106_t *)malloc(sizeof(st_mobile_106_t) * detectResult.face_count); - memset(faces, 0, sizeof(st_mobile_106_t)*detectResult.face_count); + st_mobile_106_t *faces = &detectResult.p_faces[0].face106; CVPixelBufferLockBaseAddress(pixelBuffer, 0); unsigned char* pixelData = (unsigned char*)CVPixelBufferGetBaseAddress(pixelBuffer); int iBytesPerRow = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); @@ -65,7 +62,6 @@ - (st_result_t)detectAttributeWithPixelbuffer:(CVPixelBufferRef)pixelBuffer faces:faces attrArray:pAttrArray]; CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - free(faces);faces=nil; return ret; } @@ -137,5 +133,81 @@ - (NSString *)getDescriptionOfAttribute:(st_mobile_attributes_t)attribute { return strAttrDescription; } + +- (st_result_t)detectAttributeWithPixelbuffer:(CVPixelBufferRef)pixelBuffer + detectResult:(st_mobile_human_action_t)detectResult + attrArray:(st_mobile_attributes_t *)pAttrArray withGenderCallback:(void(^)(BOOL isMale))callback { + if (detectResult.face_count == 0) return ST_E_INVALIDARG; + st_mobile_106_t *faces = &detectResult.p_faces[0].face106; + CVPixelBufferLockBaseAddress(pixelBuffer, 0); + unsigned char* pixelData = (unsigned char*)CVPixelBufferGetBaseAddress(pixelBuffer); + int iBytesPerRow = (int)CVPixelBufferGetBytesPerRow(pixelBuffer); + int iWidth = (int)CVPixelBufferGetWidth(pixelBuffer); + int iHeight = (int)CVPixelBufferGetHeight(pixelBuffer); + st_result_t ret = [self detectAttributeWithBuffer:pixelData + pixelFormat:ST_PIX_FMT_BGRA8888 + width:iWidth + height:iHeight + stride:iBytesPerRow + faces:faces + attrArray:pAttrArray withGenderCallback:callback]; + CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); + return ret; +} + +- (st_result_t)detectAttributeWithBuffer:(unsigned char *)buffer + pixelFormat:(st_pixel_format)pixelFormat + width:(int)width + height:(int)height + stride:(int)stride + faces:(st_mobile_106_t *)faces + attrArray:(st_mobile_attributes_t *)pAttrArray withGenderCallback:(void(^)(BOOL isMale))callback { + if (!_hAttributeHandle) { + if (callback) { + callback(NO); + } + return ST_E_HANDLE; + } + EFFECTSTIMELOG(key) + st_result_t iRet = st_mobile_face_attribute_detect(_hAttributeHandle, + buffer, + pixelFormat, + width, + height, + stride, + faces, + 1, // 这里仅取一张脸也就是第一张脸的属性作为演示 + &pAttrArray); + if (iRet != ST_OK) { + NSLog(@"st_mobile_face_attribute_detect error %d", iRet); + } + EFFECTSTIMEPRINT(key, "st_mobile_face_attribute_detect") + st_mobile_attributes_t attributeDisplay = pAttrArray[0]; + [self getDescriptionOfAttribute:attributeDisplay withGenderCallback:callback]; + return iRet; +} + +- (void)getDescriptionOfAttribute:(st_mobile_attributes_t)attribute withGenderCallback:(void(^)(BOOL isMale))callback { + if (callback) { + for (int i = 0; i < attribute.attribute_count; i ++) { + + // 读取一条属性 + st_mobile_attribute_t attributeOne = attribute.p_attributes[i]; + + // 获取属性类别 + const char *attr_category = attributeOne.category; + const char *attr_label = attributeOne.label; + // 性别 + if (0 == strcmp(attr_category, "gender")) { + + if (0 == strcmp(attr_label, "male") ) { + callback(YES); + } else if (0 == strcmp(attr_label, "female") ) { + callback(NO); + } + } + } + } +} #endif @end diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.h index fb3aebdc3..accbed4a1 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.h @@ -15,14 +15,18 @@ @interface EffectsDetector : NSObject +#if __has_include("st_mobile_common.h") + /// 初始化对象 /// @param type 类型 - (instancetype)initWithType:(EffectsType)type; -#if __has_include("st_mobile_common.h") /// 添加model /// @param modelPath 模型路径 - (st_result_t)setModelPath:(NSString *)modelPath; +- (st_result_t)setModelPath:(NSString *)modelPath withFirstPhaseFinished:(void(^)(void))finishedCallback; + +- (st_result_t)setParam:(st_human_action_param_type)type andValue:(float)value; /// 人脸检测函数 /// @param pixelBuffer 每帧图像数据 @@ -65,6 +69,7 @@ -(st_result_t)resetHumanAction; -(st_result_t)getMeshList:(st_mobile_face_mesh_list_t *)p_mesh; +-(st_result_t)getMeshInfo:(st_mobile_mesh_info_t *)mesh_info; #endif diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.m index caec7309b..409065c1d 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsDetector.m @@ -8,7 +8,11 @@ #import #import "EffectsDetector.h" +#if __has_include("st_mobile_common.h") +#import "st_mobile_human_action.h" +#endif #import +#import "EFGlobalSingleton.h" @interface EffectsDetector () { @@ -30,15 +34,14 @@ - (void)dealloc{ - (instancetype)initWithType:(EffectsType)type{ if ((self = [super init])) { -#if __has_include("st_mobile_common.h") [self createHandlerWithType:type]; -#endif } return self; } -#if __has_include("st_mobile_common.h") + - (void)createHandlerWithType:(EffectsType)type{ +#if __has_include("st_mobile_common.h") if (!_hDetector) { int config = ST_MOBILE_TRACKING_MULTI_THREAD; switch (type) { @@ -58,7 +61,8 @@ - (void)createHandlerWithType:(EffectsType)type{ NSLog(@"st_mobile_human_action_create error %d", ret); } - ret = st_mobile_human_action_setparam(_hDetector, ST_HUMAN_ACTION_PARAM_MESH_MODE, 0x111000); + ret = st_mobile_human_action_setparam(_hDetector, ST_HUMAN_ACTION_PARAM_MESH_MODE, ST_MOBILE_MESH_PART_FACE|ST_MOBILE_MESH_PART_EYE|ST_MOBILE_MESH_PART_MOUTH|ST_MOBILE_MESH_PART_SKULL|ST_MOBILE_MESH_PART_EAR|ST_MOBILE_MESH_PART_NECK|ST_MOBILE_MESH_PART_EYEBROW); + if (ret != ST_OK) { NSLog(@"st_mobile_human_action_setparam error %d", ret); } @@ -67,9 +71,21 @@ - (void)createHandlerWithType:(EffectsType)type{ if (ret != ST_OK) { NSLog(@"st_mobile_human_action_setparam error %d", ret); } + + ret = st_mobile_human_action_setparam(_hDetector, ST_HUMAN_ACTION_PARAM_HEAD_SEGMENT_INSTANCE, 1.0); + if (ret != ST_OK) { + NSLog(@"st_mobile_human_action_setparam error %d", ret); + } + + ret = st_mobile_human_action_setparam(_hDetector, ST_HUMAN_ACTION_PARAM_FACE_MESH_OUTPUT_FORMAT, ST_3D_WORLD_COORDINATE); + if (ret != ST_OK) { + NSLog(@"st_mobile_human_action_setparam error %d", ret); + } } +#endif } +#if __has_include("st_mobile_common.h") st_result_t addSubModel(st_handle_t handle, NSString* file) { st_result_t iRet = st_mobile_human_action_add_sub_model(handle, file.UTF8String); if (iRet != ST_OK) { @@ -84,22 +100,71 @@ - (st_result_t)setModelPath:(NSString *)modelPath{ st_result_t state = ST_OK; NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:modelPath error:nil]; +// NSTimeInterval last = CFAbsoluteTimeGetCurrent(); + for(NSString *file in files) { +// if ([file containsString:@"M_SenseME_Face_"] || [file containsString:@"Occlusion"] || [file containsString:@"M_SenseME_3DMesh_Face2396pt"]) { + NSString *fullPath = [modelPath stringByAppendingPathComponent:file]; + + state = st_mobile_human_action_add_sub_model(_hDetector, fullPath.UTF8String); + if ([fullPath containsString:@"Skin"]) { // 皮肤分割 + [EFGlobalSingleton sharedInstance].efHasSegmentCapability = state != ST_E_NO_CAPABILITY; + } + if (state != ST_OK) { + NSLog(@"st mobile human action add %@ model failed: %d", fullPath, state); + } +// } + } +// NSLog(@"@mahaomeng cost %f", CFAbsoluteTimeGetCurrent()-last); + return state; +} +- (st_result_t)setModelPath:(NSString *)modelPath withFirstPhaseFinished:(void(^)(void))finishedCallback { + st_result_t state = ST_OK; + + NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:modelPath error:nil]; +// NSTimeInterval last = CFAbsoluteTimeGetCurrent(); + for(NSString *file in files) { + if ([file containsString:@"M_SenseME_Face_"] || [file containsString:@"Occlusion"] || [file containsString:@"M_SenseME_3DMesh_Face2396pt"]) { + NSString *fullPath = [modelPath stringByAppendingPathComponent:file]; + + state = st_mobile_human_action_add_sub_model(_hDetector, fullPath.UTF8String); + if ([fullPath containsString:@"Skin"]) { // 皮肤分割 + [EFGlobalSingleton sharedInstance].efHasSegmentCapability = state != ST_E_NO_CAPABILITY; + } + if (state != ST_OK) { + NSLog(@"st mobile human action add %@ model failed: %d", fullPath, state); + } + } + } + if (finishedCallback) { + finishedCallback(); + } for(NSString *file in files) { + if ([file containsString:@"M_SenseME_Face_"] || [file containsString:@"Occlusion"] || [file containsString:@"M_SenseME_3DMesh_Face2396pt"]) { + continue; + } NSString *fullPath = [modelPath stringByAppendingPathComponent:file]; - + state = st_mobile_human_action_add_sub_model(_hDetector, fullPath.UTF8String); if ([fullPath containsString:@"Skin"]) { // 皮肤分割 -// [EFGlobalSingleton sharedInstance].efHasSegmentCapability = state != ST_E_NO_CAPABILITY; + [EFGlobalSingleton sharedInstance].efHasSegmentCapability = state != ST_E_NO_CAPABILITY; } if (state != ST_OK) { NSLog(@"st mobile human action add %@ model failed: %d", fullPath, state); } } - + return state; } +-(st_result_t)setParam:(st_human_action_param_type)type andValue:(float)value { + st_result_t iRet = st_mobile_human_action_setparam(_hDetector, type, value); + if (iRet != ST_OK) { + NSLog(@"st_mobile_human_action_setparam error %d", iRet); + } + return iRet; +} + - (st_result_t)detectHumanActionWithPixelbuffer:(CVPixelBufferRef)pixelBuffer config:(unsigned long long)detectConfig rotate:(st_rotate_type)rotate @@ -188,14 +253,24 @@ - (st_face_shape_t)detectFaceShape:(st_mobile_face_t)p_face { -(st_result_t)getMeshList:(st_mobile_face_mesh_list_t *)p_mesh { st_result_t state; - st_mobile_face_mesh_list_t unuse_mesh_list; - state = st_mobile_human_action_get_mesh_list(_hDetector, ST_MOBILE_FACE_MESH, p_mesh, &unuse_mesh_list); + st_mobile_mesh_info_t mesh_info; + state = st_mobile_human_action_get_mesh_info(_hDetector, ST_MOBILE_FACE_MESH, &mesh_info); + if (state != ST_OK) { NSLog(@"st_mobile_human_action_get_mesh_list failed"); } return state; } +-(st_result_t)getMeshInfo:(st_mobile_mesh_info_t *)mesh_info { + st_result_t state; + state = st_mobile_human_action_get_mesh_info(_hDetector, ST_MOBILE_FACE_MESH, mesh_info); + if (state != ST_OK) { + NSLog(@"st_mobile_human_action_get_mesh_info failed"); + } + return state; +} + -(st_result_t)resetHumanAction { if (_hDetector) { return st_mobile_human_action_reset(_hDetector); diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsLicense.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsLicense.m index 58e10b5aa..e472a0c49 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsLicense.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsLicense.m @@ -45,29 +45,7 @@ + (NSString *)getActiveCodeWithData:(NSData *)dataLicense{ + (BOOL)authorizeWithLicensePath:(NSString *)licensePath{ NSData * dataLicense = [NSData dataWithContentsOfFile:licensePath]; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSString *strActiveCode = [userDefaults objectForKey:strActiveCodeKey]; - if (strActiveCode.length) { -#if __has_include("st_mobile_common.h") - st_result_t iRet = ST_E_FAIL; - iRet = st_mobile_check_activecode_from_buffer( - [dataLicense bytes], - (int)[dataLicense length], - strActiveCode.UTF8String, - (int)[strActiveCode length] - ); - - if (iRet) { - return NO; - } - return YES; -#endif - } - strActiveCode = [self getActiveCodeWithData:dataLicense]; - if (strActiveCode) { - return YES; - } - return NO; + return [self authorizeWithLicenseData:dataLicense]; } + (BOOL)authorizeWithLicenseData:(NSData *)dataLicense{ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.h index 81fd5b083..edb1efaf3 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.h +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.h @@ -6,10 +6,10 @@ // Copyright © 2021 sjuinan. All rights reserved. // -#import +#import #import -#import "EffectsDetector.h" #if __has_include("st_mobile_common.h") +#import "EffectsDetector.h" #import "st_mobile_common.h" #import "st_mobile_effect.h" #endif @@ -18,7 +18,6 @@ @protocol EFEffectsProcessDelegate - (void)updateEffectsFacePoint:(CGPoint)point; - #if __has_include("st_mobile_common.h") - (void)updateCommonObjectPosition:(st_rect_t)rect; #endif @@ -38,6 +37,8 @@ @property (nonatomic, assign) uint64_t detectConfig; +@property (nonatomic, assign) EFDetectConfigMode configMode; + /// 鉴权 /// @param licensePath 授权文件路径 + (BOOL)authorizeWithLicensePath:(NSString *)licensePath; @@ -48,12 +49,13 @@ /// 初始化对象 /// @param type 类型 -- (instancetype)initWithType:(EffectsType)type glContext:(EAGLContext *)glContext; +- (instancetype)initWithType:(EffectsType)type glContext:(EAGLContext *)glContext; #if __has_include("st_mobile_common.h") /// 加载模型 /// @param modelPath 模型文件路径(可将多个模型放在一个文件中,SDK内部遍历加载Model) - (st_result_t)setModelPath:(NSString *)modelPath; +- (st_result_t)setModelPath:(NSString *)modelPath withFirstPhaseFinished:(void(^)(void))finishedCallback; /// 设置特效 /// @param type 特效类型 @@ -116,6 +118,8 @@ - (void)addStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback; +-(void)changeStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback; + /// 获取获取素材的贴纸信息 /// @param package_id package_id /// @param modules 贴纸信息 @@ -144,20 +148,25 @@ rotate:(st_rotate_type)rotate cameraPosition:(AVCaptureDevicePosition)position humanAction:(st_mobile_human_action_t *)detectResult - animalResult:(st_mobile_animal_face_t **)animalResult - animalCount:(int *)animalCount; + animalResult:(st_mobile_animal_result_t *)animalResult; -(st_result_t)resetHumanAction; +-(st_result_t)setHumanActionParam:(st_human_action_param_type)type andValue:(float)value; +-(st_result_t)setEffectParam:(st_effect_param_t)param andValue:(float)value; + - (st_result_t)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outTexture:(GLuint)outTexture outPixelFormat:(st_pixel_format)fmt_out outData:(unsigned char *)img_out; +-(st_result_t)detectAttribute:(unsigned char *)imageData pixelFormat:(st_pixel_format)pixel_format imageWidth:(int)image_width imageHeight:(int)image_height imageStride:(int)image_stride orientation:(st_rotate_type)orientation withGenderCallback:(void(^)(BOOL isMale))callback; + +-(st_result_t)detectAttribute:(unsigned char *)imageData pixelFormat:(st_pixel_format)pixel_format imageWidth:(int)image_width imageHeight:(int)image_height detectResult:(st_mobile_human_action_t)detectResult withGenderCallback:(void(^)(BOOL isMale))callback; + /// 处理视频数据 /// @param pixelBuffer 视频数据 /// @param rotate 当前手机的旋转方向 diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.m index 59189338f..b232abbd2 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/EffectsProcess.m @@ -8,6 +8,7 @@ #import "EffectsProcess.h" #import "EffectsLicense.h" +#import "EffectsDetector.h" #import #import #import "Effects.h" @@ -63,7 +64,7 @@ - (void)dealloc{ if (_inputTexture) { glDeleteTextures(1, &_inputTexture); } - + if (_cvTextureCache) { CVOpenGLESTextureCacheFlush(_cvTextureCache, 0); CFRelease(_cvTextureCache); @@ -85,22 +86,18 @@ - (instancetype)initWithType:(EffectsType)type self.glContext = glContext; [self setCurrentEAGLContext:self.glContext]; CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.glContext, NULL, &_cvTextureCache); +#if __has_include("st_mobile_common.h") self.detector = [[EffectsDetector alloc] initWithType:type]; +#endif self.animalDetect = [[EffectsAnimal alloc] initWithType:type]; self.attriDetect = [[EffectsAttribute alloc] init]; self.commonObject = [[EffectsCommonObject alloc] init]; self.effect = [[Effects alloc] initWithType:type context:self.glContext]; - + } return self; } -- (void)setCurrentEAGLContext:(EAGLContext *)context{ - if (![[EAGLContext currentContext] isEqual:self.glContext]) { - [EAGLContext setCurrentContext:self.glContext]; - } -} - /// 鉴权 /// @param licensePath 授权文件路径 + (BOOL)authorizeWithLicensePath:(NSString *)licensePath{ @@ -129,6 +126,11 @@ - (st_result_t)setModelPath:(NSString *)modelPath{ return state; } +- (st_result_t)setModelPath:(NSString *)modelPath withFirstPhaseFinished:(void(^)(void))finishedCallback { + st_result_t state = [self.detector setModelPath:modelPath withFirstPhaseFinished:finishedCallback]; + return state; +} + - (st_result_t)setEffectType:(st_effect_beauty_type_t)type path:(NSString *)path{ return [self.effect setEffectType:type path:path]; } @@ -211,6 +213,10 @@ - (void)addStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:( [self.effect addStickerWithPath:stickerPath callBackCustomEventIncluded:callback]; } +-(void)changeStickerWithPath:(NSString *)stickerPath callBackCustomEventIncluded:(void(^)(st_result_t state, int stickerId, uint64_t action, uint64_t customEvent))callback { + [self.effect changeStickerWithPath:stickerPath callBackCustomEventIncluded:callback]; +} + -(st_result_t)getModulesInPackage:(int)package_id modules:(st_effect_module_info_t*)modules { return [self.effect getModulesInPackage:package_id modules:modules]; } @@ -260,23 +266,21 @@ - (st_result_t)detectWithPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate cameraPosition:(AVCaptureDevicePosition)position humanAction:(st_mobile_human_action_t *)detectResult - animalResult:(st_mobile_animal_face_t **)animalResult - animalCount:(int *)animalCount{ + animalResult:(st_mobile_animal_result_t *)animalResult { if(![EffectsToken sharedInstance].bAuthrize) return ST_E_NO_CAPABILITY; if (!self.detector) return ST_E_FAIL; + self.cameraPosition = position; OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); if (pixelFormat != kCVPixelFormatType_32BGRA) { return [self detectYUVPixelBuffer:pixelBuffer rotate:rotate humanAction:detectResult - animalResult:animalResult - animalCount:animalCount]; + animalResult:animalResult]; }else{ return [self detectRGBPixelBuffer:pixelBuffer rotate:rotate humanAction:detectResult - animalResult:animalResult - animalCount:animalCount]; + animalResult:animalResult]; } } @@ -284,11 +288,18 @@ -(st_result_t)resetHumanAction { return [self.detector resetHumanAction] || [self.animalDetect resetAnimalFaceTracker]; } +-(st_result_t)setHumanActionParam:(st_human_action_param_type)type andValue:(float)value { + return [self.detector setParam:type andValue:value]; +} + +-(st_result_t)setEffectParam:(st_effect_param_t)param andValue:(float)value { + return [self.effect setParam:param andValue:value]; +} + - (st_result_t)detectYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t *)detectResult - animalResult:(st_mobile_animal_face_t **)animalResult - animalCount:(int *)animalCount{ + animalResult:(st_mobile_animal_result_t *)animalResult { uint64_t config = [self getDetectConfig]; CVPixelBufferLockBaseAddress(pixelBuffer, 0); unsigned char *yData = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); @@ -332,8 +343,7 @@ - (st_result_t)detectYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer height:yHeight stride:iBytesPerRow config:(st_mobile_animal_type)animalConfig - detectResult:animalResult - animalCount:animalCount]; + detectResult:animalResult]; } //focus center @@ -389,8 +399,7 @@ - (st_result_t)detectYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer - (st_result_t)detectRGBPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t *)detectResult - animalResult:(st_mobile_animal_face_t **)animalResult - animalCount:(int *)animalCount{ + animalResult:(st_mobile_animal_result_t *)animalResult { uint64_t config = [self getDetectConfig]; //detect human action st_result_t ret = [self.detector detectHumanActionWithPixelbuffer:pixelBuffer @@ -404,8 +413,7 @@ - (st_result_t)detectRGBPixelBuffer:(CVPixelBufferRef)pixelBuffer ret = [self.animalDetect detectAnimalWithPixelbuffer:pixelBuffer rotate:rotate config:(st_mobile_animal_type)animalConfig - detectResult:animalResult - animalCount:animalCount]; + detectResult:animalResult]; } //get face center point @@ -447,11 +455,69 @@ - (st_result_t)detectRGBPixelBuffer:(CVPixelBufferRef)pixelBuffer return ST_OK; } +-(st_result_t)detectAttribute:(unsigned char *)imageData pixelFormat:(st_pixel_format)pixel_format imageWidth:(int)image_width imageHeight:(int)image_height imageStride:(int)image_stride orientation:(st_rotate_type)orientation withGenderCallback:(void(^)(BOOL isMale))callback { + unsigned long long config = [self getDetectConfig]; + st_mobile_human_action_t detectResult; + st_result_t ret = ST_OK; + ret = [self.detector detectHumanActionWithBuffer:imageData size:0 config:config rotate:ST_CLOCKWISE_ROTATE_0 pixelFormat:pixel_format width:image_width height:image_height stride:image_stride detectResult:&detectResult]; + if (ret != ST_OK) { + NSLog(@"%s - %d", __func__, __LINE__); + return ret; + } + if (detectResult.face_count == 0) return ST_E_INVALIDARG; + st_mobile_106_t *faces = &detectResult.p_faces[0].face106; + st_mobile_attributes_t *pAttrArray = NULL; + ret = [self.attriDetect detectAttributeWithBuffer:imageData pixelFormat:pixel_format width:image_width height:image_height stride:image_width *4 faces:faces attrArray:pAttrArray withGenderCallback:callback]; + if (ret != ST_OK) { + NSLog(@"%s - %d", __func__, __LINE__); + return ret; + } + return ret; +} + +-(st_result_t)detectAttribute:(unsigned char *)imageData pixelFormat:(st_pixel_format)pixel_format imageWidth:(int)image_width imageHeight:(int)image_height detectResult:(st_mobile_human_action_t)detectResult withGenderCallback:(void(^)(BOOL isMale))callback { + st_result_t ret = ST_OK; + if (detectResult.face_count == 0) return ST_E_INVALIDARG; + st_mobile_106_t *faces = &detectResult.p_faces[0].face106; + st_mobile_attributes_t *pAttrArray = NULL; + ret = [self.attriDetect detectAttributeWithBuffer:imageData pixelFormat:pixel_format width:image_width height:image_height stride:image_width *4 faces:faces attrArray:pAttrArray withGenderCallback:callback]; + if (ret != ST_OK) { + NSLog(@"%s - %d", __func__, __LINE__); + return ret; + } + return ret; +} + +//iRet = st_mobile_human_action_detect(_hDetector, +// pBGRAImageIn, +// ST_PIX_FMT_BGRA8888, +// iWidth, +// iHeight, +// iBytesPerRow, +// ST_CLOCKWISE_ROTATE_0, +// ST_MOBILE_FACE_DETECT , +// &detectResult); + +//- (st_result_t)detectAttributeWithPixelbuffer:(CVPixelBufferRef)pixelBuffer +// detectResult:(st_mobile_human_action_t)detectResult +// attrArray:(st_mobile_attributes_t *)pAttrArray withGenderCallback:(void(^)(BOOL isMale))callback { + +//st_mobile_human_action_detect( +// st_handle_t handle, +// const unsigned char *image, +// st_pixel_format pixel_format, +// int image_width, +// int image_height, +// int image_stride, +// st_rotate_type orientation, +// unsigned long long detect_config, +// st_mobile_human_action_t *p_human_action +//); + - (st_result_t)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outTexture:(GLuint)outTexture outPixelFormat:(st_pixel_format)fmt_out outData:(unsigned char *)img_out{ @@ -463,7 +529,6 @@ - (st_result_t)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:rotate humanAction:detectResult animalResult:animalResult - animalCount:animalCount outTexture:outTexture outPixelFormat:fmt_out outData:img_out]; @@ -472,7 +537,6 @@ - (st_result_t)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:rotate humanAction:detectResult animalResult:animalResult - animalCount:animalCount outTexture:outTexture outPixelFormat:fmt_out outData:img_out]; @@ -482,8 +546,7 @@ - (st_result_t)renderPixelBuffer:(CVPixelBufferRef)pixelBuffer - (st_result_t)renderYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outTexture:(GLuint)outTexture outPixelFormat:(st_pixel_format)fmt_out outData:(unsigned char *)img_out{ @@ -524,7 +587,6 @@ - (st_result_t)renderYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:rotate detectResult:detectResult animalResult:animalResult - animalCount:animalCount outPixelFormat:fmt_out outBuffer:img_out]; @@ -539,8 +601,7 @@ - (st_result_t)renderYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer - (st_result_t)renderRGBPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate humanAction:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t *)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outTexture:(GLuint)outTexture outPixelFormat:(st_pixel_format)fmt_out outData:(unsigned char *)img_out{ @@ -576,7 +637,6 @@ - (st_result_t)renderRGBPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:rotate detectResult:detectResult animalResult:animalResult - animalCount:animalCount outPixelFormat:fmt_out outBuffer:img_out]; CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); @@ -616,8 +676,8 @@ - (st_result_t)processData:(unsigned char *)data return ret; } //detect animal - st_mobile_animal_face_t *animalResult = NULL; - int animal_count = 0; + st_mobile_animal_result_t animalResult; + memset(&animalResult, 0, sizeof(st_mobile_animal_result_t)); uint64_t animalConfig = [_effect getAnimalDetectConfig]; if (animalConfig) { ret = [self.animalDetect detectAnimalWithBuffer:data @@ -627,8 +687,7 @@ - (st_result_t)processData:(unsigned char *)data height:height stride:width * 4 config:(st_mobile_animal_type)animalConfig//ST_MOBILE_DOG_DETECT - detectResult:&animalResult - animalCount:&animal_count]; + detectResult:&animalResult]; } //attribute @@ -659,13 +718,13 @@ - (st_result_t)processData:(unsigned char *)data stride:width * 4 rotate:rotate detectResult:detectResult - animalResult:animalResult - animalCount:animal_count + animalResult:&animalResult outPixelFormat:fmt_out outBuffer:outData]; EFFECTSTIMEPRINT(total_cost, "total_cost"); return ST_OK; } +#endif - (GLuint)createTextureWidth:(int)width height:(int)height{ [self setCurrentEAGLContext:self.glContext]; @@ -737,6 +796,7 @@ - (BOOL)getTextureWithPixelBuffer:(CVPixelBufferRef)pixelBuffer return YES; } +#if __has_include("st_mobile_common.h") - (st_mobile_human_action_t)detectHumanActionWithPixelBuffer:(CVPixelBufferRef)pixelBuffer { return [self.detector detectHumanActionWithPixelBuffer:pixelBuffer]; @@ -750,6 +810,7 @@ - (void)setObjectTrackRect:(st_rect_t)rect{ _bObject = rect.top | rect.left | rect.right | rect.bottom; [self.commonObject setObjectRect:rect]; } +#endif - (BOOL)isAuthrized{ return [EffectsToken sharedInstance].bAuthrize; @@ -779,22 +840,29 @@ - (void)deleteTexture:(GLuint *)texture if (*cvTexture) CFRelease(*cvTexture); } #pragma mark - 3D mesh +#if __has_include("st_mobile_common.h") -(void)getMeshList { - st_mobile_face_mesh_list_t mesh_list; - - st_result_t state = [self.detector getMeshList:&mesh_list]; + st_mobile_mesh_info_t mesh_info; + st_result_t state = [self.detector getMeshInfo:&mesh_info]; if (state != ST_OK) { NSLog(@"detect human action error %d", state); return; } - state = [self.effect setFaceMeshList:mesh_list]; + state = [self.effect setFaceMeshList:*(mesh_info.p_mesh)]; if (state != ST_OK) { NSLog(@"effect set face mesh list error %d", state); } } +#endif #pragma mark - Private +- (void)setCurrentEAGLContext:(EAGLContext *)context{ + if (![[EAGLContext currentContext] isEqual:self.glContext]) { + [EAGLContext setCurrentContext:self.glContext]; + } +} +#if __has_include("st_mobile_common.h") - (st_result_t)processYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotate:(st_rotate_type)rotate outTexture:(GLuint)outTexture @@ -841,8 +909,8 @@ - (st_result_t)processYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer } //detect animal - st_mobile_animal_face_t *animalResult = NULL; - int animal_count = 0; + st_mobile_animal_result_t animalResult; + memset(&animalResult, 0, sizeof(st_mobile_animal_result_t)); uint64_t animalConfig = [_effect getAnimalDetectConfig]; if (animalConfig) { ret = [self.animalDetect detectAnimalWithBuffer:needPadding?detectData:yData @@ -852,8 +920,7 @@ - (st_result_t)processYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer height:yHeight stride:iBytesPerRow config:(st_mobile_animal_type)animalConfig//ST_MOBILE_DOG_DETECT - detectResult:&animalResult - animalCount:&animal_count]; + detectResult:&animalResult]; } //render @@ -883,8 +950,7 @@ - (st_result_t)processYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer stride:yWidth rotate:rotate detectResult:detectResult - animalResult:animalResult - animalCount:animal_count + animalResult:&animalResult outPixelFormat:fmt_out outBuffer:img_out]; @@ -961,15 +1027,14 @@ - (GLuint)processRGBAPixelBuffer:(CVPixelBufferRef)pixelBuffer } //detect animal - st_mobile_animal_face_t *animalResult = NULL; - int animal_count = 0; + st_mobile_animal_result_t animalResult; + memset(&animalResult, 0, sizeof(st_mobile_animal_result_t)); uint64_t animalConfig = [_effect getAnimalDetectConfig]; if (animalConfig) { ret = [self.animalDetect detectAnimalWithPixelbuffer:pixelBuffer rotate:rotate config:(st_mobile_animal_type)animalConfig//ST_MOBILE_DOG_DETECT - detectResult:&animalResult - animalCount:&animal_count]; + detectResult:&animalResult]; } //render @@ -1002,8 +1067,7 @@ - (GLuint)processRGBAPixelBuffer:(CVPixelBufferRef)pixelBuffer stride:width * 4 rotate:rotate detectResult:detectResult - animalResult:animalResult - animalCount:animal_count + animalResult:&animalResult outPixelFormat:fmt_out outBuffer:img_out]; CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); @@ -1055,8 +1119,7 @@ - (GLuint)processInputTexture:(GLuint)originTexture stride:(int)stride rotate:(st_rotate_type)rotate detectResult:(st_mobile_human_action_t)detectResult - animalResult:(st_mobile_animal_face_t*)animalResult - animalCount:(int)animalCount + animalResult:(st_mobile_animal_result_t *)animalResult outPixelFormat:(st_pixel_format)fmt_out outBuffer:(unsigned char *)img_out{ //render texture to outTexture @@ -1075,7 +1138,6 @@ - (GLuint)processInputTexture:(GLuint)originTexture rotate:rotate detectResult:detectResult animalResult:animalResult - animalCount:animalCount outDetectResult:beautyOutDecResult withCache:_cvTextureCache outPixelFormat:fmt_out @@ -1084,6 +1146,7 @@ - (GLuint)processInputTexture:(GLuint)originTexture st_mobile_human_action_delete(&beautyOutDecResult); return outputTexture; } +#endif - (void)solvePaddingImage:(Byte *)pImage width:(int)iWidth height:(int)iHeight bytesPerRow:(int *)pBytesPerRow { @@ -1105,13 +1168,18 @@ - (void)solvePaddingImage:(Byte *)pImage width:(int)iWidth height:(int)iHeight b *pBytesPerRow = iBytesPerRowCopied; free(pCopiedImage); } - +#if __has_include("st_mobile_common.h") - (uint64_t)getDetectConfig{ + if (self.configMode == EFDetectConfigModeItsMe) { + return [self getDetectConfigWithMode:EFDetectConfigModeItsMe]; + } return [self.effect getDetectConfig] | (self.detectConfig?self.detectConfig:0); } +- (uint64_t)getDetectConfigWithMode:(EFDetectConfigMode)configMode { + return [self.effect getDetectConfigWithMode:configMode] | (self.detectConfig?self.detectConfig:0); +} #endif - - (GLuint)createaTextureWithData:(unsigned char *)data width:(int)width height:(int)height{ diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/SENSEME.lic b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/SENSEME.lic deleted file mode 100644 index 8b1378917..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/SENSEME.lic +++ /dev/null @@ -1 +0,0 @@ - diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/VideoProcessingManager.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/VideoProcessingManager.m index 74e9fa410..91c4f4297 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/VideoProcessingManager.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/SenseBeautify/Manager/VideoProcessingManager.m @@ -20,11 +20,12 @@ @interface VideoProcessingManager () BOOL _isFirstLaunch; } -@property (nonatomic, strong) EAGLContext *glContext; +@property (nonatomic, strong, readwrite) EAGLContext *glContext; @property (nonatomic) UIDeviceOrientation deviceOrientation; @property (nonatomic) dispatch_queue_t renderQueue; ///贴纸id @property (nonatomic, assign) int stickerId; +@property (nonatomic, copy) NSString *stickerPath; @property (nonatomic, assign) int filterId; @end @@ -34,16 +35,15 @@ @implementation VideoProcessingManager - (instancetype)init { if (self = [super init]) { self.renderQueue = dispatch_queue_create("com.render.queue", DISPATCH_QUEUE_SERIAL); - self.glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - self.effectsProcess = [[EffectsProcess alloc] initWithType:EffectsTypeVideo glContext:self.glContext]; //effects dispatch_async(self.renderQueue, ^{ #if __has_include("st_mobile_common.h") + self.glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; + self.effectsProcess = [[EffectsProcess alloc] initWithType:EffectsTypeVideo glContext:self.glContext]; NSBundle *bundle = [BundleUtil bundleWithBundleName:@"SenseLib" podName:@"senseLib"]; [self.effectsProcess setModelPath:[bundle pathForResource:@"model" ofType:@"bundle"]]; [EAGLContext setCurrentContext:self.glContext]; - self.effectsProcess.detectConfig = ST_MOBILE_FACE_DETECT; - +// self.effectsProcess.detectConfig = ST_MOBILE_FACE_DETECT; #endif }); } @@ -68,10 +68,26 @@ - (void)setStickerWithPath: (NSString *)stickerPath callBack:(void (^)(int))call } - (void)addStylePath: (NSString *)stylePath groupId: (int)groudId strength: (CGFloat)strength callBack:(void (^)(int))callback { - NSString *path = [[NSBundle mainBundle] pathForResource:stylePath ofType:nil]; #if __has_include("st_mobile_common.h") + if (self.stickerId && [stylePath isEqualToString:self.stickerPath]) { + if (groudId == 0) { + [self.effectsProcess setPackageId:self.stickerId groupType:EFFECT_BEAUTY_GROUP_MAKEUP strength:strength]; + } else { + [self.effectsProcess setPackageId:self.stickerId groupType:EFFECT_BEAUTY_GROUP_FILTER strength:strength]; + } + if (callback) { + callback(self.stickerId); + } + return; + } + if (self.stickerId) { + [self removeStickerId:self.stickerId]; + } + NSString *path = [[NSBundle mainBundle] pathForResource:stylePath ofType:nil]; __weak VideoProcessingManager *weakself = self; [self.effectsProcess addStickerWithPath:path callBack:^(st_result_t state, int sticker, uint64_t action) { + weakself.stickerId = sticker; + weakself.stickerPath = path; if (groudId == 0) { [weakself.effectsProcess setPackageId:sticker groupType:EFFECT_BEAUTY_GROUP_MAKEUP strength:strength]; } else { @@ -110,48 +126,40 @@ - (CVPixelBufferRef)videoProcessHandler:(CVPixelBufferRef)pixelBuffer { CVPixelBufferLockBaseAddress(pixelBuffer, 0); int width = (int)CVPixelBufferGetWidth(pixelBuffer); int heigh = (int)CVPixelBufferGetHeight(pixelBuffer); +#if __has_include("st_mobile_common.h") if (_outTexture) { int _cacheW = (int)CVPixelBufferGetWidth(_outputPixelBuffer); int _cacheH = (int)CVPixelBufferGetHeight(_outputPixelBuffer); if (_cacheH != heigh || _cacheW != width) { - GLuint testTexture = 0; -#if __has_include("st_mobile_common.h") + GLuint testTexture = 0; //TODO: shengtao [self.effectsProcess deleteTexture:&testTexture pixelBuffer:&_outputPixelBuffer cvTexture:&_outputCVTexture]; -#endif _outTexture = 0; _outputPixelBuffer = NULL; _outputCVTexture = NULL; } - } - if(!_outTexture){ -#if __has_include("st_mobile_common.h") + } else { [self.effectsProcess createGLObjectWith:width height:heigh texture:&_outTexture pixelBuffer:&_outputPixelBuffer cvTexture:&_outputCVTexture]; -#endif } -#if __has_include("st_mobile_common.h") st_mobile_human_action_t detectResult; memset(&detectResult, 0, sizeof(st_mobile_human_action_t)); st_result_t ret = [self.effectsProcess detectWithPixelBuffer:pixelBuffer rotate:[self getRotateType] cameraPosition:AVCaptureDevicePositionFront humanAction:&detectResult - animalResult:nil - animalCount:nil]; + animalResult:nil]; if (ret != ST_OK) { NSLog(@"人脸检测失败"); CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); return pixelBuffer; } - [self.effectsProcess renderPixelBuffer:pixelBuffer rotate:[self getRotateType] humanAction:detectResult animalResult:nil - animalCount:0 outTexture:self->_outTexture outPixelFormat:ST_PIX_FMT_BGRA8888 outData:nil]; diff --git a/iOS/APIExample/beauty_build.sh b/iOS/APIExample/beauty_build.sh new file mode 100755 index 000000000..b112b89f2 --- /dev/null +++ b/iOS/APIExample/beauty_build.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env sh + +## config beauty +# sed -i -e "s#io.agora.api.example#io.agora.entfull#g" app/build.gradle +# rm -f app/build.gradle-e +# cd app/src/main || exit 1 +# curl -L -H "X-JFrog-Art-Api:${JFROG_API_KEY}" -O "https://artifactory-api.bj2.agoralab.co/artifactory/qa_test_data/beauty/vender_faceunity_resources_apiexample.zip" +# unzip -o vender_faceunity_resources_apiexample.zip +# rm -f vender_faceunity_resources_apiexample.zip + +sed -i -e "s#io.agora.api.example#io.agora.entfull#g" app/build.gradle +rm -f app/build.gradle-e +cd app/src/main || exit 1 +curl -L -O "https://artifactory.agoralab.co/artifactory/qa_test_data/beauty/vender_bytedance_4.6.0_resources.zip" +unzip -o vender_faceunity_resources_apiexample.zip +rm -f vender_faceunity_resources_apiexample.zip + diff --git a/iOS/APIExample/bytedEffect.podspec b/iOS/APIExample/bytedEffect.podspec index 73100b59a..e58175407 100644 --- a/iOS/APIExample/bytedEffect.podspec +++ b/iOS/APIExample/bytedEffect.podspec @@ -1,22 +1,23 @@ Pod::Spec.new do |s| s.name = "bytedEffect" - s.version = "4.3.0" + s.version = "4.5.1" s.license = { "type" => "Copyright", "text" => "Copyright 2018 agora.io. All rights reserved.\n"} s.homepage = 'https://github.com' s.author = { "Agora Lab" => "developer@agora.io" } s.summary = 'Demo for effect-sdk' s.description = "iOS library for agora A/V communication, broadcasting and data channel service." s.platform = :ios - s.frameworks = 'Accelerate','AssetsLibrary','AVFoundation','CoreGraphics','CoreImage','CoreMedia','CoreVideo','Foundation','QuartzCore','UIKit','CoreMotion' + s.frameworks = 'Accelerate','AssetsLibrary','AVFoundation','CoreGraphics','CoreImage','CoreMedia','CoreVideo','Foundation','QuartzCore','UIKit','CoreMotion','Accelerate','JavaScriptCore' s.weak_frameworks = 'Metal','MetalPerformanceShaders', 'Photos', 'CoreML' s.source = { :git => "" } - s.source_files = "ByteEffectLib/**/*.h" + # s.source_files = "ByteEffectLib/**/*.h" # s.public_header_files = "ByteEffectLib/**/*.h" # s.header_mappings_dir = "ByteEffectLib/BytedEffectSDK/" + s.vendored_framework = "ByteEffectLib/*.framework" s.vendored_libraries = "ByteEffectLib/*.a" s.resource_bundles = {"ByteEffectLib" => "ByteEffectLib/**/*.bundle"} s.platform = :ios, '9.0' s.requires_arc = true - s.libraries = 'z' + s.libraries = 'z', 'stdc++' s.dependency 'SSZipArchive' end diff --git a/iOS/APIExample/fu.podspec b/iOS/APIExample/fu.podspec index bc13d1397..e3f695410 100644 --- a/iOS/APIExample/fu.podspec +++ b/iOS/APIExample/fu.podspec @@ -8,9 +8,9 @@ Pod::Spec.new do |spec| spec.author = { "Agora Lab" => "developer@agora.io" } spec.platform = :ios spec.source = { :git => "" } - spec.vendored_frameworks = "FULib/FURenderKit.framework" + # spec.vendored_frameworks = "FULib/FURenderKit.framework" spec.resource_bundles = {"FURenderKit" => "FULib/Resources/*"} spec.requires_arc = true spec.ios.deployment_target = '9.0' - spec.dependency 'FURenderKit' + spec.dependency 'FURenderKit', '8.7.0' end \ No newline at end of file diff --git a/iOS/APIExample/sense.podspec b/iOS/APIExample/sense.podspec index 8739aa686..b4877fa64 100644 --- a/iOS/APIExample/sense.podspec +++ b/iOS/APIExample/sense.podspec @@ -1,5 +1,5 @@ Pod::Spec.new do |spec| - spec.name = "senseLib" + spec.name = "SenseLib" spec.version = "1.0" spec.summary = "Agora iOS video SDK" spec.description = "iOS library for agora A/V communication, broadcasting and data channel service." @@ -8,11 +8,11 @@ Pod::Spec.new do |spec| spec.author = { "Agora Lab" => "developer@agora.io" } spec.platform = :ios spec.source = { :git => "" } - spec.source_files = 'SenseLib/**/*.{h,m, model}' + spec.source_files = 'SenseLib/**/*.{h,m}' + spec.resources = "SenseLib/**/*.zip", "SenseLib/filter_style/*.model", "SenseLib/*.lic", spec.library = "z" spec.vendored_libraries = "SenseLib/**/*.a" spec.resource_bundles = {"SenseLib" => "SenseLib/**/*.bundle"} - spec.resources = "SenseLib/**/*.zip" spec.requires_arc = true spec.ios.deployment_target = '9.0' end \ No newline at end of file From 8efc0caa5e377fd2e2dcf07fbf05aa9c3f4d07f8 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 19:38:09 +0800 Subject: [PATCH 02/28] Add and download beauty resources CI script --- .github/ci/build/modify_podfile.py | 4 +++- .../ThirdBeautify/FUBeautify/Manager/authpack.h | 1 - iOS/APIExample/cloud_build.sh | 15 ++++++++++++++- iOS/APIExample/fu.podspec | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) delete mode 100644 iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/authpack.h diff --git a/.github/ci/build/modify_podfile.py b/.github/ci/build/modify_podfile.py index 3cf89c2bd..f5f1c8756 100644 --- a/.github/ci/build/modify_podfile.py +++ b/.github/ci/build/modify_podfile.py @@ -10,6 +10,8 @@ def modfiy(path): line = "" elif 'sh .download_script' in line: line = line.replace('true', 'false') + "\n" + elif 'fuLib' in line: + line = "pod 'fuLib', :path => 'fu.podspec'" contents.append(line) file.close() @@ -21,4 +23,4 @@ def modfiy(path): if __name__ == '__main__': path = sys.argv[1:][0] - modfiy(path.strip()) \ No newline at end of file + modfiy(path.strip()) diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/authpack.h b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/authpack.h deleted file mode 100644 index 9c1656707..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/authpack.h +++ /dev/null @@ -1 +0,0 @@ -static char g_auth_package[]={}; diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index de0bac2cb..2a09058eb 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -10,7 +10,13 @@ if [ "$BUILD_NUMBER" = "" ]; then fi -cd ${PROJECT_PATH} +cd ${PROJECT_PATH} + +#下载美颜资源 +echo "start download fu resource" +curl -L -H "X-JFrog-Art-Api:${JFROG_API_KEY}" -O "https://artifactory.agoralab.co/artifactory/qa_test_data/beauty/vender_bytedance_iOS.zip" +unzip -o vender_bytedance_iOS.zip +rm -f vender_bytedance_iOS.zip #打开第三方播放器配置 sed -i -e "s#\# pod 'ijkplayer'# pod 'ijkplayer'#g" Podfile @@ -35,20 +41,26 @@ PBXPROJ_PATH=${TARGET_NAME}.xcodeproj/project.pbxproj /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH + # Release /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH # 屏幕共享Extension # Debug /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH + # Release /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH # SimpleFilter # Debug @@ -63,6 +75,7 @@ PBXPROJ_PATH=${TARGET_NAME}.xcodeproj/project.pbxproj #修改build number # Debug /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:CURRENT_PROJECT_VERSION ${BUILD_NUMBER}" $PBXPROJ_PATH + # Release /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:CURRENT_PROJECT_VERSION ${BUILD_NUMBER}" $PBXPROJ_PATH diff --git a/iOS/APIExample/fu.podspec b/iOS/APIExample/fu.podspec index e3f695410..3fc502618 100644 --- a/iOS/APIExample/fu.podspec +++ b/iOS/APIExample/fu.podspec @@ -10,6 +10,7 @@ Pod::Spec.new do |spec| spec.source = { :git => "" } # spec.vendored_frameworks = "FULib/FURenderKit.framework" spec.resource_bundles = {"FURenderKit" => "FULib/Resources/*"} + spec.source_files = "FULib/*.h" spec.requires_arc = true spec.ios.deployment_target = '9.0' spec.dependency 'FURenderKit', '8.7.0' From 0e74b63a92f59f4bd3cbc0f06649047660d7a5fe Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 19:43:33 +0800 Subject: [PATCH 03/28] Test Beauty Resources CI Script --- .github/ci/build/modify_podfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ci/build/modify_podfile.py b/.github/ci/build/modify_podfile.py index f5f1c8756..26cb12dc2 100644 --- a/.github/ci/build/modify_podfile.py +++ b/.github/ci/build/modify_podfile.py @@ -10,8 +10,8 @@ def modfiy(path): line = "" elif 'sh .download_script' in line: line = line.replace('true', 'false') + "\n" - elif 'fuLib' in line: - line = "pod 'fuLib', :path => 'fu.podspec'" + elif 'SenseLib' in line: + line = "pod 'SenseLib', :path => 'sense.podspec'" contents.append(line) file.close() From f346d5735b0dd6ad99fc56ff2fc0ae577a397fe2 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 19:45:44 +0800 Subject: [PATCH 04/28] Delete useless scripts --- iOS/APIExample/beauty_build.sh | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100755 iOS/APIExample/beauty_build.sh diff --git a/iOS/APIExample/beauty_build.sh b/iOS/APIExample/beauty_build.sh deleted file mode 100755 index b112b89f2..000000000 --- a/iOS/APIExample/beauty_build.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env sh - -## config beauty -# sed -i -e "s#io.agora.api.example#io.agora.entfull#g" app/build.gradle -# rm -f app/build.gradle-e -# cd app/src/main || exit 1 -# curl -L -H "X-JFrog-Art-Api:${JFROG_API_KEY}" -O "https://artifactory-api.bj2.agoralab.co/artifactory/qa_test_data/beauty/vender_faceunity_resources_apiexample.zip" -# unzip -o vender_faceunity_resources_apiexample.zip -# rm -f vender_faceunity_resources_apiexample.zip - -sed -i -e "s#io.agora.api.example#io.agora.entfull#g" app/build.gradle -rm -f app/build.gradle-e -cd app/src/main || exit 1 -curl -L -O "https://artifactory.agoralab.co/artifactory/qa_test_data/beauty/vender_bytedance_4.6.0_resources.zip" -unzip -o vender_faceunity_resources_apiexample.zip -rm -f vender_faceunity_resources_apiexample.zip - From d306efa0295dd3699ffe8739453951afe9858c2b Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 20:38:45 +0800 Subject: [PATCH 05/28] Delete the authpack file --- iOS/APIExample/APIExample.xcodeproj/project.pbxproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj index 58ba1bdc3..44f29c857 100644 --- a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj +++ b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj @@ -534,7 +534,6 @@ E7A49CEE29029E0000F06DD4 /* ThirdBeautify.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThirdBeautify.swift; sourceTree = ""; }; E7A49CF129029E0000F06DD4 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/FUBeautify.strings"; sourceTree = ""; }; E7A49CF229029E0000F06DD4 /* FUBeautifyVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUBeautifyVC.h; sourceTree = ""; }; - E7A49CF329029E0000F06DD4 /* authpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authpack.h; sourceTree = ""; }; E7A49CF529029E0000F06DD4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/FUBeautify.storyboard; sourceTree = ""; }; E7A49CF629029E0000F06DD4 /* FUManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUManager.h; sourceTree = ""; }; E7A49CF729029E0000F06DD4 /* FUBeautifyVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUBeautifyVC.m; sourceTree = ""; }; @@ -1431,7 +1430,6 @@ E7A49D0029029E1900F06DD4 /* Manager */ = { isa = PBXGroup; children = ( - E7A49CF329029E0000F06DD4 /* authpack.h */, E7A49CF629029E0000F06DD4 /* FUManager.h */, E7A49CF829029E0000F06DD4 /* FUManager.m */, ); From 7c0aaa047427f55dac1ab1932dd69c3bff41d806 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 20:48:25 +0800 Subject: [PATCH 06/28] Fix CI error --- .../ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m | 3 ++- .../Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m index 1be3981e4..e312eb363 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/FURender/FUBeautyRender.m @@ -7,7 +7,8 @@ #import "FUBeautyRender.h" #import "BundleUtil.h" -#if __has_include("FUManager.h") + +#if __has_include(FURenderMoudle) #import "authpack.h" #endif diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m index 9cdb90e87..922d54311 100755 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/FUBeautify/Manager/FUManager.m @@ -7,9 +7,9 @@ // #import "FUManager.h" -#import "authpack.h" #import "BundleUtil.h" #if __has_include() +#import "authpack.h" #import #endif From c7051e3a4dce4bc226ce9e5550f039f184423973 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Fri, 25 Oct 2024 21:05:24 +0800 Subject: [PATCH 07/28] Add logs --- iOS/APIExample/cloud_build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 2a09058eb..71f533e39 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -14,6 +14,7 @@ cd ${PROJECT_PATH} #下载美颜资源 echo "start download fu resource" +echo "JFROG_API_KEY is $JFROG_API_KEY" curl -L -H "X-JFrog-Art-Api:${JFROG_API_KEY}" -O "https://artifactory.agoralab.co/artifactory/qa_test_data/beauty/vender_bytedance_iOS.zip" unzip -o vender_bytedance_iOS.zip rm -f vender_bytedance_iOS.zip From 687b8824c6b8fe41cbf3fb0033193a650516cd44 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 11:39:50 +0800 Subject: [PATCH 08/28] Modify the download address of sense beauty SDK --- iOS/APIExample/cloud_build.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 71f533e39..3074d416f 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -13,9 +13,8 @@ fi cd ${PROJECT_PATH} #下载美颜资源 -echo "start download fu resource" -echo "JFROG_API_KEY is $JFROG_API_KEY" -curl -L -H "X-JFrog-Art-Api:${JFROG_API_KEY}" -O "https://artifactory.agoralab.co/artifactory/qa_test_data/beauty/vender_bytedance_iOS.zip" +echo "start download fu resource : $sense_lib" +curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_bytedance_iOS.zip" unzip -o vender_bytedance_iOS.zip rm -f vender_bytedance_iOS.zip From 582ecdf369039b3b1dc9ed18a7d068a603c479ba Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 14:05:02 +0800 Subject: [PATCH 09/28] Modify the certificate setting --- iOS/APIExample/cloud_build.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 3074d416f..b26cadd28 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -39,26 +39,26 @@ PBXPROJ_PATH=${TARGET_NAME}.xcodeproj/project.pbxproj # Debug /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH # Release /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH # 屏幕共享Extension # Debug /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH # Release /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'GM72UGLGZW'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH From 173d354619a2645ee75b23695cf5ebb15e9cd32b Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 14:49:14 +0800 Subject: [PATCH 10/28] Add a script log --- iOS/APIExample/cloud_build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index b26cadd28..75735a791 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -79,6 +79,9 @@ PBXPROJ_PATH=${TARGET_NAME}.xcodeproj/project.pbxproj # Release /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:CURRENT_PROJECT_VERSION ${BUILD_NUMBER}" $PBXPROJ_PATH +MODIFIED_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :objects:03D13BF72448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER" "$PBXPROJ_PATH") +echo "Modified Bundle Identifier: $MODIFIED_BUNDLE_ID" + # 读取APPID环境变量 echo AGORA_APP_ID: $APP_ID From b1848444245edb73abf0095643551fc32aeee243 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 15:24:01 +0800 Subject: [PATCH 11/28] Modify the plist file --- iOS/APIExample/ExportOptions.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index 48bb7f98f..80f2f9b2f 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -10,9 +10,9 @@ development provisioningProfiles - io.agora.api.examples + io.agora.entfull AgoraLab2020 - io.agora.api.examples.Agora-ScreenShare-Extension + io.agora.entfull.Agora-ScreenShare-Extension AgoraLab2020 signingCertificate From 2d49a1e03872aa705cde4f91a0235de0569b8034 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 15:38:24 +0800 Subject: [PATCH 12/28] Add logs --- iOS/APIExample/cloud_build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 75735a791..225d3176c 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -108,19 +108,25 @@ ARCHIVE_PATH="${WORKSPACE}/${TARGET_NAME}_${BUILD_NUMBER}.xcarchive" # plist路径 PLIST_PATH="${PROJECT_PATH}/ExportOptions.plist" +echo "start xcode build, appPath: $APP_PATH, target: $TARGET_NAME, config: $CONFIGURATION, archivePath: $ARCHIVE_PATH" # archive 这边使用的工作区间 也可以使用project xcodebuild CODE_SIGN_STYLE="Manual" archive -workspace "${APP_PATH}" -scheme "${TARGET_NAME}" clean CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO -configuration "${CONFIGURATION}" -archivePath "${ARCHIVE_PATH}" -destination 'generic/platform=iOS' -quiet || exit 1 +echo "xcode build finished" + cd ${WORKSPACE} # 压缩archive 7za a -tzip "${TARGET_NAME}_${BUILD_NUMBER}.xcarchive.zip" "${ARCHIVE_PATH}" # 签名 +echo "start export, targetName: $TARGET_NAME, bundleNumber: $BUILD_NUMBER, plistPath: $PLIST_PATH" # sh sign "${TARGET_NAME}_${BUILD_NUMBER}.xcarchive.zip" --type xcarchive --plist "${PLIST_PATH}" sh export "${TARGET_NAME}_${BUILD_NUMBER}.xcarchive.zip" --plist "${PLIST_PATH}" +echo "export finished" + SDK_VERSION=$(echo $sdk_url | cut -d "/" -f 5) OUTPUT_FILE=${WORKSPACE}/${TARGET_NAME}_${BUILD_NUMBER}_${SDK_VERSION}_$(date "+%Y%m%d%H%M%S").ipa mv ${TARGET_NAME}_${BUILD_NUMBER}.ipa $OUTPUT_FILE From 24ce10802606d5b123bd57e6a1c429366d638136 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 19:14:05 +0800 Subject: [PATCH 13/28] Update plist and certificate --- iOS/APIExample/cloud_build.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 225d3176c..bfa92bcc1 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -39,26 +39,26 @@ PBXPROJ_PATH=${TARGET_NAME}.xcodeproj/project.pbxproj # Debug /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'JDPG69R49Z'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF72448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH # Release /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:DEVELOPMENT_TEAM 'JDPG69R49Z'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:03D13BF82448758C00B599B3:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull" $PBXPROJ_PATH # 屏幕共享Extension # Debug /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'JDPG69R49Z'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB825205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH # Release /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:CODE_SIGN_STYLE 'Manual'" $PBXPROJ_PATH -/usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'YS397FG5PA'" $PBXPROJ_PATH +/usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:DEVELOPMENT_TEAM 'JDPG69R49Z'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PROVISIONING_PROFILE_SPECIFIER 'App'" $PBXPROJ_PATH /usr/libexec/PlistBuddy -c "Set :objects:0339BEB925205B80007D4FDD:buildSettings:PRODUCT_BUNDLE_IDENTIFIER io.agora.entfull.Agora-ScreenShare-Extension" $PBXPROJ_PATH From a7d0405cef3cc897def61e9d4732cfba431f9628 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 19:22:24 +0800 Subject: [PATCH 14/28] update plist --- iOS/APIExample/ExportOptions.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index 80f2f9b2f..fe20b328a 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -11,9 +11,9 @@ provisioningProfiles io.agora.entfull - AgoraLab2020 + wildcard io.agora.entfull.Agora-ScreenShare-Extension - AgoraLab2020 + wildcard signingCertificate Apple Development From 88077d960e890732771771a25192e46c7ce5524a Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 19:32:20 +0800 Subject: [PATCH 15/28] update plist --- iOS/APIExample/ExportOptions.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index fe20b328a..1dd6b30fd 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -22,7 +22,7 @@ stripSwiftSymbols teamID - JDPG69R49Z + YS397FG5PA thinning <none> From 1575950493b5f456bee5f0597305a159b476073b Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 20:10:35 +0800 Subject: [PATCH 16/28] Update plist --- iOS/APIExample/ExportOptions.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index 1dd6b30fd..f7b77fdce 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -11,9 +11,9 @@ provisioningProfiles io.agora.entfull - wildcard + AgoraLab2024 io.agora.entfull.Agora-ScreenShare-Extension - wildcard + AgoraLab2024 signingCertificate Apple Development From bf832e6b73f6c9ab91f3c8e76c23d7035ae71468 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 20:15:21 +0800 Subject: [PATCH 17/28] Update plist --- iOS/APIExample/ExportOptions.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index f7b77fdce..9514c0546 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -22,7 +22,7 @@ stripSwiftSymbols teamID - YS397FG5PA + JDPG69R49Z thinning <none> From fcdf4b2d2a079d0cd8118514130c29031e3d764d Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Mon, 28 Oct 2024 20:34:02 +0800 Subject: [PATCH 18/28] Update plist --- iOS/APIExample/ExportOptions.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index 9514c0546..80f2f9b2f 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -11,9 +11,9 @@ provisioningProfiles io.agora.entfull - AgoraLab2024 + AgoraLab2020 io.agora.entfull.Agora-ScreenShare-Extension - AgoraLab2024 + AgoraLab2020 signingCertificate Apple Development From 254268161c8cdda539a3bb3da9ef7a79206e7e71 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 14:39:58 +0800 Subject: [PATCH 19/28] Add logs --- .github/ci/build/build_ios.sh | 2 ++ iOS/APIExample/Podfile | 6 +++--- iOS/APIExample/cloud_build.sh | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/ci/build/build_ios.sh b/.github/ci/build/build_ios.sh index f8491ac4c..07517f9eb 100644 --- a/.github/ci/build/build_ios.sh +++ b/.github/ci/build/build_ios.sh @@ -70,6 +70,8 @@ mkdir ./$unzip_name/samples cp -rf ./iOS/${ios_direction} ./$unzip_name/samples/API-Example || exit 1 ls -al ./$unzip_name/samples/API-Example/ mv ./$unzip_name/samples/API-Example/sdk.podspec ./$unzip_name/ || exit 1 + +echo "work space1: $WORKSPACE" python3 ./.github/ci/build/modify_podfile.py ./$unzip_name/samples/API-Example/Podfile || exit 1 diff --git a/iOS/APIExample/Podfile b/iOS/APIExample/Podfile index fe6a2926d..f00176dd5 100644 --- a/iOS/APIExample/Podfile +++ b/iOS/APIExample/Podfile @@ -22,9 +22,9 @@ target 'APIExample' do pod 'SwiftLint', '~> 0.53.0' pod 'SnapKit', '~> 5.7.0' -# pod 'senseLib', :path => 'sense.podspec' -# pod 'bytedEffect', :path => 'bytedEffect.podspec' -# pod 'fuLib', :path => 'fu.podspec' + #pod 'SenseLib', :path => 'sense.podspec' + #pod 'bytedEffect', :path => 'bytedEffect.podspec' + #pod 'fuLib', :path => 'fu.podspec' end target 'Agora-ScreenShare-Extension' do diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index bfa92bcc1..5370dfb00 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -21,6 +21,9 @@ rm -f vender_bytedance_iOS.zip #打开第三方播放器配置 sed -i -e "s#\# pod 'ijkplayer'# pod 'ijkplayer'#g" Podfile +echo "work space: $WORKSPACE" +echo "project path: $PROJECT_PATH" + pod install || exit 1 # 打包环境 From d167b3cde5d5816b742f6de375cbd5864d71f570 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 15:59:11 +0800 Subject: [PATCH 20/28] Modify the beauty configuration script --- .github/ci/build/modify_podfile.py | 2 -- iOS/APIExample/Podfile | 10 +++++----- iOS/APIExample/cloud_build.sh | 6 ++++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/ci/build/modify_podfile.py b/.github/ci/build/modify_podfile.py index 26cb12dc2..c9ad317ec 100644 --- a/.github/ci/build/modify_podfile.py +++ b/.github/ci/build/modify_podfile.py @@ -10,8 +10,6 @@ def modfiy(path): line = "" elif 'sh .download_script' in line: line = line.replace('true', 'false') + "\n" - elif 'SenseLib' in line: - line = "pod 'SenseLib', :path => 'sense.podspec'" contents.append(line) file.close() diff --git a/iOS/APIExample/Podfile b/iOS/APIExample/Podfile index f00176dd5..648b28054 100644 --- a/iOS/APIExample/Podfile +++ b/iOS/APIExample/Podfile @@ -4,8 +4,8 @@ #source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git' def common_pods - pod 'AgoraRtcEngine_iOS', '4.5.0' -# pod 'sdk', :path => 'sdk.podspec' + #pod 'AgoraRtcEngine_iOS', '4.5.0' + pod 'sdk', :path => 'sdk.podspec' end target 'APIExample' do @@ -22,9 +22,9 @@ target 'APIExample' do pod 'SwiftLint', '~> 0.53.0' pod 'SnapKit', '~> 5.7.0' - #pod 'SenseLib', :path => 'sense.podspec' - #pod 'bytedEffect', :path => 'bytedEffect.podspec' - #pod 'fuLib', :path => 'fu.podspec' +# pod 'SenseLib', :path => 'sense.podspec' +# pod 'bytedEffect', :path => 'bytedEffect.podspec' +# pod 'fuLib', :path => 'fu.podspec' end target 'Agora-ScreenShare-Extension' do diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 5370dfb00..159bb0ff2 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -21,9 +21,15 @@ rm -f vender_bytedance_iOS.zip #打开第三方播放器配置 sed -i -e "s#\# pod 'ijkplayer'# pod 'ijkplayer'#g" Podfile +#打开第三方美颜 +sed -i -e "s#\# pod 'SenseLib'# pod 'SenseLib'#g" Podfile +sed -i -e "s#\# pod 'bytedEffect'# pod 'bytedEffect'#g" Podfile +sed -i -e "s#\# pod 'fuLib'# pod 'fuLib'#g" Podfile + echo "work space: $WORKSPACE" echo "project path: $PROJECT_PATH" + pod install || exit 1 # 打包环境 From 463fe1b769a8eb3af5b3a3b7d7537430f4e16183 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 16:10:07 +0800 Subject: [PATCH 21/28] update podfile --- iOS/APIExample/Podfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/Podfile b/iOS/APIExample/Podfile index 648b28054..54f98ffb2 100644 --- a/iOS/APIExample/Podfile +++ b/iOS/APIExample/Podfile @@ -4,8 +4,8 @@ #source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git' def common_pods - #pod 'AgoraRtcEngine_iOS', '4.5.0' - pod 'sdk', :path => 'sdk.podspec' + pod 'AgoraRtcEngine_iOS', '4.5.0' + #pod 'sdk', :path => 'sdk.podspec' end target 'APIExample' do From 004cc149e5922efdb05253630ae79fc113604fcd Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 16:21:04 +0800 Subject: [PATCH 22/28] Modify the script --- iOS/APIExample/cloud_build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 159bb0ff2..0f5b44f1a 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -23,8 +23,8 @@ sed -i -e "s#\# pod 'ijkplayer'# pod 'ijkplayer'#g" Podfile #打开第三方美颜 sed -i -e "s#\# pod 'SenseLib'# pod 'SenseLib'#g" Podfile -sed -i -e "s#\# pod 'bytedEffect'# pod 'bytedEffect'#g" Podfile -sed -i -e "s#\# pod 'fuLib'# pod 'fuLib'#g" Podfile +#sed -i -e "s#\# pod 'bytedEffect'# pod 'bytedEffect'#g" Podfile +#sed -i -e "s#\# pod 'fuLib'# pod 'fuLib'#g" Podfile echo "work space: $WORKSPACE" echo "project path: $PROJECT_PATH" From c645637d154d44f0378e3417e0a721758536e002 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 16:46:59 +0800 Subject: [PATCH 23/28] Use the script to modify the content of ExportOption.plist, change bundleId to the value corresponding to the beauty SDK. --- iOS/APIExample/ExportOptions.plist | 4 ++-- iOS/APIExample/cloud_build.sh | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/iOS/APIExample/ExportOptions.plist b/iOS/APIExample/ExportOptions.plist index 80f2f9b2f..48bb7f98f 100644 --- a/iOS/APIExample/ExportOptions.plist +++ b/iOS/APIExample/ExportOptions.plist @@ -10,9 +10,9 @@ development provisioningProfiles - io.agora.entfull + io.agora.api.examples AgoraLab2020 - io.agora.entfull.Agora-ScreenShare-Extension + io.agora.api.examples.Agora-ScreenShare-Extension AgoraLab2020 signingCertificate diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 0f5b44f1a..b26ed24ed 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -117,6 +117,17 @@ ARCHIVE_PATH="${WORKSPACE}/${TARGET_NAME}_${BUILD_NUMBER}.xcarchive" # plist路径 PLIST_PATH="${PROJECT_PATH}/ExportOptions.plist" +# 修改ExportOptions.plist +# 修改 io.agora.api.examples 的值 +echo "start modify ExportOption.plist" +/usr/libexec/PlistBuddy -c "Set :provisioningProfiles:io.agora.api.examples io.agora.entfull" "$PLIST_PATH" + +# 修改 io.agora.api.examples.Agora-ScreenShare-Extension 的值 +/usr/libexec/PlistBuddy -c "Set :provisioningProfiles:io.agora.api.examples.Agora-ScreenShare-Extension io.agora.entfull.Agora-ScreenShare-Extension" "$PLIST_PATH" + +echo "修改后的 provisioningProfiles 值:" +/usr/libexec/PlistBuddy -c "Print :provisioningProfiles" "$PLIST_PATH" + echo "start xcode build, appPath: $APP_PATH, target: $TARGET_NAME, config: $CONFIGURATION, archivePath: $ARCHIVE_PATH" # archive 这边使用的工作区间 也可以使用project From 74c197057933c29a6fcf73d12ff3ad1c04620cab Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 17:01:04 +0800 Subject: [PATCH 24/28] Modify the script --- iOS/APIExample/cloud_build.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index b26ed24ed..274ed7e99 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -120,11 +120,19 @@ PLIST_PATH="${PROJECT_PATH}/ExportOptions.plist" # 修改ExportOptions.plist # 修改 io.agora.api.examples 的值 echo "start modify ExportOption.plist" -/usr/libexec/PlistBuddy -c "Set :provisioningProfiles:io.agora.api.examples io.agora.entfull" "$PLIST_PATH" +# 先获取原始值 +value1=$(/usr/libexec/PlistBuddy -c "Print :provisioningProfiles:io.agora.api.examples" "$PLIST_PATH") +value2=$(/usr/libexec/PlistBuddy -c "Print :provisioningProfiles:io.agora.api.examples.Agora-ScreenShare-Extension" "$PLIST_PATH") -# 修改 io.agora.api.examples.Agora-ScreenShare-Extension 的值 -/usr/libexec/PlistBuddy -c "Set :provisioningProfiles:io.agora.api.examples.Agora-ScreenShare-Extension io.agora.entfull.Agora-ScreenShare-Extension" "$PLIST_PATH" +# 删除原始键 +/usr/libexec/PlistBuddy -c "Delete :provisioningProfiles:io.agora.api.examples" "$PLIST_PATH" +/usr/libexec/PlistBuddy -c "Delete :provisioningProfiles:io.agora.api.examples.Agora-ScreenShare-Extension" "$PLIST_PATH" +# 添加新键和值 +/usr/libexec/PlistBuddy -c "Add :provisioningProfiles:io.agora.entfull string $value1" "$PLIST_PATH" +/usr/libexec/PlistBuddy -c "Add :provisioningProfiles:io.agora.entfull.Agora-ScreenShare-Extension string $value2" "$PLIST_PATH" + +# 打印修改后的 provisioningProfiles 值 echo "修改后的 provisioningProfiles 值:" /usr/libexec/PlistBuddy -c "Print :provisioningProfiles" "$PLIST_PATH" From a6919a92843dda921d7971c4cdaa85c1adeb2e28 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 18:01:16 +0800 Subject: [PATCH 25/28] Update cloud_build.sh --- iOS/APIExample/cloud_build.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 274ed7e99..7f584c561 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -13,18 +13,28 @@ fi cd ${PROJECT_PATH} #下载美颜资源 -echo "start download fu resource : $sense_lib" +echo "start download bytedance resource : $bytedance_lib" curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_bytedance_iOS.zip" unzip -o vender_bytedance_iOS.zip rm -f vender_bytedance_iOS.zip +echo "start download sense resource : $sense_lib" +curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_sense_iOS.zip" +unzip -o vender_sense_iOS.zip +rm -f vender_sense_iOS.zip + +echo "start download fu resource : $fu_lib" +curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_fu_iOS.zip" +unzip -o vender_fu_iOS.zip +rm -f vender_fu_iOS.zip + #打开第三方播放器配置 sed -i -e "s#\# pod 'ijkplayer'# pod 'ijkplayer'#g" Podfile #打开第三方美颜 sed -i -e "s#\# pod 'SenseLib'# pod 'SenseLib'#g" Podfile -#sed -i -e "s#\# pod 'bytedEffect'# pod 'bytedEffect'#g" Podfile -#sed -i -e "s#\# pod 'fuLib'# pod 'fuLib'#g" Podfile +sed -i -e "s#\# pod 'bytedEffect'# pod 'bytedEffect'#g" Podfile +sed -i -e "s#\# pod 'fuLib'# pod 'fuLib'#g" Podfile echo "work space: $WORKSPACE" echo "project path: $PROJECT_PATH" From 457a7532a2833ae4c1bc311e7f2af35d9a730574 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 18:08:13 +0800 Subject: [PATCH 26/28] Modify sticker path --- .../BeautyAPI/Render/BytesRender/BytesBeautyRender.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m index 99f993e01..cce26dd58 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/BeautyAPI/Render/BytesRender/BytesBeautyRender.m @@ -187,7 +187,7 @@ - (void)setMakeup:(BOOL)isSelected { - (void)setSticker:(BOOL)isSelected { #if __has_include(BytesMoudle) if (isSelected) { - [self.effectManager setStickerPath:@"zhaocaimao"]; + [self.effectManager setStickerPath:@"stickers_zhaocaimao"]; } else { [self.effectManager setStickerPath:@""]; } From 9be799ce96fb33f617420a279a7edc0f2db9e4d6 Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 18:18:26 +0800 Subject: [PATCH 27/28] Modify the script --- iOS/APIExample/cloud_build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iOS/APIExample/cloud_build.sh b/iOS/APIExample/cloud_build.sh index 7f584c561..e784bbc55 100755 --- a/iOS/APIExample/cloud_build.sh +++ b/iOS/APIExample/cloud_build.sh @@ -14,17 +14,17 @@ cd ${PROJECT_PATH} #下载美颜资源 echo "start download bytedance resource : $bytedance_lib" -curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_bytedance_iOS.zip" +curl -L -O "$bytedance_lib" unzip -o vender_bytedance_iOS.zip rm -f vender_bytedance_iOS.zip echo "start download sense resource : $sense_lib" -curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_sense_iOS.zip" +curl -L -O "$sense_lib" unzip -o vender_sense_iOS.zip rm -f vender_sense_iOS.zip echo "start download fu resource : $fu_lib" -curl -L -O "https://fullapp.oss-cn-beijing.aliyuncs.com/API-Examples/ci/beauty/ios/vender_fu_iOS.zip" +curl -L -O "$fu_lib" unzip -o vender_fu_iOS.zip rm -f vender_fu_iOS.zip From d2a01fdba7fc1a07781c329d51427ccfa8fdc00d Mon Sep 17 00:00:00 2001 From: qinhui <> Date: Tue, 29 Oct 2024 19:05:31 +0800 Subject: [PATCH 28/28] Read bytes beauty license path from bundle, modify beauty installation instructions --- .../Base.lproj/BytedEffect.storyboard | 18 ++++++------ .../ByteBeautify/Manager/BELicenseHelper.mm | 28 +++++++++++++------ .../Base.lproj/FUBeautify.storyboard | 19 ++++++------- .../Base.lproj/SenseBeautify.storyboard | 19 ++++++------- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Base.lproj/BytedEffect.storyboard b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Base.lproj/BytedEffect.storyboard index f4fcda5fc..078ebc6c2 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Base.lproj/BytedEffect.storyboard +++ b/iOS/APIExample/APIExample/Examples/Advanced/ThirdBeautify/ByteBeautify/Base.lproj/BytedEffect.storyboard @@ -1,9 +1,9 @@ - + - + @@ -105,14 +105,12 @@