diff options
Diffstat (limited to 'camera/Camera.cpp')
-rw-r--r-- | camera/Camera.cpp | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/camera/Camera.cpp b/camera/Camera.cpp new file mode 100644 index 0000000..8620e71 --- /dev/null +++ b/camera/Camera.cpp @@ -0,0 +1,359 @@ +/* +** +** Copyright (C) 2008, The Android Open Source Project +** Copyright (C) 2008 HTC Inc. +** +** 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_NDEBUG 0 +#define LOG_TAG "Camera" +#include <utils/Log.h> +#include <utils/threads.h> + +#include <binder/IServiceManager.h> +#include <binder/IMemory.h> + +#include <camera/Camera.h> +#include <camera/ICameraService.h> + +#include <surfaceflinger/Surface.h> + +namespace android { + +// client singleton for camera service binder interface +Mutex Camera::mLock; +sp<ICameraService> Camera::mCameraService; +sp<Camera::DeathNotifier> Camera::mDeathNotifier; + +// establish binder interface to camera service +const sp<ICameraService>& Camera::getCameraService() +{ + Mutex::Autolock _l(mLock); + if (mCameraService.get() == 0) { + sp<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder; + do { + binder = sm->getService(String16("media.camera")); + if (binder != 0) + break; + LOGW("CameraService not published, waiting..."); + usleep(500000); // 0.5 s + } while(true); + if (mDeathNotifier == NULL) { + mDeathNotifier = new DeathNotifier(); + } + binder->linkToDeath(mDeathNotifier); + mCameraService = interface_cast<ICameraService>(binder); + } + LOGE_IF(mCameraService==0, "no CameraService!?"); + return mCameraService; +} + +// --------------------------------------------------------------------------- + +Camera::Camera() +{ + init(); +} + +// construct a camera client from an existing camera remote +sp<Camera> Camera::create(const sp<ICamera>& camera) +{ + LOGV("create"); + if (camera == 0) { + LOGE("camera remote is a NULL pointer"); + return 0; + } + + sp<Camera> c = new Camera(); + if (camera->connect(c) == NO_ERROR) { + c->mStatus = NO_ERROR; + c->mCamera = camera; + camera->asBinder()->linkToDeath(c); + } + return c; +} + +void Camera::init() +{ + mStatus = UNKNOWN_ERROR; +} + +Camera::~Camera() +{ + disconnect(); +} + +sp<Camera> Camera::connect() +{ + LOGV("connect"); + sp<Camera> c = new Camera(); + const sp<ICameraService>& cs = getCameraService(); + if (cs != 0) { + c->mCamera = cs->connect(c); + } + if (c->mCamera != 0) { + c->mCamera->asBinder()->linkToDeath(c); + c->mStatus = NO_ERROR; + } else { + c.clear(); + } + return c; +} + +void Camera::disconnect() +{ + LOGV("disconnect"); + if (mCamera != 0) { + mCamera->disconnect(); + mCamera = 0; + } +} + +status_t Camera::reconnect() +{ + LOGV("reconnect"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->connect(this); +} + +sp<ICamera> Camera::remote() +{ + return mCamera; +} + +status_t Camera::lock() +{ + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->lock(); +} + +status_t Camera::unlock() +{ + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->unlock(); +} + +// pass the buffered ISurface to the camera service +status_t Camera::setPreviewDisplay(const sp<Surface>& surface) +{ + LOGV("setPreviewDisplay"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + if (surface != 0) { + return c->setPreviewDisplay(surface->getISurface()); + } else { + LOGD("app passed NULL surface"); + return c->setPreviewDisplay(0); + } +} + +status_t Camera::setPreviewDisplay(const sp<ISurface>& surface) +{ + LOGV("setPreviewDisplay"); + if (surface == 0) { + LOGD("app passed NULL surface"); + } + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->setPreviewDisplay(surface); +} + + +// start preview mode +status_t Camera::startPreview() +{ + LOGV("startPreview"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->startPreview(); +} + +// start recording mode, must call setPreviewDisplay first +status_t Camera::startRecording() +{ + LOGV("startRecording"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->startRecording(); +} + +// stop preview mode +void Camera::stopPreview() +{ + LOGV("stopPreview"); + sp <ICamera> c = mCamera; + if (c == 0) return; + c->stopPreview(); +} + +// stop recording mode +void Camera::stopRecording() +{ + LOGV("stopRecording"); + sp <ICamera> c = mCamera; + if (c == 0) return; + c->stopRecording(); +} + +// release a recording frame +void Camera::releaseRecordingFrame(const sp<IMemory>& mem) +{ + LOGV("releaseRecordingFrame"); + sp <ICamera> c = mCamera; + if (c == 0) return; + c->releaseRecordingFrame(mem); +} + +// get preview state +bool Camera::previewEnabled() +{ + LOGV("previewEnabled"); + sp <ICamera> c = mCamera; + if (c == 0) return false; + return c->previewEnabled(); +} + +// get recording state +bool Camera::recordingEnabled() +{ + LOGV("recordingEnabled"); + sp <ICamera> c = mCamera; + if (c == 0) return false; + return c->recordingEnabled(); +} + +status_t Camera::autoFocus() +{ + LOGV("autoFocus"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->autoFocus(); +} + +status_t Camera::cancelAutoFocus() +{ + LOGV("cancelAutoFocus"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->cancelAutoFocus(); +} + +// take a picture +status_t Camera::takePicture() +{ + LOGV("takePicture"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->takePicture(); +} + +// set preview/capture parameters - key/value pairs +status_t Camera::setParameters(const String8& params) +{ + LOGV("setParameters"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->setParameters(params); +} + +// get preview/capture parameters - key/value pairs +String8 Camera::getParameters() const +{ + LOGV("getParameters"); + String8 params; + sp <ICamera> c = mCamera; + if (c != 0) params = mCamera->getParameters(); + return params; +} + +// send command to camera driver +status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) +{ + LOGV("sendCommand"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->sendCommand(cmd, arg1, arg2); +} + +void Camera::setListener(const sp<CameraListener>& listener) +{ + Mutex::Autolock _l(mLock); + mListener = listener; +} + +void Camera::setPreviewCallbackFlags(int flag) +{ + LOGV("setPreviewCallbackFlags"); + sp <ICamera> c = mCamera; + if (c == 0) return; + mCamera->setPreviewCallbackFlag(flag); +} + +// callback from camera service +void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->notify(msgType, ext1, ext2); + } +} + +// callback from camera service when frame or image is ready +void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postData(msgType, dataPtr); + } +} + +// callback from camera service when timestamped frame is ready +void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postDataTimestamp(timestamp, msgType, dataPtr); + } +} + +void Camera::binderDied(const wp<IBinder>& who) { + LOGW("ICamera died"); + notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); +} + +void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { + LOGV("binderDied"); + Mutex::Autolock _l(Camera::mLock); + Camera::mCameraService.clear(); + LOGW("Camera server died!"); +} + +}; // namespace android + |