diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 946a0aa..32eed3f 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -99,6 +99,13 @@
     OMX_U32 nUsage;             // OUT
 };
 
+// An enum OMX_COLOR_FormatAndroidOpaque to indicate an opaque colorformat
+// is declared in media/stagefright/openmax/OMX_IVCommon.h
+// This will inform the encoder that the actual
+// colorformat will be relayed by the GRalloc Buffers.
+// OMX_COLOR_FormatAndroidOpaque  = 0x7F000001,
+
+
 }  // namespace android
 
 extern android::OMXPluginBase *createOMXPlugin();
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index 37dbcd8..3818e63 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -29,7 +29,7 @@
 class MediaBuffer;
 class MetaData;
 
-struct MediaSource : public RefBase {
+struct MediaSource : public virtual RefBase {
     MediaSource();
 
     // To be called before any other methods on this object, except
diff --git a/include/media/stagefright/SurfaceEncoder.h b/include/media/stagefright/SurfaceEncoder.h
new file mode 100644
index 0000000..7627a29
--- /dev/null
+++ b/include/media/stagefright/SurfaceEncoder.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_SURFACEENCODER_H
+#define ANDROID_GUI_SURFACEENCODER_H
+
+#include <gui/ISurfaceTexture.h>
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc;
+class String8;
+class GraphicBuffer;
+
+class SurfaceEncoder : public BnSurfaceTexture, public MediaSource,
+                                            public MediaBufferObserver {
+public:
+    enum { MIN_UNDEQUEUED_BUFFERS = 3 };
+    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 };
+
+    struct FrameAvailableListener : public virtual RefBase {
+        // onFrameAvailable() is called from queueBuffer() is the FIFO is
+        // empty. You can use SurfaceEncoder::getQueuedCount() to
+        // figure out if there are more frames waiting.
+        // This is called without any lock held can be called concurrently by
+        // multiple threads.
+        virtual void onFrameAvailable() = 0;
+    };
+
+    SurfaceEncoder(uint32_t bufW, uint32_t bufH);
+
+    virtual ~SurfaceEncoder();
+
+
+    // For the MediaSource interface for use by StageFrightRecorder:
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+    virtual sp<MetaData> getFormat();
+
+    // Get / Set the frame rate used for encoding. Default fps = 30
+    void setFrameRate(uint32_t fps) ;
+    uint32_t getFrameRate( ) const;
+
+    // The call for the StageFrightRecorder to tell us that
+    // it is done using the MediaBuffer data so that its state
+    // can be set to FREE for dequeuing
+    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
+    // SurfaceEncoder object (i.e. they are not owned by the client).
+    virtual status_t setBufferCount(int bufferCount);
+
+    virtual sp<GraphicBuffer> requestBuffer(int 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 SurfaceEncoder. 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,
+            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 status_t setScalingMode(int mode) { } // no op for encoding
+    virtual int query(int what, int* value);
+
+    // Just confirming to the ISurfaceTexture interface as of now
+    virtual status_t setCrop(const Rect& reg) { return OK; }
+    virtual status_t setTransform(uint32_t transform) {return OK;}
+
+    // 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 SurfaceEncoder.  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
+    // SurfaceEncoder and no corresponding disconnect call was made.
+    virtual status_t connect(int api);
+
+    // disconnect attempts to disconnect a client API from the SurfaceEncoder.
+    // 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 SurfaceEncoder 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 updateFrameInfoLocked().
+    //
+    // The timestamp is in nanoseconds, and is monotonically increasing. Its
+    // other semantics (zero point, etc) are source-dependent and should be
+    // documented by the source.
+    int64_t getTimestamp();
+
+    // setFrameAvailableListener sets the listener object that will be notified
+    // when a new frame becomes available.
+    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+    // getAllocator retrieves the binder object that must be referenced as long
+    // as the GraphicBuffers dequeued from this SurfaceEncoder are referenced.
+    // Holding this binder reference prevents SurfaceFlinger from freeing the
+    // buffers before the client is done with them.
+    sp<IBinder> getAllocator();
+
+
+    // getCurrentBuffer returns the buffer associated with the current image.
+    sp<GraphicBuffer> getCurrentBuffer() const;
+
+    // dump our state in a String
+    void dump(String8& result) const;
+    void dump(String8& result, const char* prefix, char* buffer,
+                                                    size_t SIZE) const;
+
+    protected:
+
+    // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
+    // all slots.
+    void freeAllBuffers();
+    static bool isExternalFormat(uint32_t format);
+
+private:
+
+    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];
+
+    // 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;
+
+    // mCurrentSlot is the buffer slot index of the buffer that is currently
+    // being used by buffer consumer
+    // (e.g. StageFrightRecorder in the case of SurfaceEncoder or GLTexture
+    // in the case of SurfaceTexture).
+    // It is initialized to INVALID_BUFFER_SLOT,
+    // indicating that no buffer slot is currently bound to the texture. Note,
+    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+    // that no buffer is bound to the texture. A call to setBufferCount will
+    // 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 SurfaceEncoder objects. It must be locked whenever the
+    // member variables are accessed.
+    mutable Mutex mMutex;
+
+    ////////////////////////// For MediaSource
+    // Set to a default of 30 fps if not specified by the client side
+    int32_t mFrameRate;
+
+    // mStarted is a flag to check if the recording has started
+    bool mStarted;
+
+    // mFrameAvailableCondition condition used to indicate whether there
+    // is a frame available for dequeuing
+    Condition mFrameAvailableCondition;
+    Condition mFrameCompleteCondition;
+
+    // Avoid copying and equating and default constructor
+    DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceEncoder);
+
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SURFACETEXTURE_H
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index f46f25c..848c5a1 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -55,7 +55,7 @@
 
     PIXEL_FORMAT_OPAQUE         = -1,
         // System chooses an opaque format (no alpha bits required)
-    
+
     // real pixel formats supported for rendering -----------------------------
 
     PIXEL_FORMAT_RGBA_8888   = HAL_PIXEL_FORMAT_RGBA_8888,  // 4x8-bit RGBA
@@ -84,7 +84,7 @@
         INDEX_GREEN   = 2,
         INDEX_BLUE    = 3
     };
-    
+
     enum { // components
         ALPHA               = 1,
         RGB                 = 2,
@@ -98,10 +98,10 @@
         uint8_t h;
         uint8_t l;
     };
-    
+
     inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { }
     size_t getScanlineSize(unsigned int width) const;
-    size_t getSize(size_t ci) const { 
+    size_t getSize(size_t ci) const {
         return (ci <= 3) ? (cinfo[ci].h - cinfo[ci].l) : 0;
     }
     size_t      version;
@@ -112,7 +112,7 @@
         szinfo      cinfo[4];
         struct {
             uint8_t     h_alpha;
-            uint8_t     l_alpha;    
+            uint8_t     l_alpha;
             uint8_t     h_red;
             uint8_t     l_red;
             uint8_t     h_green;
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index e17e1e8..67c0ea4 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -42,6 +42,7 @@
         SampleTable.cpp                   \
         StagefrightMediaScanner.cpp       \
         StagefrightMetadataRetriever.cpp  \
+        SurfaceEncoder.cpp                \
         ThrottledSource.cpp               \
         TimeSource.cpp                    \
         TimedEventQueue.cpp               \
diff --git a/media/libstagefright/SurfaceEncoder.cpp b/media/libstagefright/SurfaceEncoder.cpp
new file mode 100644
index 0000000..e4c1938
--- /dev/null
+++ b/media/libstagefright/SurfaceEncoder.cpp
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "SurfaceEncoder"
+
+#include <media/stagefright/SurfaceEncoder.h>
+#include <ui/GraphicBuffer.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/openmax/OMX_IVCommon.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <OMX_Component.h>
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+namespace android {
+
+SurfaceEncoder::SurfaceEncoder(uint32_t bufW, uint32_t bufH) :
+    mDefaultWidth(bufW),
+    mDefaultHeight(bufH),
+    mPixelFormat(0),
+    mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+    mClientBufferCount(0),
+    mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+    mCurrentSlot(INVALID_BUFFER_SLOT),
+    mCurrentTimestamp(0),
+    mSynchronousMode(true),
+    mConnectedApi(NO_CONNECTED_API),
+    mFrameRate(30),
+    mStarted(false)   {
+    LOGV("SurfaceEncoder::SurfaceEncoder");
+    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
+}
+
+SurfaceEncoder::~SurfaceEncoder() {
+    LOGV("SurfaceEncoder::~SurfaceEncoder");
+    if (mStarted) {
+        stop();
+    }
+    freeAllBuffers();
+}
+
+size_t SurfaceEncoder::getQueuedCount() const {
+    Mutex::Autolock lock(mMutex);
+    return mQueue.size();
+}
+
+status_t SurfaceEncoder::setBufferCountServerLocked(int bufferCount) {
+    if (bufferCount > NUM_BUFFER_SLOTS)
+        return BAD_VALUE;
+
+    // special-case, nothing to do
+    if (bufferCount == mBufferCount)
+        return OK;
+
+    if (!mClientBufferCount &&
+        bufferCount >= mBufferCount) {
+        // easy, we just have more buffers
+        mBufferCount = bufferCount;
+        mServerBufferCount = bufferCount;
+        mDequeueCondition.signal();
+    } else {
+        // we're here because we're either
+        // - reducing the number of available buffers
+        // - or there is a client-buffer-count in effect
+
+        // less than 2 buffers is never allowed
+        if (bufferCount < 2)
+            return BAD_VALUE;
+
+        // when there is non client-buffer-count in effect, the client is not
+        // allowed to dequeue more than one buffer at a time,
+        // so the next time they dequeue a buffer, we know that they don't
+        // own one. the actual resizing will happen during the next
+        // dequeueBuffer.
+
+        mServerBufferCount = bufferCount;
+    }
+    return OK;
+}
+
+// Called from the consumer side
+status_t SurfaceEncoder::setBufferCountServer(int bufferCount) {
+    Mutex::Autolock lock(mMutex);
+    return setBufferCountServerLocked(bufferCount);
+}
+
+status_t SurfaceEncoder::setBufferCount(int bufferCount) {
+    LOGV("SurfaceEncoder::setBufferCount");
+    if (bufferCount > NUM_BUFFER_SLOTS) {
+        LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+    // Error out if the user has dequeued buffers
+    for (int i = 0 ; i < mBufferCount ; i++) {
+        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
+            LOGE("setBufferCount: client owns some buffers");
+            return INVALID_OPERATION;
+        }
+    }
+
+    if (bufferCount == 0) {
+        const int minBufferSlots = mSynchronousMode ?
+                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+        mClientBufferCount = 0;
+        bufferCount = (mServerBufferCount >= minBufferSlots) ?
+                mServerBufferCount : minBufferSlots;
+        return setBufferCountServerLocked(bufferCount);
+    }
+
+    // We don't allow the client to set a buffer-count less than
+    // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
+    if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
+        return BAD_VALUE;
+    }
+
+    // here we're guaranteed that the client doesn't have dequeued buffers
+    // and will release all of its buffer references.
+    freeAllBuffers();
+    mBufferCount = bufferCount;
+    mClientBufferCount = bufferCount;
+    mCurrentSlot = INVALID_BUFFER_SLOT;
+    mQueue.clear();
+    mDequeueCondition.signal();
+    return OK;
+}
+
+sp<GraphicBuffer> SurfaceEncoder::requestBuffer(int buf) {
+    LOGV("SurfaceEncoder::requestBuffer");
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || mBufferCount <= buf) {
+        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
+                mBufferCount, buf);
+        return 0;
+    }
+    mSlots[buf].mRequestBufferCalled = true;
+    return mSlots[buf].mGraphicBuffer;
+}
+
+status_t SurfaceEncoder::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
+                                            uint32_t format, uint32_t usage) {
+    LOGV("dequeueBuffer");
+
+
+    // Check for the buffer size- the client should just use the
+    // default width and height, and not try to set those.
+    // This is needed since
+    // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
+    // queried by OMX in the beginning and not every time a frame comes.
+    // Not sure if there is  a way to update the
+    // frame size while recording. So as of now, the client side
+    // sets the default values via the constructor, and the encoder is
+    // setup to encode frames of that size
+    // The design might need to change in the future.
+    // TODO: Currently just uses mDefaultWidth/Height. In the future
+    // we might declare mHeight and mWidth and check against those here.
+    if ((w != 0) || (h != 0)) {
+        LOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
+                mDefaultWidth, mDefaultHeight, w, h);
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+
+    status_t returnFlags(OK);
+
+    int found, foundSync;
+    int dequeuedCount = 0;
+    bool tryAgain = true;
+    while (tryAgain) {
+        // We need to wait for the FIFO to drain if the number of buffer
+        // needs to change.
+        //
+        // The condition "number of buffer needs to change" is true if
+        // - the client doesn't care about how many buffers there are
+        // - AND the actual number of buffer is different from what was
+        //   set in the last setBufferCountServer()
+        //                         - OR -
+        //   setBufferCountServer() was set to a value incompatible with
+        //   the synchronization mode (for instance because the sync mode
+        //   changed since)
+        //
+        // As long as this condition is true AND the FIFO is not empty, we
+        // wait on mDequeueCondition.
+
+        int minBufferCountNeeded = mSynchronousMode ?
+                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+
+        if (!mClientBufferCount &&
+                ((mServerBufferCount != mBufferCount) ||
+                        (mServerBufferCount < minBufferCountNeeded))) {
+            // wait for the FIFO to drain
+            while (!mQueue.isEmpty()) {
+                LOGV("Waiting for the FIFO to drain");
+                mDequeueCondition.wait(mMutex);
+            }
+            // need to check again since the mode could have changed
+            // while we were waiting
+            minBufferCountNeeded = mSynchronousMode ?
+                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+        }
+
+        if (!mClientBufferCount &&
+                ((mServerBufferCount != mBufferCount) ||
+                        (mServerBufferCount < minBufferCountNeeded))) {
+            // here we're guaranteed that mQueue is empty
+            freeAllBuffers();
+            mBufferCount = mServerBufferCount;
+            if (mBufferCount < minBufferCountNeeded)
+                mBufferCount = minBufferCountNeeded;
+            mCurrentSlot = INVALID_BUFFER_SLOT;
+            returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
+        }
+
+        // look for a free buffer to give to the client
+        found = INVALID_BUFFER_SLOT;
+        foundSync = INVALID_BUFFER_SLOT;
+        dequeuedCount = 0;
+        for (int i = 0; i < mBufferCount; i++) {
+            const int state = mSlots[i].mBufferState;
+            if (state == BufferSlot::DEQUEUED) {
+                dequeuedCount++;
+                continue; // won't be continuing if could
+                // dequeue a non 'FREE' current slot like
+                // that in SurfaceTexture
+            }
+            // In case of Encoding, we do not deque the mCurrentSlot buffer
+            //  since we follow synchronous mode (unlike possibly in
+            //  SurfaceTexture that could be using the asynch mode
+            //  or has some mechanism in GL to be able to wait till the
+            //  currentslot is done using the data)
+            // Here, we have to wait for the MPEG4Writer(or equiv)
+            // to tell us when it's done using the current buffer
+            if (state == BufferSlot::FREE) {
+                foundSync = i;
+                // Unlike that in SurfaceTexture,
+                // We don't need to worry if it is the
+                // currentslot or not as it is in state FREE
+                found = i;
+                break;
+            }
+        }
+
+        // clients are not allowed to dequeue more than one buffer
+        // if they didn't set a buffer count.
+        if (!mClientBufferCount && dequeuedCount) {
+            return -EINVAL;
+        }
+
+        // See whether a buffer has been queued since the last setBufferCount so
+        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
+        bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
+        if (bufferHasBeenQueued) {
+            // make sure the client is not trying to dequeue more buffers
+            // than allowed.
+            const int avail = mBufferCount - (dequeuedCount+1);
+            if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
+                LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
+                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
+                        dequeuedCount);
+                return -EBUSY;
+            }
+        }
+
+        // we're in synchronous mode and didn't find a buffer, we need to wait
+        // for for some buffers to be consumed
+        tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
+        if (tryAgain) {
+            LOGW("Waiting..In synchronous mode and no buffer to dQ");
+            mDequeueCondition.wait(mMutex);
+        }
+    }
+
+    if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
+        // foundSync guaranteed to be != INVALID_BUFFER_SLOT
+        found = foundSync;
+    }
+
+    if (found == INVALID_BUFFER_SLOT) {
+        return -EBUSY;
+    }
+
+    const int buf = found;
+    *outBuf = found;
+
+    const bool useDefaultSize = !w && !h;
+    if (useDefaultSize) {
+        // use the default size
+        w = mDefaultWidth;
+        h = mDefaultHeight;
+    }
+
+    const bool updateFormat = (format != 0);
+    if (!updateFormat) {
+        // keep the current (or default) format
+        format = mPixelFormat;
+    }
+
+    // buffer is now in DEQUEUED (but can also be current at the same time,
+    // if we're in synchronous mode)
+    mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
+
+    const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+    if ((buffer == NULL) ||
+        (uint32_t(buffer->width)  != w) ||
+        (uint32_t(buffer->height) != h) ||
+        (uint32_t(buffer->format) != format) ||
+        ((uint32_t(buffer->usage) & usage) != usage)) {
+            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+            status_t error;
+            sp<GraphicBuffer> graphicBuffer(
+                    mGraphicBufferAlloc->createGraphicBuffer(
+                                    w, h, format, usage, &error));
+            if (graphicBuffer == 0) {
+                LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
+                return error;
+            }
+            if (updateFormat) {
+                mPixelFormat = format;
+            }
+            mSlots[buf].mGraphicBuffer = graphicBuffer;
+            mSlots[buf].mRequestBufferCalled = false;
+            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
+    }
+    return returnFlags;
+}
+
+status_t SurfaceEncoder::setSynchronousMode(bool enabled) {
+    Mutex::Autolock lock(mMutex);
+
+    status_t err = OK;
+    if (!enabled) {
+        // going to asynchronous mode, drain the queue
+        while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
+            mDequeueCondition.wait(mMutex);
+        }
+    }
+
+    if (mSynchronousMode != enabled) {
+        // - if we're going to asynchronous mode, the queue is guaranteed to be
+        // empty here
+        // - if the client set the number of buffers, we're guaranteed that
+        // we have at least 3 (because we don't allow less)
+        mSynchronousMode = enabled;
+        mDequeueCondition.signal();
+    }
+    return err;
+}
+
+status_t SurfaceEncoder::connect(int api) {
+    LOGV("SurfaceEncoder::connect");
+    Mutex::Autolock lock(mMutex);
+    int err = NO_ERROR;
+    switch (api) {
+        case NATIVE_WINDOW_API_EGL:
+        case NATIVE_WINDOW_API_CPU:
+        case NATIVE_WINDOW_API_MEDIA:
+        case NATIVE_WINDOW_API_CAMERA:
+            if (mConnectedApi != NO_CONNECTED_API) {
+                err = -EINVAL;
+            } else {
+                mConnectedApi = api;
+            }
+            break;
+        default:
+            err = -EINVAL;
+            break;
+    }
+    return err;
+}
+
+status_t SurfaceEncoder::disconnect(int api) {
+    LOGV("SurfaceEncoder::disconnect");
+    Mutex::Autolock lock(mMutex);
+    int err = NO_ERROR;
+    switch (api) {
+        case NATIVE_WINDOW_API_EGL:
+        case NATIVE_WINDOW_API_CPU:
+        case NATIVE_WINDOW_API_MEDIA:
+        case NATIVE_WINDOW_API_CAMERA:
+            if (mConnectedApi == api) {
+                mConnectedApi = NO_CONNECTED_API;
+            } else {
+                err = -EINVAL;
+            }
+            break;
+        default:
+            err = -EINVAL;
+            break;
+    }
+    return err;
+}
+
+status_t SurfaceEncoder::queueBuffer(int buf, int64_t timestamp,
+        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+    LOGV("queueBuffer");
+
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || buf >= mBufferCount) {
+        LOGE("queueBuffer: slot index out of range [0, %d]: %d",
+                mBufferCount, buf);
+        return -EINVAL;
+    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+        LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
+                buf, mSlots[buf].mBufferState);
+        return -EINVAL;
+    } else if (!mSlots[buf].mRequestBufferCalled) {
+        LOGE("queueBuffer: slot %d was enqueued without requesting a "
+                "buffer", buf);
+        return -EINVAL;
+    }
+
+    if (mSynchronousMode) {
+        // in synchronous mode we queue all buffers in a FIFO
+        mQueue.push_back(buf);
+        LOGV("Client queued buffer on slot: %d, Q size = %d",
+                                                buf, mQueue.size());
+    } else {
+        // in asynchronous mode we only keep the most recent buffer
+        if (mQueue.empty()) {
+            mQueue.push_back(buf);
+        } else {
+            Fifo::iterator front(mQueue.begin());
+            // buffer currently queued is freed
+            mSlots[*front].mBufferState = BufferSlot::FREE;
+            // and we record the new buffer index in the queued list
+            *front = buf;
+        }
+    }
+
+    mSlots[buf].mBufferState = BufferSlot::QUEUED;
+    mSlots[buf].mTimestamp = timestamp;
+    // TODO: (Confirm) Don't want to signal dequeue here.
+    // May be just in asynchronous mode?
+    // mDequeueCondition.signal();
+
+    // Once the queuing is done, we need to let the listener
+    // and signal the buffer consumer (encoder) know that a
+    // buffer is available
+    onFrameReceivedLocked();
+
+    *outWidth = mDefaultWidth;
+    *outHeight = mDefaultHeight;
+    *outTransform = 0;
+
+    return OK;
+}
+
+
+// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
+// or listeners that a frame has been received
+// It is supposed to be called only from queuebuffer.
+// 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
+status_t SurfaceEncoder::onFrameReceivedLocked() {
+    LOGV("On Frame Received");
+    // Signal the encoder that a new frame has arrived
+    mFrameAvailableCondition.signal();
+
+    // call back the listener
+    // TODO: The listener may not be needed in SurfaceEncoder at all.
+    // This can be made a SurfaceTexture specific thing
+    sp<FrameAvailableListener> listener;
+    if (mSynchronousMode || mQueue.empty()) {
+        listener = mFrameAvailableListener;
+    }
+
+    if (listener != 0) {
+        listener->onFrameAvailable();
+    }
+    return OK;
+}
+
+
+void SurfaceEncoder::cancelBuffer(int buf) {
+    LOGV("SurfaceEncoder::cancelBuffer");
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || buf >= mBufferCount) {
+        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
+                mBufferCount, buf);
+        return;
+    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+        LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
+                buf, mSlots[buf].mBufferState);
+        return;
+    }
+    mSlots[buf].mBufferState = BufferSlot::FREE;
+    mDequeueCondition.signal();
+}
+
+nsecs_t SurfaceEncoder::getTimestamp() {
+    LOGV("SurfaceEncoder::getTimestamp");
+    Mutex::Autolock lock(mMutex);
+    return mCurrentTimestamp;
+}
+
+
+void SurfaceEncoder::setFrameAvailableListener(
+        const sp<FrameAvailableListener>& listener) {
+    LOGV("SurfaceEncoder::setFrameAvailableListener");
+    Mutex::Autolock lock(mMutex);
+    mFrameAvailableListener = listener;
+}
+
+sp<IBinder> SurfaceEncoder::getAllocator() {
+    LOGV("getAllocator");
+    return mGraphicBufferAlloc->asBinder();
+}
+
+
+void SurfaceEncoder::freeAllBuffers() {
+    LOGV("freeAllBuffers");
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        mSlots[i].mGraphicBuffer = 0;
+        mSlots[i].mBufferState = BufferSlot::FREE;
+    }
+}
+
+sp<GraphicBuffer> SurfaceEncoder::getCurrentBuffer() const {
+    Mutex::Autolock lock(mMutex);
+    return mCurrentBuf;
+}
+
+int SurfaceEncoder::query(int what, int* outValue)
+{
+    LOGV("query");
+    Mutex::Autolock lock(mMutex);
+    int value;
+    switch (what) {
+    case NATIVE_WINDOW_WIDTH:
+        value = mDefaultWidth;
+        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+            value = mCurrentBuf->width;
+        break;
+    case NATIVE_WINDOW_HEIGHT:
+        value = mDefaultHeight;
+        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+            value = mCurrentBuf->height;
+        break;
+    case NATIVE_WINDOW_FORMAT:
+        value = mPixelFormat;
+        break;
+    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+        value = mSynchronousMode ?
+                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    outValue[0] = value;
+    return NO_ERROR;
+}
+
+void SurfaceEncoder::dump(String8& result) const
+{
+    char buffer[1024];
+    dump(result, "", buffer, 1024);
+}
+
+void SurfaceEncoder::dump(String8& result, const char* prefix,
+        char* buffer, size_t SIZE) const
+{
+    Mutex::Autolock _l(mMutex);
+    snprintf(buffer, SIZE,
+            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+            "mPixelFormat=%d, \n",
+            prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
+            mPixelFormat);
+    result.append(buffer);
+
+    String8 fifo;
+    int fifoSize = 0;
+    Fifo::const_iterator i(mQueue.begin());
+    while (i != mQueue.end()) {
+        snprintf(buffer, SIZE, "%02d ", *i++);
+        fifoSize++;
+        fifo.append(buffer);
+    }
+
+    result.append(buffer);
+
+    struct {
+        const char * operator()(int state) const {
+            switch (state) {
+                case BufferSlot::DEQUEUED: return "DEQUEUED";
+                case BufferSlot::QUEUED: return "QUEUED";
+                case BufferSlot::FREE: return "FREE";
+                default: return "Unknown";
+            }
+        }
+    } stateName;
+
+    for (int i = 0; i < mBufferCount; i++) {
+        const BufferSlot& slot(mSlots[i]);
+        snprintf(buffer, SIZE,
+                "%s%s[%02d] state=%-8s, "
+                "timestamp=%lld\n",
+                prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
+                slot.mTimestamp
+        );
+        result.append(buffer);
+    }
+}
+
+void SurfaceEncoder::setFrameRate(uint32_t fps)
+{
+    Mutex::Autolock lock(mMutex);
+    mFrameRate = fps;
+}
+
+uint32_t SurfaceEncoder::getFrameRate( ) const {
+    Mutex::Autolock lock(mMutex);
+    return mFrameRate;
+}
+
+status_t SurfaceEncoder::start(MetaData *params)
+{
+    LOGV("start");
+    Mutex::Autolock lock(mMutex);
+    CHECK(!mStarted);
+    mStarted = true;
+    return OK;
+}
+
+
+status_t SurfaceEncoder::stop()
+{
+    LOGV("Stop");
+
+    Mutex::Autolock lock(mMutex);
+    // TODO: Add waiting on mFrameCompletedCondition here?
+    mStarted = false;
+    mFrameAvailableCondition.signal();
+
+    return OK;
+}
+
+sp<MetaData> SurfaceEncoder::getFormat()
+{
+    LOGV("getFormat");
+    Mutex::Autolock autoLock(mMutex);
+    sp<MetaData> meta = new MetaData;
+    // XXX: Check if this is right. or should we wait on some
+    // condition?
+    meta->setInt32(kKeyWidth, mDefaultWidth);
+    meta->setInt32(kKeyHeight, mDefaultHeight);
+    // The encoder format is set as an opaque colorformat
+    // The encoder will later find out the actual colorformat
+    // from the GL Frames itself.
+    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
+    meta->setInt32(kKeyStride, mDefaultWidth);
+    meta->setInt32(kKeySliceHeight, mDefaultHeight);
+    meta->setInt32(kKeyFrameRate, mFrameRate);
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
+    return meta;
+}
+
+status_t SurfaceEncoder::read( MediaBuffer **buffer,
+                                const ReadOptions *options)
+{
+    LOGV("Read. Size of queued buffer: %d", mQueue.size());
+    *buffer = NULL;
+
+    Mutex::Autolock autoLock(mMutex) ;
+    // If the recording has started and the queue is empty, then just
+    // wait here till the frames come in from the client side
+    while (mStarted && mQueue.empty()) {
+        LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
+        mFrameAvailableCondition.wait(mMutex);
+    }
+
+    // If the loop was exited as a result of stopping the recording,
+    // it is OK
+    if (!mStarted) {
+        return OK;
+    }
+
+    // Update the current buffer info
+    // TODO: mCurrentSlot can be made a bufferstate since there
+    // can be more than one "current" slots.
+    Fifo::iterator front(mQueue.begin());
+    mCurrentSlot = *front;
+    mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
+    mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
+
+    // Pass the data to the MediaBuffer
+    // TODO: Change later to pass in only the metadata
+    *buffer = new MediaBuffer(mCurrentBuf);
+    (*buffer)->setObserver(this);
+    (*buffer)->add_ref();
+    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
+
+    return OK;
+}
+
+void SurfaceEncoder::signalBufferReturned(MediaBuffer *buffer) {
+    LOGV("signalBufferReturned");
+
+    bool foundBuffer = false;
+    Mutex::Autolock autoLock(mMutex);
+
+    if (!mStarted) {
+        LOGV("started = false. Nothing to do");
+        return;
+    }
+
+    for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
+        if (mSlots[*it].mGraphicBuffer  ==  buffer->graphicBuffer()) {
+            LOGV("Buffer %d returned. Setting it 'FREE'. New Queue size = %d",
+                    *it, mQueue.size()-1);
+            mSlots[*it].mBufferState = BufferSlot::FREE;
+            mQueue.erase(it);
+            buffer->setObserver(0);
+            buffer->release();
+            mDequeueCondition.signal();
+            mFrameCompleteCondition.signal();
+            foundBuffer = true;
+            break;
+        }
+    }
+
+    if (!foundBuffer) {
+        CHECK_EQ(0, "signalBufferReturned: bogus buffer");
+    }
+}
+
+
+
+} // end of namespace android
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
new file mode 100644
index 0000000..89d80a9
--- /dev/null
+++ b/media/libstagefright/tests/Android.mk
@@ -0,0 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_MODULE := SurfaceEncoder_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+    SurfaceEncoder_test.cpp \
+	DummyRecorder.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	libEGL \
+	libGLESv2 \
+	libandroid \
+	libbinder \
+	libcutils \
+	libgui \
+	libstlport \
+	libui \
+	libutils \
+	libstagefright \
+	libstagefright_omx \
+	libstagefright_foundation \
+
+LOCAL_STATIC_LIBRARIES := \
+	libgtest \
+	libgtest_main \
+
+LOCAL_C_INCLUDES := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport \
+	frameworks/base/media/libstagefright \
+	frameworks/base/media/libstagefright/include \
+	$(TOP)/frameworks/base/include/media/stagefright/openmax \
+
+include $(BUILD_EXECUTABLE)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/media/libstagefright/tests/DummyRecorder.cpp b/media/libstagefright/tests/DummyRecorder.cpp
new file mode 100644
index 0000000..8d75d6b
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DummyRecorder"
+// #define LOG_NDEBUG 0
+
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include "DummyRecorder.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+// static
+void *DummyRecorder::threadWrapper(void *pthis) {
+    LOGV("ThreadWrapper: %p", pthis);
+    DummyRecorder *writer = static_cast<DummyRecorder *>(pthis);
+    writer->readFromSource();
+    return NULL;
+}
+
+
+status_t DummyRecorder::start() {
+    LOGV("Start");
+    mStarted = true;
+
+    mSource->start();
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    int err = pthread_create(&mThread, &attr, threadWrapper, this);
+    pthread_attr_destroy(&attr);
+
+    if (err) {
+        LOGE("Error creating thread!");
+        return -ENODEV;
+    }
+    return OK;
+}
+
+
+status_t DummyRecorder::stop() {
+    LOGV("Stop");
+    mStarted = false;
+
+    mSource->stop();
+    void *dummy;
+    pthread_join(mThread, &dummy);
+    status_t err = (status_t) dummy;
+
+    LOGV("Ending the reading thread");
+    return err;
+}
+
+// pretend to read the source buffers
+void DummyRecorder::readFromSource() {
+    LOGV("ReadFromSource");
+    if (!mStarted) {
+        return;
+    }
+
+    status_t err = OK;
+    MediaBuffer *buffer;
+    LOGV("A fake writer accessing the frames");
+    while (mStarted && (err = mSource->read(&buffer)) == OK){
+        // if not getting a valid buffer from source, then exit
+        if (buffer == NULL) {
+            return;
+        }
+        buffer->release();
+        buffer = NULL;
+    }
+}
+
+
+} // end of namespace android
diff --git a/media/libstagefright/tests/DummyRecorder.h b/media/libstagefright/tests/DummyRecorder.h
new file mode 100644
index 0000000..1cbea1b
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DUMMY_RECORDER_H_
+#define DUMMY_RECORDER_H_
+
+#include <pthread.h>
+#include <utils/String8.h>
+#include <media/stagefright/foundation/ABase.h>
+
+
+namespace android {
+
+class MediaSource;
+class MediaBuffer;
+
+class DummyRecorder {
+    public:
+    // The media source from which this will receive frames
+    sp<MediaSource> mSource;
+    bool mStarted;
+    pthread_t mThread;
+
+    status_t start();
+    status_t stop();
+
+    // actual entry point for the thread
+    void readFromSource();
+
+    // static function to wrap the actual thread entry point
+    static void *threadWrapper(void *pthis);
+
+    DummyRecorder(const sp<MediaSource> &source) : mSource(source)
+                                                    , mStarted(false) {}
+    ~DummyRecorder( ) {}
+
+    private:
+
+    DISALLOW_EVIL_CONSTRUCTORS(DummyRecorder);
+};
+
+} // end of namespace android
+#endif
+
+
diff --git a/media/libstagefright/tests/SurfaceEncoder_test.cpp b/media/libstagefright/tests/SurfaceEncoder_test.cpp
new file mode 100644
index 0000000..65ce7cc
--- /dev/null
+++ b/media/libstagefright/tests/SurfaceEncoder_test.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceEncoder_test"
+// #define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+#include <utils/String8.h>
+#include <utils/Errors.h>
+
+#include <media/stagefright/SurfaceEncoder.h>
+
+#include <gui/SurfaceTextureClient.h>
+#include <ui/GraphicBuffer.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <binder/ProcessState.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <OMX_Component.h>
+
+#include "DummyRecorder.h"
+
+namespace android {
+
+
+class SurfaceEncoderTest : public ::testing::Test {
+public:
+
+    SurfaceEncoderTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
+    sp<MPEG4Writer>  setUpWriter(OMXClient &client );
+    void oneBufferPass(int width, int height );
+    static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
+    static void fillYV12BufferRect(uint8_t* buf, int w, int h,
+                        int stride, const android_native_rect_t& rect) ;
+protected:
+
+    virtual void SetUp() {
+        mSE = new SurfaceEncoder(mYuvTexWidth, mYuvTexHeight);
+        mSE->setSynchronousMode(true);
+        mSTC = new SurfaceTextureClient(mSE);
+        mANW = mSTC;
+
+    }
+
+
+    virtual void TearDown() {
+        mSE.clear();
+        mSTC.clear();
+        mANW.clear();
+    }
+
+    const int mYuvTexWidth;//  = 64;
+    const int mYuvTexHeight;// = 66;
+
+    sp<SurfaceEncoder> mSE;
+    sp<SurfaceTextureClient> mSTC;
+    sp<ANativeWindow> mANW;
+
+};
+
+void SurfaceEncoderTest::oneBufferPass(int width, int height ) {
+    LOGV("One Buffer Pass");
+    ANativeWindowBuffer* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    SurfaceEncoderTest::fillYV12Buffer(img, width, height, buf->getStride());
+    buf->unlock();
+
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+}
+
+sp<MPEG4Writer> SurfaceEncoderTest::setUpWriter(OMXClient &client ) {
+    // Writing to a file
+    const char *fileName = "/sdcard/outputSurfEnc.mp4";
+    sp<MetaData> enc_meta = new MetaData;
+    enc_meta->setInt32(kKeyBitRate, 300000);
+    enc_meta->setInt32(kKeyFrameRate, 30);
+
+    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
+
+    sp<MetaData> meta = mSE->getFormat();
+
+    int32_t width, height, stride, sliceHeight, colorFormat;
+    CHECK(meta->findInt32(kKeyWidth, &width));
+    CHECK(meta->findInt32(kKeyHeight, &height));
+    CHECK(meta->findInt32(kKeyStride, &stride));
+    CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
+    CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
+
+    enc_meta->setInt32(kKeyWidth, width);
+    enc_meta->setInt32(kKeyHeight, height);
+    enc_meta->setInt32(kKeyIFramesInterval, 1);
+    enc_meta->setInt32(kKeyStride, stride);
+    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
+    // TODO: overwriting the colorformat since the format set by GRAlloc
+    // could be wrong or not be read by OMX
+    enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+    // colorFormat);
+
+
+    sp<MediaSource> encoder =
+        OMXCodec::Create(
+                client.interface(), enc_meta, true /* createEncoder */, mSE);
+
+    sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
+    writer->addSource(encoder);
+
+    return writer;
+}
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void SurfaceEncoderTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+    const int blockWidth = w > 16 ? w / 16 : 1;
+    const int blockHeight = h > 16 ? h / 16 : 1;
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < w / 2 && y < h / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (x * 2 < w / 2 && y * 2 < h / 2) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+                        intensity;
+                }
+            }
+        }
+    }
+}
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void SurfaceEncoderTest::fillYV12BufferRect(uint8_t* buf, int w,
+                  int h, int stride, const android_native_rect_t& rect) {
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            bool inside = rect.left <= x && x < rect.right &&
+                    rect.top <= y && y < rect.bottom;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+            if (x < w / 2 && y < h / 2) {
+                bool inside = rect.left <= 2*x && 2*x < rect.right &&
+                        rect.top <= 2*y && 2*y < rect.bottom;
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+                                                inside ? 16 : 255;
+            }
+        }
+    }
+}  ///////// End of class SurfaceEncoderTest
+
+///////////////////////////////////////////////////////////////////
+// Class to imitate the recording     /////////////////////////////
+// ////////////////////////////////////////////////////////////////
+struct SimpleDummyRecorder {
+        sp<MediaSource> mSource;
+
+        SimpleDummyRecorder
+                (const sp<MediaSource> &source): mSource(source) {}
+
+        status_t start() { return mSource->start();}
+        status_t stop()  { return mSource->stop();}
+
+        // fakes reading from a media source
+        status_t readFromSource() {
+            MediaBuffer *buffer;
+            status_t err = mSource->read(&buffer);
+            if (err != OK) {
+                return err;
+            }
+            buffer->release();
+            buffer = NULL;
+            return OK;
+        }
+};
+
+///////////////////////////////////////////////////////////////////
+//           TESTS
+// Just pass one buffer from the native_window to the SurfaceEncoder
+TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
+    LOGV("Testing OneBufferPass ******************************");
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            0, 0, HAL_PIXEL_FORMAT_YV12));
+                                // OMX_COLOR_FormatYUV420Planar)); // ));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+}
+
+// Pass the buffer with the wrong height and weight and should not be accepted
+TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
+    LOGV("Testing Wrong size BufferPass ******************************");
+
+    // setting the client side buffer size different than the server size
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+             10, 10, HAL_PIXEL_FORMAT_YV12));
+                                // OMX_COLOR_FormatYUV420Planar)); // ));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    ANativeWindowBuffer* anb;
+
+    // make sure we get an error back when dequeuing!
+    ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+}
+
+
+// pass multiple buffers from the native_window the SurfaceEncoder
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceEncoderTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+    LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            0, 0, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    SimpleDummyRecorder writer(mSE);
+    writer.start();
+
+    int32_t nFramesCount = 0;
+    while (nFramesCount < 300) {
+        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+        ASSERT_EQ(NO_ERROR, writer.readFromSource());
+
+        nFramesCount++;
+    }
+    writer.stop();
+}
+
+// Delayed pass of multiple buffers from the native_window the SurfaceEncoder
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceEncoderTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
+    LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            0, 0, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    SimpleDummyRecorder writer(mSE);
+    writer.start();
+
+    int32_t nFramesCount = 1;
+    const int FRAMES_LAG = mSE->getBufferCount() - 1;
+    while (nFramesCount <= 300) {
+        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+        // Forcing the writer to lag behind a few frames
+        if (nFramesCount > FRAMES_LAG) {
+            ASSERT_EQ(NO_ERROR, writer.readFromSource());
+        }
+        nFramesCount++;
+    }
+    writer.stop();
+}
+
+// pass multiple buffers from the native_window the SurfaceEncoder
+// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
+TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
+    LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            0, 0, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    DummyRecorder writer(mSE);
+    writer.start();
+
+    int32_t nFramesCount = 0;
+    while (nFramesCount <= 300) {
+        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+        nFramesCount++;
+    }
+    writer.stop();
+}
+
+// Test to examine the actual encoding. Temporarily disabled till the
+// colorformat and encoding from GRAlloc data is resolved
+TEST_F(SurfaceEncoderTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
+    LOGV("Testing the whole pipeline with actual Recorder");
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // ));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    OMXClient client;
+    CHECK_EQ(OK, client.connect());
+
+    sp<MPEG4Writer> writer = setUpWriter(client);
+    int64_t start = systemTime();
+    CHECK_EQ(OK, writer->start());
+
+    int32_t nFramesCount = 0;
+    while (nFramesCount <= 300) {
+        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+        nFramesCount++;
+    }
+
+    CHECK_EQ(OK, writer->stop());
+    writer.clear();
+    int64_t end = systemTime();
+    client.disconnect();
+}
+
+
+} // namespace android
