17 #include <android/log.h>
18 #include <opencv2/opencv.hpp>
24 #define LOG_NDKCAM_WARN(...) Utils::log("SENSAndroidCamera", __VA_ARGS__);
25 #define LOG_NDKCAM_INFO(...) Utils::log("SENSAndroidCamera", __VA_ARGS__);
26 #define LOG_NDKCAM_DEBUG(...) Utils::log("SENSAndroidCamera", __VA_ARGS__);
55 LOG_NDKCAM_WARN(
"onSessionClosed: CaptureSession state: session %p closed", ses);
62 LOG_NDKCAM_WARN(
"onSessionReady: CaptureSession state: session %p ready", ses);
69 LOG_NDKCAM_WARN(
"onSessionActive: CaptureSession state: session %p active", ses);
75 : _cameraDeviceOpened(false)
129 ACameraIdList* cameraIds =
nullptr;
130 camera_status_t status = ACameraManager_getCameraIdList(
_cameraManager, &cameraIds);
131 ACameraManager_deleteCameraIdList(cameraIds);
154 ACameraDevice_stateCallbacks cameraDeviceListener = {
160 camera_status_t cameraState;
167 &cameraDeviceListener,
170 if (cameraState == ACAMERA_OK)
175 if (cameraState != ACAMERA_OK)
191 LOG_NDKCAM_INFO(
"openCamera: CaptureSize (%d, %d)", streamConfig.widthPix, streamConfig.heightPix);
195 LOG_NDKCAM_INFO(
"openCamera: ImageReader valid and captureSize does not fit");
264 _captureSize = cv::Size(streamConfig.widthPix, streamConfig.heightPix);
267 if (AImageReader_new(streamConfig.widthPix, streamConfig.heightPix, AIMAGE_FORMAT_YUV_420_888, 2, &
_imageReader) != AMEDIA_OK)
271 AImageReader_ImageListener listener{
288 bool provideIntrinsics)
292 Utils::warnMsg(
"SENSWebCamera",
"Call to start was ignored. Camera is currently running!", __LINE__, __FILE__);
344 ACameraCaptureSession_stateCallbacks captureSessionStateCallbacks = {
349 camera_status_t captureSessionStatus = ACameraDevice_createCaptureSession(
_cameraDevice,
351 &captureSessionStateCallbacks,
353 if (captureSessionStatus != AMEDIA_OK)
364 uint8_t afMode = ACAMERA_CONTROL_AF_MODE_OFF;
365 ACaptureRequest_setEntry_u8(
_captureRequest, ACAMERA_CONTROL_AF_MODE, 1, &afMode);
366 float focusDistance = 0.0f;
367 ACaptureRequest_setEntry_float(
_captureRequest, ACAMERA_LENS_FOCUS_DISTANCE, 1, &focusDistance);
371 uint8_t afMode = ACAMERA_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
372 ACaptureRequest_setEntry_u8(
_captureRequest, ACAMERA_CONTROL_AF_MODE, 1, &afMode);
377 uint8_t
mode = ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
378 ACaptureRequest_setEntry_u8(
_captureRequest, ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE, 1, &
mode);
382 uint8_t
mode = ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_OFF;
383 ACaptureRequest_setEntry_u8(
_captureRequest, ACAMERA_LENS_OPTICAL_STABILIZATION_MODE, 1, &
mode);
466 int32_t height, width, rowStrideY;
467 AImage_getHeight(image, &height);
468 AImage_getWidth(image, &width);
469 AImage_getPlaneRowStride(image, 0, &rowStrideY);
472 uint8_t *yPixel, *vPixel;
474 AImage_getPlaneData(image, 0, &yPixel, &yLen);
476 AImage_getPlaneData(image, 2, &vPixel, &vLen);
487 cv::Mat yuv(height + (height / 2), rowStrideY, CV_8UC1);
488 memcpy(yuv.data, yPixel, yLen);
496 memcpy(yuv.data + yLen + (rowStrideY - width), vPixel, vLen + 1);
499 if (rowStrideY > width)
501 cv::Rect roi(0, 0, width, yuv.rows);
502 cv::Mat roiYuv = yuv(roi);
511 AImage* image =
nullptr;
512 media_status_t status = AImageReader_acquireLatestImage(reader, &image);
513 if (status == AMEDIA_OK && image)
517 AImage_delete(image);
521 cv::cvtColor(yuv, bgr, cv::COLOR_YUV2BGR_NV21, 3);
524 updateFrame(bgr, cv::Mat(),
false, bgr.cols, bgr.rows);
536 std::string id(ACameraDevice_getId(dev));
562 case ERROR_CAMERA_IN_USE:
563 errStr =
"ERROR_CAMERA_IN_USE";
565 case ERROR_CAMERA_SERVICE:
566 errStr =
"ERROR_CAMERA_SERVICE";
568 case ERROR_CAMERA_DEVICE:
569 errStr =
"ERROR_CAMERA_DEVICE";
571 case ERROR_CAMERA_DISABLED:
572 errStr =
"ERROR_CAMERA_DISABLED";
574 case ERROR_MAX_CAMERAS_IN_USE:
575 errStr =
"ERROR_MAX_CAMERAS_IN_USE";
578 errStr =
"Unknown Error";
581 std::string id(ACameraDevice_getId(dev));
588 LOG_NDKCAM_INFO(
"CameraDevice %s is in error %s",
id.c_str(), errStr.c_str());
598 LOG_NDKCAM_INFO(
"onCameraStatusChanged: id: %s available: %s ",
id, available ?
"true" :
"false");
656 ACameraManager* cameraManager = ACameraManager_create();
660 ACameraIdList* cameraIds =
nullptr;
661 if (ACameraManager_getCameraIdList(cameraManager, &cameraIds) != ACAMERA_OK)
664 for (
int i = 0; i < cameraIds->numCameras; ++i)
666 std::string cameraId = cameraIds->cameraIds[i];
668 ACameraMetadata* camCharacteristics;
669 ACameraManager_getCameraCharacteristics(cameraManager, cameraId.c_str(), &camCharacteristics);
671 int32_t numEntries = 0;
672 const uint32_t* tags =
nullptr;
673 ACameraMetadata_getAllTags(camCharacteristics, &numEntries, &tags);
675 std::vector<float> focalLengthsMM;
676 cv::Size2f physicalSensorSizeMM;
680 for (
int tagIdx = 0; tagIdx < numEntries; ++tagIdx)
682 ACameraMetadata_const_entry lensInfo = {0};
684 if (tags[tagIdx] == ACAMERA_LENS_FACING)
686 ACameraMetadata_getConstEntry(camCharacteristics, tags[tagIdx], &lensInfo);
687 acamera_metadata_enum_android_lens_facing_t androidFacing =
static_cast<acamera_metadata_enum_android_lens_facing_t
>(lensInfo.data.u8[0]);
688 if (androidFacing == ACAMERA_LENS_FACING_BACK)
690 else if (androidFacing == ACAMERA_LENS_FACING_FRONT)
695 else if (tags[tagIdx] == ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
697 if (ACameraMetadata_getConstEntry(camCharacteristics, tags[tagIdx], &lensInfo) ==
700 for (
int i = 0; i < lensInfo.count; ++i)
703 focalLengthsMM.push_back(lensInfo.data.f[i]);
707 else if (tags[tagIdx] == ACAMERA_SENSOR_INFO_PHYSICAL_SIZE)
709 if (ACameraMetadata_getConstEntry(camCharacteristics, tags[tagIdx], &lensInfo) == ACAMERA_OK)
714 physicalSensorSizeMM.width = lensInfo.data.f[0];
715 physicalSensorSizeMM.height = lensInfo.data.f[1];
726 for (
int tagIdx = 0; tagIdx < numEntries; ++tagIdx)
728 if (tags[tagIdx] == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS)
730 ACameraMetadata_const_entry lensInfo = {0};
731 if (ACameraMetadata_getConstEntry(camCharacteristics, tags[tagIdx], &lensInfo) == ACAMERA_OK)
733 if (lensInfo.count & 0x3)
735 "STREAM_CONFIGURATION (%d) should multiple of 4",
739 if (lensInfo.type != ACAMERA_TYPE_INT32)
741 "STREAM_CONFIGURATION TYPE(%d) is not ACAMERA_TYPE_INT32(1)",
745 int width = 0, height = 0;
746 for (uint32_t i = 0; i < lensInfo.count; i += 4)
753 if (!lensInfo.data.i32[i + 3] && lensInfo.data.i32[i] == AIMAGE_FORMAT_YUV_420_888)
755 width = lensInfo.data.i32[i + 1];
756 height = lensInfo.data.i32[i + 2];
758 float focalLengthPix = -1.f;
759 if (focalLengthsMM.size() && physicalSensorSizeMM.width > 0 && physicalSensorSizeMM.height > 0)
763 if ((
float)physicalSensorSizeMM.width / (
float)physicalSensorSizeMM.height > (
float)width / (
float)height)
764 focalLengthPix = focalLengthsMM.front() / physicalSensorSizeMM.height * (float)height;
766 focalLengthPix = focalLengthsMM.front() / physicalSensorSizeMM.width * (float)width;
769 if (!characteristics.
contains({width, height}))
770 characteristics.
add(width, height, focalLengthPix);
776 ACameraMetadata_free(camCharacteristics);
780 ACameraManager_deleteCameraIdList(cameraIds);
781 ACameraManager_delete(cameraManager);
784 return _captureProperties;
void onSessionActive(void *ctx, ACameraCaptureSession *ses)
#define LOG_NDKCAM_INFO(...)
#define LOG_NDKCAM_WARN(...)
void onImageCallback(void *ctx, AImageReader *reader)
void onDeviceDisconnected(void *ctx, ACameraDevice *dev)
void onSessionClosed(void *ctx, ACameraCaptureSession *ses)
void onDeviceErrorChanges(void *ctx, ACameraDevice *dev, int err)
void onCameraAvailable(void *ctx, const char *id)
void onSessionReady(void *ctx, ACameraCaptureSession *ses)
std::string getPrintableState(CaptureSessionState state)
void onCameraUnavailable(void *ctx, const char *id)
#define LOG_NDKCAM_DEBUG(...)
SENSCameraFacing
Definition of camera facing.
static WAI::ModeOrbSlam2 * mode
High Resolution Timer class using C++11.
float elapsedTimeInMilliSec()
ACaptureRequest * _captureRequest
void createCaptureSession()
void onDeviceError(ACameraDevice *dev, int err)
std::atomic< bool > _cameraDeviceOpened
AImageReader * _imageReader
void onSessionState(ACameraCaptureSession *ses, CaptureSessionState state)
ACaptureSessionOutput * _captureSessionOutput
static cv::Mat convertToYuv(AImage *image)
ACameraManager_AvailabilityCallbacks _cameraManagerAvailabilityCallbacks
ACameraOutputTarget * _cameraOutputTarget
std::condition_variable _openCameraCV
std::mutex _captureSessionStateMutex
CaptureSessionState _captureSessionState
void stop() override
Stop a started camera device.
const SENSCaptureProps & captureProperties() override
Get SENSCaptureProps which contains necessary information about all available camera devices and thei...
ACameraCaptureSession * _captureSession
ACameraManager * _cameraManager
void onDeviceDisconnected(ACameraDevice *dev)
void imageCallback(AImageReader *reader)
std::condition_variable _captureSessionStateCV
std::map< std::string, bool > _cameraAvailability
const SENSCameraConfig & start(std::string deviceId, const SENSCameraStreamConfig &streamConfig, bool provideIntrinsics=true) override
ACaptureSessionOutputContainer * _captureSessionOutputContainer
std::mutex _cameraAvailabilityMutex
ACameraDevice * _cameraDevice
void onCameraStatusChanged(const char *id, bool available)
SENSCameraConfig _config
indicates what is currently running
SENSCaptureProps _captureProperties
std::atomic< bool > _started
flags if camera was started
void updateFrame(cv::Mat bgrImg, cv::Mat intrinsics, int width, int height, bool intrinsicsChanged)
void processStart()
call from start function to do startup preprocessing
const SENSCameraFacing & facing() const
bool contains(cv::Size toFind)
const std::string & deviceId() const
void add(int widthPix, int heightPix, float focalLengthPix)
bool containsDeviceId(const std::string &deviceId) const
const SENSCameraDeviceProps * camPropsForDeviceId(const std::string &deviceId) const
void warnMsg(const char *tag, const char *msg, const int line, const char *file)
Platform independent warn message output.
SENSCameraStreamConfig streamConfig
currently selected stream config index (use it to look up original capture size)
SENSCameraFocusMode focusMode
autofocus mode