• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <media/hardware/MetadataBufferType.h>
29 
30 #include "foundation/ABase.h"
31 
32 namespace android {
33 // ----------------------------------------------------------------------------
34 
35 class String8;
36 class 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 
60 class SurfaceMediaSource : public MediaSource,
61                                 public MediaBufferObserver,
62                                 protected ConsumerListener {
63 public:
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 dumpState(String8& result) const;
110     void dumpState(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 
getProducer()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 
125 protected:
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 
151 private:
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