diff options
author | Mathias Agopian <mathias@google.com> | 2012-04-10 18:53:56 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-10 18:53:56 -0700 |
commit | 2d531e1b5865d61d5ca25d77d53017b1ad180efa (patch) | |
tree | f5b15fd8836013c8fa568596aaada9e823d0b7db /include | |
parent | d2469c3fe382203eb7cd5060c94ed204bec98116 (diff) | |
parent | bdddc659a941afdb7f4958f582c6901c07246097 (diff) | |
download | frameworks_av-2d531e1b5865d61d5ca25d77d53017b1ad180efa.zip frameworks_av-2d531e1b5865d61d5ca25d77d53017b1ad180efa.tar.gz frameworks_av-2d531e1b5865d61d5ca25d77d53017b1ad180efa.tar.bz2 |
Merge "Refactored SurfaceMediaSource"
Diffstat (limited to 'include')
-rw-r--r-- | include/media/stagefright/SurfaceMediaSource.h | 255 |
1 files changed, 55 insertions, 200 deletions
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index c0dc074..e25d444 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -18,6 +18,7 @@ #define ANDROID_GUI_SURFACEMEDIASOURCE_H #include <gui/ISurfaceTexture.h> +#include <gui/BufferQueue.h> #include <utils/threads.h> #include <utils/Vector.h> @@ -31,16 +32,31 @@ class IGraphicBufferAlloc; class String8; class GraphicBuffer; -class SurfaceMediaSource : public BnSurfaceTexture, public MediaSource, - public MediaBufferObserver { +// ASSUMPTIONS +// 1. SurfaceMediaSource is initialized with width*height which +// can never change. However, deqeueue buffer does not currently +// enforce this as in BufferQueue, dequeue can be used by SurfaceTexture +// which can modify the default width and heght. Also neither the width +// nor height can be 0. +// 2. setSynchronousMode is never used (basically no one should call +// setSynchronousMode(false) +// 3. setCrop, setTransform, setScalingMode should never be used +// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a +// timestamp must be provided for the buffer. The timestamp is in +// nanoseconds, and must be monotonically increasing. Its other semantics +// (zero point, etc) are client-dependent and should be documented by the +// client. +// 5. Once disconnected, SurfaceMediaSource can be reused (can not +// connect again) +// 6. Stop is a hard stop, the last few frames held by the encoder +// may be dropped. It is possible to wait for the buffers to be +// returned (but not implemented) + +class SurfaceMediaSource : public MediaSource, + public MediaBufferObserver, + protected BufferQueue::ConsumerListener { public: - enum { MIN_UNDEQUEUED_BUFFERS = 4 }; - enum { - MIN_ASYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1, - MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS - }; - enum { NUM_BUFFER_SLOTS = 32 }; - enum { NO_CONNECTED_API = 0 }; + enum { MIN_UNDEQUEUED_BUFFERS = 4}; struct FrameAvailableListener : public virtual RefBase { // onFrameAvailable() is called from queueBuffer() is the FIFO is @@ -51,13 +67,13 @@ public: virtual void onFrameAvailable() = 0; }; - SurfaceMediaSource(uint32_t bufW, uint32_t bufH); + SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight); virtual ~SurfaceMediaSource(); - // For the MediaSource interface for use by StageFrightRecorder: virtual status_t start(MetaData *params = NULL); + virtual status_t stop() { return reset(); } virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); @@ -77,81 +93,6 @@ public: virtual void signalBufferReturned(MediaBuffer* buffer); // end of MediaSource interface - uint32_t getBufferCount( ) const { return mBufferCount;} - - - // setBufferCount updates the number of available buffer slots. After - // calling this all buffer slots are both unallocated and owned by the - // SurfaceMediaSource object (i.e. they are not owned by the client). - virtual status_t setBufferCount(int bufferCount); - - virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); - - // dequeueBuffer gets the next buffer slot index for the client to use. If a - // buffer slot is available then that slot index is written to the location - // pointed to by the buf argument and a status of OK is returned. If no - // slot is available then a status of -EBUSY is returned and buf is - // unmodified. - virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h, - uint32_t format, uint32_t usage); - - // queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a - // timestamp must be provided for the buffer. The timestamp is in - // nanoseconds, and must be monotonically increasing. Its other semantics - // (zero point, etc) are client-dependent and should be documented by the - // client. - virtual status_t queueBuffer(int buf, int64_t timestamp, - const Rect& crop, int scalingMode, uint32_t transform, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); - virtual void cancelBuffer(int buf); - - // onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder) - // or listeners that a frame has been received - // The buffer is not made available for dequeueing immediately. We need to - // wait to hear from StageFrightRecorder to set the buffer FREE - // Make sure this is called when the mutex is locked - virtual status_t onFrameReceivedLocked(); - - virtual int query(int what, int* value); - - // setSynchronousMode set whether dequeueBuffer is synchronous or - // asynchronous. In synchronous mode, dequeueBuffer blocks until - // a buffer is available, the currently bound buffer can be dequeued and - // queued buffers will be retired in order. - // The default mode is synchronous. - // TODO: Clarify the minute differences bet sycn /async - // modes (S.Encoder vis-a-vis SurfaceTexture) - virtual status_t setSynchronousMode(bool enabled); - - // connect attempts to connect a client API to the SurfaceMediaSource. This - // must be called before any other ISurfaceTexture methods are called except - // for getAllocator. - // - // This method will fail if the connect was previously called on the - // SurfaceMediaSource and no corresponding disconnect call was made. - virtual status_t connect(int api, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); - - // disconnect attempts to disconnect a client API from the SurfaceMediaSource. - // Calling this method will cause any subsequent calls to other - // ISurfaceTexture methods to fail except for getAllocator and connect. - // Successfully calling connect after this will allow the other methods to - // succeed again. - // - // This method will fail if the the SurfaceMediaSource is not currently - // connected to the specified client API. - virtual status_t disconnect(int api); - - // getqueuedCount returns the number of queued frames waiting in the - // FIFO. In asynchronous mode, this always returns 0 or 1 since - // frames are not accumulating in the FIFO. - size_t getQueuedCount() const; - - // setBufferCountServer set the buffer count. If the client has requested - // a buffer count using setBufferCount, the server-buffer count will - // take effect once the client sets the count back to zero. - status_t setBufferCountServer(int bufferCount); - // getTimestamp retrieves the timestamp associated with the image // set by the most recent call to read() // @@ -176,105 +117,42 @@ public: // pass metadata through the buffers. Currently, it is force set to true bool isMetaDataStoredInVideoBuffers() const; + sp<BufferQueue> getBufferQueue() const { return mBufferQueue; } + protected: - // freeAllBuffersLocked frees the resources (both GraphicBuffer and EGLImage) for - // all slots. - void freeAllBuffersLocked(); + // Implementation of the BufferQueue::ConsumerListener interface. These + // calls are used to notify the SurfaceTexture of asynchronous events in the + // BufferQueue. + virtual void onFrameAvailable(); + + // Used as a hook to BufferQueue::disconnect() + // This is called by the client side when it is done + // TODO: Currently, this also sets mStopped to true which + // is needed for unblocking the encoder which might be + // waiting to read more frames. So if on the client side, + // the same thread supplies the frames and also calls stop + // on the encoder, the client has to call disconnect before + // it calls stop. + // In the case of the camera, + // that need not be required since the thread supplying the + // frames is separate than the one calling stop. + virtual void onBuffersReleased(); + static bool isExternalFormat(uint32_t format); private: + // mBufferQueue is the exchange point between the producer and + // this consumer + sp<BufferQueue> mBufferQueue; - status_t setBufferCountServerLocked(int bufferCount); - - enum { INVALID_BUFFER_SLOT = -1 }; - - struct BufferSlot { - - BufferSlot() - : mBufferState(BufferSlot::FREE), - mRequestBufferCalled(false), - mTimestamp(0) { - } - - // mGraphicBuffer points to the buffer allocated for this slot or is - // NULL if no buffer has been allocated. - sp<GraphicBuffer> mGraphicBuffer; - - // BufferState represents the different states in which a buffer slot - // can be. - enum BufferState { - // FREE indicates that the buffer is not currently being used and - // will not be used in the future until it gets dequeued and - // subseqently queued by the client. - FREE = 0, - - // DEQUEUED indicates that the buffer has been dequeued by the - // client, but has not yet been queued or canceled. The buffer is - // considered 'owned' by the client, and the server should not use - // it for anything. - // - // Note that when in synchronous-mode (mSynchronousMode == true), - // the buffer that's currently attached to the texture may be - // dequeued by the client. That means that the current buffer can - // be in either the DEQUEUED or QUEUED state. In asynchronous mode, - // however, the current buffer is always in the QUEUED state. - DEQUEUED = 1, - - // QUEUED indicates that the buffer has been queued by the client, - // and has not since been made available for the client to dequeue. - // Attaching the buffer to the texture does NOT transition the - // buffer away from the QUEUED state. However, in Synchronous mode - // the current buffer may be dequeued by the client under some - // circumstances. See the note about the current buffer in the - // documentation for DEQUEUED. - QUEUED = 2, - }; - - // mBufferState is the current state of this buffer slot. - BufferState mBufferState; - - // mRequestBufferCalled is used for validating that the client did - // call requestBuffer() when told to do so. Technically this is not - // needed but useful for debugging and catching client bugs. - bool mRequestBufferCalled; - - // mTimestamp is the current timestamp for this buffer slot. This gets - // to set by queueBuffer each time this slot is queued. - int64_t mTimestamp; - }; - - // mSlots is the array of buffer slots that must be mirrored on the client - // side. This allows buffer ownership to be transferred between the client - // and server without sending a GraphicBuffer over binder. The entire array - // is initialized to NULL at construction time, and buffers are allocated - // for a slot when requestBuffer is called with that slot's index. - BufferSlot mSlots[NUM_BUFFER_SLOTS]; + // mBufferSlot caches GraphicBuffers from the buffer queue + sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; - // mDefaultWidth holds the default width of allocated buffers. It is used - // in requestBuffers() if a width and height of zero is specified. - uint32_t mDefaultWidth; - // mDefaultHeight holds the default height of allocated buffers. It is used - // in requestBuffers() if a width and height of zero is specified. - uint32_t mDefaultHeight; - - // mPixelFormat holds the pixel format of allocated buffers. It is used - // in requestBuffers() if a format of zero is specified. - uint32_t mPixelFormat; - - // mBufferCount is the number of buffer slots that the client and server - // must maintain. It defaults to MIN_ASYNC_BUFFER_SLOTS and can be changed - // by calling setBufferCount or setBufferCountServer - int mBufferCount; - - // mClientBufferCount is the number of buffer slots requested by the - // client. The default is zero, which means the client doesn't care how - // many buffers there are - int mClientBufferCount; - - // mServerBufferCount buffer count requested by the server-side - int mServerBufferCount; + // The permenent width and height of SMS buffers + int mWidth; + int mHeight; // mCurrentSlot is the buffer slot index of the buffer that is currently // being used by buffer consumer @@ -287,43 +165,21 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentSlot; - // mCurrentBuf is the graphic buffer of the current slot to be used by // buffer consumer. It's possible that this buffer is not associated // with any buffer slot, so we must track it separately in order to // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept. sp<GraphicBuffer> mCurrentBuf; - // mCurrentTimestamp is the timestamp for the current texture. It // gets set to mLastQueuedTimestamp each time updateTexImage is called. int64_t mCurrentTimestamp; - // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to - // allocate new GraphicBuffer objects. - sp<IGraphicBufferAlloc> mGraphicBufferAlloc; - // mFrameAvailableListener is the listener object that will be called when a // new frame becomes available. If it is not NULL it will be called from // queueBuffer. sp<FrameAvailableListener> mFrameAvailableListener; - // mSynchronousMode whether we're in synchronous mode or not - bool mSynchronousMode; - - // mConnectedApi indicates the API that is currently connected to this - // SurfaceTexture. It defaults to NO_CONNECTED_API (= 0), and gets updated - // by the connect and disconnect methods. - int mConnectedApi; - - // mDequeueCondition condition used for dequeueBuffer in synchronous mode - mutable Condition mDequeueCondition; - - - // mQueue is a FIFO of queued buffers used in synchronous mode - typedef Vector<int> Fifo; - Fifo mQueue; - // mMutex is the mutex used to prevent concurrent access to the member // variables of SurfaceMediaSource objects. It must be locked whenever the // member variables are accessed. @@ -353,7 +209,6 @@ private: // mFrameAvailableCondition condition used to indicate whether there // is a frame available for dequeuing Condition mFrameAvailableCondition; - Condition mFrameCompleteCondition; status_t reset(); |