Loading camera/ndk/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,9 @@ cc_library_shared { "libmediandk", "libnativewindow", ], header_libs: [ "jni_headers", ], cflags: [ "-fvisibility=hidden", "-DEXPORT=__attribute__ ((visibility (\"default\")))", Loading Loading @@ -121,7 +124,6 @@ cc_library_shared { "android.frameworks.cameraservice.common@2.0", "android.frameworks.cameraservice.service@2.0", ], static_libs: [ "android.hardware.camera.common@1.0-helper", "libarect", Loading camera/ndk/NdkCameraMetadata.cpp +94 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,68 @@ using namespace android; #ifndef __ANDROID_VNDK__ namespace { constexpr const char* android_hardware_camera2_CameraMetadata_jniClassName = "android/hardware/camera2/CameraMetadata"; constexpr const char* android_hardware_camera2_CameraCharacteristics_jniClassName = "android/hardware/camera2/CameraCharacteristics"; constexpr const char* android_hardware_camera2_CaptureResult_jniClassName = "android/hardware/camera2/CaptureResult"; jclass android_hardware_camera2_CameraCharacteristics_clazz = nullptr; jclass android_hardware_camera2_CaptureResult_clazz = nullptr; jmethodID android_hardware_camera2_CameraMetadata_getNativeMetadataPtr = nullptr; // Called at most once to initializes global variables used by JNI. bool InitJni(JNIEnv* env) { // From C++11 onward, static initializers are guaranteed to be executed at most once, // even if called from multiple threads. static bool ok = [env]() -> bool { const jclass cameraMetadataClazz = env->FindClass( android_hardware_camera2_CameraMetadata_jniClassName); if (cameraMetadataClazz == nullptr) { return false; } android_hardware_camera2_CameraMetadata_getNativeMetadataPtr = env->GetMethodID(cameraMetadataClazz, "getNativeMetadataPtr", "()J"); if (android_hardware_camera2_CameraMetadata_getNativeMetadataPtr == nullptr) { return false; } android_hardware_camera2_CameraCharacteristics_clazz = env->FindClass( android_hardware_camera2_CameraCharacteristics_jniClassName); if (android_hardware_camera2_CameraCharacteristics_clazz == nullptr) { return false; } android_hardware_camera2_CaptureResult_clazz = env->FindClass( android_hardware_camera2_CaptureResult_jniClassName); if (android_hardware_camera2_CaptureResult_clazz == nullptr) { return false; } return true; }(); return ok; } // Given cameraMetadata, an instance of android.hardware.camera2.CameraMetadata, invokes // cameraMetadata.getNativeMetadataPtr() and returns it as a CameraMetadata*. CameraMetadata* CameraMetadata_getNativeMetadataPtr(JNIEnv* env, jobject cameraMetadata) { if (cameraMetadata == nullptr) { ALOGE("%s: Invalid Java CameraMetadata object.", __FUNCTION__); return nullptr; } jlong ret = env->CallLongMethod(cameraMetadata, android_hardware_camera2_CameraMetadata_getNativeMetadataPtr); return reinterpret_cast<CameraMetadata *>(ret); } } // namespace #endif /* __ANDROID_VNDK__ */ EXPORT camera_status_t ACameraMetadata_getConstEntry( const ACameraMetadata* acm, uint32_t tag, ACameraMetadata_const_entry* entry) { Loading Loading @@ -58,7 +120,7 @@ ACameraMetadata* ACameraMetadata_copy(const ACameraMetadata* src) { return nullptr; } ACameraMetadata* copy = new ACameraMetadata(*src); copy->incStrong((void*) ACameraMetadata_copy); copy->incStrong(/*id=*/(void*) ACameraMetadata_copy); return copy; } Loading Loading @@ -86,3 +148,34 @@ bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata, return staticMetadata->isLogicalMultiCamera(numPhysicalCameras, physicalCameraIds); } #ifndef __ANDROID_VNDK__ EXPORT ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata) { ATRACE_CALL(); const bool ok = InitJni(env); LOG_ALWAYS_FATAL_IF(!ok, "Failed to find CameraMetadata Java classes."); if (cameraMetadata == nullptr) { return nullptr; } ACameraMetadata::ACAMERA_METADATA_TYPE type; if (env->IsInstanceOf(cameraMetadata, android_hardware_camera2_CameraCharacteristics_clazz)) { type = ACameraMetadata::ACM_CHARACTERISTICS; } else if (env->IsInstanceOf(cameraMetadata, android_hardware_camera2_CaptureResult_clazz)) { type = ACameraMetadata::ACM_RESULT; } else { return nullptr; } CameraMetadata* src = CameraMetadata_getNativeMetadataPtr(env, cameraMetadata); ACameraMetadata* output = new ACameraMetadata(src, type); output->incStrong(/*id=*/(void*) ACameraMetadata_fromCameraMetadata); return output; } #endif /* __ANDROID_VNDK__ */ No newline at end of file camera/ndk/impl/ACameraMetadata.cpp +48 −18 Original line number Diff line number Diff line Loading @@ -28,7 +28,37 @@ using namespace android; * ACameraMetadata Implementation */ ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) : mData(buffer), mType(type) { mData(new CameraMetadata(buffer)), mOwnsData(true), mType(type) { init(); } ACameraMetadata::ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type) : mData(cameraMetadata), mOwnsData(false), mType(type) { init(); } ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) : mOwnsData(other.mOwnsData), mType(other.mType) { if (other.mOwnsData) { mData = new CameraMetadata(*(other.mData)); } else { mData = other.mData; } } ACameraMetadata::~ACameraMetadata() { if (mOwnsData) { delete mData; } } void ACameraMetadata::init() { if (mType == ACM_CHARACTERISTICS) { filterUnsupportedFeatures(); filterStreamConfigurations(); Loading Loading @@ -61,7 +91,7 @@ ACameraMetadata::isNdkSupportedCapability(int32_t capability) { void ACameraMetadata::filterUnsupportedFeatures() { // Hide unsupported capabilities (reprocessing) camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); if (entry.count == 0 || entry.type != TYPE_BYTE) { ALOGE("%s: malformed available capability key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading @@ -80,7 +110,7 @@ ACameraMetadata::filterUnsupportedFeatures() { } } } mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); } void Loading Loading @@ -118,7 +148,7 @@ ACameraMetadata::filterDurations(uint32_t tag) { const int STREAM_WIDTH_OFFSET = 1; const int STREAM_HEIGHT_OFFSET = 2; const int STREAM_DURATION_OFFSET = 3; camera_metadata_entry entry = mData.find(tag); camera_metadata_entry entry = mData->find(tag); if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) { ALOGE("%s: malformed duration key %d! count %zu, type %d", __FUNCTION__, tag, entry.count, entry.type); Loading Loading @@ -194,7 +224,7 @@ ACameraMetadata::filterDurations(uint32_t tag) { } } mData.update(tag, filteredDurations); mData->update(tag, filteredDurations); } void Loading @@ -204,7 +234,7 @@ ACameraMetadata::filterStreamConfigurations() { const int STREAM_WIDTH_OFFSET = 1; const int STREAM_HEIGHT_OFFSET = 2; const int STREAM_IS_INPUT_OFFSET = 3; camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) { ALOGE("%s: malformed available stream configuration key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading Loading @@ -234,10 +264,10 @@ ACameraMetadata::filterStreamConfigurations() { } if (filteredStreamConfigs.size() > 0) { mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); } entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) { ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading Loading @@ -270,11 +300,11 @@ ACameraMetadata::filterStreamConfigurations() { } if (filteredDepthStreamConfigs.size() > 0) { mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs); } entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS); Vector<int32_t> filteredHeicStreamConfigs; filteredHeicStreamConfigs.setCapacity(entry.count); Loading @@ -297,9 +327,9 @@ ACameraMetadata::filterStreamConfigurations() { filteredHeicStreamConfigs.push_back(height); filteredHeicStreamConfigs.push_back(isInput); } mData.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs); mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs); entry = mData.find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS); Vector<int32_t> filteredDynamicDepthStreamConfigs; filteredDynamicDepthStreamConfigs.setCapacity(entry.count); Loading @@ -322,7 +352,7 @@ ACameraMetadata::filterStreamConfigurations() { filteredDynamicDepthStreamConfigs.push_back(height); filteredDynamicDepthStreamConfigs.push_back(isInput); } mData.update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, filteredDynamicDepthStreamConfigs); } Loading @@ -343,7 +373,7 @@ ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) Mutex::Autolock _l(mLock); camera_metadata_ro_entry rawEntry = mData.find(tag); camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData)->find(tag); if (rawEntry.count == 0) { ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag); return ACAMERA_ERROR_METADATA_NOT_FOUND; Loading Loading @@ -390,9 +420,9 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, /*out*/const uint32_t** tags) const { Mutex::Autolock _l(mLock); if (mTags.size() == 0) { size_t entry_count = mData.entryCount(); size_t entry_count = mData->entryCount(); mTags.setCapacity(entry_count); const camera_metadata_t* rawMetadata = mData.getAndLock(); const camera_metadata_t* rawMetadata = mData->getAndLock(); for (size_t i = 0; i < entry_count; i++) { camera_metadata_ro_entry_t entry; int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry); Loading @@ -405,7 +435,7 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, mTags.push_back(entry.tag); } } mData.unlock(rawMetadata); mData->unlock(rawMetadata); } *numTags = mTags.size(); Loading @@ -415,7 +445,7 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, const CameraMetadata& ACameraMetadata::getInternalData() const { return mData; return (*mData); } bool Loading camera/ndk/impl/ACameraMetadata.h +29 −13 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ using CameraMetadata = android::hardware::camera::common::V1_0::helper::CameraMe using namespace android; /** * ACameraMetadata opaque struct definition * Leave outside of android namespace because it's NDK struct * ACameraMetadata is an opaque struct definition. * It is intentionally left outside of the android namespace because it's NDK struct. */ struct ACameraMetadata : public RefBase { public: Loading @@ -47,11 +47,20 @@ struct ACameraMetadata : public RefBase { ACM_RESULT, // Read only } ACAMERA_METADATA_TYPE; // Takes ownership of pass-in buffer // Constructs a ACameraMetadata that takes ownership of `buffer`. ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type); // Clone ACameraMetadata(const ACameraMetadata& other) : mData(other.mData), mType(other.mType) {}; // Constructs a ACameraMetadata that is a view of `cameraMetadata`. // `cameraMetadata` will not be deleted by ~ACameraMetadata(). ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type); // Copy constructor. // // If `other` owns its CameraMetadata, then makes a deep copy. // Otherwise, the new instance is also a view of the same data. ACameraMetadata(const ACameraMetadata& other); ~ACameraMetadata(); camera_status_t getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const; Loading @@ -70,6 +79,9 @@ struct ACameraMetadata : public RefBase { private: // Common code called by constructors. void init(); // This function does not check whether the capability passed to it is valid. // The caller must make sure that it is. bool isNdkSupportedCapability(const int32_t capability); Loading @@ -95,11 +107,11 @@ struct ACameraMetadata : public RefBase { status_t ret = OK; if (count == 0 && data == nullptr) { ret = mData.erase(tag); ret = mData->erase(tag); } else { // Here we have to use reinterpret_cast because the NDK data type is // exact copy of internal data type but they do not inherit from each other ret = mData.update(tag, reinterpret_cast<const INTERNAL_T*>(data), count); ret = mData->update(tag, reinterpret_cast<const INTERNAL_T*>(data), count); } if (ret == OK) { Loading @@ -110,10 +122,14 @@ struct ACameraMetadata : public RefBase { } } // guard access of public APIs: get/update/getTags // Guard access of public APIs: get/update/getTags. mutable Mutex mLock; CameraMetadata mData; mutable Vector<uint32_t> mTags; // updated in getTags, cleared by update CameraMetadata* mData; // If true, has ownership of mData. Otherwise, mData is a view of an external instance. bool mOwnsData; mutable Vector<uint32_t> mTags; // Updated by `getTags()`, cleared by `update()`. const ACAMERA_METADATA_TYPE mType; static std::unordered_set<uint32_t> sSystemTags; Loading camera/ndk/include/camera/NdkCameraMetadata.h +39 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ #include <stdint.h> #include <sys/cdefs.h> #ifndef __ANDROID_VNDK__ #if __ANDROID_API__ >= 30 #include "jni.h" #endif /* __ANDROID_API__ >= 30 */ #endif /* __ANDROID_VNDK__ */ #include "NdkCameraError.h" #include "NdkCameraMetadataTags.h" Loading Loading @@ -255,6 +261,38 @@ bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata, #endif /* __ANDROID_API__ >= 29 */ #ifndef __ANDROID_VNDK__ #if __ANDROID_API__ >= 30 /** * Return a {@link ACameraMetadata} that references the same data as * {@link cameraMetadata}, which is an instance of * {@link android.hardware.camera2.CameraMetadata} (e.g., a * {@link android.hardware.camera2.CameraCharacteristics} or * {@link android.hardware.camera2.CaptureResult}). * * <p>The returned ACameraMetadata must be freed by the application by {@link ACameraMetadata_free} * after application is done using it.</p> * * <p>This function does not affect the lifetime of {@link cameraMetadata}. Attempting to use the * returned ACameraMetadata object after {@link cameraMetadata} has been garbage collected is * unsafe. To manage the lifetime beyond the current JNI function call, use * {@code env->NewGlobalRef()} and {@code env->DeleteGlobalRef()}. * * @param env the JNI environment. * @param cameraMetadata the source {@link android.hardware.camera2.CameraMetadata} from which the * returned {@link ACameraMetadata} is a view. * * @return a valid ACameraMetadata pointer or NULL if {@link cameraMetadata} is null or not a valid * instance of {@link android.hardware.camera2.CameraMetadata}. * */ ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata) __INTRODUCED_IN(30); #endif /* __ANDROID_API__ >= 30 */ #endif /* __ANDROID_VNDK__ */ __END_DECLS #endif /* _NDK_CAMERA_METADATA_H */ Loading Loading
camera/ndk/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,9 @@ cc_library_shared { "libmediandk", "libnativewindow", ], header_libs: [ "jni_headers", ], cflags: [ "-fvisibility=hidden", "-DEXPORT=__attribute__ ((visibility (\"default\")))", Loading Loading @@ -121,7 +124,6 @@ cc_library_shared { "android.frameworks.cameraservice.common@2.0", "android.frameworks.cameraservice.service@2.0", ], static_libs: [ "android.hardware.camera.common@1.0-helper", "libarect", Loading
camera/ndk/NdkCameraMetadata.cpp +94 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,68 @@ using namespace android; #ifndef __ANDROID_VNDK__ namespace { constexpr const char* android_hardware_camera2_CameraMetadata_jniClassName = "android/hardware/camera2/CameraMetadata"; constexpr const char* android_hardware_camera2_CameraCharacteristics_jniClassName = "android/hardware/camera2/CameraCharacteristics"; constexpr const char* android_hardware_camera2_CaptureResult_jniClassName = "android/hardware/camera2/CaptureResult"; jclass android_hardware_camera2_CameraCharacteristics_clazz = nullptr; jclass android_hardware_camera2_CaptureResult_clazz = nullptr; jmethodID android_hardware_camera2_CameraMetadata_getNativeMetadataPtr = nullptr; // Called at most once to initializes global variables used by JNI. bool InitJni(JNIEnv* env) { // From C++11 onward, static initializers are guaranteed to be executed at most once, // even if called from multiple threads. static bool ok = [env]() -> bool { const jclass cameraMetadataClazz = env->FindClass( android_hardware_camera2_CameraMetadata_jniClassName); if (cameraMetadataClazz == nullptr) { return false; } android_hardware_camera2_CameraMetadata_getNativeMetadataPtr = env->GetMethodID(cameraMetadataClazz, "getNativeMetadataPtr", "()J"); if (android_hardware_camera2_CameraMetadata_getNativeMetadataPtr == nullptr) { return false; } android_hardware_camera2_CameraCharacteristics_clazz = env->FindClass( android_hardware_camera2_CameraCharacteristics_jniClassName); if (android_hardware_camera2_CameraCharacteristics_clazz == nullptr) { return false; } android_hardware_camera2_CaptureResult_clazz = env->FindClass( android_hardware_camera2_CaptureResult_jniClassName); if (android_hardware_camera2_CaptureResult_clazz == nullptr) { return false; } return true; }(); return ok; } // Given cameraMetadata, an instance of android.hardware.camera2.CameraMetadata, invokes // cameraMetadata.getNativeMetadataPtr() and returns it as a CameraMetadata*. CameraMetadata* CameraMetadata_getNativeMetadataPtr(JNIEnv* env, jobject cameraMetadata) { if (cameraMetadata == nullptr) { ALOGE("%s: Invalid Java CameraMetadata object.", __FUNCTION__); return nullptr; } jlong ret = env->CallLongMethod(cameraMetadata, android_hardware_camera2_CameraMetadata_getNativeMetadataPtr); return reinterpret_cast<CameraMetadata *>(ret); } } // namespace #endif /* __ANDROID_VNDK__ */ EXPORT camera_status_t ACameraMetadata_getConstEntry( const ACameraMetadata* acm, uint32_t tag, ACameraMetadata_const_entry* entry) { Loading Loading @@ -58,7 +120,7 @@ ACameraMetadata* ACameraMetadata_copy(const ACameraMetadata* src) { return nullptr; } ACameraMetadata* copy = new ACameraMetadata(*src); copy->incStrong((void*) ACameraMetadata_copy); copy->incStrong(/*id=*/(void*) ACameraMetadata_copy); return copy; } Loading Loading @@ -86,3 +148,34 @@ bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata, return staticMetadata->isLogicalMultiCamera(numPhysicalCameras, physicalCameraIds); } #ifndef __ANDROID_VNDK__ EXPORT ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata) { ATRACE_CALL(); const bool ok = InitJni(env); LOG_ALWAYS_FATAL_IF(!ok, "Failed to find CameraMetadata Java classes."); if (cameraMetadata == nullptr) { return nullptr; } ACameraMetadata::ACAMERA_METADATA_TYPE type; if (env->IsInstanceOf(cameraMetadata, android_hardware_camera2_CameraCharacteristics_clazz)) { type = ACameraMetadata::ACM_CHARACTERISTICS; } else if (env->IsInstanceOf(cameraMetadata, android_hardware_camera2_CaptureResult_clazz)) { type = ACameraMetadata::ACM_RESULT; } else { return nullptr; } CameraMetadata* src = CameraMetadata_getNativeMetadataPtr(env, cameraMetadata); ACameraMetadata* output = new ACameraMetadata(src, type); output->incStrong(/*id=*/(void*) ACameraMetadata_fromCameraMetadata); return output; } #endif /* __ANDROID_VNDK__ */ No newline at end of file
camera/ndk/impl/ACameraMetadata.cpp +48 −18 Original line number Diff line number Diff line Loading @@ -28,7 +28,37 @@ using namespace android; * ACameraMetadata Implementation */ ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) : mData(buffer), mType(type) { mData(new CameraMetadata(buffer)), mOwnsData(true), mType(type) { init(); } ACameraMetadata::ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type) : mData(cameraMetadata), mOwnsData(false), mType(type) { init(); } ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) : mOwnsData(other.mOwnsData), mType(other.mType) { if (other.mOwnsData) { mData = new CameraMetadata(*(other.mData)); } else { mData = other.mData; } } ACameraMetadata::~ACameraMetadata() { if (mOwnsData) { delete mData; } } void ACameraMetadata::init() { if (mType == ACM_CHARACTERISTICS) { filterUnsupportedFeatures(); filterStreamConfigurations(); Loading Loading @@ -61,7 +91,7 @@ ACameraMetadata::isNdkSupportedCapability(int32_t capability) { void ACameraMetadata::filterUnsupportedFeatures() { // Hide unsupported capabilities (reprocessing) camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); if (entry.count == 0 || entry.type != TYPE_BYTE) { ALOGE("%s: malformed available capability key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading @@ -80,7 +110,7 @@ ACameraMetadata::filterUnsupportedFeatures() { } } } mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); } void Loading Loading @@ -118,7 +148,7 @@ ACameraMetadata::filterDurations(uint32_t tag) { const int STREAM_WIDTH_OFFSET = 1; const int STREAM_HEIGHT_OFFSET = 2; const int STREAM_DURATION_OFFSET = 3; camera_metadata_entry entry = mData.find(tag); camera_metadata_entry entry = mData->find(tag); if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) { ALOGE("%s: malformed duration key %d! count %zu, type %d", __FUNCTION__, tag, entry.count, entry.type); Loading Loading @@ -194,7 +224,7 @@ ACameraMetadata::filterDurations(uint32_t tag) { } } mData.update(tag, filteredDurations); mData->update(tag, filteredDurations); } void Loading @@ -204,7 +234,7 @@ ACameraMetadata::filterStreamConfigurations() { const int STREAM_WIDTH_OFFSET = 1; const int STREAM_HEIGHT_OFFSET = 2; const int STREAM_IS_INPUT_OFFSET = 3; camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) { ALOGE("%s: malformed available stream configuration key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading Loading @@ -234,10 +264,10 @@ ACameraMetadata::filterStreamConfigurations() { } if (filteredStreamConfigs.size() > 0) { mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); } entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) { ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); Loading Loading @@ -270,11 +300,11 @@ ACameraMetadata::filterStreamConfigurations() { } if (filteredDepthStreamConfigs.size() > 0) { mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs); } entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS); Vector<int32_t> filteredHeicStreamConfigs; filteredHeicStreamConfigs.setCapacity(entry.count); Loading @@ -297,9 +327,9 @@ ACameraMetadata::filterStreamConfigurations() { filteredHeicStreamConfigs.push_back(height); filteredHeicStreamConfigs.push_back(isInput); } mData.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs); mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs); entry = mData.find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS); entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS); Vector<int32_t> filteredDynamicDepthStreamConfigs; filteredDynamicDepthStreamConfigs.setCapacity(entry.count); Loading @@ -322,7 +352,7 @@ ACameraMetadata::filterStreamConfigurations() { filteredDynamicDepthStreamConfigs.push_back(height); filteredDynamicDepthStreamConfigs.push_back(isInput); } mData.update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, filteredDynamicDepthStreamConfigs); } Loading @@ -343,7 +373,7 @@ ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) Mutex::Autolock _l(mLock); camera_metadata_ro_entry rawEntry = mData.find(tag); camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData)->find(tag); if (rawEntry.count == 0) { ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag); return ACAMERA_ERROR_METADATA_NOT_FOUND; Loading Loading @@ -390,9 +420,9 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, /*out*/const uint32_t** tags) const { Mutex::Autolock _l(mLock); if (mTags.size() == 0) { size_t entry_count = mData.entryCount(); size_t entry_count = mData->entryCount(); mTags.setCapacity(entry_count); const camera_metadata_t* rawMetadata = mData.getAndLock(); const camera_metadata_t* rawMetadata = mData->getAndLock(); for (size_t i = 0; i < entry_count; i++) { camera_metadata_ro_entry_t entry; int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry); Loading @@ -405,7 +435,7 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, mTags.push_back(entry.tag); } } mData.unlock(rawMetadata); mData->unlock(rawMetadata); } *numTags = mTags.size(); Loading @@ -415,7 +445,7 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, const CameraMetadata& ACameraMetadata::getInternalData() const { return mData; return (*mData); } bool Loading
camera/ndk/impl/ACameraMetadata.h +29 −13 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ using CameraMetadata = android::hardware::camera::common::V1_0::helper::CameraMe using namespace android; /** * ACameraMetadata opaque struct definition * Leave outside of android namespace because it's NDK struct * ACameraMetadata is an opaque struct definition. * It is intentionally left outside of the android namespace because it's NDK struct. */ struct ACameraMetadata : public RefBase { public: Loading @@ -47,11 +47,20 @@ struct ACameraMetadata : public RefBase { ACM_RESULT, // Read only } ACAMERA_METADATA_TYPE; // Takes ownership of pass-in buffer // Constructs a ACameraMetadata that takes ownership of `buffer`. ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type); // Clone ACameraMetadata(const ACameraMetadata& other) : mData(other.mData), mType(other.mType) {}; // Constructs a ACameraMetadata that is a view of `cameraMetadata`. // `cameraMetadata` will not be deleted by ~ACameraMetadata(). ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type); // Copy constructor. // // If `other` owns its CameraMetadata, then makes a deep copy. // Otherwise, the new instance is also a view of the same data. ACameraMetadata(const ACameraMetadata& other); ~ACameraMetadata(); camera_status_t getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const; Loading @@ -70,6 +79,9 @@ struct ACameraMetadata : public RefBase { private: // Common code called by constructors. void init(); // This function does not check whether the capability passed to it is valid. // The caller must make sure that it is. bool isNdkSupportedCapability(const int32_t capability); Loading @@ -95,11 +107,11 @@ struct ACameraMetadata : public RefBase { status_t ret = OK; if (count == 0 && data == nullptr) { ret = mData.erase(tag); ret = mData->erase(tag); } else { // Here we have to use reinterpret_cast because the NDK data type is // exact copy of internal data type but they do not inherit from each other ret = mData.update(tag, reinterpret_cast<const INTERNAL_T*>(data), count); ret = mData->update(tag, reinterpret_cast<const INTERNAL_T*>(data), count); } if (ret == OK) { Loading @@ -110,10 +122,14 @@ struct ACameraMetadata : public RefBase { } } // guard access of public APIs: get/update/getTags // Guard access of public APIs: get/update/getTags. mutable Mutex mLock; CameraMetadata mData; mutable Vector<uint32_t> mTags; // updated in getTags, cleared by update CameraMetadata* mData; // If true, has ownership of mData. Otherwise, mData is a view of an external instance. bool mOwnsData; mutable Vector<uint32_t> mTags; // Updated by `getTags()`, cleared by `update()`. const ACAMERA_METADATA_TYPE mType; static std::unordered_set<uint32_t> sSystemTags; Loading
camera/ndk/include/camera/NdkCameraMetadata.h +39 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ #include <stdint.h> #include <sys/cdefs.h> #ifndef __ANDROID_VNDK__ #if __ANDROID_API__ >= 30 #include "jni.h" #endif /* __ANDROID_API__ >= 30 */ #endif /* __ANDROID_VNDK__ */ #include "NdkCameraError.h" #include "NdkCameraMetadataTags.h" Loading Loading @@ -255,6 +261,38 @@ bool ACameraMetadata_isLogicalMultiCamera(const ACameraMetadata* staticMetadata, #endif /* __ANDROID_API__ >= 29 */ #ifndef __ANDROID_VNDK__ #if __ANDROID_API__ >= 30 /** * Return a {@link ACameraMetadata} that references the same data as * {@link cameraMetadata}, which is an instance of * {@link android.hardware.camera2.CameraMetadata} (e.g., a * {@link android.hardware.camera2.CameraCharacteristics} or * {@link android.hardware.camera2.CaptureResult}). * * <p>The returned ACameraMetadata must be freed by the application by {@link ACameraMetadata_free} * after application is done using it.</p> * * <p>This function does not affect the lifetime of {@link cameraMetadata}. Attempting to use the * returned ACameraMetadata object after {@link cameraMetadata} has been garbage collected is * unsafe. To manage the lifetime beyond the current JNI function call, use * {@code env->NewGlobalRef()} and {@code env->DeleteGlobalRef()}. * * @param env the JNI environment. * @param cameraMetadata the source {@link android.hardware.camera2.CameraMetadata} from which the * returned {@link ACameraMetadata} is a view. * * @return a valid ACameraMetadata pointer or NULL if {@link cameraMetadata} is null or not a valid * instance of {@link android.hardware.camera2.CameraMetadata}. * */ ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata) __INTRODUCED_IN(30); #endif /* __ANDROID_API__ >= 30 */ #endif /* __ANDROID_VNDK__ */ __END_DECLS #endif /* _NDK_CAMERA_METADATA_H */ Loading