fix: Fix crash in toArrayBuffer()
by properly acquiring a reference on AHardwareBuffer*
(#2490)
* fix: Fix crash in `toArrayBuffer()` by properly acquiring a reference on `AHardwareBuffer*` * Format * Update Podfile.lock
This commit is contained in:
parent
f896831d4a
commit
ae75e22fc0
@ -15,6 +15,8 @@
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <android/hardware_buffer_jni.h>
|
||||
|
||||
#include "FinalAction.h"
|
||||
|
||||
namespace vision {
|
||||
|
||||
using namespace facebook;
|
||||
@ -92,11 +94,13 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
|
||||
jsi::HostFunctionType toArrayBuffer = JSI_FUNC {
|
||||
#if __ANDROID_API__ >= 26
|
||||
AHardwareBuffer* hardwareBuffer = this->frame->getHardwareBuffer();
|
||||
AHardwareBuffer_acquire(hardwareBuffer);
|
||||
finally([&]() { AHardwareBuffer_release(hardwareBuffer); });
|
||||
|
||||
AHardwareBuffer_Desc bufferDescription;
|
||||
AHardwareBuffer_describe(hardwareBuffer, &bufferDescription);
|
||||
__android_log_print(ANDROID_LOG_INFO, "Frame", "Buffer %i x %i @ %i", bufferDescription.width, bufferDescription.height,
|
||||
bufferDescription.stride);
|
||||
__android_log_print(ANDROID_LOG_INFO, "Frame", "Converting %i x %i @ %i HardwareBuffer...", bufferDescription.width,
|
||||
bufferDescription.height, bufferDescription.stride);
|
||||
size_t size = bufferDescription.height * bufferDescription.stride;
|
||||
|
||||
static constexpr auto ARRAYBUFFER_CACHE_PROP_NAME = "__frameArrayBufferCache";
|
||||
@ -118,16 +122,21 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
|
||||
|
||||
// Get CPU access to the HardwareBuffer (&buffer is a virtual temporary address)
|
||||
void* buffer;
|
||||
AHardwareBuffer_lock(hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_MASK, -1, nullptr, &buffer);
|
||||
int result = AHardwareBuffer_lock(hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_MASK, -1, nullptr, &buffer);
|
||||
if (result != 0) {
|
||||
throw jsi::JSError(runtime, "Failed to lock HardwareBuffer for reading!");
|
||||
}
|
||||
finally([&]() {
|
||||
int result = AHardwareBuffer_unlock(hardwareBuffer, nullptr);
|
||||
if (result != 0) {
|
||||
throw jsi::JSError(runtime, "Failed to lock HardwareBuffer for reading!");
|
||||
}
|
||||
});
|
||||
|
||||
// directly write to C++ JSI ArrayBuffer
|
||||
auto destinationBuffer = arrayBuffer.data(runtime);
|
||||
memcpy(destinationBuffer, buffer, sizeof(uint8_t) * size);
|
||||
|
||||
// Release HardwareBuffer again
|
||||
AHardwareBuffer_unlock(hardwareBuffer, nullptr);
|
||||
AHardwareBuffer_release(hardwareBuffer);
|
||||
|
||||
return arrayBuffer;
|
||||
#else
|
||||
throw jsi::JSError(runtime, "Frame.toArrayBuffer() is only available if minSdkVersion is set to 26 or higher!");
|
||||
|
34
package/cpp/FinalAction.h
Normal file
34
package/cpp/FinalAction.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// MutableRawBuffer.h
|
||||
// VisionCamera
|
||||
//
|
||||
// Created by Marc Rousavy on 17.01.24.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace vision {
|
||||
|
||||
template <typename F> struct FinalAction {
|
||||
|
||||
public:
|
||||
FinalAction(F f) : clean_{f} {}
|
||||
~FinalAction() {
|
||||
if (enabled_)
|
||||
clean_();
|
||||
}
|
||||
void disable() {
|
||||
enabled_ = false;
|
||||
};
|
||||
|
||||
private:
|
||||
F clean_;
|
||||
bool enabled_ = true;
|
||||
};
|
||||
|
||||
} // namespace vision
|
||||
|
||||
template <typename F> vision::FinalAction<F> finally(F f) {
|
||||
return vision::FinalAction<F>(std::move(f));
|
||||
}
|
Loading…
Reference in New Issue
Block a user