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