ProCamera.h revision ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98
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