308 lines
9.9 KiB
C++
308 lines
9.9 KiB
C++
/*
|
|
* Copyright (C) 2014-2017 Intel Corporation.
|
|
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* 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 "FlashLight"
|
|
|
|
#include <sys/stat.h>
|
|
#include "LogHelper.h"
|
|
#include <FlashLight.h>
|
|
#include "PlatformData.h"
|
|
|
|
namespace android {
|
|
namespace camera2 {
|
|
|
|
FlashLight& FlashLight::getInstance()
|
|
{
|
|
static FlashLight flashInstance;
|
|
return flashInstance;
|
|
}
|
|
|
|
FlashLight::FlashLight() : mCallbacks(NULL)
|
|
{
|
|
for (int camid = 0; camid< MAX_NUM_CAMERA; camid++) {
|
|
for (int flindex = 0; flindex < MAX_NUM_FLASH_OF_ONE_MODULE; flindex++) {
|
|
mFlashFds[camid][flindex] = -1;
|
|
mCameraOpen[camid] = false;
|
|
mFlashOn[camid][flindex] = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
FlashLight::~FlashLight()
|
|
{
|
|
for (int camid = 0; camid< MAX_NUM_CAMERA; camid++) {
|
|
for (int flindex = 0; flindex < MAX_NUM_FLASH_OF_ONE_MODULE; flindex++) {
|
|
if (mFlashFds[camid][flindex] >= 0)
|
|
{
|
|
setFlashMode(camid, flindex, false);
|
|
close(mFlashFds[camid][flindex]);
|
|
mFlashFds[camid][flindex] = -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int32_t FlashLight::getFlashLightInfo(
|
|
const int cameraId, bool &hasFlash,
|
|
const char* (&flashNode)[MAX_NUM_FLASH_OF_ONE_MODULE]) {
|
|
|
|
int32_t retVal = 0;
|
|
hasFlash = false;
|
|
|
|
const CameraHWInfo* camHwInfo = PlatformData::getCameraHWInfo();
|
|
CheckError(!camHwInfo, -EINVAL, "@%s, camera hw info was not uninitialized",
|
|
__FUNCTION__);
|
|
|
|
const struct SensorDriverDescriptor* sensorInfo = camHwInfo->getSensorDrvDes(cameraId);
|
|
CheckError(!sensorInfo, -EINVAL, "@%s, camera sensor info was not uninitialized",
|
|
__FUNCTION__);
|
|
|
|
int flash_num = sensorInfo->mFlashNum;
|
|
|
|
for (int i = 0; i < flash_num; i++) {
|
|
|
|
const std::string& node = sensorInfo->mModuleFlashDevName[i];
|
|
flashNode[i] = node.c_str();
|
|
}
|
|
|
|
hasFlash = flash_num > 0 ? true : false;
|
|
LOGD("@%s : hasFlash %d, flashNode[0]: %s, flashNode[1]: %s",
|
|
__FUNCTION__, hasFlash, flashNode[0], flashNode[1]);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::setCallbacks(
|
|
const camera_module_callbacks_t* callbacks)
|
|
{
|
|
int32_t retVal = 0;
|
|
mCallbacks = callbacks;
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::init(const int cameraId)
|
|
{
|
|
int32_t retVal = 0;
|
|
bool hasFlash = false;
|
|
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
|
|
= {NULL, NULL};
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
return -EINVAL;
|
|
}
|
|
|
|
getFlashLightInfo(cameraId, hasFlash, flashPath);
|
|
|
|
if (!hasFlash) {
|
|
LOGE("%s: No flash available for camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -ENOSYS;
|
|
} else if (mCameraOpen[cameraId]) {
|
|
LOGE("%s: Camera in use for camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -EBUSY;
|
|
} else if (mFlashFds[cameraId][0] >= 0) {
|
|
LOGD("%s: Flash is already inited for camera id: %d", __FUNCTION__, cameraId);
|
|
} else {
|
|
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
|
|
if (flashPath[i]) {
|
|
if (mFlashFds[cameraId][i] == -1)
|
|
mFlashFds[cameraId][i] = open(flashPath[i], O_RDWR | O_NONBLOCK);
|
|
if (mFlashFds[cameraId][i] < 0) {
|
|
LOGE("%s: Unable to open node '%s'", __FUNCTION__, flashPath[i]);
|
|
retVal = -EBUSY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOGD("@%s : retval = %d", __FUNCTION__, retVal);
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::deinit(const int cameraId)
|
|
{
|
|
int32_t retVal = 0;
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -EINVAL;
|
|
} else {
|
|
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
|
|
if (mFlashFds[cameraId][i] >= 0) {
|
|
setFlashMode(cameraId, i, false);
|
|
close(mFlashFds[cameraId][i]);
|
|
mFlashFds[cameraId][i] = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::setFlashMode(const int cameraId, const bool mode)
|
|
{
|
|
int32_t retVal = 0;
|
|
LOGD("@%s : cameraId %d, mode %d", __FUNCTION__, cameraId, mode);
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -EINVAL;
|
|
} else if (mode == mFlashOn[cameraId][0]) {
|
|
LOGD("%s: flash %d is already in requested state: %d", __FUNCTION__, cameraId, mode);
|
|
retVal = -EALREADY;
|
|
} else if (mFlashFds[cameraId][0] < 0) {
|
|
LOGE("%s: called for uninited flash: %d", __FUNCTION__, cameraId);
|
|
retVal = -EINVAL;
|
|
} else {
|
|
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
|
|
if (mFlashFds[cameraId][i] >= 0) {
|
|
retVal |= setFlashMode(cameraId, i, mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::setFlashMode(const int cameraId, int flashIdx, const bool mode)
|
|
{
|
|
int32_t retVal = 0;
|
|
LOGD("@%s : cameraId %d, mode %d", __FUNCTION__, cameraId, mode);
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -ENOSYS;
|
|
} else if (mode == mFlashOn[cameraId][flashIdx]) {
|
|
LOGD("%s: flash %d is already in requested state: %d", __FUNCTION__, cameraId, mode);
|
|
retVal = -EALREADY;
|
|
} else if (mFlashFds[cameraId][flashIdx] < 0) {
|
|
LOGE("%s: called for uninited flash: %d", __FUNCTION__, cameraId);
|
|
retVal = -ENOSYS;
|
|
} else {
|
|
struct v4l2_control control;
|
|
struct v4l2_queryctrl qctrl;
|
|
|
|
memset(&control, 0, sizeof(control));
|
|
memset(&qctrl, 0, sizeof(qctrl));
|
|
|
|
qctrl.id = V4L2_CID_FLASH_TORCH_INTENSITY;
|
|
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_QUERYCTRL, &qctrl) < 0) {
|
|
LOGE("@%s : query falsh torch power failed", __FUNCTION__);
|
|
return -ENOSYS;
|
|
}
|
|
LOGD(" qctrl.flags(0x%08x)", qctrl.flags);
|
|
if (qctrl.flags != V4L2_CTRL_FLAG_READ_ONLY) {
|
|
control.id = V4L2_CID_FLASH_TORCH_INTENSITY;
|
|
control.value = qctrl.default_value;
|
|
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_S_CTRL, &control, 0) < 0) {
|
|
LOGE("@%s : set flash intensity failed, may be not support set torch intensity.", __FUNCTION__);
|
|
return -ENOSYS;
|
|
}
|
|
}
|
|
|
|
memset(&control, 0, sizeof(control));
|
|
control.id = V4L2_CID_FLASH_LED_MODE;
|
|
control.value = mode ? V4L2_FLASH_LED_MODE_TORCH : V4L2_FLASH_LED_MODE_NONE;
|
|
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_S_CTRL, &control, 0) < 0) {
|
|
LOGE("@%s : set flash mode %d failed", __FUNCTION__, mode);
|
|
return -ENOSYS;
|
|
}
|
|
LOGI("@%s : set flash mode %d sucess", __FUNCTION__, mode);
|
|
mFlashOn[cameraId][flashIdx] = mode;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::reserveFlashForCamera(const int cameraId)
|
|
{
|
|
int32_t retVal = 0;
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -EINVAL;
|
|
} else if (mCameraOpen[cameraId]) {
|
|
LOGD("%s: Flash already reserved for camera id: %d", __FUNCTION__,
|
|
cameraId);
|
|
} else {
|
|
deinit(cameraId);
|
|
mCameraOpen[cameraId] = true;
|
|
|
|
bool hasFlash = false;
|
|
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
|
|
= {NULL, NULL};
|
|
|
|
getFlashLightInfo(cameraId, hasFlash, flashPath);
|
|
|
|
if (mCallbacks == NULL ||
|
|
mCallbacks->torch_mode_status_change == NULL) {
|
|
LOGE("%s: Callback is not defined!", __FUNCTION__);
|
|
retVal = -ENOSYS;
|
|
} else if (!hasFlash) {
|
|
LOGD("%s: no flash exists for camera id: %d", __FUNCTION__, cameraId);
|
|
} else {
|
|
char cameraIdStr[1];
|
|
snprintf(cameraIdStr, 1, "%d", cameraId);
|
|
mCallbacks->torch_mode_status_change(mCallbacks,
|
|
cameraIdStr,
|
|
TORCH_MODE_STATUS_NOT_AVAILABLE);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int32_t FlashLight::releaseFlashFromCamera(const int cameraId)
|
|
{
|
|
int32_t retVal = 0;
|
|
|
|
if (cameraId < 0 || cameraId >= MAX_NUM_FLASH_OF_ONE_MODULE) {
|
|
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
|
|
retVal = -EINVAL;
|
|
} else if (!mCameraOpen[cameraId]) {
|
|
LOGD("%s: Flash not reserved for camera id: %d", __FUNCTION__, cameraId);
|
|
} else {
|
|
mCameraOpen[cameraId] = false;
|
|
|
|
bool hasFlash = false;
|
|
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
|
|
= {NULL, NULL};
|
|
|
|
getFlashLightInfo(cameraId, hasFlash, flashPath);
|
|
|
|
if (mCallbacks == NULL ||
|
|
mCallbacks->torch_mode_status_change == NULL) {
|
|
LOGE("%s: Callback is not defined!", __FUNCTION__);
|
|
retVal = -ENOSYS;
|
|
} else if (!hasFlash) {
|
|
LOGD("%s: no flash exists for camera id: %d", __FUNCTION__, cameraId);
|
|
} else {
|
|
char cameraIdStr[1];
|
|
snprintf(cameraIdStr, 1, "%d", cameraId);
|
|
mCallbacks->torch_mode_status_change(mCallbacks,
|
|
cameraIdStr,
|
|
TORCH_MODE_STATUS_AVAILABLE_OFF);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
} /* namespace camera2 */
|
|
} /* namespace android */
|
|
|