Camera3Stream.h revision f1e98d857ec377f2c9b916073d40732e6ebb7ced
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 */
86class Camera3Stream :
87        protected camera3_stream,
88        public virtual Camera3StreamInterface,
89        public virtual RefBase {
90  public:
91
92    virtual ~Camera3Stream();
93
94    static Camera3Stream*       cast(camera3_stream *stream);
95    static const Camera3Stream* cast(const camera3_stream *stream);
96
97    /**
98     * Get the stream's ID
99     */
100    int              getId() const;
101
102    /**
103     * Get the stream's dimensions and format
104     */
105    uint32_t         getWidth() const;
106    uint32_t         getHeight() const;
107    int              getFormat() const;
108
109    /**
110     * Start the stream configuration process. Returns a handle to the stream's
111     * information to be passed into the HAL device's configure_streams call.
112     *
113     * Until finishConfiguration() is called, no other methods on the stream may be
114     * called. The usage and max_buffers fields of camera3_stream may be modified
115     * between start/finishConfiguration, but may not be changed after that.
116     * The priv field of camera3_stream may be modified at any time after
117     * startConfiguration.
118     *
119     * Returns NULL in case of error starting configuration.
120     */
121    camera3_stream*  startConfiguration();
122
123    /**
124     * Check if the stream is mid-configuration (start has been called, but not
125     * finish).  Used for lazy completion of configuration.
126     */
127    bool             isConfiguring() const;
128
129    /**
130     * Completes the stream configuration process. During this call, the stream
131     * may call the device's register_stream_buffers() method. The stream
132     * information structure returned by startConfiguration() may no longer be
133     * modified after this call, but can still be read until the destruction of
134     * the stream.
135     *
136     * Returns:
137     *   OK on a successful configuration
138     *   NO_INIT in case of a serious error from the HAL device
139     *   NO_MEMORY in case of an error registering buffers
140     *   INVALID_OPERATION in case connecting to the consumer failed
141     */
142    status_t         finishConfiguration(camera3_device *hal3Device);
143
144    /**
145     * Fill in the camera3_stream_buffer with the next valid buffer for this
146     * stream, to hand over to the HAL.
147     *
148     * This method may only be called once finishConfiguration has been called.
149     * For bidirectional streams, this method applies to the output-side
150     * buffers.
151     *
152     */
153    status_t         getBuffer(camera3_stream_buffer *buffer);
154
155    /**
156     * Return a buffer to the stream after use by the HAL.
157     *
158     * This method may only be called for buffers provided by getBuffer().
159     * For bidirectional streams, this method applies to the output-side buffers
160     */
161    status_t         returnBuffer(const camera3_stream_buffer &buffer,
162            nsecs_t timestamp);
163
164    /**
165     * Fill in the camera3_stream_buffer with the next valid buffer for this
166     * stream, to hand over to the HAL.
167     *
168     * This method may only be called once finishConfiguration has been called.
169     * For bidirectional streams, this method applies to the input-side
170     * buffers.
171     *
172     */
173    status_t         getInputBuffer(camera3_stream_buffer *buffer);
174
175    /**
176     * Return a buffer to the stream after use by the HAL.
177     *
178     * This method may only be called for buffers provided by getBuffer().
179     * For bidirectional streams, this method applies to the input-side buffers
180     */
181    status_t         returnInputBuffer(const camera3_stream_buffer &buffer);
182
183    /**
184     * Whether any of the stream's buffers are currently in use by the HAL,
185     * including buffers that have been returned but not yet had their
186     * release fence signaled.
187     */
188    bool             hasOutstandingBuffers() const;
189
190    enum {
191        TIMEOUT_NEVER = -1
192    };
193
194    /**
195     * Set the status tracker to notify about idle transitions
196     */
197    virtual status_t setStatusTracker(sp<StatusTracker> statusTracker);
198
199    /**
200     * Disconnect stream from its non-HAL endpoint. After this,
201     * start/finishConfiguration must be called before the stream can be used
202     * again. This cannot be called if the stream has outstanding dequeued
203     * buffers.
204     */
205    status_t         disconnect();
206
207    /**
208     * Debug dump of the stream's state.
209     */
210    virtual void     dump(int fd, const Vector<String16> &args) const = 0;
211
212    void             addBufferListener(
213            wp<Camera3StreamBufferListener> listener);
214    void             removeBufferListener(
215            const sp<Camera3StreamBufferListener>& listener);
216
217  protected:
218    const int mId;
219    const String8 mName;
220    // Zero for formats with fixed buffer size for given dimensions.
221    const size_t mMaxSize;
222
223    enum {
224        STATE_ERROR,
225        STATE_CONSTRUCTED,
226        STATE_IN_CONFIG,
227        STATE_IN_RECONFIG,
228        STATE_CONFIGURED
229    } mState;
230
231    mutable Mutex mLock;
232
233    Camera3Stream(int id, camera3_stream_type type,
234            uint32_t width, uint32_t height, size_t maxSize, int format);
235
236    /**
237     * Interface to be implemented by derived classes
238     */
239
240    // getBuffer / returnBuffer implementations
241
242    // Since camera3_stream_buffer includes a raw pointer to the stream,
243    // cast to camera3_stream*, implementations must increment the
244    // refcount of the stream manually in getBufferLocked, and decrement it in
245    // returnBufferLocked.
246    virtual status_t getBufferLocked(camera3_stream_buffer *buffer);
247    virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
248            nsecs_t timestamp);
249    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
250    virtual status_t returnInputBufferLocked(
251            const camera3_stream_buffer &buffer);
252    virtual bool     hasOutstandingBuffersLocked() const = 0;
253    // Can return -ENOTCONN when we are already disconnected (not an error)
254    virtual status_t disconnectLocked() = 0;
255
256    // Configure the buffer queue interface to the other end of the stream,
257    // after the HAL has provided usage and max_buffers values. After this call,
258    // the stream must be ready to produce all buffers for registration with
259    // HAL.
260    virtual status_t configureQueueLocked() = 0;
261
262    // Get the total number of buffers in the queue
263    virtual size_t   getBufferCountLocked() = 0;
264
265    // Get the usage flags for the other endpoint, or return
266    // INVALID_OPERATION if they cannot be obtained.
267    virtual status_t getEndpointUsage(uint32_t *usage) = 0;
268
269    // Tracking for idle state
270    wp<StatusTracker> mStatusTracker;
271    // Status tracker component ID
272    int mStatusId;
273
274  private:
275    uint32_t oldUsage;
276    uint32_t oldMaxBuffers;
277
278    // Gets all buffers from endpoint and registers them with the HAL.
279    status_t registerBuffersLocked(camera3_device *hal3Device);
280
281    void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
282                                  bool acquired, bool output);
283    List<wp<Camera3StreamBufferListener> > mBufferListenerList;
284
285}; // class Camera3Stream
286
287}; // namespace camera3
288
289}; // namespace android
290
291#endif
292