Merge "Connect MediaRecorder Native to SurfaceMediaSource"
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index a73267d..007aea6 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -26,6 +26,7 @@
 class ICamera;
 class ICameraRecordingProxy;
 class IMediaRecorderClient;
+class ISurfaceTexture;
 
 class IMediaRecorder: public IInterface
 {
@@ -55,6 +56,7 @@
     virtual status_t init() = 0;
     virtual status_t close() = 0;
     virtual status_t release() = 0;
+    virtual sp<ISurfaceTexture> querySurfaceMediaSource() = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index 1c08969..ef799f5 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -26,6 +26,7 @@
 
 class ICameraRecordingProxy;
 class Surface;
+class ISurfaceTexture;
 
 struct MediaRecorderBase {
     MediaRecorderBase() {}
@@ -54,6 +55,7 @@
     virtual status_t reset() = 0;
     virtual status_t getMaxAmplitude(int *max) = 0;
     virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+    virtual sp<ISurfaceTexture> querySurfaceMediaSource() const = 0;
 
 private:
     MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index af12d3c..72d3736 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -31,12 +31,15 @@
 class IMediaRecorder;
 class ICamera;
 class ICameraRecordingProxy;
+class ISurfaceTexture;
+class SurfaceTextureClient;
 
 typedef void (*media_completion_f)(status_t status, void *cookie);
 
 enum video_source {
     VIDEO_SOURCE_DEFAULT = 0,
     VIDEO_SOURCE_CAMERA = 1,
+    VIDEO_SOURCE_GRALLOC_BUFFER = 2,
 
     VIDEO_SOURCE_LIST_END  // must be last - used to validate audio source type
 };
@@ -226,6 +229,7 @@
     status_t    close();
     status_t    release();
     void        notify(int msg, int ext1, int ext2);
+    sp<ISurfaceTexture>     querySurfaceMediaSourceFromMediaServer();
 
 private:
     void                    doCleanUp();
@@ -233,6 +237,12 @@
 
     sp<IMediaRecorder>          mMediaRecorder;
     sp<MediaRecorderListener>   mListener;
+
+    // Reference toISurfaceTexture
+    // for encoding GL Frames. That is useful only when the
+    // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
+    sp<ISurfaceTexture>         mSurfaceMediaSource;
+
     media_recorder_states       mCurrentState;
     bool                        mIsAudioSourceSet;
     bool                        mIsVideoSourceSet;
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index 4251ba9..56bd9c3 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -64,8 +64,8 @@
     virtual sp<MetaData> getFormat();
 
     // Get / Set the frame rate used for encoding. Default fps = 30
-    void setFrameRate(uint32_t fps) ;
-    uint32_t getFrameRate( ) const;
+    status_t setFrameRate(int32_t fps) ;
+    int32_t getFrameRate( ) const;
 
     // The call for the StageFrightRecorder to tell us that
     // it is done using the MediaBuffer data so that its state
@@ -171,7 +171,11 @@
     void dump(String8& result, const char* prefix, char* buffer,
                                                     size_t SIZE) const;
 
-    protected:
+    // isMetaDataStoredInVideoBuffers tells the encoder whether we will
+    // pass metadata through the buffers. Currently, it is force set to true
+    bool isMetaDataStoredInVideoBuffers() const;
+
+protected:
 
     // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
     // all slots.
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index a44ef5a..7e44c29 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -23,14 +23,17 @@
 #include <camera/ICamera.h>
 #include <media/IMediaRecorderClient.h>
 #include <media/IMediaRecorder.h>
+#include <gui/ISurfaceTexture.h>
 #include <unistd.h>
 
+
 namespace android {
 
 enum {
     RELEASE = IBinder::FIRST_CALL_TRANSACTION,
     INIT,
     CLOSE,
+    QUERY_SURFACE_MEDIASOURCE,
     RESET,
     STOP,
     START,
@@ -71,6 +74,19 @@
         return reply.readInt32();
     }
 
+    sp<ISurfaceTexture> querySurfaceMediaSource()
+    {
+        LOGV("Query SurfaceMediaSource");
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
+        int returnedNull = reply.readInt32();
+        if (returnedNull) {
+            return NULL;
+        }
+        return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
+    }
+
     status_t setPreviewSurface(const sp<Surface>& surface)
     {
         LOGV("setPreviewSurface(%p)", surface.get());
@@ -440,6 +456,20 @@
             reply->writeInt32(setCamera(camera, proxy));
             return NO_ERROR;
         } break;
+        case QUERY_SURFACE_MEDIASOURCE: {
+            LOGV("QUERY_SURFACE_MEDIASOURCE");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            // call the mediaserver side to create
+            // a surfacemediasource
+            sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource();
+            // The mediaserver might have failed to create a source
+            int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
+            reply->writeInt32(returnedNull);
+            if (!returnedNull) {
+                reply->writeStrongBinder(surfaceMediaSource->asBinder());
+            }
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 9e4edd0..fab674c 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -25,6 +25,7 @@
 #include <media/IMediaPlayerService.h>
 #include <media/IMediaRecorder.h>
 #include <media/mediaplayer.h>  // for MEDIA_ERROR_SERVER_DIED
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
@@ -127,7 +128,9 @@
         return INVALID_OPERATION;
     }
 
+    // following call is made over the Binder Interface
     status_t ret = mMediaRecorder->setVideoSource(vs);
+
     if (OK != ret) {
         LOGV("setVideoSource failed: %d", ret);
         mCurrentState = MEDIA_RECORDER_ERROR;
@@ -357,7 +360,7 @@
         return INVALID_OPERATION;
     }
     if (!mIsVideoSourceSet) {
-        LOGE("try to set video size without setting video source first");
+        LOGE("Cannot set video size without setting video source first");
         return INVALID_OPERATION;
     }
 
@@ -367,9 +370,27 @@
         mCurrentState = MEDIA_RECORDER_ERROR;
         return ret;
     }
+
     return ret;
 }
 
+// Query a SurfaceMediaSurface through the Mediaserver, over the
+// binder interface. This is used by the Filter Framework (MeidaEncoder)
+// to get an <ISurfaceTexture> object to hook up to ANativeWindow.
+sp<ISurfaceTexture> MediaRecorder::
+        querySurfaceMediaSourceFromMediaServer()
+{
+    Mutex::Autolock _l(mLock);
+    mSurfaceMediaSource =
+            mMediaRecorder->querySurfaceMediaSource();
+    if (mSurfaceMediaSource == NULL) {
+        LOGE("SurfaceMediaSource could not be initialized!");
+    }
+    return mSurfaceMediaSource;
+}
+
+
+
 status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
 {
     LOGV("setVideoFrameRate(%d)", frames_per_second);
@@ -382,7 +403,7 @@
         return INVALID_OPERATION;
     }
     if (!mIsVideoSourceSet) {
-        LOGE("try to set video frame rate without setting video source first");
+        LOGE("Cannot set video frame rate without setting video source first");
         return INVALID_OPERATION;
     }
 
@@ -621,7 +642,7 @@
     return INVALID_OPERATION;
 }
 
-MediaRecorder::MediaRecorder()
+MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
 {
     LOGV("constructor");
 
@@ -632,6 +653,8 @@
     if (mMediaRecorder != NULL) {
         mCurrentState = MEDIA_RECORDER_IDLE;
     }
+
+
     doCleanUp();
 }
 
@@ -646,6 +669,10 @@
     if (mMediaRecorder != NULL) {
         mMediaRecorder.clear();
     }
+
+    if (mSurfaceMediaSource != NULL) {
+        mSurfaceMediaSource.clear();
+    }
 }
 
 status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 115db1a..905b885 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -41,6 +41,7 @@
 #include "MediaPlayerService.h"
 
 #include "StagefrightRecorder.h"
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
@@ -57,6 +58,20 @@
     return ok;
 }
 
+
+sp<ISurfaceTexture> MediaRecorderClient::querySurfaceMediaSource()
+{
+    LOGV("Query SurfaceMediaSource");
+    Mutex::Autolock lock(mLock);
+    if (mRecorder == NULL) {
+        LOGE("recorder is not initialized");
+        return NULL;
+    }
+    return mRecorder->querySurfaceMediaSource();
+}
+
+
+
 status_t MediaRecorderClient::setCamera(const sp<ICamera>& camera,
                                         const sp<ICameraRecordingProxy>& proxy)
 {
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index bbca529..c87a3c0 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -25,45 +25,51 @@
 class MediaRecorderBase;
 class MediaPlayerService;
 class ICameraRecordingProxy;
+class ISurfaceTexture;
 
 class MediaRecorderClient : public BnMediaRecorder
 {
 public:
-    virtual     status_t        setCamera(const sp<ICamera>& camera,
-                                          const sp<ICameraRecordingProxy>& proxy);
-    virtual     status_t        setPreviewSurface(const sp<Surface>& surface);
-    virtual     status_t        setVideoSource(int vs);
-    virtual     status_t        setAudioSource(int as);
-    virtual     status_t        setOutputFormat(int of);
-    virtual     status_t        setVideoEncoder(int ve);
-    virtual     status_t        setAudioEncoder(int ae);
-    virtual     status_t        setOutputFile(const char* path);
-    virtual     status_t        setOutputFile(int fd, int64_t offset, int64_t length);
-    virtual     status_t        setOutputFileAuxiliary(int fd);
-    virtual     status_t        setVideoSize(int width, int height);
-    virtual     status_t        setVideoFrameRate(int frames_per_second);
-    virtual     status_t        setParameters(const String8& params);
-    virtual     status_t        setListener(const sp<IMediaRecorderClient>& listener);
-    virtual     status_t        prepare();
-    virtual     status_t        getMaxAmplitude(int* max);
-    virtual     status_t        start();
-    virtual     status_t        stop();
-    virtual     status_t        reset();
-    virtual     status_t        init();
-    virtual     status_t        close();
-    virtual     status_t        release();
+    virtual     status_t   setCamera(const sp<ICamera>& camera,
+                                    const sp<ICameraRecordingProxy>& proxy);
+    virtual     status_t   setPreviewSurface(const sp<Surface>& surface);
+    virtual     status_t   setVideoSource(int vs);
+    virtual     status_t   setAudioSource(int as);
+    virtual     status_t   setOutputFormat(int of);
+    virtual     status_t   setVideoEncoder(int ve);
+    virtual     status_t   setAudioEncoder(int ae);
+    virtual     status_t   setOutputFile(const char* path);
+    virtual     status_t   setOutputFile(int fd, int64_t offset,
+                                                  int64_t length);
+    virtual     status_t   setOutputFileAuxiliary(int fd);
+    virtual     status_t   setVideoSize(int width, int height);
+    virtual     status_t   setVideoFrameRate(int frames_per_second);
+    virtual     status_t   setParameters(const String8& params);
+    virtual     status_t   setListener(
+                              const sp<IMediaRecorderClient>& listener);
+    virtual     status_t   prepare();
+    virtual     status_t   getMaxAmplitude(int* max);
+    virtual     status_t   start();
+    virtual     status_t   stop();
+    virtual     status_t   reset();
+    virtual     status_t   init();
+    virtual     status_t   close();
+    virtual     status_t   release();
+    virtual     status_t   dump(int fd, const Vector<String16>& args) const;
+    virtual     sp<ISurfaceTexture> querySurfaceMediaSource();
 
-    virtual     status_t        dump(int fd, const Vector<String16>& args) const;
 private:
-    friend class                MediaPlayerService;  // for accessing private constructor
+    friend class           MediaPlayerService;  // for accessing private constructor
 
-                                MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
-    virtual                     ~MediaRecorderClient();
+                           MediaRecorderClient(
+                                   const sp<MediaPlayerService>& service,
+                                                               pid_t pid);
+    virtual                ~MediaRecorderClient();
 
-    pid_t                       mPid;
-    Mutex                       mLock;
-    MediaRecorderBase           *mRecorder;
-    sp<MediaPlayerService>      mMediaPlayerService;
+    pid_t                  mPid;
+    Mutex                  mLock;
+    MediaRecorderBase      *mRecorder;
+    sp<MediaPlayerService> mMediaPlayerService;
 };
 
 }; // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 223e0be..6427bb7 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -38,10 +38,12 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/SurfaceMediaSource.h>
 #include <media/MediaProfiles.h>
 #include <camera/ICamera.h>
 #include <camera/CameraParameters.h>
 #include <surfaceflinger/Surface.h>
+
 #include <utils/Errors.h>
 #include <sys/types.h>
 #include <ctype.h>
@@ -69,7 +71,7 @@
       mOutputFd(-1), mOutputFdAux(-1),
       mAudioSource(AUDIO_SOURCE_CNT),
       mVideoSource(VIDEO_SOURCE_LIST_END),
-      mStarted(false) {
+      mStarted(false), mSurfaceMediaSource(NULL) {
 
     LOGV("Constructor");
     reset();
@@ -85,6 +87,14 @@
     return OK;
 }
 
+// The client side of mediaserver asks it to creat a SurfaceMediaSource
+// and return a interface reference. The client side will use that
+// while encoding GL Frames
+sp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const {
+    LOGV("Get SurfaceMediaSource");
+    return mSurfaceMediaSource;
+}
+
 status_t StagefrightRecorder::setAudioSource(audio_source_t as) {
     LOGV("setAudioSource: %d", as);
     if (as < AUDIO_SOURCE_DEFAULT ||
@@ -1006,13 +1016,13 @@
         source = createAudioSource();
     } else {
 
-        sp<CameraSource> cameraSource;
-        status_t err = setupCameraSource(&cameraSource);
+        sp<MediaSource> mediaSource;
+        status_t err = setupMediaSource(&mediaSource);
         if (err != OK) {
             return err;
         }
 
-        err = setupVideoEncoder(cameraSource, mVideoBitRate, &source);
+        err = setupVideoEncoder(mediaSource, mVideoBitRate, &source);
         if (err != OK) {
             return err;
         }
@@ -1042,20 +1052,19 @@
         }
     }
 
-    if (mVideoSource == VIDEO_SOURCE_DEFAULT
-            || mVideoSource == VIDEO_SOURCE_CAMERA) {
+    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
         if (mVideoEncoder != VIDEO_ENCODER_H264) {
             return ERROR_UNSUPPORTED;
         }
 
-        sp<CameraSource> cameraSource;
-        status_t err = setupCameraSource(&cameraSource);
+        sp<MediaSource> mediaSource;
+        status_t err = setupMediaSource(&mediaSource);
         if (err != OK) {
             return err;
         }
 
         sp<MediaSource> encoder;
-        err = setupVideoEncoder(cameraSource, mVideoBitRate, &encoder);
+        err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder);
 
         if (err != OK) {
             return err;
@@ -1289,6 +1298,60 @@
     }
 }
 
+// Set up the appropriate MediaSource depending on the chosen option
+status_t StagefrightRecorder::setupMediaSource(
+                      sp<MediaSource> *mediaSource) {
+    if (mVideoSource == VIDEO_SOURCE_DEFAULT
+            || mVideoSource == VIDEO_SOURCE_CAMERA) {
+        sp<CameraSource> cameraSource;
+        status_t err = setupCameraSource(&cameraSource);
+        if (err != OK) {
+            return err;
+        }
+        *mediaSource = cameraSource;
+    } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+        // If using GRAlloc buffers, setup surfacemediasource.
+        // Later a handle to that will be passed
+        // to the client side when queried
+        status_t err = setupSurfaceMediaSource();
+        if (err != OK) {
+            return err;
+        }
+        *mediaSource = mSurfaceMediaSource;
+    } else {
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+// setupSurfaceMediaSource creates a source with the given
+// width and height and framerate.
+// TODO: This could go in a static function inside SurfaceMediaSource
+// similar to that in CameraSource
+status_t StagefrightRecorder::setupSurfaceMediaSource() {
+    status_t err = OK;
+    mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight);
+    if (mSurfaceMediaSource == NULL) {
+        return NO_INIT;
+    }
+
+    if (mFrameRate == -1) {
+        int32_t frameRate = 0;
+        CHECK (mSurfaceMediaSource->getFormat()->findInt32(
+                                        kKeyFrameRate, &frameRate));
+        LOGI("Frame rate is not explicitly set. Use the current frame "
+             "rate (%d fps)", frameRate);
+        mFrameRate = frameRate;
+    } else {
+        err = mSurfaceMediaSource->setFrameRate(mFrameRate);
+    }
+    CHECK(mFrameRate != -1);
+
+    mIsMetaDataStoredInVideoBuffers =
+        mSurfaceMediaSource->isMetaDataStoredInVideoBuffers();
+    return err;
+}
+
 status_t StagefrightRecorder::setupCameraSource(
         sp<CameraSource> *cameraSource) {
     status_t err = OK;
@@ -1465,29 +1528,37 @@
     status_t err = OK;
     sp<MediaWriter> writer = new MPEG4Writer(outputFd);
 
-    if (mVideoSource == VIDEO_SOURCE_DEFAULT
-            || mVideoSource == VIDEO_SOURCE_CAMERA) {
+    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
 
-        sp<MediaSource> cameraMediaSource;
+        sp<MediaSource> mediaSource;
         if (useSplitCameraSource) {
+            // TODO: Check if there is a better way to handle this
+            if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+                LOGE("Cannot use split camera when encoding frames");
+                return INVALID_OPERATION;
+            }
             LOGV("Using Split camera source");
-            cameraMediaSource = mCameraSourceSplitter->createClient();
+            mediaSource = mCameraSourceSplitter->createClient();
         } else {
-            sp<CameraSource> cameraSource;
-            err = setupCameraSource(&cameraSource);
-            cameraMediaSource = cameraSource;
+           err = setupMediaSource(&mediaSource);
         }
+
         if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
+            // TODO: Might be able to handle downsampling even if using GRAlloc
+            if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+                LOGE("Cannot change size or Downsample when encoding frames");
+                return INVALID_OPERATION;
+            }
             // Use downsampling from the original source.
-            cameraMediaSource =
-                new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight);
+            mediaSource =
+                new VideoSourceDownSampler(mediaSource, videoWidth, videoHeight);
         }
         if (err != OK) {
             return err;
         }
 
         sp<MediaSource> encoder;
-        err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder);
+        err = setupVideoEncoder(mediaSource, videoBitRate, &encoder);
         if (err != OK) {
             return err;
         }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 034b373..1618b92 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -36,6 +36,8 @@
 class MetaData;
 struct AudioSource;
 class MediaProfiles;
+class ISurfaceTexture;
+class SurfaceMediaSource;
 
 struct StagefrightRecorder : public MediaRecorderBase {
     StagefrightRecorder();
@@ -64,6 +66,8 @@
     virtual status_t reset();
     virtual status_t getMaxAmplitude(int *max);
     virtual status_t dump(int fd, const Vector<String16>& args) const;
+    // Querying a SurfaceMediaSourcer
+    virtual sp<ISurfaceTexture> querySurfaceMediaSource() const;
 
 private:
     sp<ICamera> mCamera;
@@ -109,12 +113,18 @@
     sp<MediaSourceSplitter> mCameraSourceSplitter;
     sp<CameraSourceTimeLapse> mCameraSourceTimeLapse;
 
+
     String8 mParams;
 
     bool mIsMetaDataStoredInVideoBuffers;
     MediaProfiles *mEncoderProfiles;
 
     bool mStarted;
+    // Needed when GLFrames are encoded.
+    // An <ISurfaceTexture> pointer
+    // will be sent to the client side using which the
+    // frame buffers will be queued and dequeued
+    sp<SurfaceMediaSource> mSurfaceMediaSource;
 
     status_t setupMPEG4Recording(
         bool useSplitCameraSource,
@@ -134,7 +144,14 @@
     sp<MediaSource> createAudioSource();
     status_t checkVideoEncoderCapabilities();
     status_t checkAudioEncoderCapabilities();
+    // Generic MediaSource set-up. Returns the appropriate
+    // source (CameraSource or SurfaceMediaSource)
+    // depending on the videosource type
+    status_t setupMediaSource(sp<MediaSource> *mediaSource);
     status_t setupCameraSource(sp<CameraSource> *cameraSource);
+    // setup the surfacemediasource for the encoder
+    status_t setupSurfaceMediaSource();
+
     status_t setupAudioEncoder(const sp<MediaWriter>& writer);
     status_t setupVideoEncoder(
             sp<MediaSource> cameraSource,
@@ -176,6 +193,7 @@
     void clipNumberOfAudioChannels();
     void setDefaultProfileIfNecessary();
 
+
     StagefrightRecorder(const StagefrightRecorder &);
     StagefrightRecorder &operator=(const StagefrightRecorder &);
 };
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 7d08f09..ff4b08f 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -35,18 +35,18 @@
 namespace android {
 
 SurfaceMediaSource::SurfaceMediaSource(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)     {
+                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("SurfaceMediaSource::SurfaceMediaSource");
     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
     mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -373,7 +373,7 @@
 status_t SurfaceMediaSource::connect(int api) {
     LOGV("SurfaceMediaSource::connect");
     Mutex::Autolock lock(mMutex);
-    int err = NO_ERROR;
+    status_t err = NO_ERROR;
     switch (api) {
         case NATIVE_WINDOW_API_EGL:
         case NATIVE_WINDOW_API_CPU:
@@ -395,7 +395,7 @@
 status_t SurfaceMediaSource::disconnect(int api) {
     LOGV("SurfaceMediaSource::disconnect");
     Mutex::Autolock lock(mMutex);
-    int err = NO_ERROR;
+    status_t err = NO_ERROR;
     switch (api) {
         case NATIVE_WINDOW_API_EGL:
         case NATIVE_WINDOW_API_CPU:
@@ -620,13 +620,23 @@
     }
 }
 
-void SurfaceMediaSource::setFrameRate(uint32_t fps)
+status_t SurfaceMediaSource::setFrameRate(int32_t fps)
 {
     Mutex::Autolock lock(mMutex);
+    const int MAX_FRAME_RATE = 60;
+    if (fps < 0 || fps > MAX_FRAME_RATE) {
+        return BAD_VALUE;
+    }
     mFrameRate = fps;
+    return OK;
 }
 
-uint32_t SurfaceMediaSource::getFrameRate( ) const {
+bool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
+    LOGV("isMetaDataStoredInVideoBuffers");
+    return true;
+}
+
+int32_t SurfaceMediaSource::getFrameRate( ) const {
     Mutex::Autolock lock(mMutex);
     return mFrameRate;
 }
@@ -658,8 +668,7 @@
     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