Camera.cpp revision bfb5d5ef5bae01efac171397260a7152782d92c7
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 <binder/IPCThreadState.h> 23#include <binder/IServiceManager.h> 24#include <binder/IMemory.h> 25 26#include <camera/Camera.h> 27#include <camera/ICameraRecordingProxyListener.h> 28#include <camera/ICameraService.h> 29 30#include <gui/IGraphicBufferProducer.h> 31#include <gui/Surface.h> 32 33namespace android { 34 35// client singleton for camera service binder interface 36Mutex Camera::mLock; 37sp<ICameraService> Camera::mCameraService; 38sp<Camera::DeathNotifier> Camera::mDeathNotifier; 39 40// establish binder interface to camera service 41const sp<ICameraService>& Camera::getCameraService() 42{ 43 Mutex::Autolock _l(mLock); 44 if (mCameraService.get() == 0) { 45 sp<IServiceManager> sm = defaultServiceManager(); 46 sp<IBinder> binder; 47 do { 48 binder = sm->getService(String16("media.camera")); 49 if (binder != 0) 50 break; 51 ALOGW("CameraService not published, waiting..."); 52 usleep(500000); // 0.5 s 53 } while(true); 54 if (mDeathNotifier == NULL) { 55 mDeathNotifier = new DeathNotifier(); 56 } 57 binder->linkToDeath(mDeathNotifier); 58 mCameraService = interface_cast<ICameraService>(binder); 59 } 60 ALOGE_IF(mCameraService==0, "no CameraService!?"); 61 return mCameraService; 62} 63 64// --------------------------------------------------------------------------- 65 66Camera::Camera() 67{ 68 init(); 69} 70 71// construct a camera client from an existing camera remote 72sp<Camera> Camera::create(const sp<ICamera>& camera) 73{ 74 ALOGV("create"); 75 if (camera == 0) { 76 ALOGE("camera remote is a NULL pointer"); 77 return 0; 78 } 79 80 sp<Camera> c = new Camera(); 81 if (camera->connect(c) == NO_ERROR) { 82 c->mStatus = NO_ERROR; 83 c->mCamera = camera; 84 camera->asBinder()->linkToDeath(c); 85 return c; 86 } 87 return 0; 88} 89 90void Camera::init() 91{ 92 mStatus = UNKNOWN_ERROR; 93} 94 95Camera::~Camera() 96{ 97 // We don't need to call disconnect() here because if the CameraService 98 // thinks we are the owner of the hardware, it will hold a (strong) 99 // reference to us, and we can't possibly be here. We also don't want to 100 // call disconnect() here if we are in the same process as mediaserver, 101 // because we may be invoked by CameraService::Client::connect() and will 102 // deadlock if we call any method of ICamera here. 103} 104 105int32_t Camera::getNumberOfCameras() 106{ 107 const sp<ICameraService>& cs = getCameraService(); 108 if (cs == 0) return 0; 109 return cs->getNumberOfCameras(); 110} 111 112status_t Camera::getCameraInfo(int cameraId, 113 struct CameraInfo* cameraInfo) { 114 const sp<ICameraService>& cs = getCameraService(); 115 if (cs == 0) return UNKNOWN_ERROR; 116 return cs->getCameraInfo(cameraId, cameraInfo); 117} 118 119sp<Camera> Camera::connect(int cameraId) 120{ 121 ALOGV("connect"); 122 sp<Camera> c = new Camera(); 123 sp<ICameraClient> cl = c; 124 const sp<ICameraService>& cs = getCameraService(); 125 if (cs != 0) { 126 c->mCamera = cs->connect(cl, cameraId); 127 } 128 if (c->mCamera != 0) { 129 c->mCamera->asBinder()->linkToDeath(c); 130 c->mStatus = NO_ERROR; 131 } else { 132 c.clear(); 133 } 134 return c; 135} 136 137void Camera::disconnect() 138{ 139 ALOGV("disconnect"); 140 if (mCamera != 0) { 141 mCamera->disconnect(); 142 mCamera->asBinder()->unlinkToDeath(this); 143 mCamera = 0; 144 } 145} 146 147status_t Camera::reconnect() 148{ 149 ALOGV("reconnect"); 150 sp <ICamera> c = mCamera; 151 if (c == 0) return NO_INIT; 152 return c->connect(this); 153} 154 155sp<ICamera> Camera::remote() 156{ 157 return mCamera; 158} 159 160status_t Camera::lock() 161{ 162 sp <ICamera> c = mCamera; 163 if (c == 0) return NO_INIT; 164 return c->lock(); 165} 166 167status_t Camera::unlock() 168{ 169 sp <ICamera> c = mCamera; 170 if (c == 0) return NO_INIT; 171 return c->unlock(); 172} 173 174// pass the buffered Surface to the camera service 175status_t Camera::setPreviewDisplay(const sp<Surface>& surface) 176{ 177 ALOGV("setPreviewDisplay(%p)", surface.get()); 178 sp <ICamera> c = mCamera; 179 if (c == 0) return NO_INIT; 180 if (surface != 0) { 181 return c->setPreviewDisplay(surface); 182 } else { 183 ALOGD("app passed NULL surface"); 184 return c->setPreviewDisplay(0); 185 } 186} 187 188// pass the buffered IGraphicBufferProducer to the camera service 189status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer) 190{ 191 ALOGV("setPreviewTexture(%p)", bufferProducer.get()); 192 sp <ICamera> c = mCamera; 193 if (c == 0) return NO_INIT; 194 if (bufferProducer != 0) { 195 return c->setPreviewTexture(bufferProducer); 196 } else { 197 ALOGD("app passed NULL surface"); 198 return c->setPreviewTexture(0); 199 } 200} 201 202// start preview mode 203status_t Camera::startPreview() 204{ 205 ALOGV("startPreview"); 206 sp <ICamera> c = mCamera; 207 if (c == 0) return NO_INIT; 208 return c->startPreview(); 209} 210 211status_t Camera::storeMetaDataInBuffers(bool enabled) 212{ 213 ALOGV("storeMetaDataInBuffers: %s", 214 enabled? "true": "false"); 215 sp <ICamera> c = mCamera; 216 if (c == 0) return NO_INIT; 217 return c->storeMetaDataInBuffers(enabled); 218} 219 220// start recording mode, must call setPreviewDisplay first 221status_t Camera::startRecording() 222{ 223 ALOGV("startRecording"); 224 sp <ICamera> c = mCamera; 225 if (c == 0) return NO_INIT; 226 return c->startRecording(); 227} 228 229// stop preview mode 230void Camera::stopPreview() 231{ 232 ALOGV("stopPreview"); 233 sp <ICamera> c = mCamera; 234 if (c == 0) return; 235 c->stopPreview(); 236} 237 238// stop recording mode 239void Camera::stopRecording() 240{ 241 ALOGV("stopRecording"); 242 { 243 Mutex::Autolock _l(mLock); 244 mRecordingProxyListener.clear(); 245 } 246 sp <ICamera> c = mCamera; 247 if (c == 0) return; 248 c->stopRecording(); 249} 250 251// release a recording frame 252void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 253{ 254 ALOGV("releaseRecordingFrame"); 255 sp <ICamera> c = mCamera; 256 if (c == 0) return; 257 c->releaseRecordingFrame(mem); 258} 259 260// get preview state 261bool Camera::previewEnabled() 262{ 263 ALOGV("previewEnabled"); 264 sp <ICamera> c = mCamera; 265 if (c == 0) return false; 266 return c->previewEnabled(); 267} 268 269// get recording state 270bool Camera::recordingEnabled() 271{ 272 ALOGV("recordingEnabled"); 273 sp <ICamera> c = mCamera; 274 if (c == 0) return false; 275 return c->recordingEnabled(); 276} 277 278status_t Camera::autoFocus() 279{ 280 ALOGV("autoFocus"); 281 sp <ICamera> c = mCamera; 282 if (c == 0) return NO_INIT; 283 return c->autoFocus(); 284} 285 286status_t Camera::cancelAutoFocus() 287{ 288 ALOGV("cancelAutoFocus"); 289 sp <ICamera> c = mCamera; 290 if (c == 0) return NO_INIT; 291 return c->cancelAutoFocus(); 292} 293 294// take a picture 295status_t Camera::takePicture(int msgType) 296{ 297 ALOGV("takePicture: 0x%x", msgType); 298 sp <ICamera> c = mCamera; 299 if (c == 0) return NO_INIT; 300 return c->takePicture(msgType); 301} 302 303// set preview/capture parameters - key/value pairs 304status_t Camera::setParameters(const String8& params) 305{ 306 ALOGV("setParameters"); 307 sp <ICamera> c = mCamera; 308 if (c == 0) return NO_INIT; 309 return c->setParameters(params); 310} 311 312// get preview/capture parameters - key/value pairs 313String8 Camera::getParameters() const 314{ 315 ALOGV("getParameters"); 316 String8 params; 317 sp <ICamera> c = mCamera; 318 if (c != 0) params = mCamera->getParameters(); 319 return params; 320} 321 322// send command to camera driver 323status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 324{ 325 ALOGV("sendCommand"); 326 sp <ICamera> c = mCamera; 327 if (c == 0) return NO_INIT; 328 return c->sendCommand(cmd, arg1, arg2); 329} 330 331void Camera::setListener(const sp<CameraListener>& listener) 332{ 333 Mutex::Autolock _l(mLock); 334 mListener = listener; 335} 336 337void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 338{ 339 Mutex::Autolock _l(mLock); 340 mRecordingProxyListener = listener; 341} 342 343void Camera::setPreviewCallbackFlags(int flag) 344{ 345 ALOGV("setPreviewCallbackFlags"); 346 sp <ICamera> c = mCamera; 347 if (c == 0) return; 348 mCamera->setPreviewCallbackFlag(flag); 349} 350 351// callback from camera service 352void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 353{ 354 sp<CameraListener> listener; 355 { 356 Mutex::Autolock _l(mLock); 357 listener = mListener; 358 } 359 if (listener != NULL) { 360 listener->notify(msgType, ext1, ext2); 361 } 362} 363 364// callback from camera service when frame or image is ready 365void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 366 camera_frame_metadata_t *metadata) 367{ 368 sp<CameraListener> listener; 369 { 370 Mutex::Autolock _l(mLock); 371 listener = mListener; 372 } 373 if (listener != NULL) { 374 listener->postData(msgType, dataPtr, metadata); 375 } 376} 377 378// callback from camera service when timestamped frame is ready 379void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 380{ 381 // If recording proxy listener is registered, forward the frame and return. 382 // The other listener (mListener) is ignored because the receiver needs to 383 // call releaseRecordingFrame. 384 sp<ICameraRecordingProxyListener> proxylistener; 385 { 386 Mutex::Autolock _l(mLock); 387 proxylistener = mRecordingProxyListener; 388 } 389 if (proxylistener != NULL) { 390 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 391 return; 392 } 393 394 sp<CameraListener> listener; 395 { 396 Mutex::Autolock _l(mLock); 397 listener = mListener; 398 } 399 if (listener != NULL) { 400 listener->postDataTimestamp(timestamp, msgType, dataPtr); 401 } else { 402 ALOGW("No listener was set. Drop a recording frame."); 403 releaseRecordingFrame(dataPtr); 404 } 405} 406 407void Camera::binderDied(const wp<IBinder>& who) { 408 ALOGW("ICamera died"); 409 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 410} 411 412void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { 413 ALOGV("binderDied"); 414 Mutex::Autolock _l(Camera::mLock); 415 Camera::mCameraService.clear(); 416 ALOGW("Camera server died!"); 417} 418 419sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 420 ALOGV("getProxy"); 421 return new RecordingProxy(this); 422} 423 424status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 425{ 426 ALOGV("RecordingProxy::startRecording"); 427 mCamera->setRecordingProxyListener(listener); 428 mCamera->reconnect(); 429 return mCamera->startRecording(); 430} 431 432void Camera::RecordingProxy::stopRecording() 433{ 434 ALOGV("RecordingProxy::stopRecording"); 435 mCamera->stopRecording(); 436} 437 438void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 439{ 440 ALOGV("RecordingProxy::releaseRecordingFrame"); 441 mCamera->releaseRecordingFrame(mem); 442} 443 444Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 445{ 446 mCamera = camera; 447} 448 449}; // namespace android 450