merge in ics-mr1-release history after reset to ics-mr1
diff --git a/lvpp/VideoEditorSRC.cpp b/lvpp/VideoEditorSRC.cpp
index 1ea32ef..364343a 100755
--- a/lvpp/VideoEditorSRC.cpp
+++ b/lvpp/VideoEditorSRC.cpp
@@ -41,6 +41,7 @@
     mBuffer = NULL;
     mLeftover = 0;
     mFormatChanged = false;
+    mStopPending = false;
     mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
 
     // Input Source validation
@@ -127,6 +128,11 @@
         // Resample to target quality
         mResampler->resample(pTmpBuffer, outFrameCnt, this);
 
+        if (mStopPending) {
+            stop();
+            mStopPending = false;
+        }
+
         // Change resampler and retry if format change happened
         if (mFormatChanged) {
             mFormatChanged = false;
@@ -220,7 +226,10 @@
             // EOS or some other error
             if (err != OK) {
                 LOGV("EOS or some err: %d", err);
-                stop();
+                // We cannot call stop() here because stop() will release the
+                // AudioResampler, and we are in a callback of the AudioResampler.
+                // So just remember the fact and let read() call stop().
+                mStopPending = true;
                 return err;
             }
 
diff --git a/lvpp/VideoEditorSRC.h b/lvpp/VideoEditorSRC.h
index a5e8e22..c61b7c1 100755
--- a/lvpp/VideoEditorSRC.h
+++ b/lvpp/VideoEditorSRC.h
@@ -78,6 +78,7 @@
         MediaBuffer* mBuffer;
         int32_t mLeftover;
         bool mFormatChanged;
+        bool mStopPending;
 
         int64_t mInitialTimeStampUs;
         int64_t mAccuOutBufferSize;
diff --git a/vss/mcs/src/M4MCS_API.c b/vss/mcs/src/M4MCS_API.c
index 2ac0be1..d75a495 100755
--- a/vss/mcs/src/M4MCS_API.c
+++ b/vss/mcs/src/M4MCS_API.c
@@ -3746,7 +3746,11 @@
             /**
             * Set output video profile and level */
             pC->encodingVideoProfile = pC->InputFileProperties.uiVideoProfile;
-            pC->encodingVideoLevel = pC->InputFileProperties.uiVideoLevel;
+            /** Set the target video level, because input 3gp file may
+             *  have wrong video level value (some encoders do not respect
+             *  level restrictions like video resolution when content is created).
+             **/
+            pC->encodingVideoLevel = pParams->outputVideoLevel;
 
             // Clip's original width and height may not be
             // multiple of 16.
diff --git a/vss/src/M4xVSS_API.c b/vss/src/M4xVSS_API.c
index 37b2e47..eb85227 100755
--- a/vss/src/M4xVSS_API.c
+++ b/vss/src/M4xVSS_API.c
@@ -2587,6 +2587,10 @@
                 }
                 else
                 {
+                    pParams->outputVideoProfile =
+                        xVSS_context->pSettings->xVSS.outputVideoProfile;
+                    pParams->outputVideoLevel =
+                        xVSS_context->pSettings->xVSS.outputVideoLevel;
                     pParams->OutputVideoFormat = M4VIDEOEDITING_kNullVideo;
                     pParams->OutputVideoFrameRate =
                         M4VIDEOEDITING_k15_FPS; /* Must be set, otherwise, MCS returns an error */
diff --git a/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp b/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
index b0a6fdb..f47c921 100755
--- a/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
+++ b/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
@@ -39,6 +39,7 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
+#include <media/MediaProfiles.h>
 #include "OMX_Video.h"
 
 /********************
@@ -68,6 +69,7 @@
         virtual status_t read(MediaBuffer **buffer,
             const ReadOptions *options = NULL);
         virtual int32_t storeBuffer(MediaBuffer *buffer);
+        virtual int32_t getNumberOfBuffersInQueue();
 
     protected:
         virtual ~VideoEditorVideoEncoderSource();
@@ -242,6 +244,10 @@
     return mNbBuffer;
 }
 
+int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
+    Mutex::Autolock autolock(mLock);
+    return mNbBuffer;
+}
 /********************
  *      PULLER      *
  ********************/
@@ -257,6 +263,7 @@
     MediaBuffer* getBufferBlocking();
     MediaBuffer* getBufferNonBlocking();
     void putBuffer(MediaBuffer* buffer);
+    bool hasMediaSourceReturnedError();
 private:
     static int acquireThreadStart(void* arg);
     void acquireThreadFunc();
@@ -277,6 +284,7 @@
     bool mAskToStop;       // Asks the threads to stop
     bool mAcquireStopped;  // The acquire thread has stopped
     bool mReleaseStopped;  // The release thread has stopped
+    status_t mSourceError; // Error returned by MediaSource read
 };
 
 VideoEditorVideoEncoderPuller::VideoEditorVideoEncoderPuller(
@@ -286,6 +294,7 @@
     mAskToStop = false;
     mAcquireStopped = false;
     mReleaseStopped = false;
+    mSourceError = OK;
     androidCreateThread(acquireThreadStart, this);
     androidCreateThread(releaseThreadStart, this);
 }
@@ -294,6 +303,10 @@
     stop();
 }
 
+bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() {
+    Mutex::Autolock autolock(mLock);
+    return ((mSourceError != OK) ? true : false);
+}
 void VideoEditorVideoEncoderPuller::start() {
     Mutex::Autolock autolock(mLock);
     mAskToStart = true;
@@ -381,6 +394,7 @@
         mLock.unlock();
         status_t result = mSource->read(&pBuffer, NULL);
         mLock.lock();
+        mSourceError = result;
         if (result != OK) {
             break;
         }
@@ -464,6 +478,8 @@
     int64_t                           mFirstOutputCts;
     int64_t                           mLastOutputCts;
 
+    MediaProfiles *mVideoEditorProfile;
+    int32_t mMaxPrefetchFrames;
 } VideoEditorVideoEncoder_Context;
 
 /********************
@@ -747,6 +763,10 @@
 
     // Context initialization
     pEncoderContext->mAccessUnit = pAU;
+    pEncoderContext->mVideoEditorProfile = MediaProfiles::getInstance();
+    pEncoderContext->mMaxPrefetchFrames =
+        pEncoderContext->mVideoEditorProfile->getVideoEditorCapParamByName(
+        "maxPrefetchYUVFrames");
 
     // Allocate & initialize the encoding parameters
     SAFE_MALLOC(pEncoderContext->mCodecParams, M4ENCODER_Params, 1,
@@ -1181,14 +1201,25 @@
         MediaBuffer *outputBuffer =
                 pEncoderContext->mPuller->getBufferNonBlocking();
 
-        if (outputBuffer == NULL) break;
+        if (outputBuffer == NULL) {
+            int32_t YUVBufferNumber =
+                    pEncoderContext->mEncoderSource->getNumberOfBuffersInQueue();
+            /* Make sure that the configured maximum number of prefetch YUV frames is
+             * not exceeded. This is to limit the amount of memory usage of video editor engine.
+             * The value of maximum prefetch Yuv frames is defined in media_profiles.xml */
+            if ((YUVBufferNumber < pEncoderContext->mMaxPrefetchFrames) ||
+                (pEncoderContext->mPuller->hasMediaSourceReturnedError()
+                    == true)) {
+                break;
+            }
+        } else {
+            // Provide the encoded AU to the writer
+            err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
+                outputBuffer);
+            VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
 
-        // Provide the encoded AU to the writer
-        err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
-            outputBuffer);
-        VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
-
-        pEncoderContext->mPuller->putBuffer(outputBuffer);
+            pEncoderContext->mPuller->putBuffer(outputBuffer);
+        }
     }
 
 cleanUp: