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 <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
     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() {
    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