feat: Reintroduce Macros for Frame Processor Plugin registration (#2027)

in VisionCamera v1 & v2 there were two ObjC macros that were helping
in creation/registration of Frame Processors, but these were removed with
v3

This PR reintroduces such macros, which will not only make FP development
easier, but also it will also fix issues people had with registration of
Swift Frame Processors (+load vs +initialize issues)

Docs were also updated to reflect that the macros should be used to
correctly initialize and register ObjC/Swift Frame Processors
This commit is contained in:
Mateusz Mędrek
2023-10-19 10:35:14 +02:00
committed by GitHub
parent 2666ac53a6
commit a291642c53
15 changed files with 92 additions and 60 deletions

View File

@@ -40,7 +40,7 @@ public class ExampleFrameProcessorPlugin extends FrameProcessorPlugin {
return map;
}
ExampleFrameProcessorPlugin() {
ExampleFrameProcessorPlugin(@Nullable Map<String, Object> options) {
Log.d("ExamplePlugin", " - options: " + options.toString());
}
}

View File

@@ -4,7 +4,11 @@ import android.util.Log
import com.mrousavy.camera.frameprocessor.Frame
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin
class ExampleKotlinFrameProcessorPlugin: FrameProcessorPlugin() {
class ExampleKotlinFrameProcessorPlugin(options: Map<String, Any>?): FrameProcessorPlugin(options) {
init {
Log.d("ExampleKotlinPlugin", " - options" + options?.toString())
}
override fun callback(frame: Frame, params: Map<String, Any>?): Any? {
if (params == null) {
return null

View File

@@ -65,7 +65,7 @@ public class MainApplication extends Application implements ReactApplication {
DefaultNewArchitectureEntryPoint.load();
}
FrameProcessorPluginRegistry.addFrameProcessorPlugin("example_plugin", options -> new ExampleFrameProcessorPlugin());
FrameProcessorPluginRegistry.addFrameProcessorPlugin("example_kotlin_swift_plugin", options -> new ExampleKotlinFrameProcessorPlugin());
FrameProcessorPluginRegistry.addFrameProcessorPlugin("example_plugin", options -> new ExampleFrameProcessorPlugin(options));
FrameProcessorPluginRegistry.addFrameProcessorPlugin("example_kotlin_swift_plugin", options -> new ExampleKotlinFrameProcessorPlugin(options));
}
}

View File

@@ -18,6 +18,13 @@
@implementation ExampleFrameProcessorPlugin
- (instancetype)initWithOptions:(NSDictionary * _Nullable)options
{
self = [super initWithOptions:options];
NSLog(@"ExamplePlugin - options: %@", options);
return self;
}
- (id)callback:(Frame *)frame withArguments:(NSDictionary *)arguments {
CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
NSLog(@"ExamplePlugin: %zu x %zu Image. Logging %lu parameters:", CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer), (unsigned long)arguments.count);
@@ -38,12 +45,7 @@
};
}
+ (void) load {
[FrameProcessorPluginRegistry addFrameProcessorPlugin:@"example_plugin"
withInitializer:^FrameProcessorPlugin*(NSDictionary* options) {
return [[ExampleFrameProcessorPlugin alloc] init];
}];
}
VISION_EXPORT_FRAME_PROCESSOR(ExampleFrameProcessorPlugin, example_plugin)
@end
#endif

View File

@@ -6,26 +6,12 @@
//
#if __has_include(<VisionCamera/FrameProcessorPlugin.h>)
#import <Foundation/Foundation.h>
#import <VisionCamera/FrameProcessorPlugin.h>
#import <VisionCamera/FrameProcessorPluginRegistry.h>
#import <VisionCamera/Frame.h>
#import "VisionCameraExample-Swift.h"
// Example for a Swift Frame Processor plugin automatic registration
@interface ExampleSwiftFrameProcessorPlugin (FrameProcessorPluginLoader)
@end
@implementation ExampleSwiftFrameProcessorPlugin (FrameProcessorPluginLoader)
+ (void)initialize {
[FrameProcessorPluginRegistry addFrameProcessorPlugin:@"example_kotlin_swift_plugin"
withInitializer:^FrameProcessorPlugin* _Nonnull(NSDictionary* _Nullable options) {
return [[ExampleSwiftFrameProcessorPlugin alloc] init];
}];
}
@end
// // Example for a Swift Frame Processor plugin automatic registration
VISION_EXPORT_SWIFT_FRAME_PROCESSOR(ExampleSwiftFrameProcessorPlugin, example_kotlin_swift_plugin)
#endif

View File

@@ -11,6 +11,12 @@ import VisionCamera
// Example for a Swift Frame Processor plugin
@objc(ExampleSwiftFrameProcessorPlugin)
public class ExampleSwiftFrameProcessorPlugin: FrameProcessorPlugin {
public override init(options: [AnyHashable: Any]! = [:]) {
super.init(options: options)
print("ExampleSwiftPlugin - options: \(String(describing: options))")
}
public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?) -> Any? {
let imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer)

View File

@@ -507,7 +507,7 @@ PODS:
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.10)
- SocketRocket (0.6.1)
- VisionCamera (3.3.1):
- VisionCamera (3.4.0):
- React
- React-callinvoker
- React-Core
@@ -747,7 +747,7 @@ SPEC CHECKSUMS:
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
VisionCamera: f386aee60abb07d979c506ea9e6d4831e596cafe
VisionCamera: eead9df29ac5935d5685b5ecaea3ae8b6da84bff
Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce
PODFILE CHECKSUM: 27f53791141a3303d814e09b55770336416ff4eb

View File

@@ -17,6 +17,7 @@ import type { Routes } from './Routes'
import type { NativeStackScreenProps } from '@react-navigation/native-stack'
import { useIsFocused } from '@react-navigation/core'
import { examplePlugin } from './frame-processors/ExamplePlugin'
import { exampleKotlinSwiftPlugin } from './frame-processors/ExampleKotlinSwiftPlugin'
import { usePreferredCameraDevice } from './hooks/usePreferredCameraDevice'
const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera)
@@ -166,6 +167,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
console.log(`${frame.timestamp}: ${frame.width}x${frame.height} ${frame.pixelFormat} Frame (${frame.orientation})`)
examplePlugin(frame)
exampleKotlinSwiftPlugin(frame)
}, [])
return (

View File

@@ -1,6 +1,6 @@
import { VisionCameraProxy, Frame } from 'react-native-vision-camera'
const plugin = VisionCameraProxy.getFrameProcessorPlugin('example_kotlin_swift_plugin')
const plugin = VisionCameraProxy.getFrameProcessorPlugin('example_kotlin_swift_plugin', { foo: 'bar' })
export function exampleKotlinSwiftPlugin(frame: Frame): string[] {
'worklet'