Home | History | Annotate | Download | only in camera
      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 
     37 struct camera_metadata;
     38 
     39 namespace android {
     40 
     41 // All callbacks on this class are concurrent
     42 // (they come from separate threads)
     43 class ProCameraListener : virtual public RefBase
     44 {
     45 public:
     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 
     82 class ProCamera;
     83 
     84 template <>
     85 struct CameraTraits<ProCamera>
     86 {
     87     typedef ProCameraListener     TCamListener;
     88     typedef IProCameraUser        TCamUser;
     89     typedef IProCameraCallbacks   TCamCallbacks;
     90 };
     91 
     92 class ProCamera :
     93     public CameraBase<ProCamera>,
     94     public BnProCameraCallbacks
     95 {
     96 public:
     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 
    237 protected:
    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);
    250 private:
    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