ProCamera.h revision b84d935c179a275a47e07291d2a983daf844de80
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 * Errors: BAD_VALUE if unknown stream ID. 173 * PERMISSION_DENIED if the stream wasn't yours 174 */ 175 status_t deleteStream(int streamId); 176 177 /** 178 * Create a new HW stream, whose sink will be the window. 179 * Lock free. Service maintains counter of streams. 180 * Errors: -EBUSY if too many streams created 181 */ 182 status_t createStream(int width, int height, int format, 183 const sp<Surface>& surface, 184 /*out*/ 185 int* streamId); 186 187 /** 188 * Create a new HW stream, whose sink will be the SurfaceTexture. 189 * Lock free. Service maintains counter of streams. 190 * Errors: -EBUSY if too many streams created 191 */ 192 status_t createStream(int width, int height, int format, 193 const sp<IGraphicBufferProducer>& bufferProducer, 194 /*out*/ 195 int* streamId); 196 status_t createStreamCpu(int width, int height, int format, 197 int heapCount, 198 /*out*/ 199 sp<CpuConsumer>* cpuConsumer, 200 int* streamId); 201 202 // Create a request object from a template. 203 status_t createDefaultRequest(int templateId, 204 /*out*/ 205 camera_metadata** request) const; 206 207 // Get static camera metadata 208 camera_metadata* getCameraInfo(int cameraId); 209 210 // Blocks until a frame is available (CPU streams only) 211 // - Obtain the frame data by calling CpuConsumer::lockNextBuffer 212 // - Release the frame data after use with CpuConsumer::unlockBuffer 213 // Return value: 214 // - >0 - number of frames available to be locked 215 // - <0 - error (refer to error codes) 216 // Error codes: 217 // -ETIMEDOUT if it took too long to get a frame 218 int waitForFrameBuffer(int streamId); 219 220 // Blocks until a metadata result is available 221 // - Obtain the metadata by calling consumeFrameMetadata() 222 // Error codes: 223 // -ETIMEDOUT if it took too long to get a frame 224 status_t waitForFrameMetadata(); 225 226 // Get the latest metadata. This is destructive. 227 // - Calling this repeatedly will produce empty metadata objects. 228 // - Use waitForFrameMetadata to sync until new data is available. 229 CameraMetadata consumeFrameMetadata(); 230 231 // Convenience method to drop frame buffers (CPU streams only) 232 // Return values: 233 // >=0 - number of frames dropped (up to count) 234 // <0 - error code 235 // Error codes: 236 // BAD_VALUE - invalid streamId or count passed 237 int dropFrameBuffer(int streamId, int count); 238 239protected: 240 //////////////////////////////////////////////////////// 241 // IProCameraCallbacks implementation 242 //////////////////////////////////////////////////////// 243 virtual void notifyCallback(int32_t msgType, int32_t ext, 244 int32_t ext2); 245 virtual void dataCallback(int32_t msgType, 246 const sp<IMemory>& dataPtr, 247 camera_frame_metadata_t *metadata); 248 virtual void dataCallbackTimestamp(nsecs_t timestamp, 249 int32_t msgType, 250 const sp<IMemory>& dataPtr); 251 virtual void onLockStatusChanged( 252 IProCameraCallbacks::LockStatus newLockStatus); 253 254 virtual void onResultReceived(int32_t frameId, 255 camera_metadata* result); 256private: 257 ProCamera(int cameraId); 258 259 class ProFrameListener : public CpuConsumer::FrameAvailableListener { 260 public: 261 ProFrameListener(wp<ProCamera> camera, int streamID) { 262 mCamera = camera; 263 mStreamId = streamID; 264 } 265 266 protected: 267 virtual void onFrameAvailable() { 268 sp<ProCamera> c = mCamera.promote(); 269 if (c.get() != NULL) { 270 c->onFrameAvailable(mStreamId); 271 } 272 } 273 274 private: 275 wp<ProCamera> mCamera; 276 int mStreamId; 277 }; 278 friend class ProFrameListener; 279 280 struct StreamInfo 281 { 282 StreamInfo(int streamId) { 283 this->streamID = streamId; 284 cpuStream = false; 285 frameReady = 0; 286 } 287 288 StreamInfo() { 289 streamID = -1; 290 cpuStream = false; 291 } 292 293 int streamID; 294 bool cpuStream; 295 sp<CpuConsumer> cpuConsumer; 296 sp<ProFrameListener> frameAvailableListener; 297 sp<Surface> stc; 298 int frameReady; 299 }; 300 301 Condition mWaitCondition; 302 Mutex mWaitMutex; 303 static const nsecs_t mWaitTimeout = 1000000000; // 1sec 304 KeyedVector<int, StreamInfo> mStreams; 305 bool mMetadataReady; 306 CameraMetadata mLatestMetadata; 307 308 void onFrameAvailable(int streamId); 309 310 StreamInfo& getStreamInfo(int streamId); 311 312 friend class CameraBase; 313}; 314 315}; // namespace android 316 317#endif 318