Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Android Camera2 rewrite #1674

Merged
merged 180 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
ecb6fd5
Nuke CameraX
mrousavy Aug 1, 2023
1485910
fix: Run View Finder on UI Thread
mrousavy Aug 1, 2023
bdb61a0
Open Camera, set up Threads
mrousavy Aug 1, 2023
be20f8b
fix init
mrousavy Aug 1, 2023
9099967
Mirror if needed
mrousavy Aug 1, 2023
96a7cfd
Try PreviewView
mrousavy Aug 1, 2023
bd518db
Use max resolution
mrousavy Aug 1, 2023
0c5e04c
Add `hardwareLevel` property
mrousavy Aug 2, 2023
b43ba63
Check if output type is supported
mrousavy Aug 2, 2023
a2a294c
Replace `frameRateRanges` with `minFps` and `maxFps`
mrousavy Aug 2, 2023
1ef1a50
Remove `isHighestPhotoQualitySupported`
mrousavy Aug 2, 2023
159c3b2
Remove `colorSpace`
mrousavy Aug 2, 2023
c52b81b
HDR
mrousavy Aug 2, 2023
1766ea3
Check from format
mrousavy Aug 2, 2023
87ef655
fix
mrousavy Aug 2, 2023
b37c1e8
Remove `supportsParallelVideoProcessing`
mrousavy Aug 2, 2023
015f220
Correctly return video/photo sizes on Android now. Finally
mrousavy Aug 2, 2023
3eb7a48
Log all Device props
mrousavy Aug 2, 2023
1ff083d
Log if optimized usecase is used
mrousavy Aug 2, 2023
3fc8177
Cleanup
mrousavy Aug 2, 2023
0fd6c03
Configure Camera Input only once
mrousavy Aug 2, 2023
8b93cfa
Revert "Configure Camera Input only once"
mrousavy Aug 2, 2023
fe89045
Extract Camera configuration
mrousavy Aug 2, 2023
ee25982
Try to reconfigure all
mrousavy Aug 3, 2023
882972d
Hook based
mrousavy Aug 3, 2023
ea2ef78
Properly set up `CameraSession`
mrousavy Aug 3, 2023
30681a4
Delete unused
mrousavy Aug 3, 2023
71bc242
fix: Fix recreate when outputs change
mrousavy Aug 3, 2023
df1bf40
Update NativePreviewView.kt
mrousavy Aug 3, 2023
7317d6c
Use callback for closing
mrousavy Aug 3, 2023
8b8ba14
Catch CameraAccessException
mrousavy Aug 3, 2023
1e212d0
Finally got it stable
mrousavy Aug 3, 2023
22d07dd
Remove isMirrored
mrousavy Aug 3, 2023
db7f778
Implement `takePhoto()`
mrousavy Aug 3, 2023
645bc1a
Add ExifInterface library
mrousavy Aug 3, 2023
a83c596
Run findViewById on UI Thread
mrousavy Aug 3, 2023
dbe34ce
Add Photo Output Surface to takePhoto
mrousavy Aug 3, 2023
5c93aa8
Fix Video Stabilization Modes
mrousavy Aug 3, 2023
16c3fd1
Optimize Imports
mrousavy Aug 3, 2023
496e36d
More logs
mrousavy Aug 3, 2023
cb80f73
Update CameraSession.kt
mrousavy Aug 3, 2023
fb6cb44
Close Image
mrousavy Aug 3, 2023
cdeaf01
Use separate Executor in CameraQueue
mrousavy Aug 3, 2023
aa694c1
Delete hooks
mrousavy Aug 3, 2023
4c5c724
Use same Thread again
mrousavy Aug 3, 2023
fe8ef66
If opened, call error
mrousavy Aug 3, 2023
c3a391c
Update CameraSession.kt
mrousavy Aug 3, 2023
626438e
Log HW level
mrousavy Aug 3, 2023
224b44f
fix: Don't enable Stream Use Case if it's not 100% supported
mrousavy Aug 3, 2023
8221fd2
Move some stuff
mrousavy Aug 4, 2023
bf059d3
Cleanup PhotoOutputSynchronizer
mrousavy Aug 4, 2023
1065ae9
Try just open in suspend fun
mrousavy Aug 4, 2023
7a10c7c
Some synchronization fixes
mrousavy Aug 4, 2023
1666375
fix logs
mrousavy Aug 4, 2023
92115b6
Update CameraDevice+createCaptureSession.kt
mrousavy Aug 4, 2023
a4cecfd
Update CameraDevice+createCaptureSession.kt
mrousavy Aug 4, 2023
e4a7466
fixes
mrousavy Aug 4, 2023
17e1bc7
fix: Use Snapshot Template for speed capture prio
mrousavy Aug 4, 2023
3417d92
Use PREVIEW template for repeating request
mrousavy Aug 4, 2023
4427935
Use `TEMPLATE_RECORD` if video use-case is attached
mrousavy Aug 4, 2023
a1c1c47
Use `isRunning` flag
mrousavy Aug 4, 2023
a2f7024
Recreate session everytime on active/inactive
mrousavy Aug 4, 2023
9001002
Lazily get values in capture session
mrousavy Aug 4, 2023
1e9db32
Stability
mrousavy Aug 4, 2023
9f79e6a
Rebuild session if outputs change
mrousavy Aug 4, 2023
ec606e8
Set `didOutputsChange` back to false
mrousavy Aug 4, 2023
50c6f16
Capture first in lock
mrousavy Aug 5, 2023
2107f2c
Try
mrousavy Aug 5, 2023
a7e1e9a
kinda fix it? idk
mrousavy Aug 5, 2023
9829dc4
fix: Keep Outputs
mrousavy Aug 5, 2023
21bb04c
Refactor into single method
mrousavy Aug 5, 2023
c89d21f
Update CameraView.kt
mrousavy Aug 5, 2023
42ec0ad
Use Enums for type safety
mrousavy Aug 5, 2023
1d2241f
Implement Orientation (I think)
mrousavy Aug 8, 2023
5355f0f
Move RefCount management to Java (Frame)
mrousavy Aug 8, 2023
49c3079
Don't crash when dropping a Frame
mrousavy Aug 8, 2023
290ae45
Prefer Devices with higher max resolution
mrousavy Aug 8, 2023
fb0e02c
Prefer multi-cams
mrousavy Aug 8, 2023
a7b5d45
Use FastImage for Media Page
mrousavy Aug 8, 2023
4c40aec
Return orientation in takePhoto()
mrousavy Aug 8, 2023
86dd4c1
Load orientation from EXIF Data
mrousavy Aug 8, 2023
3df3cc5
Add `isMirrored` props and documentation for PhotoFile
mrousavy Aug 8, 2023
debe751
fix: Return `not-determined` on Android
mrousavy Aug 8, 2023
8af3baf
Update CameraViewModule.kt
mrousavy Aug 8, 2023
60feb21
chore: Upgrade packages
mrousavy Aug 8, 2023
46c6f28
fix: Fix Metro Config
mrousavy Aug 8, 2023
16c87da
Cleanup config
mrousavy Aug 8, 2023
ff10df5
Properly mirror Images on save
mrousavy Aug 8, 2023
2e30c42
Prepare MediaRecorder
mrousavy Aug 8, 2023
1404923
Start/Stop MediaRecorder
mrousavy Aug 9, 2023
32142ea
Remove `takeSnapshot()`
mrousavy Aug 9, 2023
8f77bf1
Use `MediaCodec`
mrousavy Aug 9, 2023
0464ef1
Move to `VideoRecording` class
mrousavy Aug 9, 2023
73ced94
Cleanup Snapshot
mrousavy Aug 9, 2023
cb84a0b
Create `SkiaPreviewView` hybrid class
mrousavy Aug 9, 2023
2b68fb0
Create OpenGL context
mrousavy Aug 9, 2023
c4fd87e
Create `SkiaPreviewView`
mrousavy Aug 9, 2023
fb3f922
Fix texture creation missing context
mrousavy Aug 9, 2023
495ad99
Draw red frame
mrousavy Aug 9, 2023
3114faa
Somehow get it working
mrousavy Aug 9, 2023
cb2e92e
Add Skia CMake setup
mrousavy Aug 9, 2023
08b3134
Start looping
mrousavy Aug 10, 2023
87aca51
Init OpenGL
mrousavy Aug 10, 2023
5958dfb
Refactor into `SkiaRenderer`
mrousavy Aug 10, 2023
532ea75
Cleanup PreviewSize
mrousavy Aug 10, 2023
0e71a75
Set up
mrousavy Aug 10, 2023
53c78bd
Only re-render UI if there is a new Frame
mrousavy Aug 10, 2023
74da19a
Preview
mrousavy Aug 10, 2023
d3ac954
Fix init
mrousavy Aug 10, 2023
0979087
Try rendering Preview
mrousavy Aug 10, 2023
ac2ac9a
Update SkiaPreviewView.kt
mrousavy Aug 10, 2023
58cc816
Log version
mrousavy Aug 10, 2023
458734f
Try using Skia (fail)
mrousavy Aug 10, 2023
f493df9
Drawwwww!!!!!!!!!! :tada:
mrousavy Aug 10, 2023
3cc6550
Use Preview Size
mrousavy Aug 10, 2023
e120fc3
Clear first
mrousavy Aug 10, 2023
0a52b46
Refactor into SkiaRenderer
mrousavy Aug 10, 2023
8ab4093
Add `previewType: "none"` on iOS
mrousavy Aug 10, 2023
ff2a312
Simplify a lot
mrousavy Aug 10, 2023
8047cc1
Draw Camera? For some reason? I have no idea anymore
mrousavy Aug 10, 2023
94216a6
Fix OpenGL errors
mrousavy Aug 11, 2023
f1085d7
Got it kinda working again?
mrousavy Aug 11, 2023
03cf86b
Actually draw Frame woah
mrousavy Aug 11, 2023
4dcbb03
Clean up code
mrousavy Aug 11, 2023
f2b6fab
Cleanup
mrousavy Aug 11, 2023
30025ee
Update on main
mrousavy Aug 11, 2023
3e2ed79
Synchronize render calls
mrousavy Aug 11, 2023
04f7d43
holy shit
mrousavy Aug 11, 2023
cb0ab1f
Update SkiaRenderer.cpp
mrousavy Aug 11, 2023
90a2ce3
Update SkiaRenderer.cpp
mrousavy Aug 11, 2023
4c51acd
Refactor
mrousavy Aug 11, 2023
1391b47
Update SkiaRenderer.cpp
mrousavy Aug 11, 2023
2f7e200
Check for `NO_INPUT_TEXTURE`^
mrousavy Aug 11, 2023
e86a9d2
Post & Wait
mrousavy Aug 11, 2023
f5c9a11
Set input size
mrousavy Aug 11, 2023
edabc67
Add Video back again
mrousavy Aug 11, 2023
3d6767d
Allow session without preview
mrousavy Aug 11, 2023
cb52c50
Convert JPEG to byte[]
mrousavy Aug 11, 2023
d38ba59
feat: Use `ImageReader` and use YUV Image Buffers in Skia Context (#1…
mrousavy Aug 14, 2023
c4085b7
Set minSdk to 26
mrousavy Aug 14, 2023
c4f19e8
Set surface
mrousavy Aug 14, 2023
692906b
Revert "Set minSdk to 26"
mrousavy Aug 14, 2023
78fc66c
Set previewType
mrousavy Aug 14, 2023
a81bbbc
feat: Video Recording with Camera2 (#1691)
mrousavy Aug 17, 2023
e314724
Fix Torch Mode
mrousavy Aug 17, 2023
8a36f52
Fix comparing outputs with hashCode
mrousavy Aug 17, 2023
7a41080
Update CameraSession.kt
mrousavy Aug 17, 2023
6b5dced
Correctly pass along Frame Processor
mrousavy Aug 17, 2023
18de121
fix: Use AUDIO_BIT_RATE of 16 * 44,1Khz
mrousavy Aug 17, 2023
abd6b0c
Use CAMCORDER instead of MIC microphone
mrousavy Aug 17, 2023
7c7e2d3
Use 1 channel
mrousavy Aug 17, 2023
c7e4756
fix: Use `Orientation`
mrousavy Aug 17, 2023
c5fdc2a
Add `native` PixelFormat
mrousavy Aug 17, 2023
78f796a
Update iOS to latest Skia integration
mrousavy Aug 17, 2023
df5718d
feat: Add `pixelFormat` property to Camera
mrousavy Aug 17, 2023
b414e05
Catch error in configureSession
mrousavy Aug 17, 2023
9a2abc5
Fix JPEG format
mrousavy Aug 17, 2023
490b6af
Clean up best match finder
mrousavy Aug 17, 2023
063e844
Update CameraDeviceDetails.kt
mrousavy Aug 17, 2023
b687a5b
Clamp sizes by maximum CamcorderProfile size
mrousavy Aug 17, 2023
1a53717
Remove `getAvailableVideoCodecs`
mrousavy Aug 17, 2023
edb7f2a
chore: release 3.0.0-rc.5
mrousavy Aug 17, 2023
23dc847
Use maximum video size of RECORD as default
mrousavy Aug 18, 2023
c63fefa
Update CameraDeviceDetails.kt
mrousavy Aug 18, 2023
33a3c3e
Add a todo
mrousavy Aug 18, 2023
71775b5
Add JSON device to issue report
mrousavy Aug 18, 2023
f4656cf
Prefer `full` devices and flash
mrousavy Aug 18, 2023
5f180c7
Lock to 30 FPS on Samsung
mrousavy Aug 18, 2023
885b77b
Implement Zoom
mrousavy Aug 18, 2023
6756270
Refactor
mrousavy Aug 18, 2023
59822db
Format -> PixelFormat
mrousavy Aug 18, 2023
3c24352
fix: Feat `pixelFormat` -> `pixelFormats`
mrousavy Aug 18, 2023
0e12e53
Update TROUBLESHOOTING.mdx
mrousavy Aug 18, 2023
e2ab76b
Format
mrousavy Aug 18, 2023
d5aa3c4
fix: Implement `zoom` for Photo Capture
mrousavy Aug 18, 2023
d095f56
fix: Don't run if `isActive` is `false`
mrousavy Aug 18, 2023
dec9ece
fix: Call `examplePlugin(frame)`
mrousavy Aug 18, 2023
ab185f4
fix: Fix Flash
mrousavy Aug 21, 2023
61f77a4
fix: Use `react-native-worklets-core`!
mrousavy Aug 21, 2023
d8d8638
fix: Fix import
mrousavy Aug 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/BUG_REPORT.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ body:
label: Relevant log output
description: Please copy and paste any relevant log output (Xcode Logs/Android Studio Logcat). This will be automatically formatted into code, so no need for backticks.
render: shell
- type: textarea
attributes:
label: Camera Device
description: Please paste the JSON Camera `device` that was used here. (`console.log(JSON.stringify(device, null, 2))`) This will be automatically formatted into code, so no need for backticks.
render: shell
- type: input
attributes:
label: Device
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ jobs:
run: yarn install --frozen-lockfile
- name: Install node_modules for example/
run: yarn install --frozen-lockfile --cwd example
- name: Remove react-native-worklets
run: yarn remove react-native-worklets --cwd example
- name: Remove react-native-worklets-core
run: yarn remove react-native-worklets-core --cwd example

- name: Restore Gradle cache
uses: actions/cache@v2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ jobs:
${{ runner.os }}-yarn-
- name: Install node_modules for example/
run: yarn install --frozen-lockfile --cwd ..
- name: Remove react-native-worklets
run: yarn remove react-native-worklets --cwd ..
- name: Remove react-native-worklets-core
run: yarn remove react-native-worklets-core --cwd ..

- name: Restore buildcache
uses: mikehardy/buildcache-action@v1
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

### Features

* Photo, Video and Snapshot capture
* Photo and Video capture
* Customizable devices and multi-cameras (smoothly zoom out to "fish-eye" camera)
* Customizable FPS
* [Frame Processors](https://react-native-vision-camera.com/docs/guides/frame-processors) (JS worklets to run QR-Code scanning, facial recognition, AI object detection, realtime video chats, ...)
Expand Down
6 changes: 3 additions & 3 deletions VisionCamera.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ if defined?($VCDisableSkia)
end

Pod::UI.puts("[VisionCamera] node modules #{Dir.exist?(nodeModules) ? "found at #{nodeModules}" : "not found!"}")
workletsPath = File.join(nodeModules, "react-native-worklets")
workletsPath = File.join(nodeModules, "react-native-worklets-core")
hasWorklets = File.exist?(workletsPath) && !forceDisableFrameProcessors
Pod::UI.puts("[VisionCamera] react-native-worklets #{hasWorklets ? "found" : "not found"}, Frame Processors #{hasWorklets ? "enabled" : "disabled"}!")
Pod::UI.puts("[VisionCamera] react-native-worklets-core #{hasWorklets ? "found" : "not found"}, Frame Processors #{hasWorklets ? "enabled" : "disabled"}!")

skiaPath = File.join(nodeModules, "@shopify", "react-native-skia")
hasSkia = hasWorklets && File.exist?(skiaPath) && !forceDisableSkia
Expand Down Expand Up @@ -87,7 +87,7 @@ Pod::Spec.new do |s|
s.dependency "React-callinvoker"

if hasWorklets
s.dependency "react-native-worklets"
s.dependency "react-native-worklets-core"
if hasSkia
s.dependency "react-native-skia"
end
Expand Down
31 changes: 28 additions & 3 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(PACKAGE_NAME "VisionCamera")
set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSK_GL -DSK_GANESH -DSK_BUILD_FOR_ANDROID")

# Folly
include("${NODE_MODULES_DIR}/react-native/ReactAndroid/cmake-utils/folly-flags.cmake")
Expand All @@ -14,10 +15,9 @@ add_compile_options(${folly_FLAGS})
# Third party libraries (Prefabs)
find_package(ReactAndroid REQUIRED CONFIG)
find_package(fbjni REQUIRED CONFIG)
find_package(react-native-worklets REQUIRED CONFIG)
find_package(react-native-worklets-core REQUIRED CONFIG)
find_library(LOG_LIB log)


set(RNSKIA_PATH ${NODE_MODULES_DIR}/@shopify/react-native-skia)
if(EXISTS ${RNSKIA_PATH})
find_package(shopify_react-native-skia REQUIRED CONFIG)
Expand All @@ -27,6 +27,14 @@ else()
message("VisionCamera: Skia integration disabled!")
ENDIF()

set (SKIA_LIBS_PATH "${RNSKIA_PATH}/libs/android/${ANDROID_ABI}")
add_library(skia STATIC IMPORTED)
set_property(TARGET skia PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libskia.a")
add_library(svg STATIC IMPORTED)
set_property(TARGET svg PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libsvg.a")
add_library(skshaper STATIC IMPORTED)
set_property(TARGET skshaper PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libskshaper.a")

# Add react-native-vision-camera sources
add_library(
${PACKAGE_NAME}
Expand All @@ -37,6 +45,7 @@ add_library(
src/main/cpp/JSIJNIConversion.cpp
src/main/cpp/VisionCamera.cpp
src/main/cpp/VisionCameraProxy.cpp
src/main/cpp/skia/SkiaRenderer.cpp
src/main/cpp/java-bindings/JFrame.cpp
src/main/cpp/java-bindings/JFrameProcessor.cpp
src/main/cpp/java-bindings/JFrameProcessorPlugin.cpp
Expand All @@ -62,6 +71,16 @@ target_include_directories(
# just one directory. HOWEVER, skia itself uses relative paths in
# their include statements, and so we have to include the path to skia)
"${RNSKIA_PATH}/cpp/skia"

"${RNSKIA_PATH}/cpp/skia/include/config/"
"${RNSKIA_PATH}/cpp/skia/include/core/"
"${RNSKIA_PATH}/cpp/skia/include/effects/"
"${RNSKIA_PATH}/cpp/skia/include/utils/"
"${RNSKIA_PATH}/cpp/skia/include/pathops/"
"${RNSKIA_PATH}/cpp/skia/modules/"
# "${RNSKIA_PATH}/cpp/skia/modules/skparagraph/include/"
"${RNSKIA_PATH}/cpp/skia/include/"
"${RNSKIA_PATH}/cpp/skia"
)

# Link everything together
Expand All @@ -73,6 +92,12 @@ target_link_libraries(
ReactAndroid::reactnativejni # <-- RN: React Native JNI bindings
ReactAndroid::folly_runtime # <-- RN: For casting JSI <> Java objects
fbjni::fbjni # <-- fbjni
react-native-worklets::rnworklets # <-- RN Worklets
react-native-worklets-core::rnworklets # <-- RN Worklets
GLESv2 # <-- Optional: OpenGL (for Skia)
EGL # <-- Optional: OpenGL (EGL) (for Skia)
${SKIA_PACKAGE} # <-- Optional: RN Skia
jnigraphics
skia
svg
skshaper
)
15 changes: 3 additions & 12 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -142,22 +142,13 @@ dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-android:+'

implementation 'androidx.core:core-ktx:1.3.2'
implementation "androidx.core:core-ktx:1.3.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.5.2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
implementation "androidx.exifinterface:exifinterface:1.3.6"

implementation "androidx.camera:camera-core:1.1.0"
implementation "androidx.camera:camera-camera2:1.1.0"
implementation "androidx.camera:camera-lifecycle:1.1.0"
implementation "androidx.camera:camera-video:1.1.0"

implementation "androidx.camera:camera-view:1.1.0"
implementation "androidx.camera:camera-extensions:1.1.0"

implementation "androidx.exifinterface:exifinterface:1.3.3"

implementation project(":react-native-worklets")
implementation project(":react-native-worklets-core")
implementation project(":shopify_react-native-skia")
}

Expand Down
20 changes: 10 additions & 10 deletions android/src/main/cpp/FrameHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <fbjni/fbjni.h>
#include <jni.h>

#include <react-native-worklets/WKTJsiHostObject.h>
#include <react-native-worklets-core/WKTJsiHostObject.h>
#include "JSITypedArray.h"

#include <vector>
Expand All @@ -18,7 +18,7 @@ namespace vision {

using namespace facebook;

FrameHostObject::FrameHostObject(const jni::alias_ref<JFrame::javaobject>& frame): frame(make_global(frame)), _refCount(0) { }
FrameHostObject::FrameHostObject(const jni::alias_ref<JFrame::javaobject>& frame): frame(make_global(frame)) { }

FrameHostObject::~FrameHostObject() {
// Hermes' Garbage Collector (Hades GC) calls destructors on a separate Thread
Expand All @@ -37,6 +37,7 @@ std::vector<jsi::PropNameID> FrameHostObject::getPropertyNames(jsi::Runtime& rt)
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("orientation")));
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("isMirrored")));
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("timestamp")));
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("pixelFormat")));
// Conversion
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toString")));
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("toArrayBuffer")));
Expand Down Expand Up @@ -94,8 +95,7 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
if (name == "incrementRefCount") {
auto incrementRefCount = JSI_HOST_FUNCTION_LAMBDA {
// Increment retain count by one.
std::lock_guard lock(this->_refCountMutex);
this->_refCount++;
this->frame->incrementRefCount();
return jsi::Value::undefined();
};
return jsi::Function::createFromHostFunction(runtime,
Expand All @@ -106,12 +106,8 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr

if (name == "decrementRefCount") {
auto decrementRefCount = JSI_HOST_FUNCTION_LAMBDA {
// Decrement retain count by one. If the retain count is zero, we close the Frame.
std::lock_guard lock(this->_refCountMutex);
this->_refCount--;
if (_refCount < 1) {
this->frame->close();
}
// Decrement retain count by one. If the retain count is zero, the Frame gets closed.
this->frame->decrementRefCount();
return jsi::Value::undefined();
};
return jsi::Function::createFromHostFunction(runtime,
Expand All @@ -136,6 +132,10 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
auto string = this->frame->getOrientation();
return jsi::String::createFromUtf8(runtime, string->toStdString());
}
if (name == "pixelFormat") {
auto string = this->frame->getPixelFormat();
return jsi::String::createFromUtf8(runtime, string->toStdString());
}
if (name == "timestamp") {
return jsi::Value(static_cast<double>(this->frame->getTimestamp()));
}
Expand Down
4 changes: 0 additions & 4 deletions android/src/main/cpp/FrameHostObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <fbjni/fbjni.h>
#include <vector>
#include <string>
#include <mutex>

#include "java-bindings/JFrame.h"

Expand All @@ -31,9 +30,6 @@ class JSI_EXPORT FrameHostObject : public jsi::HostObject {

private:
static auto constexpr TAG = "VisionCamera";

size_t _refCount;
std::mutex _refCountMutex;
};

} // namespace vision
2 changes: 2 additions & 0 deletions android/src/main/cpp/VisionCamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
#include "java-bindings/JFrameProcessor.h"
#include "java-bindings/JVisionCameraProxy.h"
#include "VisionCameraProxy.h"
#include "skia/SkiaRenderer.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
vision::VisionCameraInstaller::registerNatives();
vision::JFrameProcessor::registerNatives();
vision::JVisionCameraProxy::registerNatives();
vision::JVisionCameraScheduler::registerNatives();
vision::SkiaRenderer::registerNatives();
});
}
15 changes: 15 additions & 0 deletions android/src/main/cpp/java-bindings/JFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ local_ref<JString> JFrame::getOrientation() const {
return getOrientationMethod(self());
}

local_ref<JString> JFrame::getPixelFormat() const {
static const auto getPixelFormatMethod = getClass()->getMethod<JString()>("getPixelFormat");
return getPixelFormatMethod(self());
}

int JFrame::getPlanesCount() const {
static const auto getPlanesCountMethod = getClass()->getMethod<jint()>("getPlanesCount");
return getPlanesCountMethod(self());
Expand All @@ -57,6 +62,16 @@ local_ref<JArrayByte> JFrame::toByteArray() const {
return toByteArrayMethod(self());
}

void JFrame::incrementRefCount() {
static const auto incrementRefCountMethod = getClass()->getMethod<void()>("incrementRefCount");
incrementRefCountMethod(self());
}

void JFrame::decrementRefCount() {
static const auto decrementRefCountMethod = getClass()->getMethod<void()>("decrementRefCount");
decrementRefCountMethod(self());
}

void JFrame::close() {
static const auto closeMethod = getClass()->getMethod<void()>("close");
closeMethod(self());
Expand Down
3 changes: 3 additions & 0 deletions android/src/main/cpp/java-bindings/JFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ struct JFrame : public JavaClass<JFrame> {
int getBytesPerRow() const;
jlong getTimestamp() const;
local_ref<JString> getOrientation() const;
local_ref<JString> getPixelFormat() const;
local_ref<JArrayByte> toByteArray() const;
void incrementRefCount();
void decrementRefCount();
void close();
};

Expand Down
4 changes: 2 additions & 2 deletions android/src/main/cpp/java-bindings/JFrameProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include <jni.h>
#include <fbjni/fbjni.h>

#include <react-native-worklets/WKTJsiWorklet.h>
#include <react-native-worklets/WKTJsiHostObject.h>
#include <react-native-worklets-core/WKTJsiWorklet.h>
#include <react-native-worklets-core/WKTJsiHostObject.h>

#include "JFrame.h"
#include "FrameHostObject.h"
Expand Down
4 changes: 2 additions & 2 deletions android/src/main/cpp/java-bindings/JVisionCameraProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include <jsi/jsi.h>
#include <react/jni/ReadableNativeMap.h>

#include <react-native-worklets/WKTJsiWorklet.h>
#include <react-native-worklets/WKTJsiWorkletContext.h>
#include <react-native-worklets-core/WKTJsiWorklet.h>
#include <react-native-worklets-core/WKTJsiWorkletContext.h>

#include "FrameProcessorPluginHostObject.h"

Expand Down
2 changes: 1 addition & 1 deletion android/src/main/cpp/java-bindings/JVisionCameraProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <fbjni/fbjni.h>
#include <jsi/jsi.h>
#include <react-native-worklets/WKTJsiWorkletContext.h>
#include <react-native-worklets-core/WKTJsiWorkletContext.h>
#include <react/jni/ReadableNativeMap.h>

#include "JFrameProcessorPlugin.h"
Expand Down
26 changes: 26 additions & 0 deletions android/src/main/cpp/skia/OpenGLError.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by Marc Rousavy on 09.08.23.
//

#pragma once

#include <string>
#include <stdexcept>
#include <GLES2/gl2.h>

namespace vision {

inline std::string getEglErrorIfAny() {
EGLint error = glGetError();
if (error != GL_NO_ERROR) return " Error: " + std::to_string(error);
error = eglGetError();
if (error != EGL_SUCCESS) return " Error: " + std::to_string(error);
return "";
}

class OpenGLError: public std::runtime_error {
public:
explicit OpenGLError(const std::string&& message): std::runtime_error(message + getEglErrorIfAny()) {}
};

} // namespace vision
Loading
Loading