blob: 1ec9d2056bd2e845d3a61bf767d46ffd77d3e12e [file] [log] [blame]
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* 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 "Camera3HAL"
#include "Camera3HAL.h"
#include <memory>
#include "Errors.h"
#include "HALv3Utils.h"
#include "ICamera.h"
#include "Utils.h"
namespace camera3 {
/******************************************************************************
* C DEVICE INTERFACE IMPLEMENTATION WRAPPER
*****************************************************************************/
// Common check before the function call
#define FUNCTION_PREPARED_RETURN \
if (!dev) return -EINVAL; \
Camera3HAL* camera_priv = static_cast<Camera3HAL*>(dev->priv);
static int hal_dev_initialize(const struct camera3_device* dev,
const camera3_callback_ops_t* callback_ops) {
LOG1("@%s", __func__);
FUNCTION_PREPARED_RETURN
return camera_priv->initialize(callback_ops);
}
static int hal_dev_configure_streams(const struct camera3_device* dev,
camera3_stream_configuration_t* stream_list) {
LOG1("@%s", __func__);
FUNCTION_PREPARED_RETURN
return camera_priv->configure_streams(stream_list);
}
static const camera_metadata_t* hal_dev_construct_default_request_settings(
const struct camera3_device* dev, int type) {
LOG1("@%s", __func__);
if (!dev) return nullptr;
Camera3HAL* camera_priv = (Camera3HAL*)(dev->priv);
return camera_priv->construct_default_request_settings(type);
}
static int hal_dev_process_capture_request(const struct camera3_device* dev,
camera3_capture_request_t* request) {
LOG1("@%s", __func__);
FUNCTION_PREPARED_RETURN
return camera_priv->process_capture_request(request);
}
static void hal_dev_dump(const struct camera3_device* dev, int fd) {
LOG1("@%s", __func__);
if (!dev) return;
Camera3HAL* camera_priv = (Camera3HAL*)(dev->priv);
camera_priv->dump(fd);
}
static int hal_dev_flush(const struct camera3_device* dev) {
LOG1("@%s", __func__);
if (!dev) return -EINVAL;
Camera3HAL* camera_priv = (Camera3HAL*)(dev->priv);
return camera_priv->flush();
}
static camera3_device_ops hal_dev_ops = {
.initialize = hal_dev_initialize,
.configure_streams = hal_dev_configure_streams,
.register_stream_buffers = nullptr,
.construct_default_request_settings = hal_dev_construct_default_request_settings,
.process_capture_request = hal_dev_process_capture_request,
.get_metadata_vendor_tag_ops = nullptr,
.dump = hal_dev_dump,
.flush = hal_dev_flush,
.reserved = {0},
};
/******************************************************************************
* C++ CLASS IMPLEMENTATION
*****************************************************************************/
Camera3HAL::Camera3HAL(int cameraId, const hw_module_t* module)
: mCameraId(cameraId),
mInitialized(false) {
LOG1("@%s", __func__);
mDevice = {};
mDevice.common.tag = HARDWARE_DEVICE_TAG;
mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
mDevice.common.module = const_cast<hw_module_t*>(module);
// hal_dev_close is kept in the module for symmetry with dev_open
// it will be set there
mDevice.common.close = nullptr;
mDevice.ops = &hal_dev_ops;
mDevice.priv = this;
int ret = icamera::camera_device_open(cameraId);
if (ret != icamera::OK) {
LOGE("@%s, camera_device_open fails, ret:%d", __func__, ret);
icamera::camera_device_close(cameraId);
return;
}
mRequestManager = std::unique_ptr<RequestManager>(new RequestManager(cameraId));
mInitialized = true;
}
Camera3HAL::~Camera3HAL() {
LOG1("@%s", __func__);
if (mRequestManager) {
mRequestManager->flush();
mRequestManager->deinit();
mRequestManager.reset(); // mRequestManager must be released before device deinit
}
icamera::camera_device_close(mCameraId);
}
/* *********************************************************************
* Camera3 device APIs
* ********************************************************************/
int Camera3HAL::initialize(const camera3_callback_ops_t* callback_ops) {
LOG1("@%s", __func__);
CheckError(!mInitialized, -ENODEV, "@%s, mInitialized is false", __func__);
int status = icamera::OK;
if (callback_ops == nullptr) return -ENODEV;
status = mRequestManager->init(callback_ops);
if (status != icamera::OK) {
LOGE("Error register callback status = %d", status);
return -ENODEV;
}
return status;
}
int Camera3HAL::configure_streams(camera3_stream_configuration_t* stream_list) {
LOG1("@%s", __func__);
CheckError(!mInitialized, -EINVAL, "@%s, mInitialized is false", __func__);
CheckError(!stream_list, -EINVAL, "@%s, stream_list is nullptr", __func__);
if (!stream_list->streams || !stream_list->num_streams) {
LOGE("%s: Bad input! streams list ptr: %p, num %d", __func__, stream_list->streams,
stream_list->num_streams);
return -EINVAL;
}
int num = stream_list->num_streams;
LOG2("@%s, stream num:%d", __func__, num);
while (num--) {
if (!stream_list->streams[num]) {
LOGE("%s: Bad input! streams (%d) 's ptr: %p", __func__, num,
stream_list->streams[num]);
return -EINVAL;
}
}
int status = mRequestManager->configureStreams(stream_list);
return (status == icamera::OK) ? 0 : -EINVAL;
}
const camera_metadata_t* Camera3HAL::construct_default_request_settings(int type) {
LOG1("@%s, type:%d", __func__, type);
CheckError(!mInitialized, nullptr, "@%s, mInitialized is false", __func__);
if (type < CAMERA3_TEMPLATE_PREVIEW || type >= CAMERA3_TEMPLATE_COUNT) return nullptr;
const camera_metadata_t* meta = nullptr;
int status = mRequestManager->constructDefaultRequestSettings(type, &meta);
CheckError(status != icamera::OK, nullptr, "construct default request setting error");
return meta;
}
int Camera3HAL::process_capture_request(camera3_capture_request_t* request) {
LOG2("@%s", __func__);
CheckError(!mInitialized, -EINVAL, "@%s, mInitialized is false", __func__);
if (request == nullptr) {
LOGE("%s: request is null!", __func__);
return -EINVAL;
} else if (!request->num_output_buffers || request->output_buffers == nullptr) {
LOGE("%s: num_output_buffers %d, output_buffers %p", __func__, request->num_output_buffers,
request->output_buffers);
return -EINVAL;
} else if (request->output_buffers->stream == nullptr) {
LOGE("%s: output_buffers->stream is null!", __func__);
return -EINVAL;
} else if (request->output_buffers->stream->priv == nullptr) {
LOGE("%s: output_buffers->stream->priv is null!", __func__);
return -EINVAL;
} else if (request->output_buffers->buffer == nullptr ||
*(request->output_buffers->buffer) == nullptr) {
LOGE("%s: output buffer is invalid", __func__);
return -EINVAL;
}
int status = mRequestManager->processCaptureRequest(request);
if (status == icamera::OK) return icamera::OK;
return (status == icamera::BAD_VALUE) ? -EINVAL : -ENODEV;
}
void Camera3HAL::dump(int fd) {
LOG1("@%s", __func__);
CheckError(!mInitialized, VOID_VALUE, "@%s, mInitialized is false", __func__);
mRequestManager->dump(fd);
}
int Camera3HAL::flush() {
LOG1("@%s", __func__);
CheckError(!mInitialized, icamera::UNKNOWN_ERROR, "@%s, mInitialized is false", __func__);
return mRequestManager->flush();
}
} // namespace camera3