Refactored emulated camera HAL to comply with code style
Change-Id: If57b536ae6b1f9bad4213630488591a3b3cc9fdd
This commit is contained in:
952
tools/emulator/system/camera/EmulatedCamera.cpp
Executable file
952
tools/emulator/system/camera/EmulatedCamera.cpp
Executable file
@@ -0,0 +1,952 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains implementation of a class EmulatedCamera that encapsulates
|
||||
* functionality common to all emulated cameras ("fake", "webcam", "video file",
|
||||
* etc.). Instances of this class (for each emulated camera) are created during
|
||||
* the construction of the EmulatedCameraFactory instance. This class serves as
|
||||
* an entry point for all camera API calls that defined by camera_device_ops_t
|
||||
* API.
|
||||
*/
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "EmulatedCamera_Camera"
|
||||
#include <cutils/log.h>
|
||||
#include <ui/Rect.h>
|
||||
#include "EmulatedCamera.h"
|
||||
#include "EmulatedFakeCameraDevice.h"
|
||||
#include "Converters.h"
|
||||
|
||||
/* Defines whether we should trace parameter changes. */
|
||||
#define DEBUG_PARAM 1
|
||||
|
||||
namespace android {
|
||||
|
||||
#if DEBUG_PARAM
|
||||
/* Calculates and logs parameter changes.
|
||||
* Param:
|
||||
* current - Current set of camera parameters.
|
||||
* new_par - String representation of new parameters.
|
||||
*/
|
||||
static void PrintParamDiff(const CameraParameters& current, const char* new_par);
|
||||
#else
|
||||
#define PrintParamDiff(current, new_par) (void(0))
|
||||
#endif /* DEBUG_PARAM */
|
||||
|
||||
/* A helper routine that adds a value to the camera parameter.
|
||||
* Param:
|
||||
* param - Camera parameter to add a value to.
|
||||
* val - Value to add.
|
||||
* Return:
|
||||
* A new string containing parameter with the added value on success, or NULL on
|
||||
* a failure. If non-NULL string is returned, the caller is responsible for
|
||||
* freeing it with 'free'.
|
||||
*/
|
||||
static char* AddValue(const char* param, const char* val);
|
||||
|
||||
EmulatedCamera::EmulatedCamera(int cameraId, struct hw_module_t* module)
|
||||
: mPreviewWindow(),
|
||||
mCallbackNotifier(),
|
||||
mCameraID(cameraId)
|
||||
{
|
||||
/*
|
||||
* Initialize camera_device descriptor for this object.
|
||||
*/
|
||||
|
||||
/* Common header */
|
||||
common.tag = HARDWARE_DEVICE_TAG;
|
||||
common.version = 0;
|
||||
common.module = module;
|
||||
common.close = EmulatedCamera::close;
|
||||
|
||||
/* camera_device fields. */
|
||||
ops = &mDeviceOps;
|
||||
priv = this;
|
||||
}
|
||||
|
||||
EmulatedCamera::~EmulatedCamera()
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public API
|
||||
***************************************************************************/
|
||||
|
||||
status_t EmulatedCamera::Initialize()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/*
|
||||
* Fake required parameters.
|
||||
*/
|
||||
|
||||
/* Only RGBX are supported by the framework for preview window in the emulator! */
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, CameraParameters::PIXEL_FORMAT_RGBA8888);
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "60,50,25,15,10");
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(10,60)");
|
||||
mPparameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "10,60");
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");
|
||||
mPparameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
|
||||
mPparameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
|
||||
mPparameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
|
||||
mPparameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
|
||||
mPparameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
|
||||
mPparameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
|
||||
mPparameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
|
||||
mPparameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
|
||||
mPparameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
|
||||
mPparameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
|
||||
|
||||
/* Only RGB formats are supported by preview window in emulator. */
|
||||
mPparameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_RGBA8888);
|
||||
|
||||
/* We don't relay on the actual frame rates supported by the camera device,
|
||||
* since we will emulate them through timeouts in the emulated camera device
|
||||
* worker thread. */
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
|
||||
"30,24,20,15,10,5");
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(5,30)");
|
||||
mPparameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5,30");
|
||||
mPparameters.setPreviewFrameRate(24);
|
||||
|
||||
/* Only PIXEL_FORMAT_YUV420P is accepted by camera framework in emulator! */
|
||||
mPparameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
|
||||
CameraParameters::PIXEL_FORMAT_YUV420P);
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
|
||||
CameraParameters::PIXEL_FORMAT_YUV420P);
|
||||
mPparameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_YUV420P);
|
||||
|
||||
/*
|
||||
* Not supported features
|
||||
*/
|
||||
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, CameraParameters::FOCUS_MODE_FIXED);
|
||||
mPparameters.set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_FIXED);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void EmulatedCamera::onNextFrameAvailable(const void* frame,
|
||||
nsecs_t timestamp,
|
||||
EmulatedCameraDevice* camera_dev)
|
||||
{
|
||||
/* Notify the preview window first. */
|
||||
mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev);
|
||||
|
||||
/* Notify callback notifier next. */
|
||||
mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Camera API implementation.
|
||||
***************************************************************************/
|
||||
|
||||
status_t EmulatedCamera::connectCamera(hw_device_t** device)
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
status_t res = EINVAL;
|
||||
EmulatedCameraDevice* const camera_dev = getCameraDevice();
|
||||
LOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
|
||||
|
||||
if (camera_dev != NULL) {
|
||||
/* Connect to the camera device. */
|
||||
res = getCameraDevice()->connectDevice();
|
||||
if (res == NO_ERROR) {
|
||||
*device = &common;
|
||||
}
|
||||
}
|
||||
|
||||
return -res;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::closeCamera()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
return cleanupCamera();
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
const char* valstr = NULL;
|
||||
|
||||
valstr = mPparameters.get(EmulatedCamera::FACING_KEY);
|
||||
if (valstr != NULL) {
|
||||
if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
|
||||
info->facing = CAMERA_FACING_FRONT;
|
||||
}
|
||||
else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
|
||||
info->facing = CAMERA_FACING_BACK;
|
||||
}
|
||||
} else {
|
||||
info->facing = CAMERA_FACING_BACK;
|
||||
}
|
||||
|
||||
valstr = mPparameters.get(EmulatedCamera::ORIENTATION_KEY);
|
||||
if (valstr != NULL) {
|
||||
info->orientation = atoi(valstr);
|
||||
} else {
|
||||
info->orientation = 0;
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
|
||||
{
|
||||
/* Callback should return a negative errno. */
|
||||
return -mPreviewWindow.setPreviewWindow(window,
|
||||
mPparameters.getPreviewFrameRate());
|
||||
}
|
||||
|
||||
void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
|
||||
camera_data_callback data_cb,
|
||||
camera_data_timestamp_callback data_cb_timestamp,
|
||||
camera_request_memory get_memory,
|
||||
void* user)
|
||||
{
|
||||
mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
|
||||
get_memory, user);
|
||||
}
|
||||
|
||||
void EmulatedCamera::enableMsgType(int32_t msg_type)
|
||||
{
|
||||
mCallbackNotifier.enableMessage(msg_type);
|
||||
}
|
||||
|
||||
void EmulatedCamera::disableMsgType(int32_t msg_type)
|
||||
{
|
||||
mCallbackNotifier.disableMessage(msg_type);
|
||||
}
|
||||
|
||||
int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
|
||||
{
|
||||
return mCallbackNotifier.isMessageEnabled(msg_type);
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::startPreview()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/* Callback should return a negative errno. */
|
||||
return -doStartPreview();
|
||||
}
|
||||
|
||||
void EmulatedCamera::stopPreview()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
doStopPreview();
|
||||
}
|
||||
|
||||
int EmulatedCamera::isPreviewEnabled()
|
||||
{
|
||||
return mPreviewWindow.isPreviewEnabled();
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
|
||||
{
|
||||
/* Callback should return a negative errno. */
|
||||
return -mCallbackNotifier.storeMetaDataInBuffers(enable);
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::startRecording()
|
||||
{
|
||||
/* Callback should return a negative errno. */
|
||||
return -mCallbackNotifier.enableVideoRecording(mPparameters.getPreviewFrameRate());
|
||||
}
|
||||
|
||||
void EmulatedCamera::stopRecording()
|
||||
{
|
||||
mCallbackNotifier.disableVideoRecording();
|
||||
}
|
||||
|
||||
int EmulatedCamera::isRecordingEnabled()
|
||||
{
|
||||
return mCallbackNotifier.isVideoRecordingEnabled();
|
||||
}
|
||||
|
||||
void EmulatedCamera::releaseRecordingFrame(const void* opaque)
|
||||
{
|
||||
mCallbackNotifier.releaseRecordingFrame(opaque);
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::setAutoFocus()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/* TODO: Future enhancements. */
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::cancelAutoFocus()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/* TODO: Future enhancements. */
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::takePicture()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/*
|
||||
* Before taking picture, pause the camera (pause worker thread), and pause
|
||||
* the preview.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Take the picture now.
|
||||
*/
|
||||
|
||||
/*
|
||||
* After picture has been taken, resume the preview, and the camera (if any
|
||||
* has been paused.
|
||||
*/
|
||||
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::cancelPicture()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::setParameters(const char* parms)
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
PrintParamDiff(mPparameters, parms);
|
||||
|
||||
CameraParameters new_param;
|
||||
String8 str8_param(parms);
|
||||
new_param.unflatten(str8_param);
|
||||
mPparameters = new_param;
|
||||
|
||||
/*
|
||||
* In emulation, there are certain parameters that are required by the
|
||||
* framework to be exact, and supported by the camera. Since we can't predict
|
||||
* the values of such parameters, we must dynamically update them as they
|
||||
* are set by the framework.
|
||||
*/
|
||||
|
||||
/* Supported preview size. */
|
||||
const char* check = mPparameters.get(CameraParameters::KEY_PREVIEW_SIZE);
|
||||
if (check != NULL) {
|
||||
const char* current =
|
||||
mPparameters.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
|
||||
if (strstr(current, check) == NULL) {
|
||||
/* Required size doesn't exist in the list. Add it. */
|
||||
char* to_add = AddValue(current, check);
|
||||
if (to_add != NULL) {
|
||||
LOGD("+++ %s: Added %s to supported preview sizes",
|
||||
__FUNCTION__, check);
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, to_add);
|
||||
free(to_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Supported preview frame rate. */
|
||||
check = mPparameters.get(CameraParameters::KEY_PREVIEW_FRAME_RATE);
|
||||
if (check != NULL) {
|
||||
const char* current =
|
||||
mPparameters.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
|
||||
if (strstr(current, check) == NULL) {
|
||||
char* to_add = AddValue(current, check);
|
||||
if (to_add != NULL) {
|
||||
LOGD("+++ %s: Added %s to supported preview frame rates",
|
||||
__FUNCTION__, check);
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, to_add);
|
||||
free(to_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Supported picture size. */
|
||||
check = mPparameters.get(CameraParameters::KEY_PICTURE_SIZE);
|
||||
if (check != NULL) {
|
||||
const char* current =
|
||||
mPparameters.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES);
|
||||
if (strstr(current, check) == NULL) {
|
||||
char* to_add = AddValue(current, check);
|
||||
if (to_add != NULL) {
|
||||
LOGD("+++ %s: Added %s to supported picture sizes",
|
||||
__FUNCTION__, check);
|
||||
mPparameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, to_add);
|
||||
free(to_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/* A dumb variable indicating "no params" / error on the exit from
|
||||
* EmulatedCamera::getParameters(). */
|
||||
static char lNoParam = '\0';
|
||||
char* EmulatedCamera::getParameters()
|
||||
{
|
||||
String8 params(mPparameters.flatten());
|
||||
char* ret_str =
|
||||
reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
|
||||
memset(ret_str, 0, params.length()+1);
|
||||
if (ret_str != NULL) {
|
||||
strncpy(ret_str, params.string(), params.length()+1);
|
||||
return ret_str;
|
||||
} else {
|
||||
LOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
|
||||
/* Apparently, we can't return NULL fron this routine. */
|
||||
return &lNoParam;
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedCamera::putParameters(char* params)
|
||||
{
|
||||
/* This method simply frees parameters allocated in getParameters(). */
|
||||
if (params != NULL && params != &lNoParam) {
|
||||
free(params);
|
||||
}
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
|
||||
{
|
||||
LOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
|
||||
|
||||
/* TODO: Future enhancements. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EmulatedCamera::releaseCamera()
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
cleanupCamera();
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::dumpCamera(int fd)
|
||||
{
|
||||
LOGV("%s", __FUNCTION__);
|
||||
|
||||
/* TODO: Future enhancements. */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Preview management.
|
||||
***************************************************************************/
|
||||
|
||||
status_t EmulatedCamera::doStartPreview()
|
||||
{
|
||||
status_t res = mPreviewWindow.startPreview();
|
||||
|
||||
/* Start the camera. */
|
||||
if (res == NO_ERROR && !getCameraDevice()->isCapturing()) {
|
||||
res = startCamera();
|
||||
if (res != NO_ERROR) {
|
||||
/* If camera didn't start, disable the preview window. */
|
||||
mPreviewWindow.stopPreview();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::doStopPreview()
|
||||
{
|
||||
status_t res = NO_ERROR;
|
||||
/* Stop the camera. */
|
||||
if (getCameraDevice()->isCapturing()) {
|
||||
res = stopCamera();
|
||||
}
|
||||
|
||||
if (res == NO_ERROR) {
|
||||
/* Disable preview as well. */
|
||||
mPreviewWindow.stopPreview();
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::startCamera()
|
||||
{
|
||||
status_t res = EINVAL;
|
||||
EmulatedCameraDevice* camera_dev = getCameraDevice();
|
||||
if (camera_dev != NULL) {
|
||||
if (!camera_dev->isConnected()) {
|
||||
res = camera_dev->connectDevice();
|
||||
if (res != NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (!camera_dev->isCapturing()) {
|
||||
int width, height;
|
||||
/* Lets see what should we use for frame width, and height. */
|
||||
if (mPparameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
|
||||
mPparameters.getVideoSize(&width, &height);
|
||||
} else {
|
||||
mPparameters.getPreviewSize(&width, &height);
|
||||
}
|
||||
/* Lets see what should we use for the frame pixel format. */
|
||||
const char* pix_fmt =
|
||||
mPparameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
|
||||
if (pix_fmt == NULL) {
|
||||
pix_fmt = mPparameters.getPreviewFormat();
|
||||
}
|
||||
if (pix_fmt == NULL) {
|
||||
LOGE("%s: Unable to obtain video format", __FUNCTION__);
|
||||
return EINVAL;
|
||||
}
|
||||
uint32_t org_fmt;
|
||||
if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
|
||||
org_fmt = V4L2_PIX_FMT_YVU420;
|
||||
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
|
||||
org_fmt = V4L2_PIX_FMT_RGB32;
|
||||
} else {
|
||||
LOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
|
||||
return EINVAL;
|
||||
}
|
||||
LOGD("Starting camera: %dx%d -> %s", width, height, pix_fmt);
|
||||
res = camera_dev->startCapturing(width, height, org_fmt);
|
||||
if (res != NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t EmulatedCamera::stopCamera()
|
||||
{
|
||||
status_t res = NO_ERROR;
|
||||
EmulatedCameraDevice* const camera_dev = getCameraDevice();
|
||||
if (camera_dev != NULL) {
|
||||
if (camera_dev->isCapturing()) {
|
||||
res = camera_dev->stopCapturing();
|
||||
if (res != NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Private API.
|
||||
***************************************************************************/
|
||||
|
||||
status_t EmulatedCamera::cleanupCamera()
|
||||
{
|
||||
status_t res = NO_ERROR;
|
||||
|
||||
/* If preview is running - stop it. */
|
||||
res = doStopPreview();
|
||||
if (res != NO_ERROR) {
|
||||
return -res;
|
||||
}
|
||||
|
||||
/* Stop and disconnect the camera device. */
|
||||
EmulatedCameraDevice* const camera_dev = getCameraDevice();
|
||||
if (camera_dev != NULL) {
|
||||
if (camera_dev->isCapturing()) {
|
||||
res = camera_dev->stopCapturing();
|
||||
if (res != NO_ERROR) {
|
||||
return -res;
|
||||
}
|
||||
}
|
||||
if (camera_dev->isConnected()) {
|
||||
res = camera_dev->disconnectDevice();
|
||||
if (res != NO_ERROR) {
|
||||
return -res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCallbackNotifier.cleanupCBNotifier();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Camera API callbacks as defined by camera_device_ops structure.
|
||||
*
|
||||
* Callbacks here simply dispatch the calls to an appropriate method inside
|
||||
* EmulatedCamera instance, defined by the 'dev' parameter.
|
||||
***************************************************************************/
|
||||
|
||||
int EmulatedCamera::set_preview_window(struct camera_device* dev,
|
||||
struct preview_stream_ops* window)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->setPreviewWindow(window);
|
||||
}
|
||||
|
||||
void EmulatedCamera::set_callbacks(
|
||||
struct camera_device* dev,
|
||||
camera_notify_callback notify_cb,
|
||||
camera_data_callback data_cb,
|
||||
camera_data_timestamp_callback data_cb_timestamp,
|
||||
camera_request_memory get_memory,
|
||||
void* user)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
|
||||
}
|
||||
|
||||
void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->enableMsgType(msg_type);
|
||||
}
|
||||
|
||||
void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->disableMsgType(msg_type);
|
||||
}
|
||||
|
||||
int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->isMsgTypeEnabled(msg_type);
|
||||
}
|
||||
|
||||
int EmulatedCamera::start_preview(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->startPreview();
|
||||
}
|
||||
|
||||
void EmulatedCamera::stop_preview(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->stopPreview();
|
||||
}
|
||||
|
||||
int EmulatedCamera::preview_enabled(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->isPreviewEnabled();
|
||||
}
|
||||
|
||||
int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
|
||||
int enable)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->storeMetaDataInBuffers(enable);
|
||||
}
|
||||
|
||||
int EmulatedCamera::start_recording(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->startRecording();
|
||||
}
|
||||
|
||||
void EmulatedCamera::stop_recording(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->stopRecording();
|
||||
}
|
||||
|
||||
int EmulatedCamera::recording_enabled(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->isRecordingEnabled();
|
||||
}
|
||||
|
||||
void EmulatedCamera::release_recording_frame(struct camera_device* dev,
|
||||
const void* opaque)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->releaseRecordingFrame(opaque);
|
||||
}
|
||||
|
||||
int EmulatedCamera::auto_focus(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->setAutoFocus();
|
||||
}
|
||||
|
||||
int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->cancelAutoFocus();
|
||||
}
|
||||
|
||||
int EmulatedCamera::take_picture(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->takePicture();
|
||||
}
|
||||
|
||||
int EmulatedCamera::cancel_picture(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->cancelPicture();
|
||||
}
|
||||
|
||||
int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->setParameters(parms);
|
||||
}
|
||||
|
||||
char* EmulatedCamera::get_parameters(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
return ec->getParameters();
|
||||
}
|
||||
|
||||
void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->putParameters(params);
|
||||
}
|
||||
|
||||
int EmulatedCamera::send_command(struct camera_device* dev,
|
||||
int32_t cmd,
|
||||
int32_t arg1,
|
||||
int32_t arg2)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->sendCommand(cmd, arg1, arg2);
|
||||
}
|
||||
|
||||
void EmulatedCamera::release(struct camera_device* dev)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
ec->releaseCamera();
|
||||
}
|
||||
|
||||
int EmulatedCamera::dump(struct camera_device* dev, int fd)
|
||||
{
|
||||
EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->dumpCamera(fd);
|
||||
}
|
||||
|
||||
int EmulatedCamera::close(struct hw_device_t* device)
|
||||
{
|
||||
EmulatedCamera* ec =
|
||||
reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
|
||||
if (ec == NULL) {
|
||||
LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ec->closeCamera();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Static initializer for the camera callback API
|
||||
****************************************************************************/
|
||||
|
||||
camera_device_ops_t EmulatedCamera::mDeviceOps = {
|
||||
EmulatedCamera::set_preview_window,
|
||||
EmulatedCamera::set_callbacks,
|
||||
EmulatedCamera::enable_msg_type,
|
||||
EmulatedCamera::disable_msg_type,
|
||||
EmulatedCamera::msg_type_enabled,
|
||||
EmulatedCamera::start_preview,
|
||||
EmulatedCamera::stop_preview,
|
||||
EmulatedCamera::preview_enabled,
|
||||
EmulatedCamera::store_meta_data_in_buffers,
|
||||
EmulatedCamera::start_recording,
|
||||
EmulatedCamera::stop_recording,
|
||||
EmulatedCamera::recording_enabled,
|
||||
EmulatedCamera::release_recording_frame,
|
||||
EmulatedCamera::auto_focus,
|
||||
EmulatedCamera::cancel_auto_focus,
|
||||
EmulatedCamera::take_picture,
|
||||
EmulatedCamera::cancel_picture,
|
||||
EmulatedCamera::set_parameters,
|
||||
EmulatedCamera::get_parameters,
|
||||
EmulatedCamera::put_parameters,
|
||||
EmulatedCamera::send_command,
|
||||
EmulatedCamera::release,
|
||||
EmulatedCamera::dump
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Common keys
|
||||
***************************************************************************/
|
||||
|
||||
const char EmulatedCamera::FACING_KEY[] = "prop-facing";
|
||||
const char EmulatedCamera::ORIENTATION_KEY[] = "prop-orientation";
|
||||
|
||||
/****************************************************************************
|
||||
* Common string values
|
||||
***************************************************************************/
|
||||
|
||||
const char EmulatedCamera::FACING_BACK[] = "back";
|
||||
const char EmulatedCamera::FACING_FRONT[] = "front";
|
||||
|
||||
/****************************************************************************
|
||||
* Helper routines
|
||||
***************************************************************************/
|
||||
|
||||
static char* AddValue(const char* param, const char* val)
|
||||
{
|
||||
const size_t len1 = strlen(param);
|
||||
const size_t len2 = strlen(val);
|
||||
char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
|
||||
LOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
|
||||
if (ret != NULL) {
|
||||
memcpy(ret, param, len1);
|
||||
ret[len1] = ',';
|
||||
memcpy(ret + len1 + 1, val, len2);
|
||||
ret[len1 + len2 + 1] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Parameter debugging helpers
|
||||
***************************************************************************/
|
||||
|
||||
#if DEBUG_PARAM
|
||||
static void PrintParamDiff(const CameraParameters& current,
|
||||
const char* new_par)
|
||||
{
|
||||
char tmp[2048];
|
||||
const char* wrk = new_par;
|
||||
|
||||
/* Divided with ';' */
|
||||
const char* next = strchr(wrk, ';');
|
||||
while (next != NULL) {
|
||||
snprintf(tmp, sizeof(tmp), "%.*s", next-wrk, wrk);
|
||||
/* in the form key=value */
|
||||
char* val = strchr(tmp, '=');
|
||||
if (val != NULL) {
|
||||
*val = '\0'; val++;
|
||||
const char* in_current = current.get(tmp);
|
||||
if (in_current != NULL) {
|
||||
if (strcmp(in_current, val)) {
|
||||
LOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
|
||||
}
|
||||
} else {
|
||||
LOGD("+++ New parameter: %s=%s", tmp, val);
|
||||
}
|
||||
} else {
|
||||
LOGW("No value separator in %s", tmp);
|
||||
}
|
||||
wrk = next + 1;
|
||||
next = strchr(wrk, ';');
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_PARAM */
|
||||
|
||||
}; /* namespace android */
|
||||
Reference in New Issue
Block a user