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