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