Camera.cpp revision 08ad5efcef90e24db2863c0f85972ed05fe848a2
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/ISurfaceTexture.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 const sp<ICameraService>& cs = getCameraService(); 124 if (cs != 0) { 125 c->mCamera = cs->connect(c, cameraId); 126 } 127 if (c->mCamera != 0) { 128 c->mCamera->asBinder()->linkToDeath(c); 129 c->mStatus = NO_ERROR; 130 } else { 131 c.clear(); 132 } 133 return c; 134} 135 136void Camera::disconnect() 137{ 138 ALOGV("disconnect"); 139 if (mCamera != 0) { 140 mCamera->disconnect(); 141 mCamera->asBinder()->unlinkToDeath(this); 142 mCamera = 0; 143 } 144} 145 146status_t Camera::reconnect() 147{ 148 ALOGV("reconnect"); 149 sp <ICamera> c = mCamera; 150 if (c == 0) return NO_INIT; 151 return c->connect(this); 152} 153 154sp<ICamera> Camera::remote() 155{ 156 return mCamera; 157} 158 159status_t Camera::lock() 160{ 161 sp <ICamera> c = mCamera; 162 if (c == 0) return NO_INIT; 163 return c->lock(); 164} 165 166status_t Camera::unlock() 167{ 168 sp <ICamera> c = mCamera; 169 if (c == 0) return NO_INIT; 170 return c->unlock(); 171} 172 173// pass the buffered Surface to the camera service 174status_t Camera::setPreviewDisplay(const sp<Surface>& surface) 175{ 176 ALOGV("setPreviewDisplay(%p)", surface.get()); 177 sp <ICamera> c = mCamera; 178 if (c == 0) return NO_INIT; 179 if (surface != 0) { 180 return c->setPreviewDisplay(surface); 181 } else { 182 ALOGD("app passed NULL surface"); 183 return c->setPreviewDisplay(0); 184 } 185} 186 187// pass the buffered ISurfaceTexture to the camera service 188status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture) 189{ 190 ALOGV("setPreviewTexture(%p)", surfaceTexture.get()); 191 sp <ICamera> c = mCamera; 192 if (c == 0) return NO_INIT; 193 if (surfaceTexture != 0) { 194 return c->setPreviewTexture(surfaceTexture); 195 } else { 196 ALOGD("app passed NULL surface"); 197 return c->setPreviewTexture(0); 198 } 199} 200 201// start preview mode 202status_t Camera::startPreview() 203{ 204 ALOGV("startPreview"); 205 sp <ICamera> c = mCamera; 206 if (c == 0) return NO_INIT; 207 return c->startPreview(); 208} 209 210status_t Camera::storeMetaDataInBuffers(bool enabled) 211{ 212 ALOGV("storeMetaDataInBuffers: %s", 213 enabled? "true": "false"); 214 sp <ICamera> c = mCamera; 215 if (c == 0) return NO_INIT; 216 return c->storeMetaDataInBuffers(enabled); 217} 218 219// start recording mode, must call setPreviewDisplay first 220status_t Camera::startRecording() 221{ 222 ALOGV("startRecording"); 223 sp <ICamera> c = mCamera; 224 if (c == 0) return NO_INIT; 225 return c->startRecording(); 226} 227 228// stop preview mode 229void Camera::stopPreview() 230{ 231 ALOGV("stopPreview"); 232 sp <ICamera> c = mCamera; 233 if (c == 0) return; 234 c->stopPreview(); 235} 236 237// stop recording mode 238void Camera::stopRecording() 239{ 240 ALOGV("stopRecording"); 241 { 242 Mutex::Autolock _l(mLock); 243 mRecordingProxyListener.clear(); 244 } 245 sp <ICamera> c = mCamera; 246 if (c == 0) return; 247 c->stopRecording(); 248} 249 250// release a recording frame 251void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 252{ 253 ALOGV("releaseRecordingFrame"); 254 sp <ICamera> c = mCamera; 255 if (c == 0) return; 256 c->releaseRecordingFrame(mem); 257} 258 259// get preview state 260bool Camera::previewEnabled() 261{ 262 ALOGV("previewEnabled"); 263 sp <ICamera> c = mCamera; 264 if (c == 0) return false; 265 return c->previewEnabled(); 266} 267 268// get recording state 269bool Camera::recordingEnabled() 270{ 271 ALOGV("recordingEnabled"); 272 sp <ICamera> c = mCamera; 273 if (c == 0) return false; 274 return c->recordingEnabled(); 275} 276 277status_t Camera::autoFocus() 278{ 279 ALOGV("autoFocus"); 280 sp <ICamera> c = mCamera; 281 if (c == 0) return NO_INIT; 282 return c->autoFocus(); 283} 284 285status_t Camera::cancelAutoFocus() 286{ 287 ALOGV("cancelAutoFocus"); 288 sp <ICamera> c = mCamera; 289 if (c == 0) return NO_INIT; 290 return c->cancelAutoFocus(); 291} 292 293// take a picture 294status_t Camera::takePicture(int msgType) 295{ 296 ALOGV("takePicture: 0x%x", msgType); 297 sp <ICamera> c = mCamera; 298 if (c == 0) return NO_INIT; 299 return c->takePicture(msgType); 300} 301 302// set preview/capture parameters - key/value pairs 303status_t Camera::setParameters(const String8& params) 304{ 305 ALOGV("setParameters"); 306 sp <ICamera> c = mCamera; 307 if (c == 0) return NO_INIT; 308 return c->setParameters(params); 309} 310 311// get preview/capture parameters - key/value pairs 312String8 Camera::getParameters() const 313{ 314 ALOGV("getParameters"); 315 String8 params; 316 sp <ICamera> c = mCamera; 317 if (c != 0) params = mCamera->getParameters(); 318 return params; 319} 320 321// send command to camera driver 322status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 323{ 324 ALOGV("sendCommand"); 325 sp <ICamera> c = mCamera; 326 if (c == 0) return NO_INIT; 327 return c->sendCommand(cmd, arg1, arg2); 328} 329 330void Camera::setListener(const sp<CameraListener>& listener) 331{ 332 Mutex::Autolock _l(mLock); 333 mListener = listener; 334} 335 336void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 337{ 338 Mutex::Autolock _l(mLock); 339 mRecordingProxyListener = listener; 340} 341 342void Camera::setPreviewCallbackFlags(int flag) 343{ 344 ALOGV("setPreviewCallbackFlags"); 345 sp <ICamera> c = mCamera; 346 if (c == 0) return; 347 mCamera->setPreviewCallbackFlag(flag); 348} 349 350// callback from camera service 351void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 352{ 353 sp<CameraListener> listener; 354 { 355 Mutex::Autolock _l(mLock); 356 listener = mListener; 357 } 358 if (listener != NULL) { 359 listener->notify(msgType, ext1, ext2); 360 } 361} 362 363// callback from camera service when frame or image is ready 364void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 365 camera_frame_metadata_t *metadata) 366{ 367 sp<CameraListener> listener; 368 { 369 Mutex::Autolock _l(mLock); 370 listener = mListener; 371 } 372 if (listener != NULL) { 373 listener->postData(msgType, dataPtr, metadata); 374 } 375} 376 377// callback from camera service when timestamped frame is ready 378void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 379{ 380 // If recording proxy listener is registered, forward the frame and return. 381 // The other listener (mListener) is ignored because the receiver needs to 382 // call releaseRecordingFrame. 383 sp<ICameraRecordingProxyListener> proxylistener; 384 { 385 Mutex::Autolock _l(mLock); 386 proxylistener = mRecordingProxyListener; 387 } 388 if (proxylistener != NULL) { 389 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 390 return; 391 } 392 393 sp<CameraListener> listener; 394 { 395 Mutex::Autolock _l(mLock); 396 listener = mListener; 397 } 398 if (listener != NULL) { 399 listener->postDataTimestamp(timestamp, msgType, dataPtr); 400 } else { 401 ALOGW("No listener was set. Drop a recording frame."); 402 releaseRecordingFrame(dataPtr); 403 } 404} 405 406void Camera::binderDied(const wp<IBinder>& who) { 407 ALOGW("ICamera died"); 408 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 409} 410 411void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { 412 ALOGV("binderDied"); 413 Mutex::Autolock _l(Camera::mLock); 414 Camera::mCameraService.clear(); 415 ALOGW("Camera server died!"); 416} 417 418sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 419 ALOGV("getProxy"); 420 return new RecordingProxy(this); 421} 422 423status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 424{ 425 ALOGV("RecordingProxy::startRecording"); 426 mCamera->setRecordingProxyListener(listener); 427 mCamera->reconnect(); 428 return mCamera->startRecording(); 429} 430 431void Camera::RecordingProxy::stopRecording() 432{ 433 ALOGV("RecordingProxy::stopRecording"); 434 mCamera->stopRecording(); 435} 436 437void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 438{ 439 ALOGV("RecordingProxy::releaseRecordingFrame"); 440 mCamera->releaseRecordingFrame(mem); 441} 442 443Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 444{ 445 mCamera = camera; 446} 447 448}; // namespace android 449