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