ProCamera.h revision fa4cf9d310685b4c25877cba772ff7da84caf517
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 <gui/Surface.h>
31
32#include <utils/Condition.h>
33#include <utils/Mutex.h>
34
35#include <camera/CameraBase.h>
36
37struct camera_metadata;
38
39namespace android {
40
41// All callbacks on this class are concurrent
42// (they come from separate threads)
43class ProCameraListener : virtual public RefBase
44{
45public:
46    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
47
48    // Lock has been acquired. Write operations now available.
49    virtual void onLockAcquired() = 0;
50    // Lock has been released with exclusiveUnlock.
51    virtual void onLockReleased() = 0;
52    // Lock has been stolen by another client.
53    virtual void onLockStolen() = 0;
54
55    // Lock free.
56    virtual void onTriggerNotify(int32_t msgType, int32_t ext1, int32_t ext2)
57                                                                            = 0;
58    // onFrameAvailable and OnResultReceived can come in with any order,
59    // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them
60
61    /**
62      * A new metadata buffer has been received.
63      * -- Ownership of request passes on to the callee, free with
64      *    free_camera_metadata.
65      */
66    virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0;
67
68    // TODO: make onFrameAvailable pure virtual
69
70    // A new frame buffer has been received for this stream.
71    // -- This callback only fires for createStreamCpu streams
72    // -- A buffer may be obtained by calling cpuConsumer->lockNextBuffer
73    // -- Use buf.timestamp to correlate with result'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};
81
82class ProCamera;
83
84template <>
85struct CameraTraits<ProCamera>
86{
87    typedef ProCameraListener     TCamListener;
88    typedef IProCameraUser        TCamUser;
89    typedef IProCameraCallbacks   TCamCallbacks;
90};
91
92class ProCamera :
93    public CameraBase<ProCamera>,
94    public BnProCameraCallbacks
95{
96public:
97    /**
98     * Connect a shared camera. By default access is restricted to read only
99     * (Lock free) operations. To be able to submit custom requests a lock needs
100     * to be acquired with exclusive[Try]Lock.
101     */
102    static sp<ProCamera> connect(int cameraId);
103    virtual ~ProCamera();
104
105    /**
106     * Exclusive Locks:
107     * - We may request exclusive access to a camera if no other
108     *   clients are using the camera. This works as a traditional
109     *   client, writing/reading any camera state.
110     * - An application opening the camera (a regular 'Camera') will
111     *   always steal away the exclusive lock from a ProCamera,
112     *   this will call onLockReleased.
113     * - onLockAcquired will be called again once it is possible
114     *   to again exclusively lock the camera.
115     *
116     */
117
118    /**
119     * All exclusiveLock/unlock functions are asynchronous. The remote endpoint
120     * shall not block while waiting to acquire the lock. Instead the lock
121     * notifications will come in asynchronously on the listener.
122     */
123
124    /**
125      * Attempt to acquire the lock instantly (non-blocking)
126      * - If this succeeds, you do not need to wait for onLockAcquired
127      *   but the event will still be fired
128      *
129      * Returns -EBUSY if already locked. 0 on success.
130      */
131    status_t exclusiveTryLock();
132    // always returns 0. wait for onLockAcquired before lock is acquired.
133    status_t exclusiveLock();
134    // release a lock if we have one, or cancel the lock request.
135    status_t exclusiveUnlock();
136
137    // exclusive lock = do whatever we want. no lock = read only.
138    bool hasExclusiveLock();
139
140    /**
141     * < 0 error, >= 0 the request ID. streaming to have the request repeat
142     *    until cancelled.
143     * The request queue is flushed when a lock is released or stolen
144     *    if not locked will return PERMISSION_DENIED
145     */
146    int submitRequest(const struct camera_metadata* metadata,
147                                                        bool streaming = false);
148    // if not locked will return PERMISSION_DENIED, BAD_VALUE if requestId bad
149    status_t cancelRequest(int requestId);
150
151    /**
152     * Ask for a stream to be enabled.
153     * Lock free. Service maintains counter of streams.
154     */
155    status_t requestStream(int streamId);
156// TODO: remove requestStream, its useless.
157
158    /**
159      * Delete a stream.
160      * Lock free.
161      *
162      * NOTE: As a side effect this cancels ALL streaming requests.
163      *
164      * Errors: BAD_VALUE if unknown stream ID.
165      *         PERMISSION_DENIED if the stream wasn't yours
166      */
167    status_t deleteStream(int streamId);
168
169    /**
170      * Create a new HW stream, whose sink will be the window.
171      * Lock free. Service maintains counter of streams.
172      * Errors: -EBUSY if too many streams created
173      */
174    status_t createStream(int width, int height, int format,
175                          const sp<Surface>& surface,
176                          /*out*/
177                          int* streamId);
178
179    /**
180      * Create a new HW stream, whose sink will be the SurfaceTexture.
181      * Lock free. Service maintains counter of streams.
182      * Errors: -EBUSY if too many streams created
183      */
184    status_t createStream(int width, int height, int format,
185                          const sp<IGraphicBufferProducer>& bufferProducer,
186                          /*out*/
187                          int* streamId);
188    status_t createStreamCpu(int width, int height, int format,
189                          int heapCount,
190                          /*out*/
191                          sp<CpuConsumer>* cpuConsumer,
192                          int* streamId);
193    status_t createStreamCpu(int width, int height, int format,
194                          int heapCount,
195                          bool synchronousMode,
196                          /*out*/
197                          sp<CpuConsumer>* cpuConsumer,
198                          int* streamId);
199
200    // Create a request object from a template.
201    status_t createDefaultRequest(int templateId,
202                                 /*out*/
203                                  camera_metadata** request) const;
204
205    // Get static camera metadata
206    camera_metadata* getCameraInfo(int cameraId);
207
208    // Blocks until a frame is available (CPU streams only)
209    // - Obtain the frame data by calling CpuConsumer::lockNextBuffer
210    // - Release the frame data after use with CpuConsumer::unlockBuffer
211    // Return value:
212    // - >0 - number of frames available to be locked
213    // - <0 - error (refer to error codes)
214    // Error codes:
215    // -ETIMEDOUT if it took too long to get a frame
216    int waitForFrameBuffer(int streamId);
217
218    // Blocks until a metadata result is available
219    // - Obtain the metadata by calling consumeFrameMetadata()
220    // Error codes:
221    // -ETIMEDOUT if it took too long to get a frame
222    status_t waitForFrameMetadata();
223
224    // Get the latest metadata. This is destructive.
225    // - Calling this repeatedly will produce empty metadata objects.
226    // - Use waitForFrameMetadata to sync until new data is available.
227    CameraMetadata consumeFrameMetadata();
228
229    // Convenience method to drop frame buffers (CPU streams only)
230    // Return values:
231    //  >=0 - number of frames dropped (up to count)
232    //  <0  - error code
233    // Error codes:
234    //   BAD_VALUE - invalid streamId or count passed
235    int dropFrameBuffer(int streamId, int count);
236
237protected:
238    ////////////////////////////////////////////////////////
239    // IProCameraCallbacks implementation
240    ////////////////////////////////////////////////////////
241    virtual void        notifyCallback(int32_t msgType,
242                                       int32_t ext,
243                                       int32_t ext2);
244
245    virtual void        onLockStatusChanged(
246                                IProCameraCallbacks::LockStatus newLockStatus);
247
248    virtual void        onResultReceived(int32_t frameId,
249                                         camera_metadata* result);
250private:
251    ProCamera(int cameraId);
252
253    class ProFrameListener : public CpuConsumer::FrameAvailableListener {
254    public:
255        ProFrameListener(wp<ProCamera> camera, int streamID) {
256            mCamera = camera;
257            mStreamId = streamID;
258        }
259
260    protected:
261        virtual void onFrameAvailable() {
262            sp<ProCamera> c = mCamera.promote();
263            if (c.get() != NULL) {
264                c->onFrameAvailable(mStreamId);
265            }
266        }
267
268    private:
269        wp<ProCamera> mCamera;
270        int mStreamId;
271    };
272    friend class ProFrameListener;
273
274    struct StreamInfo
275    {
276        StreamInfo(int streamId) {
277            this->streamID = streamId;
278            cpuStream = false;
279            frameReady = 0;
280        }
281
282        StreamInfo() {
283            streamID = -1;
284            cpuStream = false;
285        }
286
287        int  streamID;
288        bool cpuStream;
289        sp<CpuConsumer> cpuConsumer;
290        bool synchronousMode;
291        sp<ProFrameListener> frameAvailableListener;
292        sp<Surface> stc;
293        int frameReady;
294    };
295
296    Condition mWaitCondition;
297    Mutex     mWaitMutex;
298    static const nsecs_t mWaitTimeout = 1000000000; // 1sec
299    KeyedVector<int, StreamInfo> mStreams;
300    bool mMetadataReady;
301    CameraMetadata mLatestMetadata;
302
303    void onFrameAvailable(int streamId);
304
305    StreamInfo& getStreamInfo(int streamId);
306
307    friend class CameraBase;
308};
309
310}; // namespace android
311
312#endif
313