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<IGraphicBufferProducer> getProducer() const { return mProducer; }
    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(const BufferItem& item);
    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     // SurfaceMediaSource can't handle sideband streams, so this is not expected
    143     // to ever be called. Does nothing.
    144     virtual void onSidebandStreamChanged();
    145 
    146     static bool isExternalFormat(uint32_t format);
    147 
    148 private:
    149     // A BufferQueue, represented by these interfaces, is the exchange point
    150     // between the producer and this consumer
    151     sp<IGraphicBufferProducer> mProducer;
    152     sp<IGraphicBufferConsumer> mConsumer;
    153 
    154     struct SlotData {
    155         sp<GraphicBuffer> mGraphicBuffer;
    156         uint64_t mFrameNumber;
    157     };
    158 
    159     // mSlots caches GraphicBuffers and frameNumbers from the buffer queue
    160     SlotData mSlots[BufferQueue::NUM_BUFFER_SLOTS];
    161 
    162     // The permenent width and height of SMS buffers
    163     int mWidth;
    164     int mHeight;
    165 
    166     // mCurrentSlot is the buffer slot index of the buffer that is currently
    167     // being used by buffer consumer
    168     // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
    169     // in the case of Surface).
    170     // It is initialized to INVALID_BUFFER_SLOT,
    171     // indicating that no buffer slot is currently bound to the texture. Note,
    172     // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
    173     // that no buffer is bound to the texture. A call to setBufferCount will
    174     // reset mCurrentTexture to INVALID_BUFFER_SLOT.
    175     int mCurrentSlot;
    176 
    177     // mCurrentBuffers is a list of the graphic buffers that are being used by
    178     // buffer consumer (i.e. the video encoder). It's possible that these
    179     // buffers are not associated with any buffer slots, so we must track them
    180     // separately.  Buffers are added to this list in read, and removed from
    181     // this list in signalBufferReturned
    182     Vector<sp<GraphicBuffer> > mCurrentBuffers;
    183 
    184     size_t mNumPendingBuffers;
    185 
    186 #if DEBUG_PENDING_BUFFERS
    187     Vector<MediaBuffer *> mPendingBuffers;
    188 #endif
    189 
    190     // mCurrentTimestamp is the timestamp for the current texture. It
    191     // gets set to mLastQueuedTimestamp each time updateTexImage is called.
    192     int64_t mCurrentTimestamp;
    193 
    194     // mFrameAvailableListener is the listener object that will be called when a
    195     // new frame becomes available. If it is not NULL it will be called from
    196     // queueBuffer.
    197     sp<FrameAvailableListener> mFrameAvailableListener;
    198 
    199     // mMutex is the mutex used to prevent concurrent access to the member
    200     // variables of SurfaceMediaSource objects. It must be locked whenever the
    201     // member variables are accessed.
    202     mutable Mutex mMutex;
    203 
    204     ////////////////////////// For MediaSource
    205     // Set to a default of 30 fps if not specified by the client side
    206     int32_t mFrameRate;
    207 
    208     // mStarted is a flag to check if the recording is going on
    209     bool mStarted;
    210 
    211     // mNumFramesReceived indicates the number of frames recieved from
    212     // the client side
    213     int mNumFramesReceived;
    214     // mNumFramesEncoded indicates the number of frames passed on to the
    215     // encoder
    216     int mNumFramesEncoded;
    217 
    218     // mFirstFrameTimestamp is the timestamp of the first received frame.
    219     // It is used to offset the output timestamps so recording starts at time 0.
    220     int64_t mFirstFrameTimestamp;
    221     // mStartTimeNs is the start time passed into the source at start, used to
    222     // offset timestamps.
    223     int64_t mStartTimeNs;
    224 
    225     size_t mMaxAcquiredBufferCount;
    226 
    227     bool mUseAbsoluteTimestamps;
    228 
    229     // mFrameAvailableCondition condition used to indicate whether there
    230     // is a frame available for dequeuing
    231     Condition mFrameAvailableCondition;
    232 
    233     Condition mMediaBuffersAvailableCondition;
    234 
    235     // Avoid copying and equating and default constructor
    236     DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);
    237 };
    238 
    239 // ----------------------------------------------------------------------------
    240 }; // namespace android
    241 
    242 #endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
    243