Files
android_development/tools/emulator/system/camera/EmulatedCamera.cpp
Vladimir Chtchetkine 4d7f7de700 Use actual JPEG quality when compressing picture
Sometimes framework chooses to override the default JPEG quality value (90), so we need to
respect that when compressing frame during picture taking.

Change-Id: Ic7ad8938d33d94d34ecd0b979e5c8c3e8246fd53
2011-09-21 15:33:18 -07:00

996 lines
31 KiB
C++
Executable File

/*
* 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()
{
/*
* Fake required parameters.
*/
/* Only RGBX are supported by the framework for preview window in the emulator! */
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, CameraParameters::PIXEL_FORMAT_RGBA8888);
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "60,50,25,15,10");
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(10,60)");
mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "10,60");
mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");
mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
/* Only RGB formats are supported by preview window in emulator. */
mParameters.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. */
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
"30,24,20,15,10,5");
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(5,30)");
mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5,30");
mParameters.setPreviewFrameRate(24);
/* Only PIXEL_FORMAT_YUV420P is accepted by camera framework in emulator! */
mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
CameraParameters::PIXEL_FORMAT_YUV420P);
mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
CameraParameters::PIXEL_FORMAT_JPEG);
mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
/*
* Not supported features
*/
mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, CameraParameters::FOCUS_MODE_FIXED);
mParameters.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 = mParameters.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 = mParameters.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,
mParameters.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()
{
/* Callback should return a negative errno. */
return -doStartPreview();
}
void EmulatedCamera::stopPreview()
{
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(mParameters.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__);
status_t res;
int width, height;
uint32_t org_fmt;
/* Collect frame info for the picture. */
mParameters.getPictureSize(&width, &height);
const char* pix_fmt = mParameters.getPictureFormat();
if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
org_fmt = V4L2_PIX_FMT_YUV420;
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
org_fmt = V4L2_PIX_FMT_RGB32;
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
org_fmt = V4L2_PIX_FMT_NV21;
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
/* We only have JPEG converted for NV21 format. */
org_fmt = V4L2_PIX_FMT_NV21;
} else {
LOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
return EINVAL;
}
/* Get JPEG quality. */
int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
if (jpeg_quality <= 0) {
jpeg_quality = 90; /* Fall back to default. */
}
/*
* Make sure preview is not running, and device is stopped before taking
* picture.
*/
const bool preview_on = mPreviewWindow.isPreviewEnabled();
if (preview_on) {
doStopPreview();
}
/* Camera device should have been stopped when the shutter message has been
* enabled. */
EmulatedCameraDevice* const camera_dev = getCameraDevice();
if (camera_dev->isStarted()) {
LOGW("%s: Camera device is started", __FUNCTION__);
camera_dev->stopDeliveringFrames();
camera_dev->stopDevice();
}
/*
* Take the picture now.
*/
/* Start camera device for the picture frame. */
LOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
res = camera_dev->startDevice(width, height, org_fmt);
if (res != NO_ERROR) {
if (preview_on) {
doStartPreview();
}
return res;
}
/* Deliver one frame only. */
mCallbackNotifier.setJpegQuality(jpeg_quality);
mCallbackNotifier.setTakingPicture(true);
res = camera_dev->startDeliveringFrames(true);
if (res != NO_ERROR) {
mCallbackNotifier.setTakingPicture(false);
if (preview_on) {
doStartPreview();
}
}
return res;
}
status_t EmulatedCamera::cancelPicture()
{
LOGV("%s", __FUNCTION__);
return NO_ERROR;
}
status_t EmulatedCamera::setParameters(const char* parms)
{
LOGV("%s", __FUNCTION__);
PrintParamDiff(mParameters, parms);
CameraParameters new_param;
String8 str8_param(parms);
new_param.unflatten(str8_param);
mParameters = 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 = mParameters.get(CameraParameters::KEY_PREVIEW_SIZE);
if (check != NULL) {
const char* current =
mParameters.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);
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, to_add);
free(to_add);
}
}
}
/* Supported preview frame rate. */
check = mParameters.get(CameraParameters::KEY_PREVIEW_FRAME_RATE);
if (check != NULL) {
const char* current =
mParameters.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);
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, to_add);
free(to_add);
}
}
}
/* Supported picture size. */
check = mParameters.get(CameraParameters::KEY_PICTURE_SIZE);
if (check != NULL) {
const char* current =
mParameters.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);
mParameters.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(mParameters.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()
{
LOGV("%s", __FUNCTION__);
EmulatedCameraDevice* camera_dev = getCameraDevice();
if (camera_dev->isStarted()) {
camera_dev->stopDeliveringFrames();
camera_dev->stopDevice();
}
status_t res = mPreviewWindow.startPreview();
if (res != NO_ERROR) {
return res;
}
/* Make sure camera device is connected. */
if (!camera_dev->isConnected()) {
res = camera_dev->connectDevice();
if (res != NO_ERROR) {
mPreviewWindow.stopPreview();
return res;
}
}
int width, height;
/* Lets see what should we use for frame width, and height. */
if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
mParameters.getVideoSize(&width, &height);
} else {
mParameters.getPreviewSize(&width, &height);
}
/* Lets see what should we use for the frame pixel format. */
const char* pix_fmt =
mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
if (pix_fmt == NULL) {
pix_fmt = mParameters.getPreviewFormat();
}
if (pix_fmt == NULL) {
LOGE("%s: Unable to obtain video format", __FUNCTION__);
mPreviewWindow.stopPreview();
return EINVAL;
}
uint32_t org_fmt;
if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
org_fmt = V4L2_PIX_FMT_YUV420;
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
org_fmt = V4L2_PIX_FMT_RGB32;
} else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
org_fmt = V4L2_PIX_FMT_NV21;
} else {
LOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
mPreviewWindow.stopPreview();
return EINVAL;
}
LOGD("Starting camera: %dx%d -> %.4s", width, height, pix_fmt);
res = camera_dev->startDevice(width, height, org_fmt);
if (res != NO_ERROR) {
mPreviewWindow.stopPreview();
return res;
}
res = camera_dev->startDeliveringFrames(false);
if (res != NO_ERROR) {
camera_dev->stopDevice();
mPreviewWindow.stopPreview();
}
return res;
}
status_t EmulatedCamera::doStopPreview()
{
LOGV("%s", __FUNCTION__);
status_t res = NO_ERROR;
if (mPreviewWindow.isPreviewEnabled()) {
/* Stop the camera. */
if (getCameraDevice()->isStarted()) {
getCameraDevice()->stopDeliveringFrames();
res = getCameraDevice()->stopDevice();
}
if (res == NO_ERROR) {
/* Disable preview as well. */
mPreviewWindow.stopPreview();
}
}
return NO_ERROR;
}
/****************************************************************************
* 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->isStarted()) {
camera_dev->stopDeliveringFrames();
res = camera_dev->stopDevice();
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 */