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