| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 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_SERVERS_CAMERA3_STREAM_H | 
|  | 18 | #define ANDROID_SERVERS_CAMERA3_STREAM_H | 
|  | 19 |  | 
|  | 20 | #include <gui/Surface.h> | 
|  | 21 | #include <utils/RefBase.h> | 
|  | 22 | #include <utils/String8.h> | 
|  | 23 | #include <utils/String16.h> | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 24 | #include <utils/List.h> | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 25 |  | 
|  | 26 | #include "hardware/camera3.h" | 
|  | 27 |  | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 28 | #include "Camera3StreamBufferListener.h" | 
|  | 29 | #include "Camera3StreamInterface.h" | 
|  | 30 |  | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 31 | namespace android { | 
|  | 32 |  | 
|  | 33 | namespace camera3 { | 
|  | 34 |  | 
|  | 35 | /** | 
|  | 36 | * A class for managing a single stream of input or output data from the camera | 
|  | 37 | * device. | 
|  | 38 | * | 
|  | 39 | * The stream has an internal state machine to track whether it's | 
|  | 40 | * connected/configured/etc. | 
|  | 41 | * | 
|  | 42 | * States: | 
|  | 43 | * | 
|  | 44 | *  STATE_ERROR: A serious error has occurred, stream is unusable. Outstanding | 
|  | 45 | *    buffers may still be returned. | 
|  | 46 | * | 
|  | 47 | *  STATE_CONSTRUCTED: The stream is ready for configuration, but buffers cannot | 
|  | 48 | *    be gotten yet. Not connected to any endpoint, no buffers are registered | 
|  | 49 | *    with the HAL. | 
|  | 50 | * | 
|  | 51 | *  STATE_IN_CONFIG: Configuration has started, but not yet concluded. During this | 
|  | 52 | *    time, the usage, max_buffers, and priv fields of camera3_stream returned by | 
|  | 53 | *    startConfiguration() may be modified. | 
|  | 54 | * | 
|  | 55 | *  STATE_IN_RE_CONFIG: Configuration has started, and the stream has been | 
|  | 56 | *    configured before. Need to track separately from IN_CONFIG to avoid | 
|  | 57 | *    re-registering buffers with HAL. | 
|  | 58 | * | 
|  | 59 | *  STATE_CONFIGURED: Stream is configured, and has registered buffers with the | 
|  | 60 | *    HAL. The stream's getBuffer/returnBuffer work. The priv pointer may still be | 
|  | 61 | *    modified. | 
|  | 62 | * | 
|  | 63 | * Transition table: | 
|  | 64 | * | 
|  | 65 | *    <none>               => STATE_CONSTRUCTED: | 
|  | 66 | *        When constructed with valid arguments | 
|  | 67 | *    <none>               => STATE_ERROR: | 
|  | 68 | *        When constructed with invalid arguments | 
|  | 69 | *    STATE_CONSTRUCTED    => STATE_IN_CONFIG: | 
|  | 70 | *        When startConfiguration() is called | 
|  | 71 | *    STATE_IN_CONFIG      => STATE_CONFIGURED: | 
|  | 72 | *        When finishConfiguration() is called | 
|  | 73 | *    STATE_IN_CONFIG      => STATE_ERROR: | 
|  | 74 | *        When finishConfiguration() fails to allocate or register buffers. | 
|  | 75 | *    STATE_CONFIGURED     => STATE_IN_RE_CONFIG:  * | 
|  | 76 | *        When startConfiguration() is called again, after making sure stream is | 
|  | 77 | *        idle with waitUntilIdle(). | 
|  | 78 | *    STATE_IN_RE_CONFIG   => STATE_CONFIGURED: | 
|  | 79 | *        When finishConfiguration() is called. | 
|  | 80 | *    STATE_IN_RE_CONFIG   => STATE_ERROR: | 
|  | 81 | *        When finishConfiguration() fails to allocate or register buffers. | 
|  | 82 | *    STATE_CONFIGURED     => STATE_CONSTRUCTED: | 
|  | 83 | *        When disconnect() is called after making sure stream is idle with | 
|  | 84 | *        waitUntilIdle(). | 
| Igor Murashkin | 13d315e | 2014-04-03 18:09:04 -0700 | [diff] [blame] | 85 | * | 
|  | 86 | * Status Tracking: | 
|  | 87 | *    Each stream is tracked by StatusTracker as a separate component, | 
|  | 88 | *    depending on the handed out buffer count. The state must be STATE_CONFIGURED | 
|  | 89 | *    in order for the component to be marked. | 
|  | 90 | * | 
|  | 91 | *    It's marked in one of two ways: | 
|  | 92 | * | 
|  | 93 | *    - ACTIVE: One or more buffers have been handed out (with #getBuffer). | 
|  | 94 | *    - IDLE: All buffers have been returned (with #returnBuffer), and their | 
|  | 95 | *          respective release_fence(s) have been signaled. | 
|  | 96 | * | 
|  | 97 | *    A typical use case is output streams. When the HAL has any buffers | 
|  | 98 | *    dequeued, the stream is marked ACTIVE. When the HAL returns all buffers | 
|  | 99 | *    (e.g. if no capture requests are active), the stream is marked IDLE. | 
|  | 100 | *    In this use case, the app consumer does not affect the component status. | 
|  | 101 | * | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 102 | */ | 
|  | 103 | class Camera3Stream : | 
|  | 104 | protected camera3_stream, | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 105 | public virtual Camera3StreamInterface, | 
|  | 106 | public virtual RefBase { | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 107 | public: | 
|  | 108 |  | 
|  | 109 | virtual ~Camera3Stream(); | 
|  | 110 |  | 
|  | 111 | static Camera3Stream*       cast(camera3_stream *stream); | 
|  | 112 | static const Camera3Stream* cast(const camera3_stream *stream); | 
|  | 113 |  | 
|  | 114 | /** | 
|  | 115 | * Get the stream's ID | 
|  | 116 | */ | 
|  | 117 | int              getId() const; | 
|  | 118 |  | 
|  | 119 | /** | 
|  | 120 | * Get the stream's dimensions and format | 
|  | 121 | */ | 
| Eino-Ville Talvala | 3d82c0d | 2015-02-23 15:19:19 -0800 | [diff] [blame] | 122 | uint32_t          getWidth() const; | 
|  | 123 | uint32_t          getHeight() const; | 
|  | 124 | int               getFormat() const; | 
|  | 125 | android_dataspace getDataSpace() const; | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 126 |  | 
|  | 127 | /** | 
|  | 128 | * Start the stream configuration process. Returns a handle to the stream's | 
|  | 129 | * information to be passed into the HAL device's configure_streams call. | 
|  | 130 | * | 
|  | 131 | * Until finishConfiguration() is called, no other methods on the stream may be | 
|  | 132 | * called. The usage and max_buffers fields of camera3_stream may be modified | 
|  | 133 | * between start/finishConfiguration, but may not be changed after that. | 
|  | 134 | * The priv field of camera3_stream may be modified at any time after | 
|  | 135 | * startConfiguration. | 
|  | 136 | * | 
|  | 137 | * Returns NULL in case of error starting configuration. | 
|  | 138 | */ | 
|  | 139 | camera3_stream*  startConfiguration(); | 
|  | 140 |  | 
|  | 141 | /** | 
|  | 142 | * Check if the stream is mid-configuration (start has been called, but not | 
|  | 143 | * finish).  Used for lazy completion of configuration. | 
|  | 144 | */ | 
|  | 145 | bool             isConfiguring() const; | 
|  | 146 |  | 
|  | 147 | /** | 
|  | 148 | * Completes the stream configuration process. During this call, the stream | 
|  | 149 | * may call the device's register_stream_buffers() method. The stream | 
|  | 150 | * information structure returned by startConfiguration() may no longer be | 
|  | 151 | * modified after this call, but can still be read until the destruction of | 
|  | 152 | * the stream. | 
|  | 153 | * | 
|  | 154 | * Returns: | 
|  | 155 | *   OK on a successful configuration | 
|  | 156 | *   NO_INIT in case of a serious error from the HAL device | 
|  | 157 | *   NO_MEMORY in case of an error registering buffers | 
|  | 158 | *   INVALID_OPERATION in case connecting to the consumer failed | 
|  | 159 | */ | 
|  | 160 | status_t         finishConfiguration(camera3_device *hal3Device); | 
|  | 161 |  | 
|  | 162 | /** | 
| Eino-Ville Talvala | 1754351 | 2014-08-06 14:32:02 -0700 | [diff] [blame] | 163 | * Cancels the stream configuration process. This returns the stream to the | 
|  | 164 | * initial state, allowing it to be configured again later. | 
|  | 165 | * This is done if the HAL rejects the proposed combined stream configuration | 
|  | 166 | */ | 
|  | 167 | status_t         cancelConfiguration(); | 
|  | 168 |  | 
|  | 169 | /** | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 170 | * Fill in the camera3_stream_buffer with the next valid buffer for this | 
|  | 171 | * stream, to hand over to the HAL. | 
|  | 172 | * | 
|  | 173 | * This method may only be called once finishConfiguration has been called. | 
|  | 174 | * For bidirectional streams, this method applies to the output-side | 
|  | 175 | * buffers. | 
|  | 176 | * | 
|  | 177 | */ | 
|  | 178 | status_t         getBuffer(camera3_stream_buffer *buffer); | 
|  | 179 |  | 
|  | 180 | /** | 
|  | 181 | * Return a buffer to the stream after use by the HAL. | 
|  | 182 | * | 
|  | 183 | * This method may only be called for buffers provided by getBuffer(). | 
|  | 184 | * For bidirectional streams, this method applies to the output-side buffers | 
|  | 185 | */ | 
|  | 186 | status_t         returnBuffer(const camera3_stream_buffer &buffer, | 
|  | 187 | nsecs_t timestamp); | 
|  | 188 |  | 
|  | 189 | /** | 
| Igor Murashkin | 5a269fa | 2013-04-15 14:59:22 -0700 | [diff] [blame] | 190 | * Fill in the camera3_stream_buffer with the next valid buffer for this | 
|  | 191 | * stream, to hand over to the HAL. | 
|  | 192 | * | 
|  | 193 | * This method may only be called once finishConfiguration has been called. | 
|  | 194 | * For bidirectional streams, this method applies to the input-side | 
|  | 195 | * buffers. | 
|  | 196 | * | 
|  | 197 | */ | 
|  | 198 | status_t         getInputBuffer(camera3_stream_buffer *buffer); | 
|  | 199 |  | 
|  | 200 | /** | 
|  | 201 | * Return a buffer to the stream after use by the HAL. | 
|  | 202 | * | 
|  | 203 | * This method may only be called for buffers provided by getBuffer(). | 
|  | 204 | * For bidirectional streams, this method applies to the input-side buffers | 
|  | 205 | */ | 
|  | 206 | status_t         returnInputBuffer(const camera3_stream_buffer &buffer); | 
|  | 207 |  | 
|  | 208 | /** | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 209 | * Whether any of the stream's buffers are currently in use by the HAL, | 
|  | 210 | * including buffers that have been returned but not yet had their | 
|  | 211 | * release fence signaled. | 
|  | 212 | */ | 
|  | 213 | bool             hasOutstandingBuffers() const; | 
|  | 214 |  | 
|  | 215 | enum { | 
|  | 216 | TIMEOUT_NEVER = -1 | 
|  | 217 | }; | 
| Eino-Ville Talvala | f1e98d8 | 2013-09-06 09:32:43 -0700 | [diff] [blame] | 218 |  | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 219 | /** | 
| Eino-Ville Talvala | f1e98d8 | 2013-09-06 09:32:43 -0700 | [diff] [blame] | 220 | * Set the status tracker to notify about idle transitions | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 221 | */ | 
| Eino-Ville Talvala | f1e98d8 | 2013-09-06 09:32:43 -0700 | [diff] [blame] | 222 | virtual status_t setStatusTracker(sp<StatusTracker> statusTracker); | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 223 |  | 
|  | 224 | /** | 
|  | 225 | * Disconnect stream from its non-HAL endpoint. After this, | 
|  | 226 | * start/finishConfiguration must be called before the stream can be used | 
|  | 227 | * again. This cannot be called if the stream has outstanding dequeued | 
|  | 228 | * buffers. | 
|  | 229 | */ | 
|  | 230 | status_t         disconnect(); | 
|  | 231 |  | 
|  | 232 | /** | 
|  | 233 | * Debug dump of the stream's state. | 
|  | 234 | */ | 
|  | 235 | virtual void     dump(int fd, const Vector<String16> &args) const = 0; | 
|  | 236 |  | 
| Zhijun He | f0d962a | 2014-06-30 10:24:11 -0700 | [diff] [blame] | 237 | /** | 
|  | 238 | * Add a camera3 buffer listener. Adding the same listener twice has | 
|  | 239 | * no effect. | 
|  | 240 | */ | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 241 | void             addBufferListener( | 
|  | 242 | wp<Camera3StreamBufferListener> listener); | 
| Zhijun He | f0d962a | 2014-06-30 10:24:11 -0700 | [diff] [blame] | 243 |  | 
|  | 244 | /** | 
|  | 245 | * Remove a camera3 buffer listener. Removing the same listener twice | 
|  | 246 | * or the listener that was never added has no effect. | 
|  | 247 | */ | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 248 | void             removeBufferListener( | 
|  | 249 | const sp<Camera3StreamBufferListener>& listener); | 
|  | 250 |  | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 251 | protected: | 
|  | 252 | const int mId; | 
|  | 253 | const String8 mName; | 
|  | 254 | // Zero for formats with fixed buffer size for given dimensions. | 
|  | 255 | const size_t mMaxSize; | 
|  | 256 |  | 
|  | 257 | enum { | 
|  | 258 | STATE_ERROR, | 
|  | 259 | STATE_CONSTRUCTED, | 
|  | 260 | STATE_IN_CONFIG, | 
|  | 261 | STATE_IN_RECONFIG, | 
|  | 262 | STATE_CONFIGURED | 
|  | 263 | } mState; | 
|  | 264 |  | 
|  | 265 | mutable Mutex mLock; | 
|  | 266 |  | 
|  | 267 | Camera3Stream(int id, camera3_stream_type type, | 
| Eino-Ville Talvala | 3d82c0d | 2015-02-23 15:19:19 -0800 | [diff] [blame] | 268 | uint32_t width, uint32_t height, size_t maxSize, int format, | 
| Yin-Chia Yeh | b97babb | 2015-03-12 13:42:44 -0700 | [diff] [blame^] | 269 | android_dataspace dataSpace, camera3_stream_rotation_t rotation); | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 270 |  | 
|  | 271 | /** | 
|  | 272 | * Interface to be implemented by derived classes | 
|  | 273 | */ | 
|  | 274 |  | 
|  | 275 | // getBuffer / returnBuffer implementations | 
|  | 276 |  | 
|  | 277 | // Since camera3_stream_buffer includes a raw pointer to the stream, | 
|  | 278 | // cast to camera3_stream*, implementations must increment the | 
|  | 279 | // refcount of the stream manually in getBufferLocked, and decrement it in | 
|  | 280 | // returnBufferLocked. | 
| Igor Murashkin | 5a269fa | 2013-04-15 14:59:22 -0700 | [diff] [blame] | 281 | virtual status_t getBufferLocked(camera3_stream_buffer *buffer); | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 282 | virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer, | 
| Igor Murashkin | 5a269fa | 2013-04-15 14:59:22 -0700 | [diff] [blame] | 283 | nsecs_t timestamp); | 
|  | 284 | virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer); | 
|  | 285 | virtual status_t returnInputBufferLocked( | 
|  | 286 | const camera3_stream_buffer &buffer); | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 287 | virtual bool     hasOutstandingBuffersLocked() const = 0; | 
| Igor Murashkin | e2172be | 2013-05-28 15:31:39 -0700 | [diff] [blame] | 288 | // Can return -ENOTCONN when we are already disconnected (not an error) | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 289 | virtual status_t disconnectLocked() = 0; | 
|  | 290 |  | 
|  | 291 | // Configure the buffer queue interface to the other end of the stream, | 
|  | 292 | // after the HAL has provided usage and max_buffers values. After this call, | 
|  | 293 | // the stream must be ready to produce all buffers for registration with | 
|  | 294 | // HAL. | 
|  | 295 | virtual status_t configureQueueLocked() = 0; | 
|  | 296 |  | 
|  | 297 | // Get the total number of buffers in the queue | 
|  | 298 | virtual size_t   getBufferCountLocked() = 0; | 
|  | 299 |  | 
| Zhijun He | 6adc9cc | 2014-04-15 14:09:55 -0700 | [diff] [blame] | 300 | // Get handout output buffer count. | 
|  | 301 | virtual size_t   getHandoutOutputBufferCountLocked() = 0; | 
|  | 302 |  | 
|  | 303 | // Get handout input buffer count. | 
|  | 304 | virtual size_t   getHandoutInputBufferCountLocked() = 0; | 
|  | 305 |  | 
| Eino-Ville Talvala | b2f5b19 | 2013-07-30 14:36:03 -0700 | [diff] [blame] | 306 | // Get the usage flags for the other endpoint, or return | 
|  | 307 | // INVALID_OPERATION if they cannot be obtained. | 
|  | 308 | virtual status_t getEndpointUsage(uint32_t *usage) = 0; | 
|  | 309 |  | 
| Eino-Ville Talvala | f1e98d8 | 2013-09-06 09:32:43 -0700 | [diff] [blame] | 310 | // Tracking for idle state | 
|  | 311 | wp<StatusTracker> mStatusTracker; | 
|  | 312 | // Status tracker component ID | 
|  | 313 | int mStatusId; | 
|  | 314 |  | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 315 | private: | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 316 | uint32_t oldUsage; | 
|  | 317 | uint32_t oldMaxBuffers; | 
| Zhijun He | 6adc9cc | 2014-04-15 14:09:55 -0700 | [diff] [blame] | 318 | Condition mOutputBufferReturnedSignal; | 
|  | 319 | Condition mInputBufferReturnedSignal; | 
|  | 320 | static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 321 |  | 
|  | 322 | // Gets all buffers from endpoint and registers them with the HAL. | 
|  | 323 | status_t registerBuffersLocked(camera3_device *hal3Device); | 
|  | 324 |  | 
| Igor Murashkin | 2fba584 | 2013-04-22 14:03:54 -0700 | [diff] [blame] | 325 | void fireBufferListenersLocked(const camera3_stream_buffer& buffer, | 
|  | 326 | bool acquired, bool output); | 
|  | 327 | List<wp<Camera3StreamBufferListener> > mBufferListenerList; | 
|  | 328 |  | 
| Eino-Ville Talvala | fd58f1a | 2013-03-06 16:20:06 -0800 | [diff] [blame] | 329 | }; // class Camera3Stream | 
|  | 330 |  | 
|  | 331 | }; // namespace camera3 | 
|  | 332 |  | 
|  | 333 | }; // namespace android | 
|  | 334 |  | 
|  | 335 | #endif |