Camera3Stream.h revision 6adc9ccb2948d9421a0ed4b74f52b909bcec2037
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     * Fill in the camera3_stream_buffer with the next valid buffer for this
163     * stream, to hand over to the HAL.
164     *
165     * This method may only be called once finishConfiguration has been called.
166     * For bidirectional streams, this method applies to the output-side
167     * buffers.
168     *
169     */
170    status_t         getBuffer(camera3_stream_buffer *buffer);
171
172    /**
173     * Return a buffer to the stream after use by the HAL.
174     *
175     * This method may only be called for buffers provided by getBuffer().
176     * For bidirectional streams, this method applies to the output-side buffers
177     */
178    status_t         returnBuffer(const camera3_stream_buffer &buffer,
179            nsecs_t timestamp);
180
181    /**
182     * Fill in the camera3_stream_buffer with the next valid buffer for this
183     * stream, to hand over to the HAL.
184     *
185     * This method may only be called once finishConfiguration has been called.
186     * For bidirectional streams, this method applies to the input-side
187     * buffers.
188     *
189     */
190    status_t         getInputBuffer(camera3_stream_buffer *buffer);
191
192    /**
193     * Return a buffer to the stream after use by the HAL.
194     *
195     * This method may only be called for buffers provided by getBuffer().
196     * For bidirectional streams, this method applies to the input-side buffers
197     */
198    status_t         returnInputBuffer(const camera3_stream_buffer &buffer);
199
200    /**
201     * Whether any of the stream's buffers are currently in use by the HAL,
202     * including buffers that have been returned but not yet had their
203     * release fence signaled.
204     */
205    bool             hasOutstandingBuffers() const;
206
207    enum {
208        TIMEOUT_NEVER = -1
209    };
210
211    /**
212     * Set the status tracker to notify about idle transitions
213     */
214    virtual status_t setStatusTracker(sp<StatusTracker> statusTracker);
215
216    /**
217     * Disconnect stream from its non-HAL endpoint. After this,
218     * start/finishConfiguration must be called before the stream can be used
219     * again. This cannot be called if the stream has outstanding dequeued
220     * buffers.
221     */
222    status_t         disconnect();
223
224    /**
225     * Debug dump of the stream's state.
226     */
227    virtual void     dump(int fd, const Vector<String16> &args) const = 0;
228
229    void             addBufferListener(
230            wp<Camera3StreamBufferListener> listener);
231    void             removeBufferListener(
232            const sp<Camera3StreamBufferListener>& listener);
233
234  protected:
235    const int mId;
236    const String8 mName;
237    // Zero for formats with fixed buffer size for given dimensions.
238    const size_t mMaxSize;
239
240    enum {
241        STATE_ERROR,
242        STATE_CONSTRUCTED,
243        STATE_IN_CONFIG,
244        STATE_IN_RECONFIG,
245        STATE_CONFIGURED
246    } mState;
247
248    mutable Mutex mLock;
249
250    Camera3Stream(int id, camera3_stream_type type,
251            uint32_t width, uint32_t height, size_t maxSize, int format);
252
253    /**
254     * Interface to be implemented by derived classes
255     */
256
257    // getBuffer / returnBuffer implementations
258
259    // Since camera3_stream_buffer includes a raw pointer to the stream,
260    // cast to camera3_stream*, implementations must increment the
261    // refcount of the stream manually in getBufferLocked, and decrement it in
262    // returnBufferLocked.
263    virtual status_t getBufferLocked(camera3_stream_buffer *buffer);
264    virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
265            nsecs_t timestamp);
266    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
267    virtual status_t returnInputBufferLocked(
268            const camera3_stream_buffer &buffer);
269    virtual bool     hasOutstandingBuffersLocked() const = 0;
270    // Can return -ENOTCONN when we are already disconnected (not an error)
271    virtual status_t disconnectLocked() = 0;
272
273    // Configure the buffer queue interface to the other end of the stream,
274    // after the HAL has provided usage and max_buffers values. After this call,
275    // the stream must be ready to produce all buffers for registration with
276    // HAL.
277    virtual status_t configureQueueLocked() = 0;
278
279    // Get the total number of buffers in the queue
280    virtual size_t   getBufferCountLocked() = 0;
281
282    // Get handout output buffer count.
283    virtual size_t   getHandoutOutputBufferCountLocked() = 0;
284
285    // Get handout input buffer count.
286    virtual size_t   getHandoutInputBufferCountLocked() = 0;
287
288    // Get the usage flags for the other endpoint, or return
289    // INVALID_OPERATION if they cannot be obtained.
290    virtual status_t getEndpointUsage(uint32_t *usage) = 0;
291
292    // Tracking for idle state
293    wp<StatusTracker> mStatusTracker;
294    // Status tracker component ID
295    int mStatusId;
296
297  private:
298    uint32_t oldUsage;
299    uint32_t oldMaxBuffers;
300    Condition mOutputBufferReturnedSignal;
301    Condition mInputBufferReturnedSignal;
302    static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms
303
304    // Gets all buffers from endpoint and registers them with the HAL.
305    status_t registerBuffersLocked(camera3_device *hal3Device);
306
307    void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
308                                  bool acquired, bool output);
309    List<wp<Camera3StreamBufferListener> > mBufferListenerList;
310
311}; // class Camera3Stream
312
313}; // namespace camera3
314
315}; // namespace android
316
317#endif
318