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