SurfaceMediaSource.h revision a54dee4002624e0885b39451cb29028406f5bf8e
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/*
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Copyright (C) 2011 The Android Open Source Project
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Licensed under the Apache License, Version 2.0 (the "License");
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * you may not use this file except in compliance with the License.
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * You may obtain a copy of the License at
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *      http://www.apache.org/licenses/LICENSE-2.0
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Unless required by applicable law or agreed to in writing, software
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * distributed under the License is distributed on an "AS IS" BASIS,
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * See the License for the specific language governing permissions and
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * limitations under the License.
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner */
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define ANDROID_GUI_SURFACEMEDIASOURCE_H
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <gui/ISurfaceTexture.h>
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <gui/BufferQueue.h>
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <utils/threads.h>
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <utils/Vector.h>
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <media/stagefright/MediaSource.h>
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <media/stagefright/MediaBuffer.h>
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace android {
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ----------------------------------------------------------------------------
3017dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass IGraphicBufferAlloc;
326bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass String8;
336bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass GraphicBuffer;
346bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ASSUMPTIONS
366bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton// 1. SurfaceMediaSource is initialized with width*height which
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// can never change.  However, deqeueue buffer does not currently
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// enforce this as in BufferQueue, dequeue can be used by SurfaceTexture
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// which can modify the default width and heght.  Also neither the width
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// nor height can be 0.
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 2. setSynchronousMode is never used (basically no one should call
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// setSynchronousMode(false)
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 3. setCrop, setTransform, setScalingMode should never be used
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
4536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton// timestamp must be provided for the buffer. The timestamp is in
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// nanoseconds, and must be monotonically increasing. Its other semantics
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// (zero point, etc) are client-dependent and should be documented by the
4836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton// client.
495d81f49f0b45f8810cfaf1fa3437aa72bed0c3afGreg Clayton// 5. Once disconnected, SurfaceMediaSource can be reused (can not
505d81f49f0b45f8810cfaf1fa3437aa72bed0c3afGreg Clayton// connect again)
5117dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// 6. Stop is a hard stop, the last few frames held by the encoder
5217dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// may be dropped.  It is possible to wait for the buffers to be
5317dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// returned (but not implemented)
546bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton
556bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton#define DEBUG_PENDING_BUFFERS   0
566bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton
576bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass SurfaceMediaSource : public MediaSource,
586bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton                                public MediaBufferObserver,
596bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton                                protected BufferQueue::ConsumerListener {
606bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonpublic:
616bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton    enum { MIN_UNDEQUEUED_BUFFERS = 4};
626bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton
636bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton    struct FrameAvailableListener : public virtual RefBase {
646bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton        // onFrameAvailable() is called from queueBuffer() is the FIFO is
65994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata        // empty. You can use SurfaceMediaSource::getQueuedCount() to
66994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata        // figure out if there are more frames waiting.
67994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata        // This is called without any lock held can be called concurrently by
68994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata        // multiple threads.
69994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata        virtual void onFrameAvailable() = 0;
706bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton    };
716bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton
7217dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton    SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight);
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual ~SurfaceMediaSource();
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For the MediaSource interface for use by StageFrightRecorder:
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual status_t start(MetaData *params = NULL);
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual status_t stop();
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual status_t read(MediaBuffer **buffer,
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const ReadOptions *options = NULL);
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual sp<MetaData> getFormat();
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Get / Set the frame rate used for encoding. Default fps = 30
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    status_t setFrameRate(int32_t fps) ;
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int32_t getFrameRate( ) const;
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The call for the StageFrightRecorder to tell us that
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // it is done using the MediaBuffer data so that its state
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // can be set to FREE for dequeuing
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual void signalBufferReturned(MediaBuffer* buffer);
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // end of MediaSource interface
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // getTimestamp retrieves the timestamp associated with the image
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // set by the most recent call to read()
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //
96    // The timestamp is in nanoseconds, and is monotonically increasing. Its
97    // other semantics (zero point, etc) are source-dependent and should be
98    // documented by the source.
99    int64_t getTimestamp();
100
101    // setFrameAvailableListener sets the listener object that will be notified
102    // when a new frame becomes available.
103    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
104
105    // dump our state in a String
106    void dump(String8& result) const;
107    void dump(String8& result, const char* prefix, char* buffer,
108                                                    size_t SIZE) const;
109
110    // isMetaDataStoredInVideoBuffers tells the encoder whether we will
111    // pass metadata through the buffers. Currently, it is force set to true
112    bool isMetaDataStoredInVideoBuffers() const;
113
114    sp<BufferQueue> getBufferQueue() const { return mBufferQueue; }
115
116    // To be called before start()
117    status_t setMaxAcquiredBufferCount(size_t count);
118
119protected:
120
121    // Implementation of the BufferQueue::ConsumerListener interface.  These
122    // calls are used to notify the SurfaceTexture of asynchronous events in the
123    // BufferQueue.
124    virtual void onFrameAvailable();
125
126    // Used as a hook to BufferQueue::disconnect()
127    // This is called by the client side when it is done
128    // TODO: Currently, this also sets mStopped to true which
129    // is needed for unblocking the encoder which might be
130    // waiting to read more frames. So if on the client side,
131    // the same thread supplies the frames and also calls stop
132    // on the encoder, the client has to call disconnect before
133    // it calls stop.
134    // In the case of the camera,
135    // that need not be required since the thread supplying the
136    // frames is separate than the one calling stop.
137    virtual void onBuffersReleased();
138
139    static bool isExternalFormat(uint32_t format);
140
141private:
142    // mBufferQueue is the exchange point between the producer and
143    // this consumer
144    sp<BufferQueue> mBufferQueue;
145
146    // mBufferSlot caches GraphicBuffers from the buffer queue
147    sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS];
148
149
150    // The permenent width and height of SMS buffers
151    int mWidth;
152    int mHeight;
153
154    // mCurrentSlot is the buffer slot index of the buffer that is currently
155    // being used by buffer consumer
156    // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
157    // in the case of SurfaceTexture).
158    // It is initialized to INVALID_BUFFER_SLOT,
159    // indicating that no buffer slot is currently bound to the texture. Note,
160    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
161    // that no buffer is bound to the texture. A call to setBufferCount will
162    // reset mCurrentTexture to INVALID_BUFFER_SLOT.
163    int mCurrentSlot;
164
165    // mCurrentBuffers is a list of the graphic buffers that are being used by
166    // buffer consumer (i.e. the video encoder). It's possible that these
167    // buffers are not associated with any buffer slots, so we must track them
168    // separately.  Buffers are added to this list in read, and removed from
169    // this list in signalBufferReturned
170    Vector<sp<GraphicBuffer> > mCurrentBuffers;
171
172    size_t mNumPendingBuffers;
173
174#if DEBUG_PENDING_BUFFERS
175    Vector<MediaBuffer *> mPendingBuffers;
176#endif
177
178    // mCurrentTimestamp is the timestamp for the current texture. It
179    // gets set to mLastQueuedTimestamp each time updateTexImage is called.
180    int64_t mCurrentTimestamp;
181
182    // mFrameAvailableListener is the listener object that will be called when a
183    // new frame becomes available. If it is not NULL it will be called from
184    // queueBuffer.
185    sp<FrameAvailableListener> mFrameAvailableListener;
186
187    // mMutex is the mutex used to prevent concurrent access to the member
188    // variables of SurfaceMediaSource objects. It must be locked whenever the
189    // member variables are accessed.
190    mutable Mutex mMutex;
191
192    ////////////////////////// For MediaSource
193    // Set to a default of 30 fps if not specified by the client side
194    int32_t mFrameRate;
195
196    // mStarted is a flag to check if the recording is going on
197    bool mStarted;
198
199    // mNumFramesReceived indicates the number of frames recieved from
200    // the client side
201    int mNumFramesReceived;
202    // mNumFramesEncoded indicates the number of frames passed on to the
203    // encoder
204    int mNumFramesEncoded;
205
206    // mFirstFrameTimestamp is the timestamp of the first received frame.
207    // It is used to offset the output timestamps so recording starts at time 0.
208    int64_t mFirstFrameTimestamp;
209    // mStartTimeNs is the start time passed into the source at start, used to
210    // offset timestamps.
211    int64_t mStartTimeNs;
212
213    size_t mMaxAcquiredBufferCount;
214
215    // mFrameAvailableCondition condition used to indicate whether there
216    // is a frame available for dequeuing
217    Condition mFrameAvailableCondition;
218
219    Condition mMediaBuffersAvailableCondition;
220
221    // Avoid copying and equating and default constructor
222    DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);
223};
224
225// ----------------------------------------------------------------------------
226}; // namespace android
227
228#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
229