Camera.cpp revision 280405a138a0068694f3c39b4290f510173133d9
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& clientPackageName, 75 int clientUid) 76{ 77 return CameraBaseT::connect(cameraId, clientPackageName, clientUid); 78} 79 80status_t Camera::connectLegacy(int cameraId, int halVersion, 81 const String16& clientPackageName, 82 int clientUid, 83 sp<Camera>& camera) 84{ 85 ALOGV("%s: connect legacy camera device", __FUNCTION__); 86 sp<Camera> c = new Camera(cameraId); 87 sp<ICameraClient> cl = c; 88 status_t status = NO_ERROR; 89 const sp<ICameraService>& cs = CameraBaseT::getCameraService(); 90 91 if (cs != 0) { 92 status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName, 93 clientUid, /*out*/c->mCamera); 94 } 95 if (status == OK && c->mCamera != 0) { 96 IInterface::asBinder(c->mCamera)->linkToDeath(c); 97 c->mStatus = NO_ERROR; 98 camera = c; 99 } else { 100 ALOGW("An error occurred while connecting to camera: %d", cameraId); 101 c.clear(); 102 } 103 return status; 104} 105 106status_t Camera::reconnect() 107{ 108 ALOGV("reconnect"); 109 sp <ICamera> c = mCamera; 110 if (c == 0) return NO_INIT; 111 return c->connect(this); 112} 113 114status_t Camera::lock() 115{ 116 sp <ICamera> c = mCamera; 117 if (c == 0) return NO_INIT; 118 return c->lock(); 119} 120 121status_t Camera::unlock() 122{ 123 sp <ICamera> c = mCamera; 124 if (c == 0) return NO_INIT; 125 return c->unlock(); 126} 127 128// pass the buffered IGraphicBufferProducer to the camera service 129status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) 130{ 131 ALOGV("setPreviewTarget(%p)", bufferProducer.get()); 132 sp <ICamera> c = mCamera; 133 if (c == 0) return NO_INIT; 134 ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); 135 return c->setPreviewTarget(bufferProducer); 136} 137 138// start preview mode 139status_t Camera::startPreview() 140{ 141 ALOGV("startPreview"); 142 sp <ICamera> c = mCamera; 143 if (c == 0) return NO_INIT; 144 return c->startPreview(); 145} 146 147status_t Camera::storeMetaDataInBuffers(bool enabled) 148{ 149 ALOGV("storeMetaDataInBuffers: %s", 150 enabled? "true": "false"); 151 sp <ICamera> c = mCamera; 152 if (c == 0) return NO_INIT; 153 return c->storeMetaDataInBuffers(enabled); 154} 155 156// start recording mode, must call setPreviewTarget first 157status_t Camera::startRecording() 158{ 159 ALOGV("startRecording"); 160 sp <ICamera> c = mCamera; 161 if (c == 0) return NO_INIT; 162 return c->startRecording(); 163} 164 165// stop preview mode 166void Camera::stopPreview() 167{ 168 ALOGV("stopPreview"); 169 sp <ICamera> c = mCamera; 170 if (c == 0) return; 171 c->stopPreview(); 172} 173 174// stop recording mode 175void Camera::stopRecording() 176{ 177 ALOGV("stopRecording"); 178 { 179 Mutex::Autolock _l(mLock); 180 mRecordingProxyListener.clear(); 181 } 182 sp <ICamera> c = mCamera; 183 if (c == 0) return; 184 c->stopRecording(); 185} 186 187// release a recording frame 188void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 189{ 190 ALOGV("releaseRecordingFrame"); 191 sp <ICamera> c = mCamera; 192 if (c == 0) return; 193 c->releaseRecordingFrame(mem); 194} 195 196// get preview state 197bool Camera::previewEnabled() 198{ 199 ALOGV("previewEnabled"); 200 sp <ICamera> c = mCamera; 201 if (c == 0) return false; 202 return c->previewEnabled(); 203} 204 205// get recording state 206bool Camera::recordingEnabled() 207{ 208 ALOGV("recordingEnabled"); 209 sp <ICamera> c = mCamera; 210 if (c == 0) return false; 211 return c->recordingEnabled(); 212} 213 214status_t Camera::autoFocus() 215{ 216 ALOGV("autoFocus"); 217 sp <ICamera> c = mCamera; 218 if (c == 0) return NO_INIT; 219 return c->autoFocus(); 220} 221 222status_t Camera::cancelAutoFocus() 223{ 224 ALOGV("cancelAutoFocus"); 225 sp <ICamera> c = mCamera; 226 if (c == 0) return NO_INIT; 227 return c->cancelAutoFocus(); 228} 229 230// take a picture 231status_t Camera::takePicture(int msgType) 232{ 233 ALOGV("takePicture: 0x%x", msgType); 234 sp <ICamera> c = mCamera; 235 if (c == 0) return NO_INIT; 236 return c->takePicture(msgType); 237} 238 239// set preview/capture parameters - key/value pairs 240status_t Camera::setParameters(const String8& params) 241{ 242 ALOGV("setParameters"); 243 sp <ICamera> c = mCamera; 244 if (c == 0) return NO_INIT; 245 return c->setParameters(params); 246} 247 248// get preview/capture parameters - key/value pairs 249String8 Camera::getParameters() const 250{ 251 ALOGV("getParameters"); 252 String8 params; 253 sp <ICamera> c = mCamera; 254 if (c != 0) params = mCamera->getParameters(); 255 return params; 256} 257 258// send command to camera driver 259status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 260{ 261 ALOGV("sendCommand"); 262 sp <ICamera> c = mCamera; 263 if (c == 0) return NO_INIT; 264 return c->sendCommand(cmd, arg1, arg2); 265} 266 267void Camera::setListener(const sp<CameraListener>& listener) 268{ 269 Mutex::Autolock _l(mLock); 270 mListener = listener; 271} 272 273void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 274{ 275 Mutex::Autolock _l(mLock); 276 mRecordingProxyListener = listener; 277} 278 279void Camera::setPreviewCallbackFlags(int flag) 280{ 281 ALOGV("setPreviewCallbackFlags"); 282 sp <ICamera> c = mCamera; 283 if (c == 0) return; 284 mCamera->setPreviewCallbackFlag(flag); 285} 286 287status_t Camera::setPreviewCallbackTarget( 288 const sp<IGraphicBufferProducer>& callbackProducer) 289{ 290 sp <ICamera> c = mCamera; 291 if (c == 0) return NO_INIT; 292 return c->setPreviewCallbackTarget(callbackProducer); 293} 294 295// callback from camera service 296void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 297{ 298 return CameraBaseT::notifyCallback(msgType, ext1, ext2); 299} 300 301// callback from camera service when frame or image is ready 302void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 303 camera_frame_metadata_t *metadata) 304{ 305 sp<CameraListener> listener; 306 { 307 Mutex::Autolock _l(mLock); 308 listener = mListener; 309 } 310 if (listener != NULL) { 311 listener->postData(msgType, dataPtr, metadata); 312 } 313} 314 315// callback from camera service when timestamped frame is ready 316void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 317{ 318 // If recording proxy listener is registered, forward the frame and return. 319 // The other listener (mListener) is ignored because the receiver needs to 320 // call releaseRecordingFrame. 321 sp<ICameraRecordingProxyListener> proxylistener; 322 { 323 Mutex::Autolock _l(mLock); 324 proxylistener = mRecordingProxyListener; 325 } 326 if (proxylistener != NULL) { 327 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 328 return; 329 } 330 331 sp<CameraListener> listener; 332 { 333 Mutex::Autolock _l(mLock); 334 listener = mListener; 335 } 336 337 if (listener != NULL) { 338 listener->postDataTimestamp(timestamp, msgType, dataPtr); 339 } else { 340 ALOGW("No listener was set. Drop a recording frame."); 341 releaseRecordingFrame(dataPtr); 342 } 343} 344 345sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 346 ALOGV("getProxy"); 347 return new RecordingProxy(this); 348} 349 350status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 351{ 352 ALOGV("RecordingProxy::startRecording"); 353 mCamera->setRecordingProxyListener(listener); 354 mCamera->reconnect(); 355 return mCamera->startRecording(); 356} 357 358void Camera::RecordingProxy::stopRecording() 359{ 360 ALOGV("RecordingProxy::stopRecording"); 361 mCamera->stopRecording(); 362} 363 364void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 365{ 366 ALOGV("RecordingProxy::releaseRecordingFrame"); 367 mCamera->releaseRecordingFrame(mem); 368} 369 370Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 371{ 372 mCamera = camera; 373} 374 375}; // namespace android 376