Loading camera/ndk/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ LOCAL_MODULE:= libcamera2ndk LOCAL_C_INCLUDES := \ system/media/camera/include \ frameworks/av/include/camera/ndk frameworks/av/include/camera/ndk \ frameworks/av/include/ndk \ LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))' Loading camera/ndk/impl/ACameraMetadata.cpp +71 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "ACameraMetadata.h" #include <utils/Vector.h> #include <system/graphics.h> #include "NdkImage.h" using namespace android; Loading @@ -29,6 +31,7 @@ ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYP mData(buffer), mType(type) { if (mType == ACM_CHARACTERISTICS) { filterUnsupportedFeatures(); filterStreamConfigurations(); } // TODO: filter request/result keys } Loading Loading @@ -60,7 +63,7 @@ void ACameraMetadata::filterUnsupportedFeatures() { // Hide unsupported capabilities (reprocessing) camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); if (entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE) { if (entry.count == 0 || entry.type != TYPE_BYTE) { ALOGE("%s: malformed available capability key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); return; Loading @@ -75,7 +78,73 @@ ACameraMetadata::filterUnsupportedFeatures() { } } mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); // TODO: Hide unsupported streams (input/bidirectional streams) } void ACameraMetadata::filterStreamConfigurations() { const int STREAM_CONFIGURATION_SIZE = 4; const int STREAM_FORMAT_OFFSET = 0; 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); 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); return; } Vector<int32_t> filteredStreamConfigs; filteredStreamConfigs.setCapacity(entry.count); for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) { int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET]; int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET]; int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET]; int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET]; if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) { // Hide input streams continue; } // Translate HAL formats to NDK format if (format == HAL_PIXEL_FORMAT_BLOB) { format = AIMAGE_FORMAT_JPEG; } filteredStreamConfigs.push_back(format); filteredStreamConfigs.push_back(width); filteredStreamConfigs.push_back(height); filteredStreamConfigs.push_back(isInput); } mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); Vector<int32_t> filteredDepthStreamConfigs; filteredDepthStreamConfigs.setCapacity(entry.count); for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) { int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET]; int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET]; int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET]; int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET]; if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) { // Hide input streams continue; } // Translate HAL formats to NDK format if (format == HAL_PIXEL_FORMAT_BLOB) { format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD; } else if (format == HAL_PIXEL_FORMAT_Y16) { format = AIMAGE_FORMAT_DEPTH16; } filteredDepthStreamConfigs.push_back(format); filteredDepthStreamConfigs.push_back(width); filteredDepthStreamConfigs.push_back(height); filteredDepthStreamConfigs.push_back(isInput); } mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs); } bool Loading camera/ndk/impl/ACameraMetadata.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ struct ACameraMetadata : public RefBase { inline bool isVendorTag(const uint32_t tag); bool isCaptureRequestTag(const uint32_t tag); void filterUnsupportedFeatures(); // Hide features not yet supported by NDK void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats template<typename INTERNAL_T, typename NDK_T> camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) { Loading include/ndk/NdkImage.h 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file defines an NDK API. * Do not remove methods. * Do not change method signatures. * Do not change the value of constants. * Do not change the size of any of the classes defined in here. * Do not reference types that are not part of the NDK. * Do not #include files that aren't part of the NDK. */ #ifndef _NDK_IMAGE_H #define _NDK_IMAGE_H #include "NdkMediaError.h" #ifdef __cplusplus extern "C" { #endif typedef struct AImage AImage; // Formats not listed here will not be supported by AImageReader enum { AIMAGE_FORMAT_YUV_420_888 = 0x23, AIMAGE_FORMAT_JPEG = 0x100, AIMAGE_FORMAT_RAW16 = 0x20, AIMAGE_FORMAT_RAW_PRIVATE = 0x24, AIMAGE_FORMAT_RAW10 = 0x25, AIMAGE_FORMAT_RAW12 = 0x26, AIMAGE_FORMAT_DEPTH16 = 0x44363159, AIMAGE_FORMAT_DEPTH_POINT_CLOUD = 0x101 }; typedef struct AImageCropRect { int32_t left; int32_t top; int32_t right; int32_t bottom; } AImageCropRect; // Return the image back to system and delete the AImage from memory // Do NOT use `image` after this call void AImage_delete(AImage* image); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getPlanePixelStride( const AImage* image, int planeIdx, /*out*/int32_t* pixelStride); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getPlaneRowStride( const AImage* image, int planeIdx, /*out*/int32_t* rowStride); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted // Note that once the AImage or the parent AImageReader is deleted, the `*data` returned from // previous AImage_getPlaneData call becomes dangling pointer. Do NOT use it after // AImage or AImageReader is deleted media_status_t AImage_getPlaneData( const AImage* image, int planeIdx, /*out*/uint8_t** data, /*out*/int* dataLength); #ifdef __cplusplus } // extern "C" #endif #endif //_NDK_IMAGE_H include/ndk/NdkImageReader.h 0 → 100644 +77 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file defines an NDK API. * Do not remove methods. * Do not change method signatures. * Do not change the value of constants. * Do not change the size of any of the classes defined in here. * Do not reference types that are not part of the NDK. * Do not #include files that aren't part of the NDK. */ #ifndef _NDK_IMAGE_READER_H #define _NDK_IMAGE_READER_H #include <android/native_window.h> #include "NdkMediaError.h" #include "NdkImage.h" #ifdef __cplusplus extern "C" { #endif typedef struct AImageReader AImageReader; media_status_t AImageReader_new( int32_t width, int32_t height, int32_t format, int32_t maxImages, /*out*/AImageReader** reader); // Return all images acquired from this AImageReader back to system and delete // the AImageReader instance from memory // Do NOT use `reader` after this call void AImageReader_delete(AImageReader* reader); // Do NOT call ANativeWindow_release on the output. Just use AImageReader_delete. media_status_t AImageReader_getWindow(AImageReader*, /*out*/ANativeWindow** window); media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width); media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height); media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format); media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages); media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image); media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image); // The callback happens on one dedicated thread per AImageReader instance // It's okay to use AImageReader_*/AImage_* APIs within the callback typedef void (*AImageReader_ImageCallback)(void* context, AImageReader* reader); typedef struct AImageReader_ImageListener { void* context; // optional application context. AImageReader_ImageCallback onImageAvailable; } AImageReader_ImageListener; media_status_t AImageReader_setImageListener( AImageReader* reader, AImageReader_ImageListener* listener); #ifdef __cplusplus } // extern "C" #endif #endif //_NDK_IMAGE_READER_H Loading
camera/ndk/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ LOCAL_MODULE:= libcamera2ndk LOCAL_C_INCLUDES := \ system/media/camera/include \ frameworks/av/include/camera/ndk frameworks/av/include/camera/ndk \ frameworks/av/include/ndk \ LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))' Loading
camera/ndk/impl/ACameraMetadata.cpp +71 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "ACameraMetadata.h" #include <utils/Vector.h> #include <system/graphics.h> #include "NdkImage.h" using namespace android; Loading @@ -29,6 +31,7 @@ ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYP mData(buffer), mType(type) { if (mType == ACM_CHARACTERISTICS) { filterUnsupportedFeatures(); filterStreamConfigurations(); } // TODO: filter request/result keys } Loading Loading @@ -60,7 +63,7 @@ void ACameraMetadata::filterUnsupportedFeatures() { // Hide unsupported capabilities (reprocessing) camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); if (entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE) { if (entry.count == 0 || entry.type != TYPE_BYTE) { ALOGE("%s: malformed available capability key! count %zu, type %d", __FUNCTION__, entry.count, entry.type); return; Loading @@ -75,7 +78,73 @@ ACameraMetadata::filterUnsupportedFeatures() { } } mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities); // TODO: Hide unsupported streams (input/bidirectional streams) } void ACameraMetadata::filterStreamConfigurations() { const int STREAM_CONFIGURATION_SIZE = 4; const int STREAM_FORMAT_OFFSET = 0; 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); 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); return; } Vector<int32_t> filteredStreamConfigs; filteredStreamConfigs.setCapacity(entry.count); for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) { int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET]; int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET]; int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET]; int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET]; if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) { // Hide input streams continue; } // Translate HAL formats to NDK format if (format == HAL_PIXEL_FORMAT_BLOB) { format = AIMAGE_FORMAT_JPEG; } filteredStreamConfigs.push_back(format); filteredStreamConfigs.push_back(width); filteredStreamConfigs.push_back(height); filteredStreamConfigs.push_back(isInput); } mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs); entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS); Vector<int32_t> filteredDepthStreamConfigs; filteredDepthStreamConfigs.setCapacity(entry.count); for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) { int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET]; int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET]; int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET]; int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET]; if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) { // Hide input streams continue; } // Translate HAL formats to NDK format if (format == HAL_PIXEL_FORMAT_BLOB) { format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD; } else if (format == HAL_PIXEL_FORMAT_Y16) { format = AIMAGE_FORMAT_DEPTH16; } filteredDepthStreamConfigs.push_back(format); filteredDepthStreamConfigs.push_back(width); filteredDepthStreamConfigs.push_back(height); filteredDepthStreamConfigs.push_back(isInput); } mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs); } bool Loading
camera/ndk/impl/ACameraMetadata.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ struct ACameraMetadata : public RefBase { inline bool isVendorTag(const uint32_t tag); bool isCaptureRequestTag(const uint32_t tag); void filterUnsupportedFeatures(); // Hide features not yet supported by NDK void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats template<typename INTERNAL_T, typename NDK_T> camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) { Loading
include/ndk/NdkImage.h 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file defines an NDK API. * Do not remove methods. * Do not change method signatures. * Do not change the value of constants. * Do not change the size of any of the classes defined in here. * Do not reference types that are not part of the NDK. * Do not #include files that aren't part of the NDK. */ #ifndef _NDK_IMAGE_H #define _NDK_IMAGE_H #include "NdkMediaError.h" #ifdef __cplusplus extern "C" { #endif typedef struct AImage AImage; // Formats not listed here will not be supported by AImageReader enum { AIMAGE_FORMAT_YUV_420_888 = 0x23, AIMAGE_FORMAT_JPEG = 0x100, AIMAGE_FORMAT_RAW16 = 0x20, AIMAGE_FORMAT_RAW_PRIVATE = 0x24, AIMAGE_FORMAT_RAW10 = 0x25, AIMAGE_FORMAT_RAW12 = 0x26, AIMAGE_FORMAT_DEPTH16 = 0x44363159, AIMAGE_FORMAT_DEPTH_POINT_CLOUD = 0x101 }; typedef struct AImageCropRect { int32_t left; int32_t top; int32_t right; int32_t bottom; } AImageCropRect; // Return the image back to system and delete the AImage from memory // Do NOT use `image` after this call void AImage_delete(AImage* image); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getPlanePixelStride( const AImage* image, int planeIdx, /*out*/int32_t* pixelStride); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted media_status_t AImage_getPlaneRowStride( const AImage* image, int planeIdx, /*out*/int32_t* rowStride); // AMEDIA_ERROR_INVALID_OBJECT will be returned if the parent AImageReader is deleted // Note that once the AImage or the parent AImageReader is deleted, the `*data` returned from // previous AImage_getPlaneData call becomes dangling pointer. Do NOT use it after // AImage or AImageReader is deleted media_status_t AImage_getPlaneData( const AImage* image, int planeIdx, /*out*/uint8_t** data, /*out*/int* dataLength); #ifdef __cplusplus } // extern "C" #endif #endif //_NDK_IMAGE_H
include/ndk/NdkImageReader.h 0 → 100644 +77 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This file defines an NDK API. * Do not remove methods. * Do not change method signatures. * Do not change the value of constants. * Do not change the size of any of the classes defined in here. * Do not reference types that are not part of the NDK. * Do not #include files that aren't part of the NDK. */ #ifndef _NDK_IMAGE_READER_H #define _NDK_IMAGE_READER_H #include <android/native_window.h> #include "NdkMediaError.h" #include "NdkImage.h" #ifdef __cplusplus extern "C" { #endif typedef struct AImageReader AImageReader; media_status_t AImageReader_new( int32_t width, int32_t height, int32_t format, int32_t maxImages, /*out*/AImageReader** reader); // Return all images acquired from this AImageReader back to system and delete // the AImageReader instance from memory // Do NOT use `reader` after this call void AImageReader_delete(AImageReader* reader); // Do NOT call ANativeWindow_release on the output. Just use AImageReader_delete. media_status_t AImageReader_getWindow(AImageReader*, /*out*/ANativeWindow** window); media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width); media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height); media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format); media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages); media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image); media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image); // The callback happens on one dedicated thread per AImageReader instance // It's okay to use AImageReader_*/AImage_* APIs within the callback typedef void (*AImageReader_ImageCallback)(void* context, AImageReader* reader); typedef struct AImageReader_ImageListener { void* context; // optional application context. AImageReader_ImageCallback onImageAvailable; } AImageReader_ImageListener; media_status_t AImageReader_setImageListener( AImageReader* reader, AImageReader_ImageListener* listener); #ifdef __cplusplus } // extern "C" #endif #endif //_NDK_IMAGE_READER_H