blob: c712e097cb24a8855253f15c1274ad1d25d040a1 [file] [log] [blame]
/*
* 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 "CameraTestHelpers.h"
#include <android/log.h>
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
CameraHelper::~CameraHelper() { closeCamera(); }
int CameraHelper::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);
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 CameraHelper::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 CameraHelper::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 CameraHelper::takePicture() {
return ACameraCaptureSession_capture(mSession, nullptr, 1, &mCaptureRequest,
nullptr);
}