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