1/*
2 * Copyright (C) 2011 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_GUI_SURFACEMEDIASOURCE_H
18#define ANDROID_GUI_SURFACEMEDIASOURCE_H
19
20#include <gui/IGraphicBufferProducer.h>
21#include <gui/BufferQueue.h>
22
23#include <utils/threads.h>
24#include <utils/Vector.h>
25#include <media/stagefright/MediaSource.h>
26#include <media/stagefright/MediaBuffer.h>
27
28#include <MetadataBufferType.h>
29
30#include "foundation/ABase.h"
31
32namespace android {
33// ----------------------------------------------------------------------------
34
35class String8;
36class GraphicBuffer;
37
38// ASSUMPTIONS
39// 1. SurfaceMediaSource is initialized with width*height which
40// can never change.  However, deqeueue buffer does not currently
41// enforce this as in BufferQueue, dequeue can be used by Surface
42// which can modify the default width and heght.  Also neither the width
43// nor height can be 0.
44// 2. setSynchronousMode is never used (basically no one should call
45// setSynchronousMode(false)
46// 3. setCrop, setTransform, setScalingMode should never be used
47// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
48// timestamp must be provided for the buffer. The timestamp is in
49// nanoseconds, and must be monotonically increasing. Its other semantics
50// (zero point, etc) are client-dependent and should be documented by the
51// client.
52// 5. Once disconnected, SurfaceMediaSource can be reused (can not
53// connect again)
54// 6. Stop is a hard stop, the last few frames held by the encoder
55// may be dropped.  It is possible to wait for the buffers to be
56// returned (but not implemented)
57
58#define DEBUG_PENDING_BUFFERS   0
59
60class SurfaceMediaSource : public MediaSource,
61                                public MediaBufferObserver,
62                                protected ConsumerListener {
63public:
64    enum { MIN_UNDEQUEUED_BUFFERS = 4};
65
66    struct FrameAvailableListener : public virtual RefBase {
67        // onFrameAvailable() is called from queueBuffer() is the FIFO is
68        // empty. You can use SurfaceMediaSource::getQueuedCount() to
69        // figure out if there are more frames waiting.
70        // This is called without any lock held can be called concurrently by
71        // multiple threads.
72        virtual void onFrameAvailable() = 0;
73    };
74
75    SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight);
76
77    virtual ~SurfaceMediaSource();
78
79    // For the MediaSource interface for use by StageFrightRecorder:
80    virtual status_t start(MetaData *params = NULL);
81    virtual status_t stop();
82    virtual status_t read(MediaBuffer **buffer,
83            const ReadOptions *options = NULL);
84    virtual sp<MetaData> getFormat();
85
86    // Get / Set the frame rate used for encoding. Default fps = 30
87    status_t setFrameRate(int32_t fps) ;
88    int32_t getFrameRate( ) const;
89
90    // The call for the StageFrightRecorder to tell us that
91    // it is done using the MediaBuffer data so that its state
92    // can be set to FREE for dequeuing
93    virtual void signalBufferReturned(MediaBuffer* buffer);
94    // end of MediaSource interface
95
96    // getTimestamp retrieves the timestamp associated with the image
97    // set by the most recent call to read()
98    //
99    // The timestamp is in nanoseconds, and is monotonically increasing. Its
100    // other semantics (zero point, etc) are source-dependent and should be
101    // documented by the source.
102    int64_t getTimestamp();
103
104    // setFrameAvailableListener sets the listener object that will be notified
105    // when a new frame becomes available.
106    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
107
108    // dump our state in a String
109    void dump(String8& result) const;
110    void dump(String8& result, const char* prefix, char* buffer,
111                                                    size_t SIZE) const;
112
113    // metaDataStoredInVideoBuffers tells the encoder what kind of metadata
114    // is passed through the buffers. Currently, it is set to ANWBuffer
115    MetadataBufferType metaDataStoredInVideoBuffers() const;
116
117    sp<IGraphicBufferProducer> getProducer() const { return mProducer; }
118
119    // To be called before start()
120    status_t setMaxAcquiredBufferCount(size_t count);
121
122    // To be called before start()
123    status_t setUseAbsoluteTimestamps();
124
125protected:
126
127    // Implementation of the BufferQueue::ConsumerListener interface.  These
128    // calls are used to notify the Surface of asynchronous events in the
129    // BufferQueue.
130    virtual void onFrameAvailable(const BufferItem& item);
131
132    // Used as a hook to BufferQueue::disconnect()
133    // This is called by the client side when it is done
134    // TODO: Currently, this also sets mStopped to true which
135    // is needed for unblocking the encoder which might be
136    // waiting to read more frames. So if on the client side,
137    // the same thread supplies the frames and also calls stop
138    // on the encoder, the client has to call disconnect before
139    // it calls stop.
140    // In the case of the camera,
141    // that need not be required since the thread supplying the
142    // frames is separate than the one calling stop.
143    virtual void onBuffersReleased();
144
145    // SurfaceMediaSource can't handle sideband streams, so this is not expected
146    // to ever be called. Does nothing.
147    virtual void onSidebandStreamChanged();
148
149    static bool isExternalFormat(uint32_t format);
150
151private:
152    // A BufferQueue, represented by these interfaces, is the exchange point
153    // between the producer and this consumer
154    sp<IGraphicBufferProducer> mProducer;
155    sp<IGraphicBufferConsumer> mConsumer;
156
157    struct SlotData {
158        sp<GraphicBuffer> mGraphicBuffer;
159        uint64_t mFrameNumber;
160    };
161
162    // mSlots caches GraphicBuffers and frameNumbers from the buffer queue
163    SlotData mSlots[BufferQueue::NUM_BUFFER_SLOTS];
164
165    // The permenent width and height of SMS buffers
166    int mWidth;
167    int mHeight;
168
169    // mCurrentSlot is the buffer slot index of the buffer that is currently
170    // being used by buffer consumer
171    // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
172    // in the case of Surface).
173    // It is initialized to INVALID_BUFFER_SLOT,
174    // indicating that no buffer slot is currently bound to the texture. Note,
175    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
176    // that no buffer is bound to the texture. A call to setBufferCount will
177    // reset mCurrentTexture to INVALID_BUFFER_SLOT.
178    int mCurrentSlot;
179
180    // mCurrentBuffers is a list of the graphic buffers that are being used by
181    // buffer consumer (i.e. the video encoder). It's possible that these
182    // buffers are not associated with any buffer slots, so we must track them
183    // separately.  Buffers are added to this list in read, and removed from
184    // this list in signalBufferReturned
185    Vector<sp<GraphicBuffer> > mCurrentBuffers;
186
187    size_t mNumPendingBuffers;
188
189#if DEBUG_PENDING_BUFFERS
190    Vector<MediaBuffer *> mPendingBuffers;
191#endif
192
193    // mCurrentTimestamp is the timestamp for the current texture. It
194    // gets set to mLastQueuedTimestamp each time updateTexImage is called.
195    int64_t mCurrentTimestamp;
196
197    // mFrameAvailableListener is the listener object that will be called when a
198    // new frame becomes available. If it is not NULL it will be called from
199    // queueBuffer.
200    sp<FrameAvailableListener> mFrameAvailableListener;
201
202    // mMutex is the mutex used to prevent concurrent access to the member
203    // variables of SurfaceMediaSource objects. It must be locked whenever the
204    // member variables are accessed.
205    mutable Mutex mMutex;
206
207    ////////////////////////// For MediaSource
208    // Set to a default of 30 fps if not specified by the client side
209    int32_t mFrameRate;
210
211    // mStarted is a flag to check if the recording is going on
212    bool mStarted;
213
214    // mNumFramesReceived indicates the number of frames recieved from
215    // the client side
216    int mNumFramesReceived;
217    // mNumFramesEncoded indicates the number of frames passed on to the
218    // encoder
219    int mNumFramesEncoded;
220
221    // mFirstFrameTimestamp is the timestamp of the first received frame.
222    // It is used to offset the output timestamps so recording starts at time 0.
223    int64_t mFirstFrameTimestamp;
224    // mStartTimeNs is the start time passed into the source at start, used to
225    // offset timestamps.
226    int64_t mStartTimeNs;
227
228    size_t mMaxAcquiredBufferCount;
229
230    bool mUseAbsoluteTimestamps;
231
232    // mFrameAvailableCondition condition used to indicate whether there
233    // is a frame available for dequeuing
234    Condition mFrameAvailableCondition;
235
236    Condition mMediaBuffersAvailableCondition;
237
238    // Allocate and return a new MediaBuffer and pass the ANW buffer as metadata into it.
239    void passMetadataBuffer_l(MediaBuffer **buffer, ANativeWindowBuffer *bufferHandle) const;
240
241    // Avoid copying and equating and default constructor
242    DISALLOW_EVIL_CONSTRUCTORS(SurfaceMediaSource);
243};
244
245// ----------------------------------------------------------------------------
246}; // namespace android
247
248#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
249