Camera3Stream.h revision 1754351d9199721e7e7943461689e399ef015260
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>
24#include <utils/List.h>
25
26#include "hardware/camera3.h"
27
28#include "Camera3StreamBufferListener.h"
29#include "Camera3StreamInterface.h"
30
31namespace android {
32
33namespace 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().
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 *
102 */
103class Camera3Stream :
104        protected camera3_stream,
105        public virtual Camera3StreamInterface,
106        public virtual RefBase {
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     */
122    uint32_t         getWidth() const;
123    uint32_t         getHeight() const;
124    int              getFormat() const;
125
126    /**
127     * Start the stream configuration process. Returns a handle to the stream's
128     * information to be passed into the HAL device's configure_streams call.
129     *
130     * Until finishConfiguration() is called, no other methods on the stream may be
131     * called. The usage and max_buffers fields of camera3_stream may be modified
132     * between start/finishConfiguration, but may not be changed after that.
133     * The priv field of camera3_stream may be modified at any time after
134     * startConfiguration.
135     *
136     * Returns NULL in case of error starting configuration.
137     */
138    camera3_stream*  startConfiguration();
139
140    /**
141     * Check if the stream is mid-configuration (start has been called, but not
142     * finish).  Used for lazy completion of configuration.
143     */
144    bool             isConfiguring() const;
145
146    /**
147     * Completes the stream configuration process. During this call, the stream
148     * may call the device's register_stream_buffers() method. The stream
149     * information structure returned by startConfiguration() may no longer be
150     * modified after this call, but can still be read until the destruction of
151     * the stream.
152     *
153     * Returns:
154     *   OK on a successful configuration
155     *   NO_INIT in case of a serious error from the HAL device
156     *   NO_MEMORY in case of an error registering buffers
157     *   INVALID_OPERATION in case connecting to the consumer failed
158     */
159    status_t         finishConfiguration(camera3_device *hal3Device);
160
161    /**
162     * Cancels the stream configuration process. This returns the stream to the
163     * initial state, allowing it to be configured again later.
164     * This is done if the HAL rejects the proposed combined stream configuration
165     */
166    status_t         cancelConfiguration();
167
168    /**
169     * Fill in the camera3_stream_buffer with the next valid buffer for this
170     * stream, to hand over to the HAL.
171     *
172     * This method may only be called once finishConfiguration has been called.
173     * For bidirectional streams, this method applies to the output-side
174     * buffers.
175     *
176     */
177    status_t         getBuffer(camera3_stream_buffer *buffer);
178
179    /**
180     * Return a buffer to the stream after use by the HAL.
181     *
182     * This method may only be called for buffers provided by getBuffer().
183     * For bidirectional streams, this method applies to the output-side buffers
184     */
185    status_t         returnBuffer(const camera3_stream_buffer &buffer,
186            nsecs_t timestamp);
187
188    /**
189     * Fill in the camera3_stream_buffer with the next valid buffer for this
190     * stream, to hand over to the HAL.
191     *
192     * This method may only be called once finishConfiguration has been called.
193     * For bidirectional streams, this method applies to the input-side
194     * buffers.
195     *
196     */
197    status_t         getInputBuffer(camera3_stream_buffer *buffer);
198
199    /**
200     * Return a buffer to the stream after use by the HAL.
201     *
202     * This method may only be called for buffers provided by getBuffer().
203     * For bidirectional streams, this method applies to the input-side buffers
204     */
205    status_t         returnInputBuffer(const camera3_stream_buffer &buffer);
206
207    /**
208     * Whether any of the stream's buffers are currently in use by the HAL,
209     * including buffers that have been returned but not yet had their
210     * release fence signaled.
211     */
212    bool             hasOutstandingBuffers() const;
213
214    enum {
215        TIMEOUT_NEVER = -1
216    };
217
218    /**
219     * Set the status tracker to notify about idle transitions
220     */
221    virtual status_t setStatusTracker(sp<StatusTracker> statusTracker);
222
223    /**
224     * Disconnect stream from its non-HAL endpoint. After this,
225     * start/finishConfiguration must be called before the stream can be used
226     * again. This cannot be called if the stream has outstanding dequeued
227     * buffers.
228     */
229    status_t         disconnect();
230
231    /**
232     * Debug dump of the stream's state.
233     */
234    virtual void     dump(int fd, const Vector<String16> &args) const = 0;
235
236    /**
237     * Add a camera3 buffer listener. Adding the same listener twice has
238     * no effect.
239     */
240    void             addBufferListener(
241            wp<Camera3StreamBufferListener> listener);
242
243    /**
244     * Remove a camera3 buffer listener. Removing the same listener twice
245     * or the listener that was never added has no effect.
246     */
247    void             removeBufferListener(
248            const sp<Camera3StreamBufferListener>& listener);
249
250  protected:
251    const int mId;
252    const String8 mName;
253    // Zero for formats with fixed buffer size for given dimensions.
254    const size_t mMaxSize;
255
256    enum {
257        STATE_ERROR,
258        STATE_CONSTRUCTED,
259        STATE_IN_CONFIG,
260        STATE_IN_RECONFIG,
261        STATE_CONFIGURED
262    } mState;
263
264    mutable Mutex mLock;
265
266    Camera3Stream(int id, camera3_stream_type type,
267            uint32_t width, uint32_t height, size_t maxSize, int format);
268
269    /**
270     * Interface to be implemented by derived classes
271     */
272
273    // getBuffer / returnBuffer implementations
274
275    // Since camera3_stream_buffer includes a raw pointer to the stream,
276    // cast to camera3_stream*, implementations must increment the
277    // refcount of the stream manually in getBufferLocked, and decrement it in
278    // returnBufferLocked.
279    virtual status_t getBufferLocked(camera3_stream_buffer *buffer);
280    virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
281            nsecs_t timestamp);
282    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
283    virtual status_t returnInputBufferLocked(
284            const camera3_stream_buffer &buffer);
285    virtual bool     hasOutstandingBuffersLocked() const = 0;
286    // Can return -ENOTCONN when we are already disconnected (not an error)
287    virtual status_t disconnectLocked() = 0;
288
289    // Configure the buffer queue interface to the other end of the stream,
290    // after the HAL has provided usage and max_buffers values. After this call,
291    // the stream must be ready to produce all buffers for registration with
292    // HAL.
293    virtual status_t configureQueueLocked() = 0;
294
295    // Get the total number of buffers in the queue
296    virtual size_t   getBufferCountLocked() = 0;
297
298    // Get handout output buffer count.
299    virtual size_t   getHandoutOutputBufferCountLocked() = 0;
300
301    // Get handout input buffer count.
302    virtual size_t   getHandoutInputBufferCountLocked() = 0;
303
304    // Get the usage flags for the other endpoint, or return
305    // INVALID_OPERATION if they cannot be obtained.
306    virtual status_t getEndpointUsage(uint32_t *usage) = 0;
307
308    // Tracking for idle state
309    wp<StatusTracker> mStatusTracker;
310    // Status tracker component ID
311    int mStatusId;
312
313  private:
314    uint32_t oldUsage;
315    uint32_t oldMaxBuffers;
316    Condition mOutputBufferReturnedSignal;
317    Condition mInputBufferReturnedSignal;
318    static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms
319
320    // Gets all buffers from endpoint and registers them with the HAL.
321    status_t registerBuffersLocked(camera3_device *hal3Device);
322
323    void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
324                                  bool acquired, bool output);
325    List<wp<Camera3StreamBufferListener> > mBufferListenerList;
326
327}; // class Camera3Stream
328
329}; // namespace camera3
330
331}; // namespace android
332
333#endif
334