ProCamera.h revision 4bc4a3845e456fd464556d79d20650a107e873e5
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_PRO_CAMERA_H
18#define ANDROID_HARDWARE_PRO_CAMERA_H
19
20#include <utils/Timers.h>
21#include <utils/KeyedVector.h>
22#include <gui/IGraphicBufferProducer.h>
23#include <system/camera.h>
24#include <camera/IProCameraCallbacks.h>
25#include <camera/IProCameraUser.h>
26#include <camera/Camera.h>
27#include <camera/CameraMetadata.h>
28#include <gui/CpuConsumer.h>
29
30#include <utils/Condition.h>
31#include <utils/Mutex.h>
32
33struct camera_metadata;
34
35namespace android {
36
37// All callbacks on this class are concurrent
38// (they come from separate threads)
39class ProCameraListener : public CameraListener
40{
41public:
42    // Lock has been acquired. Write operations now available.
43    virtual void onLockAcquired() = 0;
44    // Lock has been released with exclusiveUnlock.
45    virtual void onLockReleased() = 0;
46    // Lock has been stolen by another client.
47    virtual void onLockStolen() = 0;
48
49    // Lock free.
50    virtual void onTriggerNotify(int32_t msgType, int32_t ext1, int32_t ext2)
51                                                                            = 0;
52
53    // OnBufferReceived and OnRequestReceived can come in with any order,
54    // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them
55
56    // A new frame buffer has been received for this stream.
57    // -- This callback only fires for createStreamCpu streams
58    // -- Use buf.timestamp to correlate with metadata's
59    //    android.sensor.timestamp
60    // -- The buffer must not be accessed after this function call completes
61    virtual void onBufferReceived(int streamId,
62                                  const CpuConsumer::LockedBuffer& buf) = 0;
63    /**
64      * A new metadata buffer has been received.
65      * -- Ownership of request passes on to the callee, free with
66      *    free_camera_metadata.
67      */
68    virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0;
69
70
71    // A new frame buffer has been received for this stream.
72    // -- This callback only fires for createStreamCpu streams
73    // -- Use buf.timestamp to correlate with metadata's android.sensor.timestamp
74    // -- The buffer should be accessed with CpuConsumer::lockNextBuffer
75    //      and CpuConsumer::unlockBuffer
76    virtual void onFrameAvailable(int streamId,
77                                  const sp<CpuConsumer>& cpuConsumer) {
78    }
79
80    virtual bool useOnFrameAvailable() {
81        return false;
82    }
83};
84
85class ProCamera : public BnProCameraCallbacks, public IBinder::DeathRecipient
86{
87public:
88    /**
89     * Connect a shared camera. By default access is restricted to read only
90     * (Lock free) operations. To be able to submit custom requests a lock needs
91     * to be acquired with exclusive[Try]Lock.
92     */
93    static sp<ProCamera> connect(int cameraId);
94    virtual void disconnect();
95    virtual ~ProCamera();
96
97    void setListener(const sp<ProCameraListener>& listener);
98
99    /**
100     * Exclusive Locks:
101     * - We may request exclusive access to a camera if no other
102     *   clients are using the camera. This works as a traditional
103     *   client, writing/reading any camera state.
104     * - An application opening the camera (a regular 'Camera') will
105     *   always steal away the exclusive lock from a ProCamera,
106     *   this will call onLockReleased.
107     * - onLockAcquired will be called again once it is possible
108     *   to again exclusively lock the camera.
109     *
110     */
111
112    /**
113     * All exclusiveLock/unlock functions are asynchronous. The remote endpoint
114     * shall not block while waiting to acquire the lock. Instead the lock
115     * notifications will come in asynchronously on the listener.
116     */
117
118    /**
119      * Attempt to acquire the lock instantly (non-blocking)
120      * - If this succeeds, you do not need to wait for onLockAcquired
121      *   but the event will still be fired
122      *
123      * Returns -EBUSY if already locked. 0 on success.
124      */
125    status_t exclusiveTryLock();
126    // always returns 0. wait for onLockAcquired before lock is acquired.
127    status_t exclusiveLock();
128    // release a lock if we have one, or cancel the lock request.
129    status_t exclusiveUnlock();
130
131    // exclusive lock = do whatever we want. no lock = read only.
132    bool hasExclusiveLock();
133
134    /**
135     * < 0 error, >= 0 the request ID. streaming to have the request repeat
136     *    until cancelled.
137     * The request queue is flushed when a lock is released or stolen
138     *    if not locked will return PERMISSION_DENIED
139     */
140    int submitRequest(const struct camera_metadata* metadata,
141                                                        bool streaming = false);
142    // if not locked will return PERMISSION_DENIED, BAD_VALUE if requestId bad
143    status_t cancelRequest(int requestId);
144
145    /**
146     * Ask for a stream to be enabled.
147     * Lock free. Service maintains counter of streams.
148     */
149    status_t requestStream(int streamId);
150// TODO: remove requestStream, its useless.
151
152    /**
153      * Delete a stream.
154      * Lock free.
155      * Errors: BAD_VALUE if unknown stream ID.
156      *         PERMISSION_DENIED if the stream wasn't yours
157      */
158    status_t deleteStream(int streamId);
159
160    /**
161      * Create a new HW stream, whose sink will be the window.
162      * Lock free. Service maintains counter of streams.
163      * Errors: -EBUSY if too many streams created
164      */
165    status_t createStream(int width, int height, int format,
166                          const sp<Surface>& surface,
167                          /*out*/
168                          int* streamId);
169
170    /**
171      * Create a new HW stream, whose sink will be the SurfaceTexture.
172      * Lock free. Service maintains counter of streams.
173      * Errors: -EBUSY if too many streams created
174      */
175    status_t createStream(int width, int height, int format,
176                          const sp<IGraphicBufferProducer>& bufferProducer,
177                          /*out*/
178                          int* streamId);
179    status_t createStreamCpu(int width, int height, int format,
180                          int heapCount,
181                          /*out*/
182                          sp<CpuConsumer>* cpuConsumer,
183                          int* streamId);
184
185    // Create a request object from a template.
186    status_t createDefaultRequest(int templateId,
187                                 /*out*/
188                                  camera_metadata** request) const;
189
190    // Get number of cameras
191    static int getNumberOfCameras();
192
193    // Get static camera metadata
194    camera_metadata* getCameraInfo(int cameraId);
195
196    // Blocks until a frame is available (CPU streams only)
197    // - Obtain the frame data by calling CpuConsumer::lockNextBuffer
198    // - Release the frame data after use with CpuConsumer::unlockBuffer
199    // Return value:
200    // - >0 - number of frames available to be locked
201    // - <0 - error (refer to error codes)
202    // Error codes:
203    // -ETIMEDOUT if it took too long to get a frame
204    int waitForFrameBuffer(int streamId);
205
206    // Blocks until a metadata result is available
207    // - Obtain the metadata by calling consumeFrameMetadata()
208    // Error codes:
209    // -ETIMEDOUT if it took too long to get a frame
210    status_t waitForFrameMetadata();
211
212    // Get the latest metadata. This is destructive.
213    // - Calling this repeatedly will produce empty metadata objects.
214    // - Use waitForFrameMetadata to sync until new data is available.
215    CameraMetadata consumeFrameMetadata();
216
217    // Convenience method to drop frame buffers (CPU streams only)
218    // Return values:
219    //  >=0 - number of frames dropped (up to count)
220    //  <0  - error code
221    // Error codes:
222    //   BAD_VALUE - invalid streamId or count passed
223    int dropFrameBuffer(int streamId, int count);
224
225    sp<IProCameraUser>         remote();
226
227protected:
228    ////////////////////////////////////////////////////////
229    // IProCameraCallbacks implementation
230    ////////////////////////////////////////////////////////
231    virtual void        notifyCallback(int32_t msgType, int32_t ext,
232                                       int32_t ext2);
233    virtual void        dataCallback(int32_t msgType,
234                                     const sp<IMemory>& dataPtr,
235                                     camera_frame_metadata_t *metadata);
236    virtual void        dataCallbackTimestamp(nsecs_t timestamp,
237                                              int32_t msgType,
238                                              const sp<IMemory>& dataPtr);
239    virtual void        onLockStatusChanged(
240                                IProCameraCallbacks::LockStatus newLockStatus);
241
242    virtual void        onResultReceived(int32_t frameId,
243                                         camera_metadata* result);
244
245    class DeathNotifier: public IBinder::DeathRecipient
246    {
247    public:
248        DeathNotifier() {
249        }
250
251        virtual void binderDied(const wp<IBinder>& who);
252    };
253
254private:
255    ProCamera();
256
257    virtual void binderDied(const wp<IBinder>& who);
258
259    // helper function to obtain camera service handle
260    static const sp<ICameraService>& getCameraService();
261
262    static sp<DeathNotifier> mDeathNotifier;
263
264    sp<IProCameraUser>  mCamera;
265    status_t            mStatus;
266
267    sp<ProCameraListener>  mListener;
268
269    friend class DeathNotifier;
270
271    static  Mutex               mLock;
272    static  sp<ICameraService>  mCameraService;
273
274    class ProFrameListener : public CpuConsumer::FrameAvailableListener {
275    public:
276        ProFrameListener(wp<ProCamera> camera, int streamID) {
277            mCamera = camera;
278            mStreamId = streamID;
279        }
280
281    protected:
282        virtual void onFrameAvailable() {
283            sp<ProCamera> c = mCamera.promote();
284            if (c.get() != NULL) {
285                c->onFrameAvailable(mStreamId);
286            }
287        }
288
289    private:
290        wp<ProCamera> mCamera;
291        int mStreamId;
292    };
293    friend class ProFrameListener;
294
295    struct StreamInfo
296    {
297        StreamInfo(int streamId) {
298            this->streamID = streamId;
299            cpuStream = false;
300            frameReady = 0;
301        }
302
303        StreamInfo() {
304            streamID = -1;
305            cpuStream = false;
306        }
307
308        int  streamID;
309        bool cpuStream;
310        sp<CpuConsumer> cpuConsumer;
311        sp<ProFrameListener> frameAvailableListener;
312        sp<Surface> stc;
313        int frameReady;
314    };
315
316    Condition mWaitCondition;
317    Mutex     mWaitMutex;
318    static const nsecs_t mWaitTimeout = 1000000000; // 1sec
319    KeyedVector<int, StreamInfo> mStreams;
320    bool mMetadataReady;
321    CameraMetadata mLatestMetadata;
322
323    void onFrameAvailable(int streamId);
324
325    StreamInfo& getStreamInfo(int streamId);
326
327
328};
329
330}; // namespace android
331
332#endif
333