Created
August 8, 2011 10:16
-
-
Save pawitp/1131527 to your computer and use it in GitHub Desktop.
Possible LibCameraWrapper implementation for Galaxy S II
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LOCAL_PATH:= $(call my-dir) | |
include $(CLEAR_VARS) | |
LOCAL_SRC_FILES:= LibCameraWrapper.cpp | |
LOCAL_SHARED_LIBRARIES:= libdl libutils libcutils libcamera_client | |
LOCAL_MODULE := libcamera | |
LOCAL_MODULE_TAGS := optional | |
LOCAL_PRELINK_MODULE := false | |
include $(BUILD_SHARED_LIBRARY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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. | |
*/ | |
// Adapted from JordanCameraWrapper | |
// We can't use CameraParameters constants because we're linking against | |
// Samsung's libcamera_client.so | |
#define LOG_TAG "LibCameraWrapper" | |
//#define LOG_NDEBUG 0 | |
#include <cmath> | |
#include <dlfcn.h> | |
#include <fcntl.h> | |
#include <linux/videodev2.h> | |
#include <sys/ioctl.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <camera/Camera.h> | |
#include "LibCameraWrapper.h" | |
namespace android { | |
typedef sp<CameraHardwareInterface> (*OpenCamFunc)(int); | |
typedef int (*GetNumCam)(); | |
typedef void (*GetCamInfo)(int, struct CameraInfo*); | |
static void * g_libHandle = NULL; | |
static OpenCamFunc g_openCameraHardware = NULL; | |
static GetNumCam g_getNumCam = NULL; | |
static GetCamInfo g_getCameraInfo = NULL; | |
static const int CAMERA_CMD_SET_OBJECT_TRACKING_POSITION = 1103; | |
static const int CAMERA_CMD_SET_TOUCH_AF = 1105; | |
static void ensureLibOpened() | |
{ | |
if (g_libHandle == NULL) { | |
g_libHandle = ::dlopen("libsamsungcamera.so", RTLD_NOW); | |
if (g_libHandle == NULL) { | |
assert(0); | |
LOGE("dlopen() error: %s\n", dlerror()); | |
} else { | |
g_openCameraHardware = (OpenCamFunc) ::dlsym(g_libHandle, "HAL_openCameraHardware"); | |
g_getNumCam = (GetNumCam) ::dlsym(g_libHandle, "HAL_getNumberOfCameras"); | |
g_getCameraInfo = (GetCamInfo) ::dlsym(g_libHandle, "HAL_getCameraInfo"); | |
assert(g_openCameraHardware != NULL); | |
} | |
} | |
} | |
extern "C" int HAL_getNumberOfCameras() | |
{ | |
ensureLibOpened(); | |
return g_getNumCam(); | |
} | |
extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) | |
{ | |
ensureLibOpened(); | |
g_getCameraInfo(cameraId, cameraInfo); | |
} | |
extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId) | |
{ | |
LOGV("openCameraHardware: call createInstance"); | |
ensureLibOpened(); | |
return LibCameraWrapper::createInstance(cameraId); | |
} | |
wp<CameraHardwareInterface> LibCameraWrapper::singleton[2] = { 0 }; | |
sp<CameraHardwareInterface> LibCameraWrapper::createInstance(int cameraId) | |
{ | |
LOGV("%s :", __func__); | |
if (singleton[cameraId] != NULL) { | |
sp<CameraHardwareInterface> hardware = singleton[cameraId].promote(); | |
if (hardware != NULL) { | |
return hardware; | |
} | |
} | |
ensureLibOpened(); | |
sp<CameraHardwareInterface> hardware(new LibCameraWrapper(cameraId)); | |
singleton[cameraId] = hardware; | |
return hardware; | |
} | |
LibCameraWrapper::LibCameraWrapper(int cameraId) : | |
mLibInterface(g_openCameraHardware(cameraId)), | |
mCameraId(cameraId), | |
mVideoMode(false), | |
mContinuousAf(false), | |
mTouchFocus(false) | |
{ | |
LOGV("%s :", __func__); | |
} | |
LibCameraWrapper::~LibCameraWrapper() | |
{ | |
LOGV("%s :", __func__); | |
} | |
sp<IMemoryHeap> | |
LibCameraWrapper::getPreviewHeap() const | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->getPreviewHeap(); | |
} | |
sp<IMemoryHeap> | |
LibCameraWrapper::getRawHeap() const | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->getRawHeap(); | |
} | |
void | |
LibCameraWrapper::setCallbacks(notify_callback notify_cb, | |
data_callback data_cb, | |
data_callback_timestamp data_cb_timestamp, | |
void* user) | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->setCallbacks(notify_cb, data_cb, data_cb_timestamp, user); | |
} | |
void | |
LibCameraWrapper::enableMsgType(int32_t msgType) | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->enableMsgType(msgType); | |
} | |
void | |
LibCameraWrapper::disableMsgType(int32_t msgType) | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->disableMsgType(msgType); | |
} | |
bool | |
LibCameraWrapper::msgTypeEnabled(int32_t msgType) | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->msgTypeEnabled(msgType); | |
} | |
status_t | |
LibCameraWrapper::startPreview() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->startPreview(); | |
} | |
bool | |
LibCameraWrapper::useOverlay() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->useOverlay(); | |
} | |
status_t | |
LibCameraWrapper::setOverlay(const sp<Overlay> &overlay) | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->setOverlay(overlay); | |
} | |
void | |
LibCameraWrapper::stopPreview() | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->stopPreview(); | |
} | |
bool | |
LibCameraWrapper::previewEnabled() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->previewEnabled(); | |
} | |
status_t | |
LibCameraWrapper::startRecording() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->startRecording(); | |
} | |
void | |
LibCameraWrapper::stopRecording() | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->stopRecording(); | |
} | |
bool | |
LibCameraWrapper::recordingEnabled() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->recordingEnabled(); | |
} | |
void | |
LibCameraWrapper::releaseRecordingFrame(const sp<IMemory>& mem) | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->releaseRecordingFrame(mem); | |
} | |
status_t | |
LibCameraWrapper::autoFocus() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->autoFocus(); | |
} | |
status_t | |
LibCameraWrapper::cancelAutoFocus() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->cancelAutoFocus(); | |
} | |
status_t | |
LibCameraWrapper::takePicture() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->takePicture(); | |
} | |
status_t | |
LibCameraWrapper::cancelPicture() | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->cancelPicture(); | |
} | |
status_t | |
LibCameraWrapper::setParameters(const CameraParameters& params) | |
{ | |
LOGV("%s :", __func__); | |
CameraParameters pars(params.flatten()); | |
if (mCameraId == 0) { | |
const char *metering; | |
const char *conAf; | |
const char *touchCoordinate; | |
/* | |
* getInt returns -1 if the value isn't present and 0 on parse failure, | |
* so if it's larger than 0, we can be sure the value was parsed properly | |
*/ | |
mVideoMode = pars.getInt("cam-mode") > 0; | |
pars.remove("cam-mode"); | |
if (mVideoMode) { | |
// Special settings in video mode | |
pars.set("video_recording_gamma", "on"); | |
pars.set("slow_ae", "on"); | |
pars.set("cam_mode", "1"); | |
pars.set("iso", "movie"); | |
pars.set("metering", "matrix"); | |
} | |
else { | |
pars.set("video_recording_gamma", "off"); | |
pars.set("slow_ae", "off"); | |
pars.set("cam_mode", "0"); | |
} | |
// Parse continuous autofoucs into a format the driver understands | |
conAf = pars.get("enable-caf"); | |
mContinuousAf = (conAf != 0 && strcmp(conAf, "on") == 0); | |
pars.set("continuous_af", mContinuousAf ? 1 : 0); | |
// Always set antibanding to 50hz | |
pars.set("antibanding", "50hz"); | |
// Parse metering into something the driver understands | |
metering = pars.get("meter-mode"); | |
if (metering != 0) { | |
if (strcmp(metering, "meter-center") == 0) { | |
pars.set("metering", "center"); | |
} | |
else if (strcmp(metering, "meter-spot") == 0) { | |
pars.set("metering", "spot"); | |
} | |
else if (strcmp(metering, "meter-matrix") == 0) { | |
pars.set("metering", "matrix"); | |
} | |
pars.remove("auto-exposure"); | |
} | |
// Read touch-to-focus | |
touchCoordinate = pars.get("touch-focus"); | |
if (touchCoordinate != 0) { | |
char *comma; | |
mTouchFocusX = strtol(touchCoordinate, &comma, 10); | |
mTouchFocusY = strtol(comma + 1, NULL, 10); | |
sendCommand(CAMERA_CMD_SET_TOUCH_AF, 0, 0); | |
sendCommand(CAMERA_CMD_SET_OBJECT_TRACKING_POSITION, mTouchFocusX, mTouchFocusY); | |
sendCommand(CAMERA_CMD_SET_TOUCH_AF, 1, 0); | |
mTouchFocus = true; | |
pars.remove("touch-focus"); | |
} | |
else if (mTouchFocus) { | |
LOGV("Disabling touch focus"); | |
sendCommand(CAMERA_CMD_SET_TOUCH_AF, 0, 0); | |
mTouchFocus = false; | |
} | |
} | |
return mLibInterface->setParameters(pars); | |
} | |
CameraParameters | |
LibCameraWrapper::getParameters() const | |
{ | |
LOGV("%s :", __func__); | |
CameraParameters ret = mLibInterface->getParameters(); | |
if (mCameraId == 0) { | |
// Auto-exposure modes. NOTE: matrix isn't a value supported in stock android | |
ret.set("meter-mode-values", "meter-center,meter-spot,meter-matrix"); | |
// This is for detecting if we're in camcorder mode or not | |
ret.set("cam-mode", mVideoMode ? "1" : "0"); | |
// Continuous AF | |
ret.set("enable-caf", mContinuousAf ? "on" : "off"); | |
// Touch-to-focus | |
if (mTouchFocus) { | |
if (mTouchFocusX > 9999 || mTouchFocusY > 9999) { | |
LOGE("ERROR: Touch focus X, Y coordinate too large."); | |
ret.set("touch-focus", ""); | |
} | |
else { | |
char touchfocus[10] = ""; | |
sprintf(touchfocus, "%d,%d", mTouchFocusX, mTouchFocusY); | |
ret.set("touch-focus", touchfocus); | |
} | |
} | |
else { | |
ret.set("touch-focus", ""); | |
} | |
} | |
return ret; | |
} | |
status_t | |
LibCameraWrapper::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->sendCommand(cmd, arg1, arg2); | |
} | |
void | |
LibCameraWrapper::release() | |
{ | |
LOGV("%s :", __func__); | |
mLibInterface->release(); | |
} | |
status_t | |
LibCameraWrapper::dump(int fd, const Vector<String16>& args) const | |
{ | |
LOGV("%s :", __func__); | |
return mLibInterface->dump(fd, args); | |
} | |
}; //namespace android |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment