You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TermApp/app/src/main/cpp/Camera.cpp

194 lines
5.1 KiB
C++

#include "TerminalDevice.h"
/*
* 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 <android/log.h>
#include <AndroidHelper.h>
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);
}