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