Camera.cpp revision 32fa6d0e65dbf956e253a1006e9419dce2fe75c9
1/* 2** 3** Copyright (C) 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "Camera" 20#include <utils/Log.h> 21#include <utils/threads.h> 22#include <utils/String16.h> 23#include <binder/IPCThreadState.h> 24#include <binder/IServiceManager.h> 25#include <binder/IMemory.h> 26 27#include <camera/Camera.h> 28#include <camera/ICameraRecordingProxyListener.h> 29#include <camera/ICameraService.h> 30#include <camera/ICamera.h> 31 32#include <gui/IGraphicBufferProducer.h> 33#include <gui/Surface.h> 34 35namespace android { 36 37Camera::Camera(int cameraId) 38 : CameraBase(cameraId) 39{ 40} 41 42CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = 43 &ICameraService::connect; 44 45// construct a camera client from an existing camera remote 46sp<Camera> Camera::create(const sp<ICamera>& camera) 47{ 48 ALOGV("create"); 49 if (camera == 0) { 50 ALOGE("camera remote is a NULL pointer"); 51 return 0; 52 } 53 54 sp<Camera> c = new Camera(-1); 55 if (camera->connect(c) == NO_ERROR) { 56 c->mStatus = NO_ERROR; 57 c->mCamera = camera; 58 IInterface::asBinder(camera)->linkToDeath(c); 59 return c; 60 } 61 return 0; 62} 63 64Camera::~Camera() 65{ 66 // We don't need to call disconnect() here because if the CameraService 67 // thinks we are the owner of the hardware, it will hold a (strong) 68 // reference to us, and we can't possibly be here. We also don't want to 69 // call disconnect() here if we are in the same process as mediaserver, 70 // because we may be invoked by CameraService::Client::connect() and will 71 // deadlock if we call any method of ICamera here. 72} 73 74sp<Camera> Camera::connect(int cameraId, const String16& opPackageName, int clientUid) 75{ 76 return CameraBaseT::connect(cameraId, opPackageName, clientUid); 77} 78 79status_t Camera::connectLegacy(int cameraId, int halVersion, 80 const String16& opPackageName, 81 int clientUid, 82 sp<Camera>& camera) 83{ 84 ALOGV("%s: connect legacy camera device", __FUNCTION__); 85 sp<Camera> c = new Camera(cameraId); 86 sp<ICameraClient> cl = c; 87 status_t status = NO_ERROR; 88 const sp<ICameraService>& cs = CameraBaseT::getCameraService(); 89 90 if (cs != 0) { 91 status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName, 92 clientUid, /*out*/c->mCamera); 93 } 94 if (status == OK && c->mCamera != 0) { 95 IInterface::asBinder(c->mCamera)->linkToDeath(c); 96 c->mStatus = NO_ERROR; 97 camera = c; 98 } else { 99 ALOGW("An error occurred while connecting to camera: %d", cameraId); 100 c.clear(); 101 } 102 return status; 103} 104 105status_t Camera::reconnect() 106{ 107 ALOGV("reconnect"); 108 sp <ICamera> c = mCamera; 109 if (c == 0) return NO_INIT; 110 return c->connect(this); 111} 112 113status_t Camera::lock() 114{ 115 sp <ICamera> c = mCamera; 116 if (c == 0) return NO_INIT; 117 return c->lock(); 118} 119 120status_t Camera::unlock() 121{ 122 sp <ICamera> c = mCamera; 123 if (c == 0) return NO_INIT; 124 return c->unlock(); 125} 126 127// pass the buffered IGraphicBufferProducer to the camera service 128status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) 129{ 130 ALOGV("setPreviewTarget(%p)", bufferProducer.get()); 131 sp <ICamera> c = mCamera; 132 if (c == 0) return NO_INIT; 133 ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); 134 return c->setPreviewTarget(bufferProducer); 135} 136 137// start preview mode 138status_t Camera::startPreview() 139{ 140 ALOGV("startPreview"); 141 sp <ICamera> c = mCamera; 142 if (c == 0) return NO_INIT; 143 return c->startPreview(); 144} 145 146status_t Camera::storeMetaDataInBuffers(bool enabled) 147{ 148 ALOGV("storeMetaDataInBuffers: %s", 149 enabled? "true": "false"); 150 sp <ICamera> c = mCamera; 151 if (c == 0) return NO_INIT; 152 return c->storeMetaDataInBuffers(enabled); 153} 154 155// start recording mode, must call setPreviewTarget first 156status_t Camera::startRecording() 157{ 158 ALOGV("startRecording"); 159 sp <ICamera> c = mCamera; 160 if (c == 0) return NO_INIT; 161 return c->startRecording(); 162} 163 164// stop preview mode 165void Camera::stopPreview() 166{ 167 ALOGV("stopPreview"); 168 sp <ICamera> c = mCamera; 169 if (c == 0) return; 170 c->stopPreview(); 171} 172 173// stop recording mode 174void Camera::stopRecording() 175{ 176 ALOGV("stopRecording"); 177 { 178 Mutex::Autolock _l(mLock); 179 mRecordingProxyListener.clear(); 180 } 181 sp <ICamera> c = mCamera; 182 if (c == 0) return; 183 c->stopRecording(); 184} 185 186// release a recording frame 187void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 188{ 189 ALOGV("releaseRecordingFrame"); 190 sp <ICamera> c = mCamera; 191 if (c == 0) return; 192 c->releaseRecordingFrame(mem); 193} 194 195// get preview state 196bool Camera::previewEnabled() 197{ 198 ALOGV("previewEnabled"); 199 sp <ICamera> c = mCamera; 200 if (c == 0) return false; 201 return c->previewEnabled(); 202} 203 204// get recording state 205bool Camera::recordingEnabled() 206{ 207 ALOGV("recordingEnabled"); 208 sp <ICamera> c = mCamera; 209 if (c == 0) return false; 210 return c->recordingEnabled(); 211} 212 213status_t Camera::autoFocus() 214{ 215 ALOGV("autoFocus"); 216 sp <ICamera> c = mCamera; 217 if (c == 0) return NO_INIT; 218 return c->autoFocus(); 219} 220 221status_t Camera::cancelAutoFocus() 222{ 223 ALOGV("cancelAutoFocus"); 224 sp <ICamera> c = mCamera; 225 if (c == 0) return NO_INIT; 226 return c->cancelAutoFocus(); 227} 228 229// take a picture 230status_t Camera::takePicture(int msgType) 231{ 232 ALOGV("takePicture: 0x%x", msgType); 233 sp <ICamera> c = mCamera; 234 if (c == 0) return NO_INIT; 235 return c->takePicture(msgType); 236} 237 238// set preview/capture parameters - key/value pairs 239status_t Camera::setParameters(const String8& params) 240{ 241 ALOGV("setParameters"); 242 sp <ICamera> c = mCamera; 243 if (c == 0) return NO_INIT; 244 return c->setParameters(params); 245} 246 247// get preview/capture parameters - key/value pairs 248String8 Camera::getParameters() const 249{ 250 ALOGV("getParameters"); 251 String8 params; 252 sp <ICamera> c = mCamera; 253 if (c != 0) params = mCamera->getParameters(); 254 return params; 255} 256 257// send command to camera driver 258status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 259{ 260 ALOGV("sendCommand"); 261 sp <ICamera> c = mCamera; 262 if (c == 0) return NO_INIT; 263 return c->sendCommand(cmd, arg1, arg2); 264} 265 266void Camera::setListener(const sp<CameraListener>& listener) 267{ 268 Mutex::Autolock _l(mLock); 269 mListener = listener; 270} 271 272void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 273{ 274 Mutex::Autolock _l(mLock); 275 mRecordingProxyListener = listener; 276} 277 278void Camera::setPreviewCallbackFlags(int flag) 279{ 280 ALOGV("setPreviewCallbackFlags"); 281 sp <ICamera> c = mCamera; 282 if (c == 0) return; 283 mCamera->setPreviewCallbackFlag(flag); 284} 285 286status_t Camera::setPreviewCallbackTarget( 287 const sp<IGraphicBufferProducer>& callbackProducer) 288{ 289 sp <ICamera> c = mCamera; 290 if (c == 0) return NO_INIT; 291 return c->setPreviewCallbackTarget(callbackProducer); 292} 293 294// callback from camera service 295void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 296{ 297 return CameraBaseT::notifyCallback(msgType, ext1, ext2); 298} 299 300// callback from camera service when frame or image is ready 301void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 302 camera_frame_metadata_t *metadata) 303{ 304 sp<CameraListener> listener; 305 { 306 Mutex::Autolock _l(mLock); 307 listener = mListener; 308 } 309 if (listener != NULL) { 310 listener->postData(msgType, dataPtr, metadata); 311 } 312} 313 314// callback from camera service when timestamped frame is ready 315void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 316{ 317 // If recording proxy listener is registered, forward the frame and return. 318 // The other listener (mListener) is ignored because the receiver needs to 319 // call releaseRecordingFrame. 320 sp<ICameraRecordingProxyListener> proxylistener; 321 { 322 Mutex::Autolock _l(mLock); 323 proxylistener = mRecordingProxyListener; 324 } 325 if (proxylistener != NULL) { 326 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 327 return; 328 } 329 330 sp<CameraListener> listener; 331 { 332 Mutex::Autolock _l(mLock); 333 listener = mListener; 334 } 335 336 if (listener != NULL) { 337 listener->postDataTimestamp(timestamp, msgType, dataPtr); 338 } else { 339 ALOGW("No listener was set. Drop a recording frame."); 340 releaseRecordingFrame(dataPtr); 341 } 342} 343 344sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 345 ALOGV("getProxy"); 346 return new RecordingProxy(this); 347} 348 349status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 350{ 351 ALOGV("RecordingProxy::startRecording"); 352 mCamera->setRecordingProxyListener(listener); 353 mCamera->reconnect(); 354 return mCamera->startRecording(); 355} 356 357void Camera::RecordingProxy::stopRecording() 358{ 359 ALOGV("RecordingProxy::stopRecording"); 360 mCamera->stopRecording(); 361} 362 363void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 364{ 365 ALOGV("RecordingProxy::releaseRecordingFrame"); 366 mCamera->releaseRecordingFrame(mem); 367} 368 369Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 370{ 371 mCamera = camera; 372} 373 374}; // namespace android 375