feat: Implement Frame.close()
(#229)
* Implement `Frame.close()` * close frame in dtor * Update JImageProxyHostObject.cpp * fix close * Check if closed * remove a few logs * r * fix `isValid` and `isReady` * Add JImage * Release JNI frame ref on destroy * fix pod setup * Fix isValid call * Fix `close` not returning a function * throw error if closed twice * iOS: Schedule `console.error` call on JS thread * Android: Log Frame Processor Error to JS * fix syntax * Check if valid `toString()` * Update Frame.ts * Remove `isReady` * Fix JImage accessors * remove `JImage` C++ sources * Throw error if accessing props on closed Frame * Delete `JImage.h`
This commit is contained in:
parent
7d3b352155
commit
fa5f5c0cab
@ -102,7 +102,6 @@ void FrameProcessorRuntimeManager::logErrorToJS(const std::string& message) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// actual JSI installer
|
// actual JSI installer
|
||||||
void FrameProcessorRuntimeManager::installJSIBindings() {
|
void FrameProcessorRuntimeManager::installJSIBindings() {
|
||||||
__android_log_write(ANDROID_LOG_INFO, TAG, "Installing JSI bindings...");
|
__android_log_write(ANDROID_LOG_INFO, TAG, "Installing JSI bindings...");
|
||||||
|
@ -14,31 +14,38 @@ using namespace jni;
|
|||||||
|
|
||||||
int JImageProxy::getWidth() {
|
int JImageProxy::getWidth() {
|
||||||
static const auto getWidthMethod = getClass()->getMethod<jint()>("getWidth");
|
static const auto getWidthMethod = getClass()->getMethod<jint()>("getWidth");
|
||||||
return getWidthMethod(javaClassLocal());
|
return getWidthMethod(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
int JImageProxy::getHeight() {
|
int JImageProxy::getHeight() {
|
||||||
static const auto getWidthMethod = getClass()->getMethod<jint()>("getHeight");
|
static const auto getWidthMethod = getClass()->getMethod<jint()>("getHeight");
|
||||||
return getWidthMethod(javaClassLocal());
|
return getWidthMethod(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JImageProxy::getIsValid() {
|
bool JImageProxy::getIsValid() {
|
||||||
return true;
|
static const auto utilsClass = findClassStatic("com/mrousavy/camera/frameprocessor/ImageProxyUtils");
|
||||||
|
static const auto isImageProxyValidMethod = utilsClass->getStaticMethod<jboolean(JImageProxy::javaobject)>("isImageProxyValid");
|
||||||
|
return isImageProxyValidMethod(utilsClass, self());
|
||||||
}
|
}
|
||||||
|
|
||||||
int JImageProxy::getPlaneCount() {
|
int JImageProxy::getPlaneCount() {
|
||||||
static const auto getPlanesMethod = getClass()->getMethod<JArrayClass<jobject>()>("getPlanes");
|
static const auto getPlanesMethod = getClass()->getMethod<JArrayClass<jobject>()>("getPlanes");
|
||||||
auto planes = getPlanesMethod(javaClassLocal());
|
auto planes = getPlanesMethod(self());
|
||||||
return planes->size();
|
return planes->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int JImageProxy::getBytesPerRow() {
|
int JImageProxy::getBytesPerRow() {
|
||||||
static const auto getPlanesMethod = getClass()->getMethod<JArrayClass<jobject>()>("getPlanes");
|
static const auto getPlanesMethod = getClass()->getMethod<JArrayClass<jobject>()>("getPlanes");
|
||||||
auto planes = getPlanesMethod(javaClassLocal());
|
auto planes = getPlanesMethod(self());
|
||||||
auto firstPlane = planes->getElement(0);
|
auto firstPlane = planes->getElement(0);
|
||||||
|
|
||||||
static const auto getRowStrideMethod = findClassLocal("android/media/Image$PlaneProxy")->getMethod<int()>("getRowStride");
|
static const auto getRowStrideMethod = findClassLocal("android/media/Image$PlaneProxy")->getMethod<int()>("getRowStride");
|
||||||
return getRowStrideMethod(firstPlane.get());
|
return getRowStrideMethod(firstPlane.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JImageProxy::close() {
|
||||||
|
static const auto closeMethod = getClass()->getMethod<void()>("close");
|
||||||
|
closeMethod(self());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace vision
|
} // namespace vision
|
||||||
|
@ -18,6 +18,8 @@ struct JImageProxy : public facebook::jni::JavaClass<JImageProxy> {
|
|||||||
bool getIsValid();
|
bool getIsValid();
|
||||||
int getPlaneCount();
|
int getPlaneCount();
|
||||||
int getBytesPerRow();
|
int getBytesPerRow();
|
||||||
|
void close();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vision
|
} // namespace vision
|
||||||
|
@ -13,11 +13,11 @@ std::vector<jsi::PropNameID> JImageProxyHostObject::getPropertyNames(jsi::Runtim
|
|||||||
std::vector<jsi::PropNameID> result;
|
std::vector<jsi::PropNameID> result;
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toString")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toString")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isValid")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isValid")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isReady")));
|
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("width")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("width")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("height")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("height")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("bytesPerRow")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("bytesPerRow")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("planesCount")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("planesCount")));
|
||||||
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("close")));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,10 @@ jsi::Value JImageProxyHostObject::get(jsi::Runtime& runtime, const jsi::PropName
|
|||||||
auto name = propNameId.utf8(runtime);
|
auto name = propNameId.utf8(runtime);
|
||||||
|
|
||||||
if (name == "toString") {
|
if (name == "toString") {
|
||||||
auto toString = [this] (jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
|
auto toString = [this] (jsi::Runtime& runtime, const jsi::Value&, const jsi::Value*, size_t) -> jsi::Value {
|
||||||
|
if (!this->frame) {
|
||||||
|
return jsi::String::createFromUtf8(runtime, "[closed frame]");
|
||||||
|
}
|
||||||
auto width = this->frame->getWidth();
|
auto width = this->frame->getWidth();
|
||||||
auto height = this->frame->getHeight();
|
auto height = this->frame->getHeight();
|
||||||
auto str = std::to_string(width) + " x " + std::to_string(height) + " Frame";
|
auto str = std::to_string(width) + " x " + std::to_string(height) + " Frame";
|
||||||
@ -33,32 +36,57 @@ jsi::Value JImageProxyHostObject::get(jsi::Runtime& runtime, const jsi::PropName
|
|||||||
};
|
};
|
||||||
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
|
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
|
||||||
}
|
}
|
||||||
|
if (name == "close") {
|
||||||
|
auto close = [this] (jsi::Runtime& runtime, const jsi::Value&, const jsi::Value*, size_t) -> jsi::Value {
|
||||||
|
if (!this->frame) {
|
||||||
|
throw jsi::JSError(runtime, "Trying to close an already closed frame! Did you call frame.close() twice?");
|
||||||
|
}
|
||||||
|
this->close();
|
||||||
|
return jsi::Value::undefined();
|
||||||
|
};
|
||||||
|
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "close"), 0, close);
|
||||||
|
}
|
||||||
|
|
||||||
if (name == "isValid") {
|
if (name == "isValid") {
|
||||||
return jsi::Value(this->frame->getIsValid());
|
return jsi::Value(this->frame && this->frame->getIsValid());
|
||||||
}
|
|
||||||
if (name == "isReady") {
|
|
||||||
return jsi::Value(this->frame->getIsValid());
|
|
||||||
}
|
}
|
||||||
if (name == "width") {
|
if (name == "width") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
return jsi::Value(this->frame->getWidth());
|
return jsi::Value(this->frame->getWidth());
|
||||||
}
|
}
|
||||||
if (name == "height") {
|
if (name == "height") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
return jsi::Value(this->frame->getHeight());
|
return jsi::Value(this->frame->getHeight());
|
||||||
}
|
}
|
||||||
if (name == "bytesPerRow") {
|
if (name == "bytesPerRow") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
return jsi::Value(this->frame->getBytesPerRow());
|
return jsi::Value(this->frame->getBytesPerRow());
|
||||||
}
|
}
|
||||||
if (name == "planesCount") {
|
if (name == "planesCount") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
return jsi::Value(this->frame->getPlaneCount());
|
return jsi::Value(this->frame->getPlaneCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsi::Value::undefined();
|
return jsi::Value::undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JImageProxyHostObject::assertIsFrameStrong(jsi::Runtime& runtime, const std::string& accessedPropName) {
|
||||||
|
if (!this->frame) {
|
||||||
|
auto message = "Cannot get `" + accessedPropName + "`, frame is already closed!";
|
||||||
|
throw jsi::JSError(runtime, message.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JImageProxyHostObject::~JImageProxyHostObject() {
|
JImageProxyHostObject::~JImageProxyHostObject() {
|
||||||
__android_log_write(ANDROID_LOG_INFO, TAG, "Destroying JImageProxyHostObject...");
|
this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JImageProxyHostObject::close() {
|
||||||
|
if (this->frame) {
|
||||||
|
this->frame->close();
|
||||||
|
this->frame.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vision
|
} // namespace vision
|
||||||
|
@ -22,14 +22,17 @@ class JSI_EXPORT JImageProxyHostObject : public jsi::HostObject {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
||||||
|
|
||||||
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
jni::local_ref<JImageProxy> frame;
|
jni::local_ref<JImageProxy> frame;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static auto constexpr TAG = "VisionCamera";
|
static auto constexpr TAG = "VisionCamera";
|
||||||
|
|
||||||
|
void assertIsFrameStrong(jsi::Runtime& runtime, const std::string& accessedPropName);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vision
|
} // namespace vision
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.mrousavy.camera.frameprocessor;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.media.Image;
|
||||||
|
import androidx.camera.core.ImageProxy;
|
||||||
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
|
|
||||||
|
public class ImageProxyUtils {
|
||||||
|
@SuppressLint("UnsafeOptInUsageError")
|
||||||
|
@DoNotStrip
|
||||||
|
public static boolean isImageProxyValid(ImageProxy imageProxy) {
|
||||||
|
try {
|
||||||
|
Image image = imageProxy.getImage();
|
||||||
|
if (image == null) return false;
|
||||||
|
// will throw an exception if the image is already closed
|
||||||
|
imageProxy.getImage().getCropRect();
|
||||||
|
// no exception thrown, image must still be valid.
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// exception thrown, image has already been closed.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,34 +10,34 @@
|
|||||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
2D25D416E10790D96A54417B /* libPods-VisionCameraExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0FC5D1C53D06B40B4CA981B8 /* libPods-VisionCameraExample.a */; };
|
|
||||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||||
B8DB3BD5263DE8B7004C18D7 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
|
B8DB3BD5263DE8B7004C18D7 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
|
||||||
B8DB3BDC263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BD8263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m */; };
|
B8DB3BDC263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BD8263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m */; };
|
||||||
B8DB3BDD263DEA31004C18D7 /* ExamplePluginSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BDA263DEA31004C18D7 /* ExamplePluginSwift.swift */; };
|
B8DB3BDD263DEA31004C18D7 /* ExamplePluginSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BDA263DEA31004C18D7 /* ExamplePluginSwift.swift */; };
|
||||||
B8DB3BDE263DEA31004C18D7 /* ExamplePluginSwift.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BDB263DEA31004C18D7 /* ExamplePluginSwift.m */; };
|
B8DB3BDE263DEA31004C18D7 /* ExamplePluginSwift.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BDB263DEA31004C18D7 /* ExamplePluginSwift.m */; };
|
||||||
B8F0E10825E0199F00586F16 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F0E10725E0199F00586F16 /* File.swift */; };
|
B8F0E10825E0199F00586F16 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F0E10725E0199F00586F16 /* File.swift */; };
|
||||||
|
C0B129659921D2EA967280B2 /* libPods-VisionCameraExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CDCFE89C25C89320B98945E /* libPods-VisionCameraExample.a */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||||
0FC5D1C53D06B40B4CA981B8 /* libPods-VisionCameraExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VisionCameraExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
13B07F961A680F5B00A75B9A /* VisionCameraExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VisionCameraExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
13B07F961A680F5B00A75B9A /* VisionCameraExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VisionCameraExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = VisionCameraExample/AppDelegate.h; sourceTree = "<group>"; };
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = VisionCameraExample/AppDelegate.h; sourceTree = "<group>"; };
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = VisionCameraExample/AppDelegate.m; sourceTree = "<group>"; };
|
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = VisionCameraExample/AppDelegate.m; sourceTree = "<group>"; };
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = VisionCameraExample/Images.xcassets; sourceTree = "<group>"; };
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = VisionCameraExample/Images.xcassets; sourceTree = "<group>"; };
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = VisionCameraExample/Info.plist; sourceTree = "<group>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = VisionCameraExample/Info.plist; sourceTree = "<group>"; };
|
||||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = VisionCameraExample/main.m; sourceTree = "<group>"; };
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = VisionCameraExample/main.m; sourceTree = "<group>"; };
|
||||||
3AE81CC8871244CDFFFE8AE3 /* Pods-VisionCameraExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraExample.release.xcconfig"; path = "Target Support Files/Pods-VisionCameraExample/Pods-VisionCameraExample.release.xcconfig"; sourceTree = "<group>"; };
|
3CDCFE89C25C89320B98945E /* libPods-VisionCameraExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VisionCameraExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = VisionCameraExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = VisionCameraExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
B8DB3BD8263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleFrameProcessorPlugin.m; sourceTree = "<group>"; };
|
B8DB3BD8263DEA31004C18D7 /* ExampleFrameProcessorPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleFrameProcessorPlugin.m; sourceTree = "<group>"; };
|
||||||
B8DB3BDA263DEA31004C18D7 /* ExamplePluginSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplePluginSwift.swift; sourceTree = "<group>"; };
|
B8DB3BDA263DEA31004C18D7 /* ExamplePluginSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplePluginSwift.swift; sourceTree = "<group>"; };
|
||||||
B8DB3BDB263DEA31004C18D7 /* ExamplePluginSwift.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExamplePluginSwift.m; sourceTree = "<group>"; };
|
B8DB3BDB263DEA31004C18D7 /* ExamplePluginSwift.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExamplePluginSwift.m; sourceTree = "<group>"; };
|
||||||
B8F0E10625E0199F00586F16 /* VisionCameraExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VisionCameraExample-Bridging-Header.h"; sourceTree = "<group>"; };
|
B8F0E10625E0199F00586F16 /* VisionCameraExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VisionCameraExample-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
B8F0E10725E0199F00586F16 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = "<group>"; };
|
B8F0E10725E0199F00586F16 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = "<group>"; };
|
||||||
E9E709EFF68B90B41F828506 /* Pods-VisionCameraExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraExample.debug.xcconfig"; path = "Target Support Files/Pods-VisionCameraExample/Pods-VisionCameraExample.debug.xcconfig"; sourceTree = "<group>"; };
|
C1D342AD8210E7627A632602 /* Pods-VisionCameraExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraExample.debug.xcconfig"; path = "Target Support Files/Pods-VisionCameraExample/Pods-VisionCameraExample.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
F64CB73AE44CAC94E069BF68 /* Pods-VisionCameraExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraExample.release.xcconfig"; path = "Target Support Files/Pods-VisionCameraExample/Pods-VisionCameraExample.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -45,7 +45,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
2D25D416E10790D96A54417B /* libPods-VisionCameraExample.a in Frameworks */,
|
C0B129659921D2EA967280B2 /* libPods-VisionCameraExample.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -74,7 +74,7 @@
|
|||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
||||||
0FC5D1C53D06B40B4CA981B8 /* libPods-VisionCameraExample.a */,
|
3CDCFE89C25C89320B98945E /* libPods-VisionCameraExample.a */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -82,8 +82,8 @@
|
|||||||
6B9684456A2045ADE5A6E47E /* Pods */ = {
|
6B9684456A2045ADE5A6E47E /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E9E709EFF68B90B41F828506 /* Pods-VisionCameraExample.debug.xcconfig */,
|
C1D342AD8210E7627A632602 /* Pods-VisionCameraExample.debug.xcconfig */,
|
||||||
3AE81CC8871244CDFFFE8AE3 /* Pods-VisionCameraExample.release.xcconfig */,
|
F64CB73AE44CAC94E069BF68 /* Pods-VisionCameraExample.release.xcconfig */,
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -150,7 +150,7 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "VisionCameraExample" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "VisionCameraExample" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
61061D8AA46EA92199E38783 /* [CP] Check Pods Manifest.lock */,
|
CF06330A830C3A8E3D0B576B /* [CP] Check Pods Manifest.lock */,
|
||||||
B81F12712604CF8800B08949 /* SwiftFormat */,
|
B81F12712604CF8800B08949 /* SwiftFormat */,
|
||||||
B81F12702604CF6600B08949 /* SwiftLint */,
|
B81F12702604CF6600B08949 /* SwiftLint */,
|
||||||
FD10A7F022414F080027D42C /* Start Packager */,
|
FD10A7F022414F080027D42C /* Start Packager */,
|
||||||
@ -158,7 +158,7 @@
|
|||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
62D9B6272AA9D5720A929C8F /* [CP] Copy Pods Resources */,
|
5E303E5293C2545D8F744D87 /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -228,29 +228,7 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
|
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
|
||||||
};
|
};
|
||||||
61061D8AA46EA92199E38783 /* [CP] Check Pods Manifest.lock */ = {
|
5E303E5293C2545D8F744D87 /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
|
||||||
"${PODS_ROOT}/Manifest.lock",
|
|
||||||
);
|
|
||||||
name = "[CP] Check Pods Manifest.lock";
|
|
||||||
outputFileListPaths = (
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
"$(DERIVED_FILE_DIR)/Pods-VisionCameraExample-checkManifestLockResult.txt",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
62D9B6272AA9D5720A929C8F /* [CP] Copy Pods Resources */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
@ -336,6 +314,28 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "if which swiftformat >/dev/null; then\n swiftformat .\nelse\n echo \"warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat\"\nfi\n";
|
shellScript = "if which swiftformat >/dev/null; then\n swiftformat .\nelse\n echo \"warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat\"\nfi\n";
|
||||||
};
|
};
|
||||||
|
CF06330A830C3A8E3D0B576B /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-VisionCameraExample-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -377,7 +377,7 @@
|
|||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = E9E709EFF68B90B41F828506 /* Pods-VisionCameraExample.debug.xcconfig */;
|
baseConfigurationReference = C1D342AD8210E7627A632602 /* Pods-VisionCameraExample.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
@ -402,7 +402,7 @@
|
|||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 3AE81CC8871244CDFFFE8AE3 /* Pods-VisionCameraExample.release.xcconfig */;
|
baseConfigurationReference = F64CB73AE44CAC94E069BF68 /* Pods-VisionCameraExample.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -1308,9 +1308,9 @@ anymatch@^3.0.3:
|
|||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
appdirsjs@^1.2.4:
|
appdirsjs@^1.2.4:
|
||||||
version "1.2.4"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.4.tgz#3ab582acc9fdfaaa0c1f81b3a25422ad4d95f9d4"
|
resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.5.tgz#c9888c8a0a908014533d5176ec56f1d5a8fd3700"
|
||||||
integrity sha512-WO5StDORR6JF/xYnXk/Fm0yu+iULaV5ULKuUw0Tu+jbgiTlSquaWBCgbpnsHLMXldf+fM3Gxn5p7vjond7He6w==
|
integrity sha512-UyaAyzj+7XLoKhbXJi4zoAw8IDXCiLNCKfQEiuCsCCTkDmiG1vpCliQn/MoUvO3DZqCN1i6gOahokcFtNSIrVA==
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
@ -2455,16 +2455,15 @@ fast-diff@^1.1.2:
|
|||||||
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||||
|
|
||||||
fast-glob@^3.1.1:
|
fast-glob@^3.1.1:
|
||||||
version "3.2.5"
|
version "3.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a"
|
||||||
integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==
|
integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@nodelib/fs.stat" "^2.0.2"
|
"@nodelib/fs.stat" "^2.0.2"
|
||||||
"@nodelib/fs.walk" "^1.2.3"
|
"@nodelib/fs.walk" "^1.2.3"
|
||||||
glob-parent "^5.1.0"
|
glob-parent "^5.1.2"
|
||||||
merge2 "^1.3.0"
|
merge2 "^1.3.0"
|
||||||
micromatch "^4.0.2"
|
micromatch "^4.0.4"
|
||||||
picomatch "^2.2.1"
|
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
@ -2691,7 +2690,7 @@ get-value@^2.0.3, get-value@^2.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||||
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
|
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
|
||||||
|
|
||||||
glob-parent@^5.1.0, glob-parent@^5.1.2:
|
glob-parent@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||||
@ -4062,7 +4061,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
|
|||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.2"
|
to-regex "^3.0.2"
|
||||||
|
|
||||||
micromatch@^4.0.2:
|
micromatch@^4.0.2, micromatch@^4.0.4:
|
||||||
version "4.0.4"
|
version "4.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||||
@ -4486,7 +4485,7 @@ path-type@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
|
picomatch@^2.0.4, picomatch@^2.2.3:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||||
|
@ -22,8 +22,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
|
jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
|
||||||
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
|
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
|
||||||
void destroyBuffer();
|
void close();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Frame* frame;
|
Frame* frame;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void assertIsFrameStrong(jsi::Runtime& runtime, const std::string& accessedPropName);
|
||||||
};
|
};
|
||||||
|
@ -14,11 +14,11 @@ std::vector<jsi::PropNameID> FrameHostObject::getPropertyNames(jsi::Runtime& rt)
|
|||||||
std::vector<jsi::PropNameID> result;
|
std::vector<jsi::PropNameID> result;
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toString")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toString")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isValid")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isValid")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isReady")));
|
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("width")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("width")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("height")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("height")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("bytesPerRow")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("bytesPerRow")));
|
||||||
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("planesCount")));
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("planesCount")));
|
||||||
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("close")));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,10 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
|
|||||||
auto name = propName.utf8(runtime);
|
auto name = propName.utf8(runtime);
|
||||||
|
|
||||||
if (name == "toString") {
|
if (name == "toString") {
|
||||||
auto toString = [this] (jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
|
auto toString = [this] (jsi::Runtime& runtime, const jsi::Value&, const jsi::Value*, size_t) -> jsi::Value {
|
||||||
|
if (this->frame == nil) {
|
||||||
|
return jsi::String::createFromUtf8(runtime, "[closed frame]");
|
||||||
|
}
|
||||||
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
||||||
auto width = CVPixelBufferGetWidth(imageBuffer);
|
auto width = CVPixelBufferGetWidth(imageBuffer);
|
||||||
auto height = CVPixelBufferGetHeight(imageBuffer);
|
auto height = CVPixelBufferGetHeight(imageBuffer);
|
||||||
@ -36,31 +39,41 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
|
|||||||
};
|
};
|
||||||
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
|
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
|
||||||
}
|
}
|
||||||
|
if (name == "close") {
|
||||||
|
auto close = [this] (jsi::Runtime& runtime, const jsi::Value&, const jsi::Value*, size_t) -> jsi::Value {
|
||||||
|
if (this->frame == nil) {
|
||||||
|
throw jsi::JSError(runtime, "Trying to close an already closed frame! Did you call frame.close() twice?");
|
||||||
|
}
|
||||||
|
this->close();
|
||||||
|
return jsi::Value::undefined();
|
||||||
|
};
|
||||||
|
return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "close"), 0, close);
|
||||||
|
}
|
||||||
|
|
||||||
if (name == "isValid") {
|
if (name == "isValid") {
|
||||||
auto isValid = frame != nil && CMSampleBufferIsValid(frame.buffer);
|
auto isValid = frame != nil && CMSampleBufferIsValid(frame.buffer);
|
||||||
return jsi::Value(isValid);
|
return jsi::Value(isValid);
|
||||||
}
|
}
|
||||||
if (name == "isReady") {
|
|
||||||
auto isReady = frame != nil && CMSampleBufferDataIsReady(frame.buffer);
|
|
||||||
return jsi::Value(isReady);
|
|
||||||
}
|
|
||||||
if (name == "width") {
|
if (name == "width") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
||||||
auto width = CVPixelBufferGetWidth(imageBuffer);
|
auto width = CVPixelBufferGetWidth(imageBuffer);
|
||||||
return jsi::Value((double) width);
|
return jsi::Value((double) width);
|
||||||
}
|
}
|
||||||
if (name == "height") {
|
if (name == "height") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
||||||
auto height = CVPixelBufferGetHeight(imageBuffer);
|
auto height = CVPixelBufferGetHeight(imageBuffer);
|
||||||
return jsi::Value((double) height);
|
return jsi::Value((double) height);
|
||||||
}
|
}
|
||||||
if (name == "bytesPerRow") {
|
if (name == "bytesPerRow") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
||||||
auto bytesPerRow = CVPixelBufferGetPlaneCount(imageBuffer);
|
auto bytesPerRow = CVPixelBufferGetPlaneCount(imageBuffer);
|
||||||
return jsi::Value((double) bytesPerRow);
|
return jsi::Value((double) bytesPerRow);
|
||||||
}
|
}
|
||||||
if (name == "planesCount") {
|
if (name == "planesCount") {
|
||||||
|
this->assertIsFrameStrong(runtime, name);
|
||||||
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
auto imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer);
|
||||||
auto planesCount = CVPixelBufferGetPlaneCount(imageBuffer);
|
auto planesCount = CVPixelBufferGetPlaneCount(imageBuffer);
|
||||||
return jsi::Value((double) planesCount);
|
return jsi::Value((double) planesCount);
|
||||||
@ -69,11 +82,21 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
|
|||||||
return jsi::Value::undefined();
|
return jsi::Value::undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameHostObject::~FrameHostObject() {
|
void FrameHostObject::assertIsFrameStrong(jsi::Runtime &runtime, const std::string &accessedPropName) {
|
||||||
destroyBuffer();
|
if (frame == nil) {
|
||||||
|
auto message = "Cannot get `" + accessedPropName + "`, frame is already closed!";
|
||||||
|
throw jsi::JSError(runtime, message.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameHostObject::destroyBuffer() {
|
FrameHostObject::~FrameHostObject() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameHostObject::close() {
|
||||||
|
if (frame != nil) {
|
||||||
|
CMSampleBufferInvalidate(frame.buffer);
|
||||||
// ARC will hopefully delete it lol
|
// ARC will hopefully delete it lol
|
||||||
this->frame = nil;
|
this->frame = nil;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -28,7 +28,6 @@ FrameProcessorCallback convertJSIFunctionToFrameProcessorCallback(jsi::Runtime &
|
|||||||
cb.call(runtime, jsi::Object::createFromHostObject(runtime, frameHostObject));
|
cb.call(runtime, jsi::Object::createFromHostObject(runtime, frameHostObject));
|
||||||
} catch (jsi::JSError& jsError) {
|
} catch (jsi::JSError& jsError) {
|
||||||
auto message = jsError.getMessage();
|
auto message = jsError.getMessage();
|
||||||
|
|
||||||
RCTBridge* bridge = [RCTBridge currentBridge];
|
RCTBridge* bridge = [RCTBridge currentBridge];
|
||||||
if (bridge != nil) {
|
if (bridge != nil) {
|
||||||
bridge.jsCallInvoker->invokeAsync([bridge, message]() {
|
bridge.jsCallInvoker->invokeAsync([bridge, message]() {
|
||||||
@ -44,6 +43,6 @@ FrameProcessorCallback convertJSIFunctionToFrameProcessorCallback(jsi::Runtime &
|
|||||||
// 1. we are sure we don't need it anymore, the frame processor worklet has finished executing.
|
// 1. we are sure we don't need it anymore, the frame processor worklet has finished executing.
|
||||||
// 2. we don't know when the JS runtime garbage collects this object, it might be holding it for a few more frames
|
// 2. we don't know when the JS runtime garbage collects this object, it might be holding it for a few more frames
|
||||||
// which then blocks the camera queue from pushing new frames (memory limit)
|
// which then blocks the camera queue from pushing new frames (memory limit)
|
||||||
frameHostObject->destroyBuffer();
|
frameHostObject->close();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
21
src/Frame.ts
21
src/Frame.ts
@ -3,13 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
export interface Frame {
|
export interface Frame {
|
||||||
/**
|
/**
|
||||||
* Whether the underlying buffer is still valid or not. The buffer will be released after the frame processor returns.
|
* Whether the underlying buffer is still valid or not. The buffer will be released after the frame processor returns, or `close()` is called.
|
||||||
*/
|
*/
|
||||||
isValid: boolean;
|
isValid: boolean;
|
||||||
/**
|
|
||||||
* Whether the underlying buffer is marked as "ready" or not.
|
|
||||||
*/
|
|
||||||
isReady: boolean;
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the frame, in pixels.
|
* Returns the width of the frame, in pixels.
|
||||||
*/
|
*/
|
||||||
@ -35,4 +31,19 @@ export interface Frame {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
toString(): string;
|
toString(): string;
|
||||||
|
/**
|
||||||
|
* Closes and disposes the Frame.
|
||||||
|
* Only close frames that you have created yourself, e.g. by copying the frame you receive in a frame processor.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* const frameProcessor = useFrameProcessor((frame) => {
|
||||||
|
* const smallerCopy = resize(frame, 480, 270)
|
||||||
|
* // run AI ...
|
||||||
|
* smallerCopy.close()
|
||||||
|
* // don't close `frame`!
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
close(): void;
|
||||||
}
|
}
|
||||||
|
29
yarn.lock
29
yarn.lock
@ -1838,9 +1838,9 @@ anymatch@^3.0.3:
|
|||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
appdirsjs@^1.2.4:
|
appdirsjs@^1.2.4:
|
||||||
version "1.2.4"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.4.tgz#3ab582acc9fdfaaa0c1f81b3a25422ad4d95f9d4"
|
resolved "https://registry.yarnpkg.com/appdirsjs/-/appdirsjs-1.2.5.tgz#c9888c8a0a908014533d5176ec56f1d5a8fd3700"
|
||||||
integrity sha512-WO5StDORR6JF/xYnXk/Fm0yu+iULaV5ULKuUw0Tu+jbgiTlSquaWBCgbpnsHLMXldf+fM3Gxn5p7vjond7He6w==
|
integrity sha512-UyaAyzj+7XLoKhbXJi4zoAw8IDXCiLNCKfQEiuCsCCTkDmiG1vpCliQn/MoUvO3DZqCN1i6gOahokcFtNSIrVA==
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
@ -3495,16 +3495,15 @@ fast-diff@^1.1.2:
|
|||||||
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||||
|
|
||||||
fast-glob@^3.1.1:
|
fast-glob@^3.1.1:
|
||||||
version "3.2.5"
|
version "3.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a"
|
||||||
integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==
|
integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@nodelib/fs.stat" "^2.0.2"
|
"@nodelib/fs.stat" "^2.0.2"
|
||||||
"@nodelib/fs.walk" "^1.2.3"
|
"@nodelib/fs.walk" "^1.2.3"
|
||||||
glob-parent "^5.1.0"
|
glob-parent "^5.1.2"
|
||||||
merge2 "^1.3.0"
|
merge2 "^1.3.0"
|
||||||
micromatch "^4.0.2"
|
micromatch "^4.0.4"
|
||||||
picomatch "^2.2.1"
|
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
@ -3859,7 +3858,7 @@ gitconfiglocal@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ini "^1.3.2"
|
ini "^1.3.2"
|
||||||
|
|
||||||
glob-parent@^5.1.0, glob-parent@^5.1.2:
|
glob-parent@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||||
@ -5402,7 +5401,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
|
|||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.2"
|
to-regex "^3.0.2"
|
||||||
|
|
||||||
micromatch@^4.0.2:
|
micromatch@^4.0.2, micromatch@^4.0.4:
|
||||||
version "4.0.4"
|
version "4.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||||
@ -6057,7 +6056,7 @@ path-type@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
|
picomatch@^2.0.4, picomatch@^2.2.3:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||||
@ -7581,9 +7580,9 @@ uglify-es@^3.1.9:
|
|||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.13.9"
|
version "3.13.10"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.9.tgz#4d8d21dcd497f29cfd8e9378b9df123ad025999b"
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d"
|
||||||
integrity sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==
|
integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==
|
||||||
|
|
||||||
ultron@1.0.x:
|
ultron@1.0.x:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user