/* * Copyright 2018 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. * */ #define LOG_TAG "CameraTestHelpers" #include "Camera.h" #include #include CCamera::CCamera() { } CCamera::~CCamera() { closeCamera(); } int CCamera::initCamera(ANativeWindow *imgReaderAnw) { if (imgReaderAnw == nullptr) { ALOGE("Cannot initialize camera before image reader get initialized."); return -1; } mImgReaderAnw = imgReaderAnw; mCameraManager = ACameraManager_create(); if (mCameraManager == nullptr) { ALOGE("Failed to create ACameraManager."); return -1; } int ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList); if (ret != AMEDIA_OK) { ALOGE("Failed to get cameraIdList: ret=%d", ret); return ret; } if (mCameraIdList->numCameras < 1) { ALOGW("Device has no NDK compatible camera."); return 0; } ALOGI("Found %d camera(s).", mCameraIdList->numCameras); // We always use the first camera. mCameraId = mCameraIdList->cameraIds[0]; if (mCameraId == nullptr) { ALOGE("Failed to get cameraId."); return -1; } ret = ACameraManager_openCamera(mCameraManager, mCameraId, &mDeviceCb,&mDevice); if (ret != AMEDIA_OK || mDevice == nullptr) { ALOGE("Failed to open camera, ret=%d, mDevice=%p.", ret, mDevice); ret = ACAMERA_ERROR_INVALID_PARAMETER; return -1; } ret = ACameraManager_getCameraCharacteristics(mCameraManager, mCameraId, &mCameraMetadata); if (ret != ACAMERA_OK || mCameraMetadata == nullptr) { ALOGE("Get camera %s characteristics failure. ret %d, metadata %p", mCameraId, ret, mCameraMetadata); return -1; } if (!isCapabilitySupported( ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)) { ALOGW("Camera does not support BACKWARD_COMPATIBLE."); return 0; } // Create capture session ret = ACaptureSessionOutputContainer_create(&mOutputs); if (ret != AMEDIA_OK) { ALOGE("ACaptureSessionOutputContainer_create failed, ret=%d", ret); return ret; } ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput); if (ret != AMEDIA_OK) { ALOGE("ACaptureSessionOutput_create failed, ret=%d", ret); return ret; } ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput); if (ret != AMEDIA_OK) { ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret); return ret; } ret = ACameraDevice_createCaptureSession(mDevice, mOutputs, &mSessionCb, &mSession); if (ret != AMEDIA_OK) { ALOGE("ACameraDevice_createCaptureSession failed, ret=%d", ret); return ret; } // Create capture request ret = ACameraDevice_createCaptureRequest(mDevice, TEMPLATE_RECORD, &mCaptureRequest); if (ret != AMEDIA_OK) { ALOGE("ACameraDevice_createCaptureRequest failed, ret=%d", ret); return ret; } ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput); if (ret != AMEDIA_OK) { ALOGE("ACameraOutputTarget_create failed, ret=%d", ret); return ret; } ret = ACaptureRequest_addTarget(mCaptureRequest, mReqImgReaderOutput); if (ret != AMEDIA_OK) { ALOGE("ACaptureRequest_addTarget failed, ret=%d", ret); return ret; } mIsCameraReady = true; return 0; } bool CCamera::isCapabilitySupported( acamera_metadata_enum_android_request_available_capabilities_t cap) { ACameraMetadata_const_entry entry; ACameraMetadata_getConstEntry(mCameraMetadata, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry); for (uint32_t i = 0; i < entry.count; i++) { if (entry.data.u8[i] == cap) { return true; } } return false; } void CCamera::closeCamera() { // Destroy capture request if (mReqImgReaderOutput) { ACameraOutputTarget_free(mReqImgReaderOutput); mReqImgReaderOutput = nullptr; } if (mCaptureRequest) { ACaptureRequest_free(mCaptureRequest); mCaptureRequest = nullptr; } // Destroy capture session if (mSession != nullptr) { ACameraCaptureSession_close(mSession); mSession = nullptr; } if (mImgReaderOutput) { ACaptureSessionOutput_free(mImgReaderOutput); mImgReaderOutput = nullptr; } if (mOutputs) { ACaptureSessionOutputContainer_free(mOutputs); mOutputs = nullptr; } // Destroy camera device if (mDevice) { ACameraDevice_close(mDevice); mDevice = nullptr; } if (mCameraMetadata) { ACameraMetadata_free(mCameraMetadata); mCameraMetadata = nullptr; } // Destroy camera manager if (mCameraIdList) { ACameraManager_deleteCameraIdList(mCameraIdList); mCameraIdList = nullptr; } if (mCameraManager) { ACameraManager_delete(mCameraManager); mCameraManager = nullptr; } mIsCameraReady = false; } int CCamera::takePicture() { return ACameraCaptureSession_capture(mSession, nullptr, 1, &mCaptureRequest, nullptr); }