Merge "Add warning about following the design rules"
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index d43cb0b..3aaacaf 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -27,7 +27,7 @@
 #include <camera/ICameraRecordingProxyListener.h>
 #include <camera/ICameraService.h>
 
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
 
 namespace android {
@@ -184,14 +184,14 @@
     }
 }
 
-// pass the buffered ISurfaceTexture to the camera service
-status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
+// pass the buffered IGraphicBufferProducer to the camera service
+status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
 {
-    ALOGV("setPreviewTexture(%p)", surfaceTexture.get());
+    ALOGV("setPreviewTexture(%p)", bufferProducer.get());
     sp <ICamera> c = mCamera;
     if (c == 0) return NO_INIT;
-    if (surfaceTexture != 0) {
-        return c->setPreviewTexture(surfaceTexture);
+    if (bufferProducer != 0) {
+        return c->setPreviewTexture(bufferProducer);
     } else {
         ALOGD("app passed NULL surface");
         return c->setPreviewTexture(0);
diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp
index 8d8408c..5d210e7 100644
--- a/camera/ICamera.cpp
+++ b/camera/ICamera.cpp
@@ -22,7 +22,7 @@
 #include <sys/types.h>
 #include <binder/Parcel.h>
 #include <camera/ICamera.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
 
 namespace android {
@@ -79,13 +79,13 @@
         return reply.readInt32();
     }
 
-    // pass the buffered SurfaceTexture to the camera service
-    status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
+    // pass the buffered IGraphicBufferProducer to the camera service
+    status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
     {
         ALOGV("setPreviewTexture");
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        sp<IBinder> b(surfaceTexture->asBinder());
+        sp<IBinder> b(bufferProducer->asBinder());
         data.writeStrongBinder(b);
         remote()->transact(SET_PREVIEW_TEXTURE, data, &reply);
         return reply.readInt32();
@@ -292,7 +292,8 @@
         case SET_PREVIEW_TEXTURE: {
             ALOGV("SET_PREVIEW_TEXTURE");
             CHECK_INTERFACE(ICamera, data, reply);
-            sp<ISurfaceTexture> st = interface_cast<ISurfaceTexture>(data.readStrongBinder());
+            sp<IGraphicBufferProducer> st =
+                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
             reply->writeInt32(setPreviewTexture(st));
             return NO_ERROR;
         } break;
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index f60b1a4..a59186a 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -9,7 +9,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libstagefright libmedia libutils libbinder libstagefright_foundation \
-        libjpeg libgui
+        libjpeg libgui libcutils
 
 LOCAL_C_INCLUDES:= \
 	frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index eb3296e..93de112 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -64,12 +64,12 @@
     return PostAndAwaitResponse(msg, &response);
 }
 
-status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) {
+status_t SimplePlayer::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) {
     sp<AMessage> msg = new AMessage(kWhatSetSurface, id());
 
     sp<SurfaceTextureClient> surfaceTextureClient;
-    if (surfaceTexture != NULL) {
-        surfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
+    if (bufferProducer != NULL) {
+        surfaceTextureClient = new SurfaceTextureClient(bufferProducer);
     }
 
     msg->setObject(
diff --git a/cmds/stagefright/SimplePlayer.h b/cmds/stagefright/SimplePlayer.h
index 2548252..0a06059 100644
--- a/cmds/stagefright/SimplePlayer.h
+++ b/cmds/stagefright/SimplePlayer.h
@@ -23,7 +23,7 @@
 struct ABuffer;
 struct ALooper;
 struct AudioTrack;
-struct ISurfaceTexture;
+struct IGraphicBufferProducer;
 struct MediaCodec;
 struct NativeWindowWrapper;
 struct NuMediaExtractor;
@@ -32,7 +32,7 @@
     SimplePlayer();
 
     status_t setDataSource(const char *path);
-    status_t setSurface(const sp<ISurfaceTexture> &surfaceTexture);
+    status_t setSurface(const sp<IGraphicBufferProducer> &bufferProducer);
     status_t prepare();
     status_t start();
     status_t stop();
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index e02f111..c30c122 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -44,7 +44,7 @@
     fprintf(stderr, "       -p encoder profile. see omx il header (default: encoder specific)\n");
     fprintf(stderr, "       -v video codec: [0] AVC [1] M4V [2] H263 (default: 0)\n");
     fprintf(stderr, "       -s(oftware) prefer software codec\n");
-    fprintf(stderr, "The output file is /sdcard/output.mp4\n");
+    fprintf(stderr, "       -o filename: output file (default: /sdcard/output.mp4)\n");
     exit(1);
 }
 
@@ -162,12 +162,12 @@
     int level = -1;        // Encoder specific default
     int profile = -1;      // Encoder specific default
     int codec = 0;
-    const char *fileName = "/sdcard/output.mp4";
+    char *fileName = "/sdcard/output.mp4";
     bool preferSoftwareCodec = false;
 
     android::ProcessState::self()->startThreadPool();
     int res;
-    while ((res = getopt(argc, argv, "b:c:f:i:n:w:t:l:p:v:hs")) >= 0) {
+    while ((res = getopt(argc, argv, "b:c:f:i:n:w:t:l:p:v:o:hs")) >= 0) {
         switch (res) {
             case 'b':
             {
@@ -235,6 +235,12 @@
                 break;
             }
 
+            case 'o':
+            {
+                fileName = optarg;
+                break;
+            }
+
             case 's':
             {
                 preferSoftwareCodec = true;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 1e0e7f8..1002ac4 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -940,8 +940,8 @@
         } else {
             CHECK(useSurfaceTexAlloc);
 
-            sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
-            gSurface = new SurfaceTextureClient(texture);
+            sp<GLConsumer> texture = new GLConsumer(0 /* tex */);
+            gSurface = new SurfaceTextureClient(texture->getBufferQueue());
         }
 
         CHECK_EQ((status_t)OK,
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 234e165..43dae1c 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -18,7 +18,7 @@
 #define ANDROID_HARDWARE_CAMERA_H
 
 #include <utils/Timers.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <system/camera.h>
 #include <camera/ICameraClient.h>
 #include <camera/ICameraRecordingProxy.h>
@@ -86,8 +86,8 @@
             // pass the buffered Surface to the camera service
             status_t    setPreviewDisplay(const sp<Surface>& surface);
 
-            // pass the buffered ISurfaceTexture to the camera service
-            status_t    setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture);
+            // pass the buffered IGraphicBufferProducer to the camera service
+            status_t    setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer);
 
             // start preview mode, must call setPreviewDisplay first
             status_t    startPreview();
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index 3d18837..eccaa41 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -27,7 +27,7 @@
 namespace android {
 
 class ICameraClient;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 class Surface;
 
 class ICamera: public IInterface
@@ -49,9 +49,9 @@
     // pass the buffered Surface to the camera service
     virtual status_t        setPreviewDisplay(const sp<Surface>& surface) = 0;
 
-    // pass the buffered ISurfaceTexture to the camera service
+    // pass the buffered IGraphicBufferProducer to the camera service
     virtual status_t        setPreviewTexture(
-            const sp<ISurfaceTexture>& surfaceTexture) = 0;
+            const sp<IGraphicBufferProducer>& bufferProducer) = 0;
 
     // set the preview callback flag to affect how the received frames from
     // preview are handled.
diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h
index 43e4de7..865ed7e 100644
--- a/include/media/AudioBufferProvider.h
+++ b/include/media/AudioBufferProvider.h
@@ -36,8 +36,11 @@
         size_t frameCount;
     };
 
-    virtual ~AudioBufferProvider() {}
+protected:
+    AudioBufferProvider() : mValid(kValid) { }
+    virtual ~AudioBufferProvider() { mValid = kDead; }
 
+public:
     // value representing an invalid presentation timestamp
     static const int64_t kInvalidPTS = 0x7FFFFFFFFFFFFFFFLL;    // <stdint.h> is too painful
 
@@ -47,6 +50,13 @@
     virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0;
 
     virtual void releaseBuffer(Buffer* buffer) = 0;
+
+    int getValid() const { return mValid; }
+    static const int kValid = 'GOOD';
+    static const int kDead = 'DEAD';
+
+private:
+    int mValid;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f1b77ab..6f85527 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -52,8 +52,11 @@
      * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
      */
     enum event_type {
-        EVENT_MORE_DATA = 0,        // Request to write more data to PCM buffer.
-        EVENT_UNDERRUN = 1,         // PCM buffer underrun occurred.
+        EVENT_MORE_DATA = 0,        // Request to write more data to buffer.
+                                    // If this event is delivered but the callback handler
+                                    // does not want to write more data, the handler must explicitly
+                                    // ignore the event by setting frameCount to zero.
+        EVENT_UNDERRUN = 1,         // Buffer underrun occurred.
         EVENT_LOOP_END = 2,         // Sample loop end was reached; playback restarted from
                                     // loop start if loop count was not 0.
         EVENT_MARKER = 3,           // Playback head is at the specified marker position
@@ -115,14 +118,16 @@
                                       uint32_t sampleRate = 0);
 
     /* Constructs an uninitialized AudioTrack. No connection with
-     * AudioFlinger takes place.
+     * AudioFlinger takes place.  Use set() after this.
      */
                         AudioTrack();
 
     /* Creates an AudioTrack object and registers it with AudioFlinger.
      * Once created, the track needs to be started before it can be used.
-     * Unspecified values are set to the audio hardware's current
-     * values.
+     * Unspecified values are set to appropriate default values.
+     * With this constructor, the track is configured for streaming mode.
+     * Data to be rendered is supplied by write() or by the callback EVENT_MORE_DATA.
+     * Intermixing a combination of write() and non-ignored EVENT_MORE_DATA is deprecated.
      *
      * Parameters:
      *
@@ -136,10 +141,10 @@
      *                     application's contribution to the
      *                     latency of the track. The actual size selected by the AudioTrack could be
      *                     larger if the requested size is not compatible with current audio HAL
-     *                     latency.  Zero means to use a default value.
+     *                     configuration.  Zero means to use a default value.
      * flags:              See comments on audio_output_flags_t in <system/audio.h>.
      * cbf:                Callback function. If not null, this function is called periodically
-     *                     to provide new PCM data.
+     *                     to provide new data and inform of marker, position updates, etc.
      * user:               Context for use by the callback receiver.
      * notificationFrames: The callback function is called each time notificationFrames PCM
      *                     frames have been consumed from track input buffer.
@@ -159,13 +164,16 @@
                                     int notificationFrames = 0,
                                     int sessionId        = 0);
 
-    /* Creates an audio track and registers it with AudioFlinger. With this constructor,
-     * the PCM data to be rendered by AudioTrack is passed in a shared memory buffer
-     * identified by the argument sharedBuffer. This prototype is for static buffer playback.
-     * PCM data must be present in memory before the AudioTrack is started.
-     * The write() and flush() methods are not supported in this case.
+    /* Creates an audio track and registers it with AudioFlinger.
+     * With this constructor, the track is configured for static buffer mode.
+     * The format must not be 8-bit linear PCM.
+     * Data to be rendered is passed in a shared memory buffer
+     * identified by the argument sharedBuffer, which must be non-0.
+     * The memory should be initialized to the desired data before calling start().
+     * The write() method is not supported in this case.
      * It is recommended to pass a callback function to be notified of playback end by an
      * EVENT_UNDERRUN event.
+     * FIXME EVENT_MORE_DATA still occurs; it must be ignored.
      */
 
                         AudioTrack( audio_stream_type_t streamType,
@@ -184,13 +192,14 @@
      */
                         ~AudioTrack();
 
-
     /* Initialize an uninitialized AudioTrack.
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful initialization
      *  - INVALID_OPERATION: AudioTrack is already initialized
      *  - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
      *  - NO_INIT: audio server or audio hardware not initialized
+     * If sharedBuffer is non-0, the frameCount parameter is ignored and
+     * replaced by the shared buffer's total allocated size in frame units.
      */
             status_t    set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT,
                             uint32_t sampleRate = 0,
@@ -205,64 +214,68 @@
                             bool threadCanCallJava = false,
                             int sessionId       = 0);
 
-
     /* Result of constructing the AudioTrack. This must be checked
      * before using any AudioTrack API (except for set()), because using
      * an uninitialized AudioTrack produces undefined results.
      * See set() method above for possible return codes.
      */
-            status_t    initCheck() const;
+            status_t    initCheck() const   { return mStatus; }
 
     /* Returns this track's estimated latency in milliseconds.
      * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
      * and audio hardware driver.
      */
-            uint32_t     latency() const;
+            uint32_t     latency() const    { return mLatency; }
 
     /* getters, see constructors and set() */
 
-            audio_stream_type_t streamType() const;
-            audio_format_t format() const;
-            uint32_t    channelCount() const;
-            uint32_t    frameCount() const;
+            audio_stream_type_t streamType() const { return mStreamType; }
+            audio_format_t format() const   { return mFormat; }
 
-    /* Return channelCount * (bit depth per channel / 8).
+    /* Return frame size in bytes, which for linear PCM is channelCount * (bit depth per channel / 8).
      * channelCount is determined from channelMask, and bit depth comes from format.
+     * For non-linear formats, the frame size is typically 1 byte.
      */
-            size_t      frameSize() const { return mFrameSize; }
+            uint32_t    channelCount() const { return mChannelCount; }
 
-            sp<IMemory>& sharedBuffer();
+            uint32_t    frameCount() const  { return mFrameCount; }
+            size_t      frameSize() const   { return mFrameSize; }
 
+    /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */
+            sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
 
     /* After it's created the track is not active. Call start() to
      * make it active. If set, the callback will start being called.
+     * If the track was previously paused, volume is ramped up over the first mix buffer.
      */
             void        start();
 
-    /* Stop a track. If set, the callback will cease being called and
+    /* Stop a track.
+     * In static buffer mode, the track is stopped immediately.
+     * In streaming mode, the callback will cease being called and
      * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
      * and will fill up buffers until the pool is exhausted.
+     * The stop does not occur immediately: any data remaining in the buffer
+     * is first drained, mixed, and output, and only then is the track marked as stopped.
      */
             void        stop();
             bool        stopped() const;
 
-    /* Flush a stopped track. All pending buffers are discarded.
-     * This function has no effect if the track is not stopped.
+    /* Flush a stopped or paused track. All previously buffered data is discarded immediately.
+     * This has the effect of draining the buffers without mixing or output.
+     * Flush is intended for streaming mode, for example before switching to non-contiguous content.
+     * This function is a no-op if the track is not stopped or paused, or uses a static buffer.
      */
             void        flush();
 
-    /* Pause a track. If set, the callback will cease being called and
+    /* Pause a track. After pause, the callback will cease being called and
      * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
      * and will fill up buffers until the pool is exhausted.
+     * Volume is ramped down over the next mix buffer following the pause request,
+     * and then the track is marked as paused.  It can be resumed with ramp up by start().
      */
             void        pause();
 
-    /* Mute or unmute this track.
-     * While muted, the callback, if set, is still called.
-     */
-            void        mute(bool);
-            bool        muted() const;
-
     /* Set volume for this track, mostly used for games' sound effects
      * left and right volumes. Levels must be >= 0.0 and <= 1.0.
      * This is the older API.  New applications should use setVolume(float) when possible.
@@ -288,6 +301,7 @@
             uint32_t    getSampleRate() const;
 
     /* Enables looping and sets the start and end points of looping.
+     * Only supported for static buffer mode.
      *
      * Parameters:
      *
@@ -303,13 +317,15 @@
 
     /* Sets marker position. When playback reaches the number of frames specified, a callback with
      * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
-     * notification callback.
+     * notification callback.  To set a marker at a position which would compute as 0,
+     * a workaround is to the set the marker at a nearby position such as -1 or 1.
      * If the AudioTrack has been opened with no callback function associated, the operation will
      * fail.
      *
      * Parameters:
      *
-     * marker:   marker position expressed in frames.
+     * marker:   marker position expressed in wrapping (overflow) frame units,
+     *           like the return value of getPosition().
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation
@@ -318,13 +334,13 @@
             status_t    setMarkerPosition(uint32_t marker);
             status_t    getMarkerPosition(uint32_t *marker) const;
 
-
     /* Sets position update period. Every time the number of frames specified has been played,
      * a callback with event type EVENT_NEW_POS is called.
      * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
      * callback.
      * If the AudioTrack has been opened with no callback function associated, the operation will
      * fail.
+     * Extremely small values may be rounded up to a value the implementation can support.
      *
      * Parameters:
      *
@@ -352,20 +368,26 @@
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation
-     *  - INVALID_OPERATION: the AudioTrack is not stopped.
+     *  - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
      *  - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack
      *               buffer
      */
             status_t    setPosition(uint32_t position);
+
+    /* Return the total number of frames played since playback start.
+     * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
+     * It is reset to zero by flush(), reload(), and stop().
+     */
             status_t    getPosition(uint32_t *position);
 
     /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
      * rewriting the buffer before restarting playback after a stop.
      * This method must be called with the AudioTrack in paused or stopped state.
+     * Not allowed in streaming mode.
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation
-     *  - INVALID_OPERATION: the AudioTrack is not stopped.
+     *  - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
      */
             status_t    reload();
 
@@ -387,7 +409,7 @@
      * Returned value:
      *  AudioTrack session ID.
      */
-            int    getSessionId() const;
+            int    getSessionId() const { return mSessionId; }
 
     /* Attach track auxiliary output to specified effect. Use effectId = 0
      * to detach track from effect.
@@ -413,6 +435,9 @@
      * or return WOULD_BLOCK depending on the value of the "blocking"
      * parameter.
      *
+     * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications,
+     * which should use write() or callback EVENT_MORE_DATA instead.
+     *
      * Interpretation of waitCount:
      *  +n  limits wait time to n * WAIT_PERIOD_MS,
      *  -1  causes an (almost) infinite wait time,
@@ -450,6 +475,7 @@
      *      STOPPED             AudioTrack was stopped during the write
      *      NO_MORE_BUFFERS     when obtainBuffer() returns same
      *      or any other error code returned by IAudioTrack::start() or restoreTrack_l().
+     * Not supported for static buffer mode.
      */
             ssize_t     write(const void* buffer, size_t size);
 
@@ -497,7 +523,10 @@
                                  audio_output_flags_t flags,
                                  const sp<IMemory>& sharedBuffer,
                                  audio_io_handle_t output);
+
+            // can only be called when !mActive
             void flush_l();
+
             status_t setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
             audio_io_handle_t getOutput_l();
             status_t restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart);
@@ -523,9 +552,7 @@
 
     audio_format_t          mFormat;                // as requested by client, not forced to 16-bit
     audio_stream_type_t     mStreamType;
-    uint8_t                 mChannelCount;
-    uint8_t                 mMuted;
-    uint8_t                 mReserved;
+    uint32_t                mChannelCount;
     audio_channel_mask_t    mChannelMask;
 
                 // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data.
@@ -550,7 +577,7 @@
     sp<IMemory>             mSharedBuffer;
     int                     mLoopCount;
     uint32_t                mRemainingFrames;
-    uint32_t                mMarkerPosition;        // in frames
+    uint32_t                mMarkerPosition;        // in wrapping (overflow) frame units
     bool                    mMarkerReached;
     uint32_t                mNewPosition;           // in frames
     uint32_t                mUpdatePeriod;          // in frames
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index 9e0e389..144be0e 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -54,11 +54,6 @@
      */
     virtual void        flush() = 0;
 
-    /* Mute or unmute this track.
-     * While muted, the callback, if set, is still called.
-     */
-    virtual void        mute(bool) = 0;
-
     /* Pause a track. If set, the callback will cease being called and
      * obtainBuffer will return an error. Buffers that are already released
      * will continue to be processed, unless/until flush() is called.
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 4ed1863..0cbd269 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -32,7 +32,7 @@
 class Parcel;
 class Surface;
 class IStreamSource;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 class IMediaPlayer: public IInterface
 {
@@ -46,7 +46,7 @@
     virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0;
     virtual status_t        setVideoSurfaceTexture(
-                                    const sp<ISurfaceTexture>& surfaceTexture) = 0;
+                                    const sp<IGraphicBufferProducer>& bufferProducer) = 0;
     virtual status_t        prepareAsync() = 0;
     virtual status_t        start() = 0;
     virtual status_t        stop() = 0;
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index ec84e25..54af0d3 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -26,7 +26,7 @@
 class ICamera;
 class ICameraRecordingProxy;
 class IMediaRecorderClient;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 class IMediaRecorder: public IInterface
 {
@@ -55,7 +55,7 @@
     virtual status_t init() = 0;
     virtual status_t close() = 0;
     virtual status_t release() = 0;
-    virtual sp<ISurfaceTexture> querySurfaceMediaSource() = 0;
+    virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/media/IRemoteDisplay.h b/include/media/IRemoteDisplay.h
index a61704e..c8baae9 100644
--- a/include/media/IRemoteDisplay.h
+++ b/include/media/IRemoteDisplay.h
@@ -39,6 +39,9 @@
 public:
     DECLARE_META_INTERFACE(RemoteDisplay);
 
+    virtual status_t pause() = 0;
+    virtual status_t resume() = 0;
+
     // Disconnects the remote display and stops listening for new connections.
     virtual status_t dispose() = 0;
 };
diff --git a/include/media/IRemoteDisplayClient.h b/include/media/IRemoteDisplayClient.h
index 252b401..7b0fa9e 100644
--- a/include/media/IRemoteDisplayClient.h
+++ b/include/media/IRemoteDisplayClient.h
@@ -26,7 +26,7 @@
 
 namespace android {
 
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 class IRemoteDisplayClient : public IInterface
 {
@@ -48,7 +48,7 @@
     // Indicates that the remote display has been connected successfully.
     // Provides a surface texture that the client should use to stream buffers to
     // the remote display.
-    virtual void onDisplayConnected(const sp<ISurfaceTexture>& surfaceTexture,
+    virtual void onDisplayConnected(const sp<IGraphicBufferProducer>& bufferProducer,
             uint32_t width, uint32_t height, uint32_t flags) = 0; // one-way
 
     // Indicates that the remote display has been disconnected normally.
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index b7bee3f..8fc72c3 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -37,7 +37,7 @@
 
 class Parcel;
 class Surface;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 template<typename T> class SortedVector;
 
@@ -131,9 +131,9 @@
         return INVALID_OPERATION;
     }
 
-    // pass the buffered ISurfaceTexture to the media player service
+    // pass the buffered IGraphicBufferProducer to the media player service
     virtual status_t    setVideoSurfaceTexture(
-                                const sp<ISurfaceTexture>& surfaceTexture) = 0;
+                                const sp<IGraphicBufferProducer>& bufferProducer) = 0;
 
     virtual status_t    prepare() = 0;
     virtual status_t    prepareAsync() = 0;
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index ef799f5..803bc64 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -26,7 +26,7 @@
 
 class ICameraRecordingProxy;
 class Surface;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 struct MediaRecorderBase {
     MediaRecorderBase() {}
@@ -55,7 +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;
+    virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
 
 private:
     MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index d753eba..e5aa033 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -33,7 +33,7 @@
 namespace android {
 
 class Surface;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 enum media_event_type {
     MEDIA_NOP               = 0, // interface test message
@@ -199,7 +199,7 @@
             status_t        setDataSource(int fd, int64_t offset, int64_t length);
             status_t        setDataSource(const sp<IStreamSource> &source);
             status_t        setVideoSurfaceTexture(
-                                    const sp<ISurfaceTexture>& surfaceTexture);
+                                    const sp<IGraphicBufferProducer>& bufferProducer);
             status_t        setListener(const sp<MediaPlayerListener>& listener);
             status_t        prepare();
             status_t        prepareAsync();
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 6d304e0..2882c41 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -31,7 +31,7 @@
 class IMediaRecorder;
 class ICamera;
 class ICameraRecordingProxy;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 class SurfaceTextureClient;
 
 typedef void (*media_completion_f)(status_t status, void *cookie);
@@ -228,7 +228,7 @@
     status_t    close();
     status_t    release();
     void        notify(int msg, int ext1, int ext2);
-    sp<ISurfaceTexture>     querySurfaceMediaSourceFromMediaServer();
+    sp<IGraphicBufferProducer>     querySurfaceMediaSourceFromMediaServer();
 
 private:
     void                    doCleanUp();
@@ -237,10 +237,10 @@
     sp<IMediaRecorder>          mMediaRecorder;
     sp<MediaRecorderListener>   mListener;
 
-    // Reference toISurfaceTexture
+    // Reference to IGraphicBufferProducer
     // for encoding GL Frames. That is useful only when the
     // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
-    sp<ISurfaceTexture>         mSurfaceMediaSource;
+    sp<IGraphicBufferProducer>  mSurfaceMediaSource;
 
     media_recorder_states       mCurrentState;
     bool                        mIsAudioSourceSet;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index cba8a6b..df1c46b 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -184,6 +184,7 @@
     bool mChannelMaskPresent;
     int32_t mChannelMask;
 
+    status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
     status_t allocateBuffersOnPort(OMX_U32 portIndex);
     status_t freeBuffersOnPort(OMX_U32 portIndex);
     status_t freeBuffer(OMX_U32 portIndex, size_t i);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index b1e57cf..88aabf6 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -18,7 +18,7 @@
 
 #define MEDIA_CODEC_H_
 
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <utils/Vector.h>
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index e91904c..be08c19 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -35,6 +35,8 @@
     kKeyHeight            = 'heig',  // int32_t, image pixel
     kKeyDisplayWidth      = 'dWid',  // int32_t, display/presentation
     kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
+    kKeySARWidth          = 'sarW',  // int32_t, sampleAspectRatio width
+    kKeySARHeight         = 'sarH',  // int32_t, sampleAspectRatio height
 
     // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
     kKeyCropRect          = 'crop',
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index e56527d..609d84f 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H
 #define ANDROID_GUI_SURFACEMEDIASOURCE_H
 
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/BufferQueue.h>
 
 #include <utils/threads.h>
@@ -35,7 +35,7 @@
 // ASSUMPTIONS
 // 1. SurfaceMediaSource is initialized with width*height which
 // can never change.  However, deqeueue buffer does not currently
-// enforce this as in BufferQueue, dequeue can be used by SurfaceTexture
+// enforce this as in BufferQueue, dequeue can be used by SurfaceTextureClient
 // which can modify the default width and heght.  Also neither the width
 // nor height can be 0.
 // 2. setSynchronousMode is never used (basically no one should call
@@ -122,7 +122,7 @@
 protected:
 
     // Implementation of the BufferQueue::ConsumerListener interface.  These
-    // calls are used to notify the SurfaceTexture of asynchronous events in the
+    // calls are used to notify the SurfaceTextureClient of asynchronous events in the
     // BufferQueue.
     virtual void onFrameAvailable();
 
@@ -157,7 +157,7 @@
     // mCurrentSlot is the buffer slot index of the buffer that is currently
     // being used by buffer consumer
     // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
-    // in the case of SurfaceTexture).
+    // in the case of SurfaceTextureClient).
     // 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
diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h
index 0ecc348..a211ed9 100644
--- a/include/private/media/VideoFrame.h
+++ b/include/private/media/VideoFrame.h
@@ -88,7 +88,8 @@
 class VideoFrame
 {
 public:
-    VideoFrame(): mWidth(0), mHeight(0), mDisplayWidth(0), mDisplayHeight(0), mSize(0), mData(0) {}
+    VideoFrame(): mWidth(0), mHeight(0), mDisplayWidth(0), mDisplayHeight(0), mSize(0), mData(0),
+            mRotationAngle(0) {}
 
     VideoFrame(const VideoFrame& copy) {
         mWidth = copy.mWidth;
@@ -105,6 +106,7 @@
                 mSize = 0;
             }
         }
+        mRotationAngle = copy.mRotationAngle;
     }
 
     ~VideoFrame() {
diff --git a/libvideoeditor/lvpp/NativeWindowRenderer.cpp b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
index 2e15ff9..114f0f6 100755
--- a/libvideoeditor/lvpp/NativeWindowRenderer.cpp
+++ b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
@@ -20,7 +20,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #include <cutils/log.h>
-#include <gui/SurfaceTexture.h>
+#include <gui/GLConsumer.h>
 #include <gui/SurfaceTextureClient.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MetaData.h>
@@ -315,7 +315,7 @@
 }
 
 void NativeWindowRenderer::render(RenderInput* input) {
-    sp<SurfaceTexture> ST = input->mST;
+    sp<GLConsumer> ST = input->mST;
     sp<SurfaceTextureClient> STC = input->mSTC;
 
     if (input->mIsExternalBuffer) {
@@ -568,8 +568,8 @@
 RenderInput::RenderInput(NativeWindowRenderer* renderer, GLuint textureId)
     : mRenderer(renderer)
     , mTextureId(textureId) {
-    mST = new SurfaceTexture(mTextureId);
-    mSTC = new SurfaceTextureClient(mST);
+    mST = new GLConsumer(mTextureId);
+    mSTC = new SurfaceTextureClient(mST->getBufferQueue());
     native_window_connect(mSTC.get(), NATIVE_WINDOW_API_MEDIA);
 }
 
diff --git a/libvideoeditor/lvpp/NativeWindowRenderer.h b/libvideoeditor/lvpp/NativeWindowRenderer.h
index 8fbb4f9..b0623ba 100755
--- a/libvideoeditor/lvpp/NativeWindowRenderer.h
+++ b/libvideoeditor/lvpp/NativeWindowRenderer.h
@@ -37,15 +37,15 @@
 // we only expect that happens briefly when one clip is about to finish
 // and the next clip is about to start.
 //
-// We allocate a SurfaceTexture for each RenderInput and the user can use
+// We allocate a SurfaceTextureClient for each RenderInput and the user can use
 // the getTargetWindow() function to get the corresponding ANativeWindow
-// for that SurfaceTexture. The intention is that the user can pass that
+// for that SurfaceTextureClient. The intention is that the user can pass that
 // ANativeWindow to OMXCodec::Create() so the codec can decode directly
 // to buffers provided by the texture.
 
 namespace android {
 
-class SurfaceTexture;
+class GLConsumer;
 class SurfaceTextureClient;
 class RenderInput;
 
@@ -110,7 +110,7 @@
     // destination aspect ratio.
     GLfloat mPositionCoordinates[8];
 
-    // We use a different GL id for each SurfaceTexture.
+    // We use a different GL id for each SurfaceTextureClient.
     GLuint mNextTextureId;
 
     // Number of existing RenderInputs, just for debugging.
@@ -146,7 +146,7 @@
 
 class RenderInput {
 public:
-    // Returns the ANativeWindow corresponds to the SurfaceTexture.
+    // Returns the ANativeWindow corresponds to the SurfaceTextureClient.
     ANativeWindow* getTargetWindow();
 
     // Updates video frame size from the MediaSource's metadata. Specifically
@@ -156,7 +156,7 @@
     // Renders the buffer with the given video effect and rending mode.
     // The video effets are defined in VideoEditorTools.h
     // Set isExternalBuffer to true only when the buffer given is not
-    // provided by the SurfaceTexture.
+    // provided by the SurfaceTextureClient.
     void render(MediaBuffer *buffer, uint32_t videoEffect,
         M4xVSS_MediaRendering renderingMode, bool isExternalBuffer);
 private:
@@ -164,7 +164,7 @@
     ~RenderInput();
     NativeWindowRenderer* mRenderer;
     GLuint mTextureId;
-    sp<SurfaceTexture> mST;
+    sp<GLConsumer> mST;
     sp<SurfaceTextureClient> mSTC;
     int mWidth, mHeight;
 
diff --git a/libvideoeditor/lvpp/PreviewPlayer.cpp b/libvideoeditor/lvpp/PreviewPlayer.cpp
index 34731d7..754c5a9 100755
--- a/libvideoeditor/lvpp/PreviewPlayer.cpp
+++ b/libvideoeditor/lvpp/PreviewPlayer.cpp
@@ -31,7 +31,7 @@
 #include <media/stagefright/OMXCodec.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <gui/Surface.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/SurfaceTextureClient.h>
 
 #include "VideoEditorPreviewController.h"
@@ -1775,12 +1775,12 @@
     setNativeWindow_l(surface);
 }
 
-void PreviewPlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+void PreviewPlayer::setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {
     Mutex::Autolock autoLock(mLock);
 
     mSurface.clear();
-    if (surfaceTexture != NULL) {
-        setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
+    if (bufferProducer != NULL) {
+        setNativeWindow_l(new SurfaceTextureClient(bufferProducer));
     }
 }
 
diff --git a/libvideoeditor/lvpp/PreviewPlayer.h b/libvideoeditor/lvpp/PreviewPlayer.h
index 177853f..5a13b58 100755
--- a/libvideoeditor/lvpp/PreviewPlayer.h
+++ b/libvideoeditor/lvpp/PreviewPlayer.h
@@ -44,7 +44,7 @@
 
     bool isPlaying() const;
     void setSurface(const sp<Surface> &surface);
-    void setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
+    void setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer);
     status_t seekTo(int64_t timeUs);
 
     status_t getVideoDimensions(int32_t *width, int32_t *height) const;
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index a47fc15..91a4415 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -81,10 +81,10 @@
     return OK;
 }
 
-status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {
     ALOGV("setVideoSurfaceTexture");
 
-    mPlayer->setSurfaceTexture(surfaceTexture);
+    mPlayer->setSurfaceTexture(bufferProducer);
     return OK;
 }
 
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h
index 2ab4eef..77194ab 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.h
@@ -99,7 +99,7 @@
 
     virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
     virtual status_t setVideoSurface(const sp<Surface> &surface);
-    virtual status_t setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
+    virtual status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index f2b6441..a35d562 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -13,6 +13,7 @@
 
 LOCAL_SRC_FILES:= \
     AudioTrack.cpp \
+    AudioTrackShared.cpp \
     IAudioFlinger.cpp \
     IAudioFlingerClient.cpp \
     IAudioTrack.cpp \
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e40895a..1d87ff8 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -138,6 +138,11 @@
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT)
 {
+    if (sharedBuffer == 0) {
+        ALOGE("sharedBuffer must be non-0");
+        mStatus = BAD_VALUE;
+        return;
+    }
     mStatus = set(streamType, sampleRate, format, channelMask,
             0 /*frameCount*/, flags, cbf, user, notificationFrames,
             sharedBuffer, false /*threadCanCallJava*/, sessionId);
@@ -304,7 +309,6 @@
     }
 
     mSharedBuffer = sharedBuffer;
-    mMuted = false;
     mActive = false;
     mUserData = user;
     mLoopCount = 0;
@@ -317,43 +321,6 @@
     return NO_ERROR;
 }
 
-status_t AudioTrack::initCheck() const
-{
-    return mStatus;
-}
-
-// -------------------------------------------------------------------------
-
-uint32_t AudioTrack::latency() const
-{
-    return mLatency;
-}
-
-audio_stream_type_t AudioTrack::streamType() const
-{
-    return mStreamType;
-}
-
-audio_format_t AudioTrack::format() const
-{
-    return mFormat;
-}
-
-uint32_t AudioTrack::channelCount() const
-{
-    return mChannelCount;
-}
-
-size_t AudioTrack::frameCount() const
-{
-    return mFrameCount;
-}
-
-sp<IMemory>& AudioTrack::sharedBuffer()
-{
-    return mSharedBuffer;
-}
-
 // -------------------------------------------------------------------------
 
 void AudioTrack::start()
@@ -435,6 +402,7 @@
         mMarkerReached = false;
         // Force flush if a shared buffer is used otherwise audioflinger
         // will not stop before end of buffer is reached.
+        // It may be needed to make sure that we stop playback, likely in case looping is on.
         if (mSharedBuffer != 0) {
             flush_l();
         }
@@ -457,26 +425,26 @@
 void AudioTrack::flush()
 {
     AutoMutex lock(mLock);
-    flush_l();
+    if (!mActive && mSharedBuffer == 0) {
+        flush_l();
+    }
 }
 
-// must be called with mLock held
 void AudioTrack::flush_l()
 {
     ALOGV("flush");
+    ALOG_ASSERT(!mActive);
 
     // clear playback marker and periodic update counter
     mMarkerPosition = 0;
     mMarkerReached = false;
     mUpdatePeriod = 0;
 
-    if (!mActive) {
-        mFlushed = true;
-        mAudioTrack->flush();
-        // Release AudioTrack callback thread in case it was waiting for new buffers
-        // in AudioTrack::obtainBuffer()
-        mCblk->cv.signal();
-    }
+    mFlushed = true;
+    mAudioTrack->flush();
+    // Release AudioTrack callback thread in case it was waiting for new buffers
+    // in AudioTrack::obtainBuffer()
+    mCblk->cv.signal();
 }
 
 void AudioTrack::pause()
@@ -490,17 +458,6 @@
     }
 }
 
-void AudioTrack::mute(bool e)
-{
-    mAudioTrack->mute(e);
-    mMuted = e;
-}
-
-bool AudioTrack::muted() const
-{
-    return mMuted;
-}
-
 status_t AudioTrack::setVolume(float left, float right)
 {
     if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) {
@@ -583,6 +540,10 @@
 // must be called with mLock held
 status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount)
 {
+    if (mSharedBuffer == 0 || mIsTimed) {
+        return INVALID_OPERATION;
+    }
+
     audio_track_cblk_t* cblk = mCblk;
 
     Mutex::Autolock _l(cblk->lock);
@@ -595,10 +556,6 @@
         return NO_ERROR;
     }
 
-    if (mIsTimed) {
-        return INVALID_OPERATION;
-    }
-
     if (loopStart >= loopEnd ||
         loopEnd - loopStart > mFrameCount ||
         cblk->server > loopStart) {
@@ -672,7 +629,7 @@
 
 status_t AudioTrack::setPosition(uint32_t position)
 {
-    if (mIsTimed) {
+    if (mSharedBuffer == 0 || mIsTimed) {
         return INVALID_OPERATION;
     }
 
@@ -708,6 +665,10 @@
 
 status_t AudioTrack::reload()
 {
+    if (mSharedBuffer == 0 || mIsTimed) {
+        return INVALID_OPERATION;
+    }
+
     AutoMutex lock(mLock);
 
     if (!stopped_l()) {
@@ -735,11 +696,6 @@
             mCblk->sampleRate, mFormat, mChannelMask, mFlags);
 }
 
-int AudioTrack::getSessionId() const
-{
-    return mSessionId;
-}
-
 status_t AudioTrack::attachAuxEffect(int effectId)
 {
     ALOGV("attachAuxEffect(%d)", effectId);
@@ -1089,10 +1045,7 @@
 ssize_t AudioTrack::write(const void* buffer, size_t userSize)
 {
 
-    if (mSharedBuffer != 0) {
-        return INVALID_OPERATION;
-    }
-    if (mIsTimed) {
+    if (mSharedBuffer != 0 || mIsTimed) {
         return INVALID_OPERATION;
     }
 
@@ -1471,8 +1424,8 @@
     snprintf(buffer, 255, "  format(%d), channel count(%d), frame count(%d)\n", mFormat,
             mChannelCount, mFrameCount);
     result.append(buffer);
-    snprintf(buffer, 255, "  sample rate(%u), status(%d), muted(%d)\n",
-            (cblk == 0) ? 0 : cblk->sampleRate, mStatus, mMuted);
+    snprintf(buffer, 255, "  sample rate(%u), status(%d)\n",
+            (cblk == 0) ? 0 : cblk->sampleRate, mStatus);
     result.append(buffer);
     snprintf(buffer, 255, "  active(%d), latency (%d)\n", mActive, mLatency);
     result.append(buffer);
@@ -1529,180 +1482,4 @@
     }
 }
 
-// =========================================================================
-
-
-audio_track_cblk_t::audio_track_cblk_t()
-    : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
-    userBase(0), serverBase(0), frameCount_(0),
-    loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000),
-    mSendLevel(0), flags(0)
-{
-}
-
-uint32_t audio_track_cblk_t::stepUser(size_t stepCount, size_t frameCount, bool isOut)
-{
-    ALOGV("stepuser %08x %08x %d", user, server, stepCount);
-
-    uint32_t u = user;
-    u += stepCount;
-    // Ensure that user is never ahead of server for AudioRecord
-    if (isOut) {
-        // If stepServer() has been called once, switch to normal obtainBuffer() timeout period
-        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
-            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
-        }
-    } else if (u > server) {
-        ALOGW("stepUser occurred after track reset");
-        u = server;
-    }
-
-    if (u >= frameCount) {
-        // common case, user didn't just wrap
-        if (u - frameCount >= userBase ) {
-            userBase += frameCount;
-        }
-    } else if (u >= userBase + frameCount) {
-        // user just wrapped
-        userBase += frameCount;
-    }
-
-    user = u;
-
-    // Clear flow control error condition as new data has been written/read to/from buffer.
-    if (flags & CBLK_UNDERRUN) {
-        android_atomic_and(~CBLK_UNDERRUN, &flags);
-    }
-
-    return u;
-}
-
-bool audio_track_cblk_t::stepServer(size_t stepCount, size_t frameCount, bool isOut)
-{
-    ALOGV("stepserver %08x %08x %d", user, server, stepCount);
-
-    if (!tryLock()) {
-        ALOGW("stepServer() could not lock cblk");
-        return false;
-    }
-
-    uint32_t s = server;
-    bool flushed = (s == user);
-
-    s += stepCount;
-    if (isOut) {
-        // Mark that we have read the first buffer so that next time stepUser() is called
-        // we switch to normal obtainBuffer() timeout period
-        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
-            bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1;
-        }
-        // It is possible that we receive a flush()
-        // while the mixer is processing a block: in this case,
-        // stepServer() is called After the flush() has reset u & s and
-        // we have s > u
-        if (flushed) {
-            ALOGW("stepServer occurred after track reset");
-            s = user;
-        }
-    }
-
-    if (s >= loopEnd) {
-        ALOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd);
-        s = loopStart;
-        if (--loopCount == 0) {
-            loopEnd = UINT_MAX;
-            loopStart = UINT_MAX;
-        }
-    }
-
-    if (s >= frameCount) {
-        // common case, server didn't just wrap
-        if (s - frameCount >= serverBase ) {
-            serverBase += frameCount;
-        }
-    } else if (s >= serverBase + frameCount) {
-        // server just wrapped
-        serverBase += frameCount;
-    }
-
-    server = s;
-
-    if (!(flags & CBLK_INVALID)) {
-        cv.signal();
-    }
-    lock.unlock();
-    return true;
-}
-
-void* audio_track_cblk_t::buffer(void *buffers, size_t frameSize, uint32_t offset) const
-{
-    return (int8_t *)buffers + (offset - userBase) * frameSize;
-}
-
-uint32_t audio_track_cblk_t::framesAvailable(size_t frameCount, bool isOut)
-{
-    Mutex::Autolock _l(lock);
-    return framesAvailable_l(frameCount, isOut);
-}
-
-uint32_t audio_track_cblk_t::framesAvailable_l(size_t frameCount, bool isOut)
-{
-    uint32_t u = user;
-    uint32_t s = server;
-
-    if (isOut) {
-        uint32_t limit = (s < loopStart) ? s : loopStart;
-        return limit + frameCount - u;
-    } else {
-        return frameCount + u - s;
-    }
-}
-
-uint32_t audio_track_cblk_t::framesReady(bool isOut)
-{
-    uint32_t u = user;
-    uint32_t s = server;
-
-    if (isOut) {
-        if (u < loopEnd) {
-            return u - s;
-        } else {
-            // do not block on mutex shared with client on AudioFlinger side
-            if (!tryLock()) {
-                ALOGW("framesReady() could not lock cblk");
-                return 0;
-            }
-            uint32_t frames = UINT_MAX;
-            if (loopCount >= 0) {
-                frames = (loopEnd - loopStart)*loopCount + u - s;
-            }
-            lock.unlock();
-            return frames;
-        }
-    } else {
-        return s - u;
-    }
-}
-
-bool audio_track_cblk_t::tryLock()
-{
-    // the code below simulates lock-with-timeout
-    // we MUST do this to protect the AudioFlinger server
-    // as this lock is shared with the client.
-    status_t err;
-
-    err = lock.tryLock();
-    if (err == -EBUSY) { // just wait a bit
-        usleep(1000);
-        err = lock.tryLock();
-    }
-    if (err != NO_ERROR) {
-        // probably, the client just died.
-        return false;
-    }
-    return true;
-}
-
-// -------------------------------------------------------------------------
-
 }; // namespace android
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
new file mode 100644
index 0000000..bee13c8
--- /dev/null
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2007 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 "AudioTrackShared"
+//#define LOG_NDEBUG 0
+
+#include <private/media/AudioTrackShared.h>
+#include <utils/Log.h>
+
+namespace android {
+
+audio_track_cblk_t::audio_track_cblk_t()
+    : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
+    userBase(0), serverBase(0), frameCount_(0),
+    loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000),
+    mSendLevel(0), flags(0)
+{
+}
+
+uint32_t audio_track_cblk_t::stepUser(size_t stepCount, size_t frameCount, bool isOut)
+{
+    ALOGV("stepuser %08x %08x %d", user, server, stepCount);
+
+    uint32_t u = user;
+    u += stepCount;
+    // Ensure that user is never ahead of server for AudioRecord
+    if (isOut) {
+        // If stepServer() has been called once, switch to normal obtainBuffer() timeout period
+        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
+            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+        }
+    } else if (u > server) {
+        ALOGW("stepUser occurred after track reset");
+        u = server;
+    }
+
+    if (u >= frameCount) {
+        // common case, user didn't just wrap
+        if (u - frameCount >= userBase ) {
+            userBase += frameCount;
+        }
+    } else if (u >= userBase + frameCount) {
+        // user just wrapped
+        userBase += frameCount;
+    }
+
+    user = u;
+
+    // Clear flow control error condition as new data has been written/read to/from buffer.
+    if (flags & CBLK_UNDERRUN) {
+        android_atomic_and(~CBLK_UNDERRUN, &flags);
+    }
+
+    return u;
+}
+
+bool audio_track_cblk_t::stepServer(size_t stepCount, size_t frameCount, bool isOut)
+{
+    ALOGV("stepserver %08x %08x %d", user, server, stepCount);
+
+    if (!tryLock()) {
+        ALOGW("stepServer() could not lock cblk");
+        return false;
+    }
+
+    uint32_t s = server;
+    bool flushed = (s == user);
+
+    s += stepCount;
+    if (isOut) {
+        // Mark that we have read the first buffer so that next time stepUser() is called
+        // we switch to normal obtainBuffer() timeout period
+        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
+            bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1;
+        }
+        // It is possible that we receive a flush()
+        // while the mixer is processing a block: in this case,
+        // stepServer() is called After the flush() has reset u & s and
+        // we have s > u
+        if (flushed) {
+            ALOGW("stepServer occurred after track reset");
+            s = user;
+        }
+    }
+
+    if (s >= loopEnd) {
+        ALOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd);
+        s = loopStart;
+        if (--loopCount == 0) {
+            loopEnd = UINT_MAX;
+            loopStart = UINT_MAX;
+        }
+    }
+
+    if (s >= frameCount) {
+        // common case, server didn't just wrap
+        if (s - frameCount >= serverBase ) {
+            serverBase += frameCount;
+        }
+    } else if (s >= serverBase + frameCount) {
+        // server just wrapped
+        serverBase += frameCount;
+    }
+
+    server = s;
+
+    if (!(flags & CBLK_INVALID)) {
+        cv.signal();
+    }
+    lock.unlock();
+    return true;
+}
+
+void* audio_track_cblk_t::buffer(void *buffers, size_t frameSize, uint32_t offset) const
+{
+    return (int8_t *)buffers + (offset - userBase) * frameSize;
+}
+
+uint32_t audio_track_cblk_t::framesAvailable(size_t frameCount, bool isOut)
+{
+    Mutex::Autolock _l(lock);
+    return framesAvailable_l(frameCount, isOut);
+}
+
+uint32_t audio_track_cblk_t::framesAvailable_l(size_t frameCount, bool isOut)
+{
+    uint32_t u = user;
+    uint32_t s = server;
+
+    if (isOut) {
+        uint32_t limit = (s < loopStart) ? s : loopStart;
+        return limit + frameCount - u;
+    } else {
+        return frameCount + u - s;
+    }
+}
+
+uint32_t audio_track_cblk_t::framesReady(bool isOut)
+{
+    uint32_t u = user;
+    uint32_t s = server;
+
+    if (isOut) {
+        if (u < loopEnd) {
+            return u - s;
+        } else {
+            // do not block on mutex shared with client on AudioFlinger side
+            if (!tryLock()) {
+                ALOGW("framesReady() could not lock cblk");
+                return 0;
+            }
+            uint32_t frames = UINT_MAX;
+            if (loopCount >= 0) {
+                frames = (loopEnd - loopStart)*loopCount + u - s;
+            }
+            lock.unlock();
+            return frames;
+        }
+    } else {
+        return s - u;
+    }
+}
+
+bool audio_track_cblk_t::tryLock()
+{
+    // the code below simulates lock-with-timeout
+    // we MUST do this to protect the AudioFlinger server
+    // as this lock is shared with the client.
+    status_t err;
+
+    err = lock.tryLock();
+    if (err == -EBUSY) { // just wait a bit
+        usleep(1000);
+        err = lock.tryLock();
+    }
+    if (err != NO_ERROR) {
+        // probably, the client just died.
+        return false;
+    }
+    return true;
+}
+
+}   // namespace android
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index a010bb6..c5fbbf0 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -32,7 +32,7 @@
     CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
     OPEN_RECORD,
     SAMPLE_RATE,
-    CHANNEL_COUNT,  // obsolete
+    RESERVED,   // obsolete, was CHANNEL_COUNT
     FORMAT,
     FRAME_COUNT,
     LATENCY,
@@ -191,17 +191,6 @@
         return reply.readInt32();
     }
 
-#if 0
-    virtual int channelCount(audio_io_handle_t output) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(CHANNEL_COUNT, data, &reply);
-        return reply.readInt32();
-    }
-#endif
-
     virtual audio_format_t format(audio_io_handle_t output) const
     {
         Parcel data, reply;
@@ -768,13 +757,6 @@
             reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
-#if 0
-        case CHANNEL_COUNT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-#endif
         case FORMAT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index 867d1a5..e92f8aa 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -33,7 +33,7 @@
     START,
     STOP,
     FLUSH,
-    MUTE,
+    RESERVED, // was MUTE
     PAUSE,
     ATTACH_AUX_EFFECT,
     ALLOCATE_TIMED_BUFFER,
@@ -88,14 +88,6 @@
         remote()->transact(FLUSH, data, &reply);
     }
 
-    virtual void mute(bool e)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        data.writeInt32(e);
-        remote()->transact(MUTE, data, &reply);
-    }
-
     virtual void pause()
     {
         Parcel data, reply;
@@ -192,11 +184,6 @@
             flush();
             return NO_ERROR;
         } break;
-        case MUTE: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            mute( data.readInt32() );
-            return NO_ERROR;
-        } break;
         case PAUSE: {
             CHECK_INTERFACE(IAudioTrack, data, reply);
             pause();
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index cb07766..e79bcd2 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -24,7 +24,7 @@
 #include <media/IMediaPlayer.h>
 #include <media/IStreamSource.h>
 
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <utils/String8.h>
 
 namespace android {
@@ -113,12 +113,12 @@
         return reply.readInt32();
     }
 
-    // pass the buffered ISurfaceTexture to the media player service
-    status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
+    // pass the buffered IGraphicBufferProducer to the media player service
+    status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
-        sp<IBinder> b(surfaceTexture->asBinder());
+        sp<IBinder> b(bufferProducer->asBinder());
         data.writeStrongBinder(b);
         remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
         return reply.readInt32();
@@ -383,9 +383,9 @@
         }
         case SET_VIDEO_SURFACETEXTURE: {
             CHECK_INTERFACE(IMediaPlayer, data, reply);
-            sp<ISurfaceTexture> surfaceTexture =
-                    interface_cast<ISurfaceTexture>(data.readStrongBinder());
-            reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
+            sp<IGraphicBufferProducer> bufferProducer =
+                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
+            reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
             return NO_ERROR;
         } break;
         case PREPARE_ASYNC: {
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index a710fd7..fdbc747 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -23,7 +23,7 @@
 #include <media/IMediaRecorderClient.h>
 #include <media/IMediaRecorder.h>
 #include <gui/Surface.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <unistd.h>
 
 
@@ -73,7 +73,7 @@
         return reply.readInt32();
     }
 
-    sp<ISurfaceTexture> querySurfaceMediaSource()
+    sp<IGraphicBufferProducer> querySurfaceMediaSource()
     {
         ALOGV("Query SurfaceMediaSource");
         Parcel data, reply;
@@ -83,7 +83,7 @@
         if (returnedNull) {
             return NULL;
         }
-        return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
+        return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
     }
 
     status_t setPreviewSurface(const sp<Surface>& surface)
@@ -444,7 +444,7 @@
             CHECK_INTERFACE(IMediaRecorder, data, reply);
             // call the mediaserver side to create
             // a surfacemediasource
-            sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource();
+            sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource();
             // The mediaserver might have failed to create a source
             int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
             reply->writeInt32(returnedNull);
diff --git a/media/libmedia/IRemoteDisplay.cpp b/media/libmedia/IRemoteDisplay.cpp
index da25a15..1e15434 100644
--- a/media/libmedia/IRemoteDisplay.cpp
+++ b/media/libmedia/IRemoteDisplay.cpp
@@ -23,6 +23,8 @@
 
 enum {
     DISPOSE = IBinder::FIRST_CALL_TRANSACTION,
+    PAUSE,
+    RESUME,
 };
 
 class BpRemoteDisplay: public BpInterface<IRemoteDisplay>
@@ -33,6 +35,20 @@
     {
     }
 
+    virtual status_t pause() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IRemoteDisplay::getInterfaceDescriptor());
+        remote()->transact(PAUSE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t resume() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IRemoteDisplay::getInterfaceDescriptor());
+        remote()->transact(RESUME, data, &reply);
+        return reply.readInt32();
+    }
+
     status_t dispose()
     {
         Parcel data, reply;
@@ -55,6 +71,21 @@
             reply->writeInt32(dispose());
             return NO_ERROR;
         }
+
+        case PAUSE:
+        {
+            CHECK_INTERFACE(IRemoteDisplay, data, reply);
+            reply->writeInt32(pause());
+            return OK;
+        }
+
+        case RESUME:
+        {
+            CHECK_INTERFACE(IRemoteDisplay, data, reply);
+            reply->writeInt32(resume());
+            return OK;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/IRemoteDisplayClient.cpp b/media/libmedia/IRemoteDisplayClient.cpp
index 4a1b570..5c494b3 100644
--- a/media/libmedia/IRemoteDisplayClient.cpp
+++ b/media/libmedia/IRemoteDisplayClient.cpp
@@ -18,7 +18,7 @@
 #include <sys/types.h>
 
 #include <media/IRemoteDisplayClient.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <utils/String8.h>
 
 namespace android {
@@ -37,12 +37,12 @@
     {
     }
 
-    void onDisplayConnected(const sp<ISurfaceTexture>& surfaceTexture,
+    void onDisplayConnected(const sp<IGraphicBufferProducer>& bufferProducer,
             uint32_t width, uint32_t height, uint32_t flags)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IRemoteDisplayClient::getInterfaceDescriptor());
-        data.writeStrongBinder(surfaceTexture->asBinder());
+        data.writeStrongBinder(bufferProducer->asBinder());
         data.writeInt32(width);
         data.writeInt32(height);
         data.writeInt32(flags);
@@ -75,8 +75,8 @@
     switch (code) {
         case ON_DISPLAY_CONNECTED: {
             CHECK_INTERFACE(IRemoteDisplayClient, data, reply);
-            sp<ISurfaceTexture> surfaceTexture(
-                    interface_cast<ISurfaceTexture>(data.readStrongBinder()));
+            sp<IGraphicBufferProducer> surfaceTexture(
+                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder()));
             uint32_t width = data.readInt32();
             uint32_t height = data.readInt32();
             uint32_t flags = data.readInt32();
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index bbbf4b6..ae527e8 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -221,12 +221,12 @@
 }
 
 status_t MediaPlayer::setVideoSurfaceTexture(
-        const sp<ISurfaceTexture>& surfaceTexture)
+        const sp<IGraphicBufferProducer>& bufferProducer)
 {
     ALOGV("setVideoSurfaceTexture");
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) return NO_INIT;
-    return mPlayer->setVideoSurfaceTexture(surfaceTexture);
+    return mPlayer->setVideoSurfaceTexture(bufferProducer);
 }
 
 // must call with lock held
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 9541015..95c7f3e 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -24,7 +24,7 @@
 #include <media/IMediaPlayerService.h>
 #include <media/IMediaRecorder.h>
 #include <media/mediaplayer.h>  // for MEDIA_ERROR_SERVER_DIED
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
@@ -348,9 +348,9 @@
 }
 
 // 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::
+// binder interface. This is used by the Filter Framework (MediaEncoder)
+// to get an <IGraphicBufferProducer> object to hook up to ANativeWindow.
+sp<IGraphicBufferProducer> MediaRecorder::
         querySurfaceMediaSourceFromMediaServer()
 {
     Mutex::Autolock _l(mLock);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index c3e5c40..4ca0811 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -714,21 +714,21 @@
 }
 
 status_t MediaPlayerService::Client::setVideoSurfaceTexture(
-        const sp<ISurfaceTexture>& surfaceTexture)
+        const sp<IGraphicBufferProducer>& bufferProducer)
 {
-    ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
+    ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());
     sp<MediaPlayerBase> p = getPlayer();
     if (p == 0) return UNKNOWN_ERROR;
 
-    sp<IBinder> binder(surfaceTexture == NULL ? NULL :
-            surfaceTexture->asBinder());
+    sp<IBinder> binder(bufferProducer == NULL ? NULL :
+            bufferProducer->asBinder());
     if (mConnectedWindowBinder == binder) {
         return OK;
     }
 
     sp<ANativeWindow> anw;
-    if (surfaceTexture != NULL) {
-        anw = new SurfaceTextureClient(surfaceTexture);
+    if (bufferProducer != NULL) {
+        anw = new SurfaceTextureClient(bufferProducer);
         status_t err = native_window_api_connect(anw.get(),
                 NATIVE_WINDOW_API_MEDIA);
 
@@ -745,10 +745,10 @@
         }
     }
 
-    // Note that we must set the player's new SurfaceTexture before
+    // Note that we must set the player's new GraphicBufferProducer before
     // disconnecting the old one.  Otherwise queue/dequeue calls could be made
     // on the disconnected ANW, which may result in errors.
-    status_t err = p->setVideoSurfaceTexture(surfaceTexture);
+    status_t err = p->setVideoSurfaceTexture(bufferProducer);
 
     disconnectNativeWindow();
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index fd648df..afb6780 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -307,7 +307,7 @@
         // IMediaPlayer interface
         virtual void            disconnect();
         virtual status_t        setVideoSurfaceTexture(
-                                        const sp<ISurfaceTexture>& surfaceTexture);
+                                        const sp<IGraphicBufferProducer>& bufferProducer);
         virtual status_t        prepareAsync();
         virtual status_t        start();
         virtual status_t        stop();
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index eadc8ee..c6d8b76 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -38,7 +38,7 @@
 #include "MediaPlayerService.h"
 
 #include "StagefrightRecorder.h"
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
@@ -56,7 +56,7 @@
 }
 
 
-sp<ISurfaceTexture> MediaRecorderClient::querySurfaceMediaSource()
+sp<IGraphicBufferProducer> MediaRecorderClient::querySurfaceMediaSource()
 {
     ALOGV("Query SurfaceMediaSource");
     Mutex::Autolock lock(mLock);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index c9ccf22..5623917 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -25,7 +25,7 @@
 class MediaRecorderBase;
 class MediaPlayerService;
 class ICameraRecordingProxy;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 
 class MediaRecorderClient : public BnMediaRecorder
 {
@@ -55,7 +55,7 @@
     virtual     status_t   close();
     virtual     status_t   release();
     virtual     status_t   dump(int fd, const Vector<String16>& args) const;
-    virtual     sp<ISurfaceTexture> querySurfaceMediaSource();
+    virtual     sp<IGraphicBufferProducer> querySurfaceMediaSource();
 
 private:
     friend class           MediaPlayerService;  // for accessing private constructor
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index f6f8f7b..24d59b4 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -36,7 +36,7 @@
 
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length);
     virtual status_t    setVideoSurfaceTexture(
-                                const sp<ISurfaceTexture>& surfaceTexture)
+                                const sp<IGraphicBufferProducer>& bufferProducer)
                             { return UNKNOWN_ERROR; }
     virtual status_t    prepare();
     virtual status_t    prepareAsync();
diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp
index 5baa3ad..20e6513 100644
--- a/media/libmediaplayerservice/RemoteDisplay.cpp
+++ b/media/libmediaplayerservice/RemoteDisplay.cpp
@@ -40,6 +40,14 @@
 RemoteDisplay::~RemoteDisplay() {
 }
 
+status_t RemoteDisplay::pause() {
+    return mSource->pause();
+}
+
+status_t RemoteDisplay::resume() {
+    return mSource->resume();
+}
+
 status_t RemoteDisplay::dispose() {
     mSource->stop();
 
diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h
index 0d87250..bd8b684 100644
--- a/media/libmediaplayerservice/RemoteDisplay.h
+++ b/media/libmediaplayerservice/RemoteDisplay.h
@@ -33,6 +33,8 @@
 struct RemoteDisplay : public BnRemoteDisplay {
     RemoteDisplay(const sp<IRemoteDisplayClient> &client, const char *iface);
 
+    virtual status_t pause();
+    virtual status_t resume();
     virtual status_t dispose();
 
 protected:
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 619c149..de61d9b 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -70,10 +70,10 @@
 }
 
 status_t StagefrightPlayer::setVideoSurfaceTexture(
-        const sp<ISurfaceTexture> &surfaceTexture) {
+        const sp<IGraphicBufferProducer> &bufferProducer) {
     ALOGV("setVideoSurfaceTexture");
 
-    return mPlayer->setSurfaceTexture(surfaceTexture);
+    return mPlayer->setSurfaceTexture(bufferProducer);
 }
 
 status_t StagefrightPlayer::prepare() {
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index e89e18a..600945e 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -41,7 +41,7 @@
     virtual status_t setDataSource(const sp<IStreamSource> &source);
 
     virtual status_t setVideoSurfaceTexture(
-            const sp<ISurfaceTexture> &surfaceTexture);
+            const sp<IGraphicBufferProducer> &bufferProducer);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 57b0ec2..497dda6 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -89,7 +89,7 @@
 // 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 {
+sp<IGraphicBufferProducer> StagefrightRecorder::querySurfaceMediaSource() const {
     ALOGV("Get SurfaceMediaSource");
     return mSurfaceMediaSource->getBufferQueue();
 }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index ec5ce7e..351efd4 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -35,7 +35,7 @@
 class MetaData;
 struct AudioSource;
 class MediaProfiles;
-class ISurfaceTexture;
+class IGraphicBufferProducer;
 class SurfaceMediaSource;
 
 struct StagefrightRecorder : public MediaRecorderBase {
@@ -65,7 +65,7 @@
     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;
+    virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const;
 
 private:
     sp<ICamera> mCamera;
@@ -116,7 +116,7 @@
 
     bool mStarted;
     // Needed when GLFrames are encoded.
-    // An <ISurfaceTexture> pointer
+    // An <IGraphicBufferProducer> pointer
     // will be sent to the client side using which the
     // frame buffers will be queued and dequeued
     sp<SurfaceMediaSource> mSurfaceMediaSource;
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index 91ffa7d..a3802eb 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -76,7 +76,7 @@
 
     // All the methods below wrap the mPlayer instance.
     virtual status_t setVideoSurfaceTexture(
-            const android::sp<android::ISurfaceTexture>& st)  {
+            const android::sp<android::IGraphicBufferProducer>& st)  {
         return mPlayer->setVideoSurfaceTexture(st);
     }
     virtual status_t prepare() {return mPlayer->prepare();}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d3ec122..517fb34 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -41,7 +41,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 
 #include "avc_utils.h"
 
@@ -50,6 +50,64 @@
 
 namespace android {
 
+struct NuPlayer::Action : public RefBase {
+    Action() {}
+
+    virtual void execute(NuPlayer *player) = 0;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(Action);
+};
+
+struct NuPlayer::SeekAction : public Action {
+    SeekAction(int64_t seekTimeUs)
+        : mSeekTimeUs(seekTimeUs) {
+    }
+
+    virtual void execute(NuPlayer *player) {
+        player->performSeek(mSeekTimeUs);
+    }
+
+private:
+    int64_t mSeekTimeUs;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
+};
+
+struct NuPlayer::SetSurfaceAction : public Action {
+    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
+        : mWrapper(wrapper) {
+    }
+
+    virtual void execute(NuPlayer *player) {
+        player->performSetSurface(mWrapper);
+    }
+
+private:
+    sp<NativeWindowWrapper> mWrapper;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
+};
+
+// Use this if there's no state necessary to save in order to execute
+// the action.
+struct NuPlayer::SimpleAction : public Action {
+    typedef void (NuPlayer::*ActionFunc)();
+
+    SimpleAction(ActionFunc func)
+        : mFunc(func) {
+    }
+
+    virtual void execute(NuPlayer *player) {
+        (player->*mFunc)();
+    }
+
+private:
+    ActionFunc mFunc;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 
 NuPlayer::NuPlayer()
@@ -63,14 +121,13 @@
       mTimeDiscontinuityPending(false),
       mFlushingAudio(NONE),
       mFlushingVideo(NONE),
-      mResetInProgress(false),
-      mResetPostponed(false),
       mSkipRenderingAudioUntilMediaTimeUs(-1ll),
       mSkipRenderingVideoUntilMediaTimeUs(-1ll),
       mVideoLateByUs(0ll),
       mNumFramesTotal(0ll),
       mNumFramesDropped(0ll),
-      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) {
+      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
+      mStarted(false) {
 }
 
 NuPlayer::~NuPlayer() {
@@ -140,11 +197,19 @@
     msg->post();
 }
 
-void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+void NuPlayer::setVideoSurfaceTextureAsync(
+        const sp<IGraphicBufferProducer> &bufferProducer) {
     sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
-    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
-                new SurfaceTextureClient(surfaceTexture) : NULL);
-    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
+
+    if (bufferProducer == NULL) {
+        msg->setObject("native-window", NULL);
+    } else {
+        msg->setObject(
+                "native-window",
+                new NativeWindowWrapper(
+                    new SurfaceTextureClient(bufferProducer)));
+    }
+
     msg->post();
 }
 
@@ -237,13 +302,24 @@
         {
             ALOGV("kWhatSetVideoNativeWindow");
 
+            mDeferredActions.push_back(
+                    new SimpleAction(&NuPlayer::performDecoderShutdown));
+
             sp<RefBase> obj;
             CHECK(msg->findObject("native-window", &obj));
 
-            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
+            mDeferredActions.push_back(
+                    new SetSurfaceAction(
+                        static_cast<NativeWindowWrapper *>(obj.get())));
 
-            // XXX - ignore error from setVideoScalingMode for now
-            setVideoScalingMode(mVideoScalingMode);
+            if (obj != NULL) {
+                // If there is a new surface texture, instantiate decoders
+                // again if possible.
+                mDeferredActions.push_back(
+                        new SimpleAction(&NuPlayer::performScanSources));
+            }
+
+            processDeferredActions();
             break;
         }
 
@@ -270,6 +346,7 @@
             mVideoLateByUs = 0;
             mNumFramesTotal = 0;
             mNumFramesDropped = 0;
+            mStarted = true;
 
             mSource->start();
 
@@ -407,7 +484,8 @@
             } else if (what == ACodec::kWhatOutputFormatChanged) {
                 if (audio) {
                     int32_t numChannels;
-                    CHECK(codecRequest->findInt32("channel-count", &numChannels));
+                    CHECK(codecRequest->findInt32(
+                                "channel-count", &numChannels));
 
                     int32_t sampleRate;
                     CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
@@ -419,13 +497,15 @@
 
                     audio_output_flags_t flags;
                     int64_t durationUs;
-                    // FIXME: we should handle the case where the video decoder is created after
-                    // we receive the format change indication. Current code will just make that
-                    // we select deep buffer with video which should not be a problem as it should
+                    // FIXME: we should handle the case where the video decoder
+                    // is created after we receive the format change indication.
+                    // Current code will just make that we select deep buffer
+                    // with video which should not be a problem as it should
                     // not prevent from keeping A/V sync.
                     if (mVideoDecoder == NULL &&
                             mSource->getDuration(&durationUs) == OK &&
-                            durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
+                            durationUs
+                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
                         flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
                     } else {
                         flags = AUDIO_OUTPUT_FLAG_NONE;
@@ -461,17 +541,35 @@
                                 "crop",
                                 &cropLeft, &cropTop, &cropRight, &cropBottom));
 
+                    int32_t displayWidth = cropRight - cropLeft + 1;
+                    int32_t displayHeight = cropBottom - cropTop + 1;
+
                     ALOGV("Video output format changed to %d x %d "
                          "(crop: %d x %d @ (%d, %d))",
                          width, height,
-                         (cropRight - cropLeft + 1),
-                         (cropBottom - cropTop + 1),
+                         displayWidth,
+                         displayHeight,
                          cropLeft, cropTop);
 
+                    sp<AMessage> videoInputFormat =
+                        mSource->getFormat(false /* audio */);
+
+                    // Take into account sample aspect ratio if necessary:
+                    int32_t sarWidth, sarHeight;
+                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
+                            && videoInputFormat->findInt32(
+                                "sar-height", &sarHeight)) {
+                        ALOGV("Sample aspect ratio %d : %d",
+                              sarWidth, sarHeight);
+
+                        displayWidth = (displayWidth * sarWidth) / sarHeight;
+
+                        ALOGV("display dimensions %d x %d",
+                              displayWidth, displayHeight);
+                    }
+
                     notifyListener(
-                            MEDIA_SET_VIDEO_SIZE,
-                            cropRight - cropLeft + 1,
-                            cropBottom - cropTop + 1);
+                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
                 }
             } else if (what == ACodec::kWhatShutdownCompleted) {
                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
@@ -495,8 +593,15 @@
                 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
             } else if (what == ACodec::kWhatDrainThisBuffer) {
                 renderBuffer(audio, codecRequest);
-            } else {
-                ALOGV("Unhandled codec notification %d.", what);
+            } else if (what != ACodec::kWhatComponentAllocated
+                    && what != ACodec::kWhatComponentConfigured
+                    && what != ACodec::kWhatBuffersAllocated) {
+                ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
+                      what,
+                      what >> 24,
+                      (what >> 16) & 0xff,
+                      (what >> 8) & 0xff,
+                      what & 0xff);
             }
 
             break;
@@ -569,47 +674,13 @@
         {
             ALOGV("kWhatReset");
 
-            cancelPollDuration();
+            mDeferredActions.push_back(
+                    new SimpleAction(&NuPlayer::performDecoderShutdown));
 
-            if (mRenderer != NULL) {
-                // There's an edge case where the renderer owns all output
-                // buffers and is paused, therefore the decoder will not read
-                // more input data and will never encounter the matching
-                // discontinuity. To avoid this, we resume the renderer.
+            mDeferredActions.push_back(
+                    new SimpleAction(&NuPlayer::performReset));
 
-                if (mFlushingAudio == AWAITING_DISCONTINUITY
-                        || mFlushingVideo == AWAITING_DISCONTINUITY) {
-                    mRenderer->resume();
-                }
-            }
-
-            if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
-                // We're currently flushing, postpone the reset until that's
-                // completed.
-
-                ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
-                      mFlushingAudio, mFlushingVideo);
-
-                mResetPostponed = true;
-                break;
-            }
-
-            if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
-                finishReset();
-                break;
-            }
-
-            mTimeDiscontinuityPending = true;
-
-            if (mAudioDecoder != NULL) {
-                flushDecoder(true /* audio */, true /* needShutdown */);
-            }
-
-            if (mVideoDecoder != NULL) {
-                flushDecoder(false /* audio */, true /* needShutdown */);
-            }
-
-            mResetInProgress = true;
+            processDeferredActions();
             break;
         }
 
@@ -618,18 +689,14 @@
             int64_t seekTimeUs;
             CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
 
-            ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
-                 seekTimeUs, seekTimeUs / 1E6);
+            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
 
-            mSource->seekTo(seekTimeUs);
+            mDeferredActions.push_back(
+                    new SimpleAction(&NuPlayer::performDecoderFlush));
 
-            if (mDriver != NULL) {
-                sp<NuPlayerDriver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    driver->notifySeekComplete();
-                }
-            }
+            mDeferredActions.push_back(new SeekAction(seekTimeUs));
 
+            processDeferredActions();
             break;
         }
 
@@ -680,39 +747,7 @@
     mFlushingAudio = NONE;
     mFlushingVideo = NONE;
 
-    if (mResetInProgress) {
-        ALOGV("reset completed");
-
-        mResetInProgress = false;
-        finishReset();
-    } else if (mResetPostponed) {
-        (new AMessage(kWhatReset, id()))->post();
-        mResetPostponed = false;
-    } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
-        postScanSources();
-    }
-}
-
-void NuPlayer::finishReset() {
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
-    ++mScanSourcesGeneration;
-    mScanSourcesPending = false;
-
-    mRenderer.clear();
-
-    if (mSource != NULL) {
-        mSource->stop();
-        mSource.clear();
-    }
-
-    if (mDriver != NULL) {
-        sp<NuPlayerDriver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifyResetComplete();
-        }
-    }
+    processDeferredActions();
 }
 
 void NuPlayer::postScanSources() {
@@ -831,6 +866,14 @@
                     mTimeDiscontinuityPending || timeChange;
 
                 if (formatChange || timeChange) {
+                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
+                        // And we'll resume scanning sources once we're done
+                        // flushing.
+                        mDeferredActions.push_front(
+                                new SimpleAction(
+                                    &NuPlayer::performScanSources));
+                    }
+
                     flushDecoder(audio, formatChange);
                 } else {
                     // This stream is unaffected by the discontinuity
@@ -1000,8 +1043,7 @@
 
 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
     mVideoScalingMode = mode;
-    if (mNativeWindow != NULL
-            && mNativeWindow->getNativeWindow() != NULL) {
+    if (mNativeWindow != NULL) {
         status_t ret = native_window_set_scaling_mode(
                 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
         if (ret != OK) {
@@ -1023,4 +1065,149 @@
     ++mPollDurationGeneration;
 }
 
+void NuPlayer::processDeferredActions() {
+    while (!mDeferredActions.empty()) {
+        // We won't execute any deferred actions until we're no longer in
+        // an intermediate state, i.e. one more more decoders are currently
+        // flushing or shutting down.
+
+        if (mRenderer != NULL) {
+            // There's an edge case where the renderer owns all output
+            // buffers and is paused, therefore the decoder will not read
+            // more input data and will never encounter the matching
+            // discontinuity. To avoid this, we resume the renderer.
+
+            if (mFlushingAudio == AWAITING_DISCONTINUITY
+                    || mFlushingVideo == AWAITING_DISCONTINUITY) {
+                mRenderer->resume();
+            }
+        }
+
+        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
+            // We're currently flushing, postpone the reset until that's
+            // completed.
+
+            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
+                  mFlushingAudio, mFlushingVideo);
+
+            break;
+        }
+
+        sp<Action> action = *mDeferredActions.begin();
+        mDeferredActions.erase(mDeferredActions.begin());
+
+        action->execute(this);
+    }
+}
+
+void NuPlayer::performSeek(int64_t seekTimeUs) {
+    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
+          seekTimeUs,
+          seekTimeUs / 1E6);
+
+    mSource->seekTo(seekTimeUs);
+
+    if (mDriver != NULL) {
+        sp<NuPlayerDriver> driver = mDriver.promote();
+        if (driver != NULL) {
+            driver->notifyPosition(seekTimeUs);
+            driver->notifySeekComplete();
+        }
+    }
+
+    // everything's flushed, continue playback.
+}
+
+void NuPlayer::performDecoderFlush() {
+    ALOGV("performDecoderFlush");
+
+    if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
+        return;
+    }
+
+    mTimeDiscontinuityPending = true;
+
+    if (mAudioDecoder != NULL) {
+        flushDecoder(true /* audio */, false /* needShutdown */);
+    }
+
+    if (mVideoDecoder != NULL) {
+        flushDecoder(false /* audio */, false /* needShutdown */);
+    }
+}
+
+void NuPlayer::performDecoderShutdown() {
+    ALOGV("performDecoderShutdown");
+
+    if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
+        return;
+    }
+
+    mTimeDiscontinuityPending = true;
+
+    if (mAudioDecoder != NULL) {
+        flushDecoder(true /* audio */, true /* needShutdown */);
+    }
+
+    if (mVideoDecoder != NULL) {
+        flushDecoder(false /* audio */, true /* needShutdown */);
+    }
+}
+
+void NuPlayer::performReset() {
+    ALOGV("performReset");
+
+    CHECK(mAudioDecoder == NULL);
+    CHECK(mVideoDecoder == NULL);
+
+    cancelPollDuration();
+
+    ++mScanSourcesGeneration;
+    mScanSourcesPending = false;
+
+    mRenderer.clear();
+
+    if (mSource != NULL) {
+        mSource->stop();
+        mSource.clear();
+    }
+
+    if (mDriver != NULL) {
+        sp<NuPlayerDriver> driver = mDriver.promote();
+        if (driver != NULL) {
+            driver->notifyResetComplete();
+        }
+    }
+
+    mStarted = false;
+}
+
+void NuPlayer::performScanSources() {
+    ALOGV("performScanSources");
+
+    if (!mStarted) {
+        return;
+    }
+
+    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
+        postScanSources();
+    }
+}
+
+void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
+    ALOGV("performSetSurface");
+
+    mNativeWindow = wrapper;
+
+    // XXX - ignore error from setVideoScalingMode for now
+    setVideoScalingMode(mVideoScalingMode);
+
+    if (mDriver != NULL) {
+        sp<NuPlayerDriver> driver = mDriver.promote();
+        if (driver != NULL) {
+            driver->notifySetSurfaceComplete();
+        }
+    }
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 31efb2e..09fc0ba 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -42,7 +42,9 @@
 
     void setDataSource(int fd, int64_t offset, int64_t length);
 
-    void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
+    void setVideoSurfaceTextureAsync(
+            const sp<IGraphicBufferProducer> &bufferProducer);
+
     void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
     void start();
 
@@ -73,6 +75,10 @@
     struct Renderer;
     struct RTSPSource;
     struct StreamingSource;
+    struct Action;
+    struct SeekAction;
+    struct SetSurfaceAction;
+    struct SimpleAction;
 
     enum {
         kWhatSetDataSource              = '=DaS',
@@ -102,6 +108,8 @@
     sp<Decoder> mAudioDecoder;
     sp<Renderer> mRenderer;
 
+    List<sp<Action> > mDeferredActions;
+
     bool mAudioEOS;
     bool mVideoEOS;
 
@@ -126,8 +134,6 @@
 
     FlushStatus mFlushingAudio;
     FlushStatus mFlushingVideo;
-    bool mResetInProgress;
-    bool mResetPostponed;
 
     int64_t mSkipRenderingAudioUntilMediaTimeUs;
     int64_t mSkipRenderingVideoUntilMediaTimeUs;
@@ -137,6 +143,8 @@
 
     int32_t mVideoScalingMode;
 
+    bool mStarted;
+
     status_t instantiateDecoder(bool audio, sp<Decoder> *decoder);
 
     status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg);
@@ -150,12 +158,20 @@
 
     static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL);
 
-    void finishReset();
     void postScanSources();
 
     void schedulePollDuration();
     void cancelPollDuration();
 
+    void processDeferredActions();
+
+    void performSeek(int64_t seekTimeUs);
+    void performDecoderFlush();
+    void performDecoderShutdown();
+    void performReset();
+    void performScanSources();
+    void performSetSurface(const sp<NativeWindowWrapper> &wrapper);
+
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
 };
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index d03601f..7043404 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -29,6 +29,7 @@
 
 NuPlayerDriver::NuPlayerDriver()
     : mResetInProgress(false),
+      mSetSurfaceInProgress(false),
       mDurationUs(-1),
       mPositionUs(-1),
       mNumFramesTotal(0),
@@ -96,8 +97,20 @@
 }
 
 status_t NuPlayerDriver::setVideoSurfaceTexture(
-        const sp<ISurfaceTexture> &surfaceTexture) {
-    mPlayer->setVideoSurfaceTexture(surfaceTexture);
+        const sp<IGraphicBufferProducer> &bufferProducer) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mResetInProgress) {
+        return INVALID_OPERATION;
+    }
+
+    mSetSurfaceInProgress = true;
+
+    mPlayer->setVideoSurfaceTextureAsync(bufferProducer);
+
+    while (mSetSurfaceInProgress) {
+        mCondition.wait(mLock);
+    }
 
     return OK;
 }
@@ -308,6 +321,13 @@
     mCondition.broadcast();
 }
 
+void NuPlayerDriver::notifySetSurfaceComplete() {
+    Mutex::Autolock autoLock(mLock);
+    CHECK(mSetSurfaceInProgress);
+    mSetSurfaceInProgress = false;
+    mCondition.broadcast();
+}
+
 void NuPlayerDriver::notifyDuration(int64_t durationUs) {
     Mutex::Autolock autoLock(mLock);
     mDurationUs = durationUs;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 4a0026c..553c406 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -38,7 +38,7 @@
     virtual status_t setDataSource(const sp<IStreamSource> &source);
 
     virtual status_t setVideoSurfaceTexture(
-            const sp<ISurfaceTexture> &surfaceTexture);
+            const sp<IGraphicBufferProducer> &bufferProducer);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();
@@ -62,6 +62,7 @@
     virtual status_t dump(int fd, const Vector<String16> &args) const;
 
     void notifyResetComplete();
+    void notifySetSurfaceComplete();
     void notifyDuration(int64_t durationUs);
     void notifyPosition(int64_t positionUs);
     void notifySeekComplete();
@@ -78,6 +79,7 @@
     // The following are protected through "mLock"
     // >>>
     bool mResetInProgress;
+    bool mSetSurfaceInProgress;
     int64_t mDurationUs;
     int64_t mPositionUs;
     int64_t mNumFramesTotal;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index a135222..7920d32 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -612,7 +612,7 @@
         sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
         BufferInfo info;
         info.mStatus = BufferInfo::OWNED_BY_US;
-        info.mData = new ABuffer(0);
+        info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */);
         info.mGraphicBuffer = graphicBuffer;
         mBuffers[kPortIndexOutput].push(info);
 
@@ -966,17 +966,23 @@
             err = INVALID_OPERATION;
         } else {
             if (encoder) {
-                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
+                if (!msg->findInt32(
+                            "flac-compression-level", &compressionLevel)) {
                     compressionLevel = 5;// default FLAC compression level
                 } else if (compressionLevel < 0) {
-                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
+                    ALOGW("compression level %d outside [0..8] range, "
+                          "using 0",
+                          compressionLevel);
                     compressionLevel = 0;
                 } else if (compressionLevel > 8) {
-                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
+                    ALOGW("compression level %d outside [0..8] range, "
+                          "using 8",
+                          compressionLevel);
                     compressionLevel = 8;
                 }
             }
-            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
+            err = setupFlacCodec(
+                    encoder, numChannels, sampleRate, compressionLevel);
         }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
         int32_t numChannels, sampleRate;
@@ -1632,6 +1638,43 @@
     return err;
 }
 
+status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
+    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
+    InitOMXParams(&params);
+    params.nPortIndex = kPortIndexOutput;
+
+    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
+
+    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
+            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
+        int32_t mbs;
+        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
+            return INVALID_OPERATION;
+        }
+        params.nCirMBs = mbs;
+    }
+
+    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
+            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
+        int32_t mbs;
+        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
+            return INVALID_OPERATION;
+        }
+        params.nAirMBs = mbs;
+
+        int32_t ref;
+        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
+            return INVALID_OPERATION;
+        }
+        params.nAirRef = ref;
+    }
+
+    status_t err = mOMX->setParameter(
+            mNode, OMX_IndexParamVideoIntraRefresh,
+            &params, sizeof(params));
+    return err;
+}
+
 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
     if (iFramesInterval < 0) {
         return 0xFFFFFFFF;
@@ -1827,11 +1870,22 @@
         frameRate = (float)tmp;
     }
 
+    status_t err = OK;
+    int32_t intraRefreshMode = 0;
+    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
+        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
+        if (err != OK) {
+            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
+                    err, intraRefreshMode);
+            return err;
+        }
+    }
+
     OMX_VIDEO_PARAM_AVCTYPE h264type;
     InitOMXParams(&h264type);
     h264type.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
+    err = mOMX->getParameter(
             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
 
     if (err != OK) {
@@ -2814,15 +2868,14 @@
                 mCodec->sendFormatChange();
             }
 
-            if (mCodec->mNativeWindow == NULL) {
-                info->mData->setRange(rangeOffset, rangeLength);
-
+            info->mData->setRange(rangeOffset, rangeLength);
 #if 0
+            if (mCodec->mNativeWindow == NULL) {
                 if (IsIDR(info->mData)) {
                     ALOGI("IDR frame");
                 }
-#endif
             }
+#endif
 
             if (mCodec->mSkipCutBuffer != NULL) {
                 mCodec->mSkipCutBuffer->submit(info->mData);
@@ -3106,11 +3159,6 @@
     mCodec->mOMX = omx;
     mCodec->mNode = node;
 
-    mCodec->mPortEOS[kPortIndexInput] =
-        mCodec->mPortEOS[kPortIndexOutput] = false;
-
-    mCodec->mInputEOSResult = OK;
-
     {
         sp<AMessage> notify = mCodec->mNotify->dup();
         notify->setInt32("what", ACodec::kWhatComponentAllocated);
@@ -3132,6 +3180,11 @@
 void ACodec::LoadedState::stateEntered() {
     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
 
+    mCodec->mPortEOS[kPortIndexInput] =
+        mCodec->mPortEOS[kPortIndexOutput] = false;
+
+    mCodec->mInputEOSResult = OK;
+
     if (mCodec->mShutdownInProgress) {
         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
 
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index a056706..85662db 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -94,6 +94,7 @@
         libstagefright_matroska \
         libstagefright_timedtext \
         libvpx \
+        libwebm \
         libstagefright_mpeg2ts \
         libstagefright_httplive \
         libstagefright_id3 \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 1e2625a..23ce088 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -48,7 +48,7 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXCodec.h>
 
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/SurfaceTextureClient.h>
 
 #include <media/stagefright/foundation/AMessage.h>
@@ -1178,12 +1178,12 @@
     return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
 }
 
-status_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+status_t AwesomePlayer::setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {
     Mutex::Autolock autoLock(mLock);
 
     status_t err;
-    if (surfaceTexture != NULL) {
-        err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
+    if (bufferProducer != NULL) {
+        err = setNativeWindow_l(new SurfaceTextureClient(bufferProducer));
     } else {
         err = setNativeWindow_l(NULL);
     }
diff --git a/media/libstagefright/FragmentedMP4Extractor.cpp b/media/libstagefright/FragmentedMP4Extractor.cpp
index 82712ef..496828d 100644
--- a/media/libstagefright/FragmentedMP4Extractor.cpp
+++ b/media/libstagefright/FragmentedMP4Extractor.cpp
@@ -222,8 +222,8 @@
 
     mGroup = new MediaBufferGroup;
 
-    int32_t max_size = 65536;
-    // XXX CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
+    // for video, make the buffer big enough for an extremely poorly compressed 1080p frame.
+    int32_t max_size = mIsAudioTrack ? 65536 : 3110400;
 
     mGroup->add_buffer(new MediaBuffer(max_size));
 
@@ -278,6 +278,10 @@
     sp<AMessage> meta = parseBuffer->meta();
     int64_t timeUs;
     CHECK(meta->findInt64("timeUs", &timeUs));
+    int32_t isSync;
+    if (meta->findInt32("is-sync-frame", &isSync) && isSync != 0) {
+        buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+    }
     buffer->meta_data()->setInt64(kKeyTime, timeUs);
     buffer->set_range(0, parseBuffer->size());
     memcpy(buffer->data(), parseBuffer->data(), parseBuffer->size());
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index d94054b..380dab4 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -350,8 +350,10 @@
 
     mInitCheck = OK;
 
-    // get iTunes-style gapless info if present
-    ID3 id3(mDataSource);
+    // Get iTunes-style gapless info if present.
+    // When getting the id3 tag, skip the V1 tags to prevent the source cache
+    // from being iterated to the end of the file.
+    ID3 id3(mDataSource, true);
     if (id3.isValid()) {
         ID3::Iterator *com = new ID3::Iterator(id3, "COM");
         if (com->done()) {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index b2afec7..1a62f9d 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1424,18 +1424,15 @@
             if (mFileMetaData != NULL) {
                 ALOGV("chunk_data_size = %lld and data_offset = %lld",
                         chunk_data_size, data_offset);
-                uint8_t *buffer = new uint8_t[chunk_data_size + 1];
+                sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
                 if (mDataSource->readAt(
-                    data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) {
-                    delete[] buffer;
-                    buffer = NULL;
-
+                    data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
                     return ERROR_IO;
                 }
                 const int kSkipBytesOfDataBox = 16;
                 mFileMetaData->setData(
                     kKeyAlbumArt, MetaData::TYPE_NONE,
-                    buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
+                    buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
             }
 
             *offset += chunk_size;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 8b52e15..14986b2 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -575,13 +575,50 @@
     /*
      * When the requested file size limit is small, the priority
      * is to meet the file size limit requirement, rather than
-     * to make the file streamable.
+     * to make the file streamable. mStreamableFile does not tell
+     * whether the actual recorded file is streamable or not.
      */
     mStreamableFile =
         (mMaxFileSizeLimitBytes != 0 &&
          mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
 
-    mWriteMoovBoxToMemory = mStreamableFile;
+    /*
+     * mWriteMoovBoxToMemory is true if the amount of data in moov box is
+     * smaller than the reserved free space at the beginning of a file, AND
+     * when the content of moov box is constructed. Note that video/audio
+     * frame data is always written to the file but not in the memory.
+     *
+     * Before stop()/reset() is called, mWriteMoovBoxToMemory is always
+     * false. When reset() is called at the end of a recording session,
+     * Moov box needs to be constructed.
+     *
+     * 1) Right before a moov box is constructed, mWriteMoovBoxToMemory
+     * to set to mStreamableFile so that if
+     * the file is intended to be streamable, it is set to true;
+     * otherwise, it is set to false. When the value is set to false,
+     * all the content of the moov box is written immediately to
+     * the end of the file. When the value is set to true, all the
+     * content of the moov box is written to an in-memory cache,
+     * mMoovBoxBuffer, util the following condition happens. Note
+     * that the size of the in-memory cache is the same as the
+     * reserved free space at the beginning of the file.
+     *
+     * 2) While the data of the moov box is written to an in-memory
+     * cache, the data size is checked against the reserved space.
+     * If the data size surpasses the reserved space, subsequent moov
+     * data could no longer be hold in the in-memory cache. This also
+     * indicates that the reserved space was too small. At this point,
+     * _all_ moov data must be written to the end of the file.
+     * mWriteMoovBoxToMemory must be set to false to direct the write
+     * to the file.
+     *
+     * 3) If the data size in moov box is smaller than the reserved
+     * space after moov box is completely constructed, the in-memory
+     * cache copy of the moov box is written to the reserved free
+     * space. Thus, immediately after the moov is completedly
+     * constructed, mWriteMoovBoxToMemory is always set to false.
+     */
+    mWriteMoovBoxToMemory = false;
     mMoovBoxBuffer = NULL;
     mMoovBoxBufferOffset = 0;
 
@@ -786,15 +823,25 @@
     }
     lseek64(mFd, mOffset, SEEK_SET);
 
-    const off64_t moovOffset = mOffset;
-    mWriteMoovBoxToMemory = mStreamableFile;
-    mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
+    // Construct moov box now
     mMoovBoxBufferOffset = 0;
-    CHECK(mMoovBoxBuffer != NULL);
+    mWriteMoovBoxToMemory = mStreamableFile;
+    if (mWriteMoovBoxToMemory) {
+        // There is no need to allocate in-memory cache
+        // for moov box if the file is not streamable.
+
+        mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
+        CHECK(mMoovBoxBuffer != NULL);
+    }
     writeMoovBox(maxDurationUs);
 
-    mWriteMoovBoxToMemory = false;
-    if (mStreamableFile) {
+    // mWriteMoovBoxToMemory could be set to false in
+    // MPEG4Writer::write() method
+    if (mWriteMoovBoxToMemory) {
+        mWriteMoovBoxToMemory = false;
+        // Content of the moov box is saved in the cache, and the in-memory
+        // moov box needs to be written to the file in a single shot.
+
         CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize);
 
         // Moov box
@@ -806,13 +853,15 @@
         lseek64(mFd, mOffset, SEEK_SET);
         writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
         write("free", 4);
+    } else {
+        ALOGI("The mp4 file will not be streamable.");
+    }
 
-        // Free temp memory
+    // Free in-memory cache for moov box
+    if (mMoovBoxBuffer != NULL) {
         free(mMoovBoxBuffer);
         mMoovBoxBuffer = NULL;
         mMoovBoxBufferOffset = 0;
-    } else {
-        ALOGI("The mp4 file will not be streamable.");
     }
 
     CHECK(mBoxes.empty());
@@ -994,23 +1043,28 @@
 
     const size_t bytes = size * nmemb;
     if (mWriteMoovBoxToMemory) {
-        // This happens only when we write the moov box at the end of
-        // recording, not for each output video/audio frame we receive.
+
         off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
         if (moovBoxSize > mEstimatedMoovBoxSize) {
+            // The reserved moov box at the beginning of the file
+            // is not big enough. Moov box should be written to
+            // the end of the file from now on, but not to the
+            // in-memory cache.
+
+            // We write partial moov box that is in the memory to
+            // the file first.
             for (List<off64_t>::iterator it = mBoxes.begin();
                  it != mBoxes.end(); ++it) {
                 (*it) += mOffset;
             }
             lseek64(mFd, mOffset, SEEK_SET);
             ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset);
-            ::write(mFd, ptr, size * nmemb);
+            ::write(mFd, ptr, bytes);
             mOffset += (bytes + mMoovBoxBufferOffset);
-            free(mMoovBoxBuffer);
-            mMoovBoxBuffer = NULL;
-            mMoovBoxBufferOffset = 0;
+
+            // All subsequent moov box content will be written
+            // to the end of the file.
             mWriteMoovBoxToMemory = false;
-            mStreamableFile = false;
         } else {
             memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes);
             mMoovBoxBufferOffset += bytes;
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 3c002fc..0345de6 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -298,6 +298,10 @@
             // wait for a buffer to be queued
             mFrameAvailableCondition.wait(mMutex);
         } else if (err == OK) {
+            err = item.mFence->waitForever(1000, "SurfaceMediaSource::read");
+            if (err) {
+                ALOGW("read: failed to wait for buffer fence: %d", err);
+            }
 
             // First time seeing the buffer?  Added it to the SMS slot
             if (item.mGraphicBuffer != NULL) {
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 74e9222..8ed07bf 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -78,6 +78,11 @@
         msg->setInt64("durationUs", durationUs);
     }
 
+    int32_t isSync;
+    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
+        msg->setInt32("is-sync-frame", 1);
+    }
+
     if (!strncasecmp("video/", mime, 6)) {
         int32_t width, height;
         CHECK(meta->findInt32(kKeyWidth, &width));
@@ -85,6 +90,13 @@
 
         msg->setInt32("width", width);
         msg->setInt32("height", height);
+
+        int32_t sarWidth, sarHeight;
+        if (meta->findInt32(kKeySARWidth, &sarWidth)
+                && meta->findInt32(kKeySARHeight, &sarHeight)) {
+            msg->setInt32("sar-width", sarWidth);
+            msg->setInt32("sar-height", sarHeight);
+        }
     } else if (!strncasecmp("audio/", mime, 6)) {
         int32_t numChannels, sampleRate;
         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
@@ -363,6 +375,11 @@
         meta->setInt64(kKeyDuration, durationUs);
     }
 
+    int32_t isSync;
+    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
+        meta->setInt32(kKeyIsSyncFrame, 1);
+    }
+
     if (mime.startsWith("video/")) {
         int32_t width;
         int32_t height;
@@ -372,6 +389,13 @@
         } else {
             ALOGW("did not find width and/or height");
         }
+
+        int32_t sarWidth, sarHeight;
+        if (msg->findInt32("sar-width", &sarWidth)
+                && msg->findInt32("sar-height", &sarHeight)) {
+            meta->setInt32(kKeySARWidth, sarWidth);
+            meta->setInt32(kKeySARHeight, sarHeight);
+        }
     } else if (mime.startsWith("audio/")) {
         int32_t numChannels;
         if (msg->findInt32("channel-count", &numChannels)) {
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index d32f4fb..22af6fb 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -426,8 +426,10 @@
         return err;
     }
 
+    // make sure that maxBytesToRead is multiple of 3, in 24-bit case
     size_t maxBytesToRead =
-        mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize;
+        mBitsPerSample == 8 ? kMaxFrameSize / 2 : 
+        (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize);
 
     size_t maxBytesAvailable =
         (mCurrentPos - mOffset >= (off64_t)mSize)
@@ -459,7 +461,7 @@
 
     buffer->set_range(0, n);
 
-    if (mWaveFormat == WAVE_FORMAT_PCM) {
+    if (mWaveFormat == WAVE_FORMAT_PCM || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
         if (mBitsPerSample == 8) {
             // Convert 8-bit unsigned samples to 16-bit signed.
 
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index a141752..b822868 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -22,6 +22,7 @@
 
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
@@ -41,7 +42,9 @@
 
 // Determine video dimensions from the sequence parameterset.
 void FindAVCDimensions(
-        const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height) {
+        const sp<ABuffer> &seqParamSet,
+        int32_t *width, int32_t *height,
+        int32_t *sarWidth, int32_t *sarHeight) {
     ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1);
 
     unsigned profile_idc = br.getBits(8);
@@ -129,6 +132,48 @@
         *height -=
             (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY;
     }
+
+    if (sarWidth != NULL) {
+        *sarWidth = 0;
+    }
+
+    if (sarHeight != NULL) {
+        *sarHeight = 0;
+    }
+
+    if (br.getBits(1)) {  // vui_parameters_present_flag
+        unsigned sar_width = 0, sar_height = 0;
+
+        if (br.getBits(1)) {  // aspect_ratio_info_present_flag
+            unsigned aspect_ratio_idc = br.getBits(8);
+
+            if (aspect_ratio_idc == 255 /* extendedSAR */) {
+                sar_width = br.getBits(16);
+                sar_height = br.getBits(16);
+            } else if (aspect_ratio_idc > 0 && aspect_ratio_idc < 14) {
+                static const int32_t kFixedSARWidth[] = {
+                    1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160
+                };
+
+                static const int32_t kFixedSARHeight[] = {
+                    1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99
+                };
+
+                sar_width = kFixedSARWidth[aspect_ratio_idc - 1];
+                sar_height = kFixedSARHeight[aspect_ratio_idc - 1];
+            }
+        }
+
+        ALOGV("sample aspect ratio = %u : %u", sar_width, sar_height);
+
+        if (sarWidth != NULL) {
+            *sarWidth = sar_width;
+        }
+
+        if (sarHeight != NULL) {
+            *sarHeight = sar_height;
+        }
+    }
 }
 
 status_t getNextNALUnit(
@@ -254,7 +299,9 @@
     }
 
     int32_t width, height;
-    FindAVCDimensions(seqParamSet, &width, &height);
+    int32_t sarWidth, sarHeight;
+    FindAVCDimensions(
+            seqParamSet, &width, &height, &sarWidth, &sarHeight);
 
     size_t stopOffset;
     sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
@@ -301,8 +348,29 @@
     meta->setInt32(kKeyWidth, width);
     meta->setInt32(kKeyHeight, height);
 
-    ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)",
-         width, height, AVCProfileToString(profile), level / 10, level % 10);
+    if (sarWidth > 1 || sarHeight > 1) {
+        // We treat 0:0 (unspecified) as 1:1.
+
+        meta->setInt32(kKeySARWidth, sarWidth);
+        meta->setInt32(kKeySARHeight, sarHeight);
+
+        ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) "
+              "SAR %d : %d",
+             width,
+             height,
+             AVCProfileToString(profile),
+             level / 10,
+             level % 10,
+             sarWidth,
+             sarHeight);
+    } else {
+        ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)",
+             width,
+             height,
+             AVCProfileToString(profile),
+             level / 10,
+             level % 10);
+    }
 
     return meta;
 }
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index d88813e..a8ab2ac 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -594,6 +594,11 @@
     }
 }
 
+void SoftAAC2::onReset() {
+    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+    mIsFirst = true;
+}
+
 void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
     if (portIndex != 1) {
         return;
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 0353196..6957ade 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -41,6 +41,7 @@
     virtual void onQueueFilled(OMX_U32 portIndex);
     virtual void onPortFlushCompleted(OMX_U32 portIndex);
     virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+    virtual void onReset();
 
 private:
     enum {
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index fb1135c..849be87 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -343,6 +343,11 @@
     }
 }
 
+void SoftMP3::onReset() {
+    pvmp3_InitDecoder(mConfig, mDecoderBuf);
+    mIsFirst = true;
+}
+
 }  // namespace android
 
 android::SoftOMXComponent *createSoftOMXComponent(
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 3a05466..4af91ea 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -42,6 +42,7 @@
     virtual void onQueueFilled(OMX_U32 portIndex);
     virtual void onPortFlushCompleted(OMX_U32 portIndex);
     virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+    virtual void onReset();
 
 private:
     enum {
diff --git a/media/libstagefright/codecs/on2/dec/Android.mk b/media/libstagefright/codecs/on2/dec/Android.mk
index 3223871..0082d7c 100644
--- a/media/libstagefright/codecs/on2/dec/Android.mk
+++ b/media/libstagefright/codecs/on2/dec/Android.mk
@@ -5,9 +5,9 @@
         SoftVPX.cpp
 
 LOCAL_C_INCLUDES := \
-        $(TOP)/external/libvpx \
-        $(TOP)/external/libvpx/vpx_codec \
-        $(TOP)/external/libvpx/vpx_ports \
+        $(TOP)/external/libvpx/libvpx \
+        $(TOP)/external/libvpx/libvpx/vpx_codec \
+        $(TOP)/external/libvpx/libvpx/vpx_ports \
         frameworks/av/media/libstagefright/include \
         frameworks/native/include/media/openmax \
 
@@ -21,4 +21,3 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
-
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index ac88107..13dfc8c 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -410,6 +410,11 @@
     }
 }
 
+void SoftVorbis::onReset() {
+    mNumFramesOutput = 0;
+    vorbis_dsp_restart(mState);
+}
+
 void SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
     if (portIndex != 1) {
         return;
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
index e252f55..cb628a0 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
@@ -43,6 +43,7 @@
     virtual void onQueueFilled(OMX_U32 portIndex);
     virtual void onPortFlushCompleted(OMX_U32 portIndex);
     virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+    virtual void onReset();
 
 private:
     enum {
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 2704a37..77f21b7 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -24,7 +24,7 @@
 #include <media/stagefright/MetaData.h>
 #include <system/window.h>
 #include <ui/GraphicBufferMapper.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 69274ca..22c2f5a 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -30,7 +30,7 @@
 
 static const size_t kMaxMetadataSize = 3 * 1024 * 1024;
 
-ID3::ID3(const sp<DataSource> &source)
+ID3::ID3(const sp<DataSource> &source, bool ignoreV1)
     : mIsValid(false),
       mData(NULL),
       mSize(0),
@@ -38,7 +38,7 @@
       mVersion(ID3_UNKNOWN) {
     mIsValid = parseV2(source);
 
-    if (!mIsValid) {
+    if (!mIsValid && !ignoreV1) {
         mIsValid = parseV1(source);
     }
 }
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 1422687..2306f31 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -36,7 +36,7 @@
 struct MediaExtractor;
 struct MediaSource;
 struct NuCachedSource2;
-struct ISurfaceTexture;
+struct IGraphicBufferProducer;
 
 class DrmManagerClinet;
 class DecryptHandle;
@@ -81,7 +81,7 @@
 
     bool isPlaying() const;
 
-    status_t setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
+    status_t setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer);
     void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink);
     status_t setLooping(bool shouldLoop);
 
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 8714008..3028f56 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -35,7 +35,7 @@
         ID3_V2_4,
     };
 
-    ID3(const sp<DataSource> &source);
+    ID3(const sp<DataSource> &source, bool ignoreV1 = false);
     ~ID3();
 
     bool isValid() const;
diff --git a/media/libstagefright/include/SimpleSoftOMXComponent.h b/media/libstagefright/include/SimpleSoftOMXComponent.h
index 50cd275..f8c61eb 100644
--- a/media/libstagefright/include/SimpleSoftOMXComponent.h
+++ b/media/libstagefright/include/SimpleSoftOMXComponent.h
@@ -71,6 +71,7 @@
 
     virtual void onPortFlushCompleted(OMX_U32 portIndex);
     virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+    virtual void onReset();
 
     PortInfo *editPortInfo(OMX_U32 portIndex);
 
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index e418822..d517320 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -36,8 +36,11 @@
     kAVCProfileCAVLC444Intra = 0x2c
 };
 
+// Optionally returns sample aspect ratio as well.
 void FindAVCDimensions(
-        const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height);
+        const sp<ABuffer> &seqParamSet,
+        int32_t *width, int32_t *height,
+        int32_t *sarWidth = NULL, int32_t *sarHeight = NULL);
 
 unsigned parseUE(ABitReader *br);
 
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index 2cccb4f..2d8c1e1 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -5,7 +5,7 @@
         MatroskaExtractor.cpp
 
 LOCAL_C_INCLUDES:= \
-        $(TOP)/external/libvpx/mkvparser \
+        $(TOP)/external/libvpx/libwebm \
         $(TOP)/frameworks/native/include/media/openmax \
 
 LOCAL_CFLAGS += -Wno-multichar
diff --git a/media/libstagefright/mp4/FragmentedMP4Parser.cpp b/media/libstagefright/mp4/FragmentedMP4Parser.cpp
index 54c3d63..0102656 100644
--- a/media/libstagefright/mp4/FragmentedMP4Parser.cpp
+++ b/media/libstagefright/mp4/FragmentedMP4Parser.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "FragmentedMP4Parser"
 #include <utils/Log.h>
 
+#include "include/avc_utils.h"
 #include "include/ESDS.h"
 #include "include/FragmentedMP4Parser.h"
 #include "TrackFragment.h"
@@ -132,6 +133,10 @@
             CHECK(mFile != NULL);
         }
 
+    virtual ~FileSource() {
+        fclose(mFile);
+    }
+
     virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
         fseek(mFile, offset, SEEK_SET);
         return fread(data, 1, size, mFile);
@@ -319,8 +324,7 @@
         off_t totalOffset = mFirstMoofOffset;
         for (int i = 0; i < numSidxEntries; i++) {
             const SidxEntry *se = &info->mSidx[i];
-            totalTime += se->mDurationUs;
-            if (totalTime > position) {
+            if (totalTime + se->mDurationUs > position) {
                 mBuffer->setRange(0,0);
                 mBufferPos = totalOffset;
                 if (mFinalResult == ERROR_END_OF_STREAM) {
@@ -329,9 +333,10 @@
                     resumeIfNecessary();
                 }
                 info->mFragments.clear();
-                info->mDecodingTime = position * info->mMediaTimeScale / 1000000ll;
+                info->mDecodingTime = totalTime * info->mMediaTimeScale / 1000000ll;
                 return OK;
             }
+            totalTime += se->mDurationUs;
             totalOffset += se->mSize;
         }
     }
@@ -961,6 +966,10 @@
                sample.mSize);
 
         (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs);
+        if (IsIDR(*accessUnit)) {
+            (*accessUnit)->meta()->setInt32("is-sync-frame", 1);
+        }
+
         return OK;
     }
 
@@ -1003,6 +1012,9 @@
                     "timeUs", presentationTimeUs);
         }
     }
+    if (IsIDR(*accessUnit)) {
+        (*accessUnit)->meta()->setInt32("is-sync-frame", 1);
+    }
 
     return OK;
 }
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index c79e01f..4999663 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -450,6 +450,10 @@
     checkTransitions();
 }
 
+void SimpleSoftOMXComponent::onReset() {
+    // no-op
+}
+
 void SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) {
     CHECK_LT(portIndex, mPorts.size());
 
@@ -581,6 +585,10 @@
         if (transitionComplete) {
             mState = mTargetState;
 
+            if (mState == OMX_StateLoaded) {
+                onReset();
+            }
+
             notify(OMX_EventCmdComplete, OMX_CommandStateSet, mState, NULL);
         }
     }
diff --git a/media/libstagefright/rtsp/AAMRAssembler.cpp b/media/libstagefright/rtsp/AAMRAssembler.cpp
index fb8abc5..9e8725a 100644
--- a/media/libstagefright/rtsp/AAMRAssembler.cpp
+++ b/media/libstagefright/rtsp/AAMRAssembler.cpp
@@ -145,7 +145,6 @@
 
     unsigned payloadHeader = buffer->data()[0];
     unsigned CMR = payloadHeader >> 4;
-    CHECK_EQ(payloadHeader & 0x0f, 0u);  // RR
 
     Vector<uint8_t> tableOfContents;
 
diff --git a/media/libstagefright/rtsp/AH263Assembler.cpp b/media/libstagefright/rtsp/AH263Assembler.cpp
index d0313cc..75cd911 100644
--- a/media/libstagefright/rtsp/AH263Assembler.cpp
+++ b/media/libstagefright/rtsp/AH263Assembler.cpp
@@ -13,6 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AH263Assembler"
+#include <utils/Log.h>
 
 #include "AH263Assembler.h"
 
@@ -100,11 +103,34 @@
     }
 
     unsigned payloadHeader = U16_AT(buffer->data());
-    CHECK_EQ(payloadHeader >> 11, 0u);  // RR=0
     unsigned P = (payloadHeader >> 10) & 1;
     unsigned V = (payloadHeader >> 9) & 1;
     unsigned PLEN = (payloadHeader >> 3) & 0x3f;
-    // unsigned PEBIT = payloadHeader & 7;
+    unsigned PEBIT = payloadHeader & 7;
+
+    // V=0
+    if (V != 0u) {
+        queue->erase(queue->begin());
+        ++mNextExpectedSeqNo;
+        ALOGW("Packet discarded due to VRC (V != 0)");
+        return MALFORMED_PACKET;
+    }
+
+    // PLEN=0
+    if (PLEN != 0u) {
+        queue->erase(queue->begin());
+        ++mNextExpectedSeqNo;
+        ALOGW("Packet discarded (PLEN != 0)");
+        return MALFORMED_PACKET;
+    }
+
+    // PEBIT=0
+    if (PEBIT != 0u) {
+        queue->erase(queue->begin());
+        ++mNextExpectedSeqNo;
+        ALOGW("Packet discarded (PEBIT != 0)");
+        return MALFORMED_PACKET;
+    }
 
     size_t skip = V + PLEN + (P ? 0 : 2);
 
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 539a888..161bd4f 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -830,6 +830,7 @@
 
     if (i < 0) {
         // This is an unsolicited server->client message.
+        *index = -1;
         return OK;
     }
 
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index a61d6a2..6a98509 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -107,7 +107,7 @@
                     window.get(), NULL);
         } else {
             ALOGV("No actual display. Choosing EGLSurface based on SurfaceMediaSource");
-            sp<ISurfaceTexture> sms = (new SurfaceMediaSource(
+            sp<IGraphicBufferProducer> sms = (new SurfaceMediaSource(
                     getSurfaceWidth(), getSurfaceHeight()))->getBufferQueue();
             sp<SurfaceTextureClient> stc = new SurfaceTextureClient(sms);
             sp<ANativeWindow> window = stc;
@@ -361,7 +361,7 @@
         mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
 
         // Manual cast is required to avoid constructor ambiguity
-        mSTC = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >( mSMS->getBufferQueue()));
+        mSTC = new SurfaceTextureClient(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
         mANW = mSTC;
     }
 
@@ -396,7 +396,7 @@
         ALOGV("SMS-GLTest::SetUp()");
         android::ProcessState::self()->startThreadPool();
         mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
-        mSTC = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >( mSMS->getBufferQueue()));
+        mSTC = new SurfaceTextureClient(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
         mANW = mSTC;
 
         // Doing the setup related to the GL Side
@@ -482,7 +482,7 @@
 
 // query the mediarecorder for a surfacemeidasource and create an egl surface with that
 void SurfaceMediaSourceGLTest::setUpEGLSurfaceFromMediaRecorder(sp<MediaRecorder>& mr) {
-    sp<ISurfaceTexture> iST = mr->querySurfaceMediaSourceFromMediaServer();
+    sp<IGraphicBufferProducer> iST = mr->querySurfaceMediaSourceFromMediaServer();
     mSTC = new SurfaceTextureClient(iST);
     mANW = mSTC;
 
@@ -749,7 +749,7 @@
             mYuvTexHeight, 30);
     // get the reference to the surfacemediasource living in
     // mediaserver that is created by stagefrightrecorder
-    sp<ISurfaceTexture> iST = mr->querySurfaceMediaSourceFromMediaServer();
+    sp<IGraphicBufferProducer> iST = mr->querySurfaceMediaSourceFromMediaServer();
     mSTC = new SurfaceTextureClient(iST);
     mANW = mSTC;
     ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
@@ -781,7 +781,7 @@
     ALOGV("Verify creating a surface w/ right config + dummy writer*********");
 
     mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
-    mSTC = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >( mSMS->getBufferQueue()));
+    mSTC = new SurfaceTextureClient(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
     mANW = mSTC;
 
     DummyRecorder writer(mSMS);
diff --git a/media/libstagefright/wifi-display/sink/RTPSink.cpp b/media/libstagefright/wifi-display/sink/RTPSink.cpp
index 0918034..640e055 100644
--- a/media/libstagefright/wifi-display/sink/RTPSink.cpp
+++ b/media/libstagefright/wifi-display/sink/RTPSink.cpp
@@ -238,9 +238,9 @@
 
 RTPSink::RTPSink(
         const sp<ANetworkSession> &netSession,
-        const sp<ISurfaceTexture> &surfaceTex)
+        const sp<IGraphicBufferProducer> &bufferProducer)
     : mNetSession(netSession),
-      mSurfaceTex(surfaceTex),
+      mSurfaceTex(bufferProducer),
       mRTPPort(0),
       mRTPSessionID(0),
       mRTCPSessionID(0),
diff --git a/media/libstagefright/wifi-display/sink/RTPSink.h b/media/libstagefright/wifi-display/sink/RTPSink.h
index a1d127d..2183fd6 100644
--- a/media/libstagefright/wifi-display/sink/RTPSink.h
+++ b/media/libstagefright/wifi-display/sink/RTPSink.h
@@ -35,7 +35,7 @@
 // the RTCP channel.
 struct RTPSink : public AHandler {
     RTPSink(const sp<ANetworkSession> &netSession,
-            const sp<ISurfaceTexture> &surfaceTex);
+            const sp<IGraphicBufferProducer> &bufferProducer);
 
     // If TCP interleaving is used, no UDP sockets are created, instead
     // incoming RTP/RTCP packets (arriving on the RTSP control connection)
@@ -66,7 +66,7 @@
     struct StreamSource;
 
     sp<ANetworkSession> mNetSession;
-    sp<ISurfaceTexture> mSurfaceTex;
+    sp<IGraphicBufferProducer> mSurfaceTex;
     KeyedVector<uint32_t, sp<Source> > mSources;
 
     int32_t mRTPPort;
diff --git a/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp b/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
index b913124..8ffb877 100644
--- a/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
+++ b/media/libstagefright/wifi-display/sink/TunnelRenderer.cpp
@@ -159,9 +159,9 @@
 
 TunnelRenderer::TunnelRenderer(
         const sp<AMessage> &notifyLost,
-        const sp<ISurfaceTexture> &surfaceTex)
+        const sp<IGraphicBufferProducer> &bufferProducer)
     : mNotifyLost(notifyLost),
-      mSurfaceTex(surfaceTex),
+      mSurfaceTex(bufferProducer),
       mTotalBytesQueued(0ll),
       mLastDequeuedExtSeqNo(-1),
       mFirstFailedAttemptUs(-1ll),
diff --git a/media/libstagefright/wifi-display/sink/TunnelRenderer.h b/media/libstagefright/wifi-display/sink/TunnelRenderer.h
index c9597e0..52e6e66 100644
--- a/media/libstagefright/wifi-display/sink/TunnelRenderer.h
+++ b/media/libstagefright/wifi-display/sink/TunnelRenderer.h
@@ -36,7 +36,7 @@
 struct TunnelRenderer : public AHandler {
     TunnelRenderer(
             const sp<AMessage> &notifyLost,
-            const sp<ISurfaceTexture> &surfaceTex);
+            const sp<IGraphicBufferProducer> &bufferProducer);
 
     sp<ABuffer> dequeueBuffer();
 
@@ -55,7 +55,7 @@
     mutable Mutex mLock;
 
     sp<AMessage> mNotifyLost;
-    sp<ISurfaceTexture> mSurfaceTex;
+    sp<IGraphicBufferProducer> mSurfaceTex;
 
     List<sp<ABuffer> > mPackets;
     int64_t mTotalBytesQueued;
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
index c3e0470..0f0caf1 100644
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
+++ b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
@@ -31,10 +31,10 @@
 
 WifiDisplaySink::WifiDisplaySink(
         const sp<ANetworkSession> &netSession,
-        const sp<ISurfaceTexture> &surfaceTex)
+        const sp<IGraphicBufferProducer> &bufferProducer)
     : mState(UNDEFINED),
       mNetSession(netSession),
-      mSurfaceTex(surfaceTex),
+      mSurfaceTex(bufferProducer),
       mSessionID(0),
       mNextCSeq(1) {
 }
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h b/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
index f886ee5..a508839 100644
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
+++ b/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
@@ -34,7 +34,7 @@
 struct WifiDisplaySink : public AHandler {
     WifiDisplaySink(
             const sp<ANetworkSession> &netSession,
-            const sp<ISurfaceTexture> &surfaceTex = NULL);
+            const sp<IGraphicBufferProducer> &bufferProducer = NULL);
 
     void start(const char *sourceHost, int32_t sourcePort);
     void start(const char *uri);
@@ -76,7 +76,7 @@
 
     State mState;
     sp<ANetworkSession> mNetSession;
-    sp<ISurfaceTexture> mSurfaceTex;
+    sp<IGraphicBufferProducer> mSurfaceTex;
     AString mSetupURI;
     AString mRTSPHost;
     int32_t mSessionID;
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index 82c98b9..7a87444 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -161,7 +161,24 @@
         mOutputFormat->setInt32("bitrate", videoBitrate);
         mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant);
         mOutputFormat->setInt32("frame-rate", 30);
-        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
+        mOutputFormat->setInt32("i-frame-interval", 15);  // Iframes every 15 secs
+
+        // Configure encoder to use intra macroblock refresh mode
+        mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic);
+
+        int width, height, mbs;
+        if (!mOutputFormat->findInt32("width", &width)
+                || !mOutputFormat->findInt32("height", &height)) {
+            return ERROR_UNSUPPORTED;
+        }
+
+        // Update macroblocks in a cyclic fashion with 10% of all MBs within
+        // frame gets updated at one time. It takes about 10 frames to
+        // completely update a whole video frame. If the frame rate is 30,
+        // it takes about 333 ms in the best case (if next frame is not an IDR)
+        // to recover from a lost/corrupted packet.
+        mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100;
+        mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs);
     }
 
     ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
diff --git a/media/libstagefright/wifi-display/source/MediaPuller.cpp b/media/libstagefright/wifi-display/source/MediaPuller.cpp
index ab69c4a..189bea3 100644
--- a/media/libstagefright/wifi-display/source/MediaPuller.cpp
+++ b/media/libstagefright/wifi-display/source/MediaPuller.cpp
@@ -34,7 +34,8 @@
     : mSource(source),
       mNotify(notify),
       mPullGeneration(0),
-      mIsAudio(false) {
+      mIsAudio(false),
+      mPaused(false) {
     sp<MetaData> meta = source->getFormat();
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
@@ -71,6 +72,14 @@
     msg->post();
 }
 
+void MediaPuller::pause() {
+    (new AMessage(kWhatPause, id()))->post();
+}
+
+void MediaPuller::resume() {
+    (new AMessage(kWhatResume, id()))->post();
+}
+
 void MediaPuller::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatStart:
@@ -95,7 +104,6 @@
 
             uint32_t replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
-
             response->postReply(replyID);
             break;
         }
@@ -130,6 +138,16 @@
             MediaBuffer *mbuf;
             status_t err = mSource->read(&mbuf);
 
+            if (mPaused) {
+                if (err == OK) {
+                    mbuf->release();
+                    mbuf = NULL;
+                }
+
+                schedulePull();
+                break;
+            }
+
             if (err != OK) {
                 if (err == ERROR_END_OF_STREAM) {
                     ALOGI("stream ended.");
@@ -176,6 +194,18 @@
             break;
         }
 
+        case kWhatPause:
+        {
+            mPaused = true;
+            break;
+        }
+
+        case kWhatResume:
+        {
+            mPaused = false;
+            break;
+        }
+
         default:
             TRESPASS();
     }
diff --git a/media/libstagefright/wifi-display/source/MediaPuller.h b/media/libstagefright/wifi-display/source/MediaPuller.h
index 728da7b..1291bb3 100644
--- a/media/libstagefright/wifi-display/source/MediaPuller.h
+++ b/media/libstagefright/wifi-display/source/MediaPuller.h
@@ -35,6 +35,9 @@
     status_t start();
     void stopAsync(const sp<AMessage> &notify);
 
+    void pause();
+    void resume();
+
 protected:
     virtual void onMessageReceived(const sp<AMessage> &msg);
     virtual ~MediaPuller();
@@ -44,12 +47,15 @@
         kWhatStart,
         kWhatStop,
         kWhatPull,
+        kWhatPause,
+        kWhatResume,
     };
 
     sp<MediaSource> mSource;
     sp<AMessage> mNotify;
     int32_t mPullGeneration;
     bool mIsAudio;
+    bool mPaused;
 
     status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
     void schedulePull();
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 4e5eb52..d6b87a7 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -76,6 +76,9 @@
     status_t start();
     void stopAsync();
 
+    void pause();
+    void resume();
+
     void queueAccessUnit(const sp<ABuffer> &accessUnit);
     sp<ABuffer> dequeueAccessUnit();
 
@@ -208,6 +211,14 @@
     }
 }
 
+void WifiDisplaySource::PlaybackSession::Track::pause() {
+    mMediaPuller->pause();
+}
+
+void WifiDisplaySource::PlaybackSession::Track::resume() {
+    mMediaPuller->resume();
+}
+
 void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
         const sp<AMessage> &msg) {
     switch (msg->what()) {
@@ -325,6 +336,7 @@
       mInterfaceAddr(interfaceAddr),
       mHDCP(hdcp),
       mWeAreDead(false),
+      mPaused(false),
       mLastLifesignUs(),
       mVideoTrackIndex(-1),
       mPrevTimeUs(-1ll),
@@ -383,6 +395,8 @@
 status_t WifiDisplaySource::PlaybackSession::play() {
     updateLiveness();
 
+    (new AMessage(kWhatResume, id()))->post();
+
     return OK;
 }
 
@@ -413,6 +427,8 @@
 status_t WifiDisplaySource::PlaybackSession::pause() {
     updateLiveness();
 
+    (new AMessage(kWhatPause, id()))->post();
+
     return OK;
 }
 
@@ -590,6 +606,34 @@
             break;
         }
 
+        case kWhatPause:
+        {
+            if (mPaused) {
+                break;
+            }
+
+            for (size_t i = 0; i < mTracks.size(); ++i) {
+                mTracks.editValueAt(i)->pause();
+            }
+
+            mPaused = true;
+            break;
+        }
+
+        case kWhatResume:
+        {
+            if (!mPaused) {
+                break;
+            }
+
+            for (size_t i = 0; i < mTracks.size(); ++i) {
+                mTracks.editValueAt(i)->resume();
+            }
+
+            mPaused = false;
+            break;
+        }
+
         default:
             TRESPASS();
     }
@@ -742,7 +786,7 @@
     return OK;
 }
 
-sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
+sp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
     return mBufferQueue;
 }
 
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index dabc1c4..281548d 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -26,7 +26,7 @@
 struct ABuffer;
 struct BufferQueue;
 struct IHDCP;
-struct ISurfaceTexture;
+struct IGraphicBufferProducer;
 struct MediaPuller;
 struct MediaSource;
 struct TSPacketizer;
@@ -56,7 +56,7 @@
     status_t finishPlay();
     status_t pause();
 
-    sp<ISurfaceTexture> getSurfaceTexture();
+    sp<IGraphicBufferProducer> getSurfaceTexture();
     int32_t width() const;
     int32_t height() const;
 
@@ -84,6 +84,8 @@
         kWhatUpdateSurface,
         kWhatFinishPlay,
         kWhatPacketize,
+        kWhatPause,
+        kWhatResume,
     };
 
     sp<ANetworkSession> mNetSession;
@@ -93,6 +95,7 @@
     in_addr mInterfaceAddr;
     sp<IHDCP> mHDCP;
     bool mWeAreDead;
+    bool mPaused;
 
     int64_t mLastLifesignUs;
 
diff --git a/media/libstagefright/wifi-display/source/Sender.h b/media/libstagefright/wifi-display/source/Sender.h
index 73e3d19..66951f7 100644
--- a/media/libstagefright/wifi-display/source/Sender.h
+++ b/media/libstagefright/wifi-display/source/Sender.h
@@ -25,7 +25,7 @@
 #define LOG_TRANSPORT_STREAM            0
 #define TRACK_BANDWIDTH                 0
 
-#define ENABLE_RETRANSMISSION                   0
+#define ENABLE_RETRANSMISSION                   1
 
 // If retransmission is enabled the following define determines what
 // kind we support, if RETRANSMISSION_ACCORDING_TO_RFC_XXXX is 0
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 78d6e62..9ec1064 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -25,7 +25,7 @@
 #include "Sender.h"
 
 #include <binder/IServiceManager.h>
-#include <gui/ISurfaceTexture.h>
+#include <gui/IGraphicBufferProducer.h>
 #include <media/IHDCP.h>
 #include <media/IMediaPlayerService.h>
 #include <media/IRemoteDisplayClient.h>
@@ -65,6 +65,21 @@
 WifiDisplaySource::~WifiDisplaySource() {
 }
 
+static status_t PostAndAwaitResponse(
+        const sp<AMessage> &msg, sp<AMessage> *response) {
+    status_t err = msg->postAndAwaitResponse(response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (response == NULL || !(*response)->findInt32("err", &err)) {
+        err = OK;
+    }
+
+    return err;
+}
+
 status_t WifiDisplaySource::start(const char *iface) {
     CHECK_EQ(mState, INITIALIZED);
 
@@ -72,34 +87,28 @@
     msg->setString("iface", iface);
 
     sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-
-    if (err != OK) {
-        return err;
-    }
-
-    if (!response->findInt32("err", &err)) {
-        err = OK;
-    }
-
-    return err;
+    return PostAndAwaitResponse(msg, &response);
 }
 
 status_t WifiDisplaySource::stop() {
     sp<AMessage> msg = new AMessage(kWhatStop, id());
 
     sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
+    return PostAndAwaitResponse(msg, &response);
+}
 
-    if (err != OK) {
-        return err;
-    }
+status_t WifiDisplaySource::pause() {
+    sp<AMessage> msg = new AMessage(kWhatPause, id());
 
-    if (!response->findInt32("err", &err)) {
-        err = OK;
-    }
+    sp<AMessage> response;
+    return PostAndAwaitResponse(msg, &response);
+}
 
-    return err;
+status_t WifiDisplaySource::resume() {
+    sp<AMessage> msg = new AMessage(kWhatResume, id());
+
+    sp<AMessage> response;
+    return PostAndAwaitResponse(msg, &response);
 }
 
 void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
@@ -236,6 +245,20 @@
                         mClient->onDisplayError(
                                 IRemoteDisplayClient::kDisplayErrorUnknown);
                     }
+
+#if 0
+                    // testing only.
+                    char val[PROPERTY_VALUE_MAX];
+                    if (property_get("media.wfd.trigger", val, NULL)) {
+                        if (!strcasecmp(val, "pause") && mState == PLAYING) {
+                            mState = PLAYING_TO_PAUSED;
+                            sendTrigger(mClientSessionID, TRIGGER_PAUSE);
+                        } else if (!strcasecmp(val, "play") && mState == PAUSED) {
+                            mState = PAUSED_TO_PLAYING;
+                            sendTrigger(mClientSessionID, TRIGGER_PLAY);
+                        }
+                    }
+#endif
                     break;
                 }
 
@@ -254,8 +277,8 @@
             if (mState >= AWAITING_CLIENT_PLAY) {
                 // We have a session, i.e. a previous SETUP succeeded.
 
-                status_t err = sendM5(
-                        mClientSessionID, true /* requestShutdown */);
+                status_t err = sendTrigger(
+                        mClientSessionID, TRIGGER_TEARDOWN);
 
                 if (err == OK) {
                     mState = AWAITING_CLIENT_TEARDOWN;
@@ -273,6 +296,46 @@
             break;
         }
 
+        case kWhatPause:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            status_t err = OK;
+
+            if (mState != PLAYING) {
+                err = INVALID_OPERATION;
+            } else {
+                mState = PLAYING_TO_PAUSED;
+                sendTrigger(mClientSessionID, TRIGGER_PAUSE);
+            }
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatResume:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            status_t err = OK;
+
+            if (mState != PAUSED) {
+                err = INVALID_OPERATION;
+            } else {
+                mState = PAUSED_TO_PLAYING;
+                sendTrigger(mClientSessionID, TRIGGER_PLAY);
+            }
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+            response->postReply(replyID);
+            break;
+        }
+
         case kWhatReapDeadClients:
         {
             mReaperPending = false;
@@ -400,7 +463,7 @@
                     if (mSetupTriggerDeferred) {
                         mSetupTriggerDeferred = false;
 
-                        sendM5(mClientSessionID, false /* requestShutdown */);
+                        sendTrigger(mClientSessionID, TRIGGER_SETUP);
                     }
                     break;
                 }
@@ -574,13 +637,25 @@
     return OK;
 }
 
-status_t WifiDisplaySource::sendM5(int32_t sessionID, bool requestShutdown) {
+status_t WifiDisplaySource::sendTrigger(
+        int32_t sessionID, TriggerType triggerType) {
     AString body = "wfd_trigger_method: ";
-    if (requestShutdown) {
-        ALOGI("Sending TEARDOWN trigger.");
-        body.append("TEARDOWN");
-    } else {
-        body.append("SETUP");
+    switch (triggerType) {
+        case TRIGGER_SETUP:
+            body.append("SETUP");
+            break;
+        case TRIGGER_TEARDOWN:
+            ALOGI("Sending TEARDOWN trigger.");
+            body.append("TEARDOWN");
+            break;
+        case TRIGGER_PAUSE:
+            body.append("PAUSE");
+            break;
+        case TRIGGER_PLAY:
+            body.append("PLAY");
+            break;
+        default:
+            TRESPASS();
     }
 
     body.append("\r\n");
@@ -807,7 +882,7 @@
         return OK;
     }
 
-    return sendM5(sessionID, false /* requestShutdown */);
+    return sendTrigger(sessionID, TRIGGER_SETUP);
 }
 
 status_t WifiDisplaySource::onReceiveM5Response(
@@ -1184,6 +1259,11 @@
         return err;
     }
 
+    if (mState == PAUSED_TO_PLAYING) {
+        mState = PLAYING;
+        return OK;
+    }
+
     playbackSession->finishPlay();
 
     CHECK_EQ(mState, AWAITING_CLIENT_PLAY);
@@ -1205,6 +1285,12 @@
         return ERROR_MALFORMED;
     }
 
+    ALOGI("Received PAUSE request.");
+
+    if (mState != PLAYING_TO_PAUSED) {
+        return INVALID_OPERATION;
+    }
+
     status_t err = playbackSession->pause();
     CHECK_EQ(err, (status_t)OK);
 
@@ -1214,6 +1300,12 @@
 
     err = mNetSession->sendRequest(sessionID, response.c_str());
 
+    if (err != OK) {
+        return err;
+    }
+
+    mState = PAUSED;
+
     return err;
 }
 
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 1e855e7..974e070 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -44,6 +44,9 @@
     status_t start(const char *iface);
     status_t stop();
 
+    status_t pause();
+    status_t resume();
+
 protected:
     virtual ~WifiDisplaySource();
     virtual void onMessageReceived(const sp<AMessage> &msg);
@@ -59,6 +62,9 @@
         AWAITING_CLIENT_PLAY,
         ABOUT_TO_PLAY,
         PLAYING,
+        PLAYING_TO_PAUSED,
+        PAUSED,
+        PAUSED_TO_PLAYING,
         AWAITING_CLIENT_TEARDOWN,
         STOPPING,
         STOPPED,
@@ -68,6 +74,8 @@
         kWhatStart,
         kWhatRTSPNotify,
         kWhatStop,
+        kWhatPause,
+        kWhatResume,
         kWhatReapDeadClients,
         kWhatPlaybackSessionNotify,
         kWhatKeepAlive,
@@ -147,7 +155,17 @@
     status_t sendM1(int32_t sessionID);
     status_t sendM3(int32_t sessionID);
     status_t sendM4(int32_t sessionID);
-    status_t sendM5(int32_t sessionID, bool requestShutdown);
+
+    enum TriggerType {
+        TRIGGER_SETUP,
+        TRIGGER_TEARDOWN,
+        TRIGGER_PAUSE,
+        TRIGGER_PLAY,
+    };
+
+    // M5
+    status_t sendTrigger(int32_t sessionID, TriggerType triggerType);
+
     status_t sendM16(int32_t sessionID);
 
     status_t onReceiveM1Response(
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
index 03a1123..2ec9b4f 100644
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -47,7 +47,7 @@
     RemoteDisplayClient();
 
     virtual void onDisplayConnected(
-            const sp<ISurfaceTexture> &surfaceTexture,
+            const sp<IGraphicBufferProducer> &bufferProducer,
             uint32_t width,
             uint32_t height,
             uint32_t flags);
@@ -67,7 +67,7 @@
     bool mDone;
 
     sp<SurfaceComposerClient> mComposerClient;
-    sp<ISurfaceTexture> mSurfaceTexture;
+    sp<IGraphicBufferProducer> mSurfaceTexture;
     sp<IBinder> mDisplayBinder;
 
     DISALLOW_EVIL_CONSTRUCTORS(RemoteDisplayClient);
@@ -83,14 +83,14 @@
 }
 
 void RemoteDisplayClient::onDisplayConnected(
-        const sp<ISurfaceTexture> &surfaceTexture,
+        const sp<IGraphicBufferProducer> &bufferProducer,
         uint32_t width,
         uint32_t height,
         uint32_t flags) {
     ALOGI("onDisplayConnected width=%u, height=%u, flags = 0x%08x",
           width, height, flags);
 
-    mSurfaceTexture = surfaceTexture;
+    mSurfaceTexture = bufferProducer;
     mDisplayBinder = mComposerClient->createDisplay(
             String8("foo"), false /* secure */);
 
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index c4050b8..6d42143 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -66,9 +66,6 @@
 
 LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
 
-# uncomment for systrace
-# LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
-
 # uncomment for dumpsys to write most recent audio output to .wav file
 # 47.5 seconds at 44.1 kHz, 8 megabytes
 # LOCAL_CFLAGS += -DTEE_SINK_FRAMES=0x200000
@@ -81,6 +78,13 @@
 # LOCAL_SRC_FILES += AudioWatchdog.cpp
 # LOCAL_CFLAGS += -DAUDIO_WATCHDOG
 
+# Define ANDROID_SMP appropriately. Used to get inline tracing fast-path.
+ifeq ($(TARGET_CPU_SMP),true)
+    LOCAL_CFLAGS += -DANDROID_SMP=1
+else
+    LOCAL_CFLAGS += -DANDROID_SMP=0
+endif
+
 include $(BUILD_SHARED_LIBRARY)
 
 #
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 46a8e0f..6d3f0a1 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -385,7 +385,6 @@
         virtual status_t    start();
         virtual void        stop();
         virtual void        flush();
-        virtual void        mute(bool);
         virtual void        pause();
         virtual status_t    attachAuxEffect(int effectId);
         virtual status_t    allocateTimedBuffer(size_t size,
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index b3ca877..08325ad 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -1109,6 +1109,12 @@
         e0 &= ~(1<<i);
         track_t& t = state->tracks[i];
         t.buffer.frameCount = state->frameCount;
+        int valid = t.bufferProvider->getValid();
+        if (valid != AudioBufferProvider::kValid) {
+            ALOGE("invalid bufferProvider=%p name=%d frameCount=%d valid=%#x enabledTracks=%#x",
+                    t.bufferProvider, i, t.buffer.frameCount, valid, enabledTracks);
+            // expect to crash
+        }
         t.bufferProvider->getNextBuffer(&t.buffer, pts);
         t.frameCount = t.buffer.frameCount;
         t.in = t.buffer.raw;
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 2005899..9283f53 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -23,6 +23,8 @@
 #define LOG_TAG "FastMixer"
 //#define LOG_NDEBUG 0
 
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+
 #include <sys/atomics.h>
 #include <time.h>
 #include <utils/Log.h>
@@ -377,14 +379,14 @@
                 // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
                 // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
                 size_t framesReady = fastTrack->mBufferProvider->framesReady();
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-                // I wish we had formatted trace names
-                char traceName[16];
-                strcpy(traceName, "framesReady");
-                traceName[11] = i + (i < 10 ? '0' : 'A' - 10);
-                traceName[12] = '\0';
-                ATRACE_INT(traceName, framesReady);
-#endif
+                if (ATRACE_ENABLED()) {
+                    // I wish we had formatted trace names
+                    char traceName[16];
+                    strcpy(traceName, "framesReady");
+                    traceName[11] = i + (i < 10 ? '0' : 'A' - 10);
+                    traceName[12] = '\0';
+                    ATRACE_INT(traceName, framesReady);
+                }
                 FastTrackDump *ftDump = &dumpState->mTracks[i];
                 FastTrackUnderruns underruns = ftDump->mUnderruns;
                 if (framesReady < frameCount) {
@@ -430,13 +432,9 @@
             // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
             //       but this code should be modified to handle both non-blocking and blocking sinks
             dumpState->mWriteSequence++;
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-            Tracer::traceBegin(ATRACE_TAG, "write");
-#endif
+            ATRACE_BEGIN("write");
             ssize_t framesWritten = outputSink->write(mixBuffer, frameCount);
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-            Tracer::traceEnd(ATRACE_TAG);
-#endif
+            ATRACE_END();
             dumpState->mWriteSequence++;
             if (framesWritten >= 0) {
                 ALOG_ASSERT(framesWritten <= frameCount);
@@ -491,9 +489,7 @@
                 sleepNs = -1;
               if (isWarm) {
                 if (sec > 0 || nsec > underrunNs) {
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-                    ScopedTrace st(ATRACE_TAG, "underrun");
-#endif
+                    ATRACE_NAME("underrun");
                     // FIXME only log occasionally
                     ALOGV("underrun: time since last cycle %d.%03ld sec",
                             (int) sec, nsec / 1000000L);
@@ -573,10 +569,8 @@
                 // this store #4 is not atomic with respect to stores #1, #2, #3 above, but
                 // the newest open and oldest closed halves are atomic with respect to each other
                 dumpState->mBounds = bounds;
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
                 ATRACE_INT("cycle_ms", monotonicNs / 1000000);
                 ATRACE_INT("load_us", loadNs / 1000);
-#endif
               }
 #endif
             } else {
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index b898924..aaa5333 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -44,7 +44,6 @@
 
             void        flush();
             void        destroy();
-            void        mute(bool);
             int         name() const { return mName; }
 
             audio_stream_type_t streamType() const {
@@ -78,7 +77,6 @@
 
     virtual size_t framesReady() const;
 
-    bool isMuted() const { return mMute; }
     bool isPausing() const {
         return mState == PAUSING;
     }
@@ -105,17 +103,14 @@
 
 public:
     void triggerEvents(AudioSystem::sync_event_t type);
+    void invalidate();
+    bool isInvalid() const { return mIsInvalid; }
     virtual bool isTimedTrack() const { return false; }
     bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
     virtual bool isOut() const;
 
 protected:
 
-    // written by Track::mute() called by binder thread(s), without a mutex or barrier.
-    // read by Track::isMuted() called by playback thread, also without a mutex or barrier.
-    // The lack of mutex or barrier is safe because the mute status is only used by itself.
-    bool                mMute;
-
     // FILLED state is used for suppressing volume ramp at begin of playing
     enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE};
     mutable uint8_t     mFillingUpStatus;
@@ -150,6 +145,7 @@
     volatile float      mCachedVolume;  // combined master volume and stream type volume;
                                         // 'volatile' means accessed without lock or
                                         // barrier, but is read/written atomically
+    bool                mIsInvalid; // non-resettable latch, set by invalidate()
 };  // end of Track
 
 class TimedTrack : public Track {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1ceb850..d2b2931 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -18,6 +18,7 @@
 
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include <math.h>
 #include <fcntl.h>
@@ -25,6 +26,7 @@
 #include <cutils/properties.h>
 #include <cutils/compiler.h>
 #include <utils/Log.h>
+#include <utils/Trace.h>
 
 #include <private/media/AudioTrackShared.h>
 #include <hardware/audio.h>
@@ -1522,8 +1524,7 @@
 
     for (size_t i = 0; i < mTracks.size(); ++i) {
         sp<Track> track = mTracks[i];
-        if (sessionId == track->sessionId() &&
-                !(track->mCblk->flags & CBLK_INVALID)) {
+        if (sessionId == track->sessionId() && !track->isInvalid()) {
             result |= TRACK_SESSION;
             break;
         }
@@ -1541,8 +1542,7 @@
     }
     for (size_t i = 0; i < mTracks.size(); i++) {
         sp<Track> track = mTracks[i];
-        if (sessionId == track->sessionId() &&
-                !(track->mCblk->flags & CBLK_INVALID)) {
+        if (sessionId == track->sessionId() && !track->isInvalid()) {
             return AudioSystem::getStrategyForStream(track->streamType());
         }
     }
@@ -1652,9 +1652,7 @@
     if (mNormalSink != 0) {
 #define mBitShift 2 // FIXME
         size_t count = mixBufferSize >> mBitShift;
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-        Tracer::traceBegin(ATRACE_TAG, "write");
-#endif
+        ATRACE_BEGIN("write");
         // update the setpoint when AudioFlinger::mScreenState changes
         uint32_t screenState = AudioFlinger::mScreenState;
         if (screenState != mScreenState) {
@@ -1666,9 +1664,7 @@
             }
         }
         ssize_t framesWritten = mNormalSink->write(mMixBuffer, count);
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-        Tracer::traceEnd(ATRACE_TAG);
-#endif
+        ATRACE_END();
         if (framesWritten > 0) {
             bytesWritten = framesWritten << mBitShift;
         } else {
@@ -1723,8 +1719,7 @@
     for (size_t i = 0; i < size; i++) {
         sp<Track> t = mTracks[i];
         if (t->streamType() == streamType) {
-            android_atomic_or(CBLK_INVALID, &t->mCblk->flags);
-            t->mCblk->cv.signal();
+            t->invalidate();
         }
     }
 }
@@ -2000,9 +1995,7 @@
             if (!mStandby && delta > maxPeriod) {
                 mNumDelayedWrites++;
                 if ((now - lastWarning) > kWarningThrottleNs) {
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
-                    ScopedTrace st(ATRACE_TAG, "underrun");
-#endif
+                    ATRACE_NAME("underrun");
                     ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
                             ns2ms(delta), mNumDelayedWrites, this);
                     lastWarning = now;
@@ -2548,8 +2541,7 @@
                 }
                 // cache the combined master volume and stream type volume for fast mixer; this
                 // lacks any synchronization or barrier so VolumeProvider may read a stale value
-                track->mCachedVolume = track->isMuted() ?
-                        0 : masterVolume * mStreamTypes[track->streamType()].volume;
+                track->mCachedVolume = masterVolume * mStreamTypes[track->streamType()].volume;
                 ++fastTracks;
             } else {
                 // was it previously active?
@@ -2641,8 +2633,7 @@
 
             // compute volume for this track
             uint32_t vl, vr, va;
-            if (track->isMuted() || track->isPausing() ||
-                mStreamTypes[track->streamType()].mute) {
+            if (track->isPausing() || mStreamTypes[track->streamType()].mute) {
                 vl = vr = va = 0;
                 if (track->isPausing()) {
                     track->setPaused();
@@ -3143,8 +3134,7 @@
 
             // compute volume for this track
             float left, right;
-            if (track->isMuted() || mMasterMute || track->isPausing() ||
-                mStreamTypes[track->streamType()].mute) {
+            if (mMasterMute || track->isPausing() || mStreamTypes[track->streamType()].mute) {
                 left = right = 0;
                 if (track->isPausing()) {
                     track->setPaused();
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2c6ba8b..9b611d2 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -248,10 +248,6 @@
     mTrack->flush();
 }
 
-void AudioFlinger::TrackHandle::mute(bool e) {
-    mTrack->mute(e);
-}
-
 void AudioFlinger::TrackHandle::pause() {
     mTrack->pause();
 }
@@ -315,7 +311,6 @@
             IAudioFlinger::track_flags_t flags)
     :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
             sessionId),
-    mMute(false),
     mFillingUpStatus(FS_INVALID),
     // mRetryCount initialized later when needed
     mSharedBuffer(sharedBuffer),
@@ -328,7 +323,8 @@
     mFlags(flags),
     mFastIndex(-1),
     mUnderrunCount(0),
-    mCachedVolume(1.0)
+    mCachedVolume(1.0),
+    mIsInvalid(false)
 {
     if (mCblk != NULL) {
         // to avoid leaking a track name, do not allocate one unless there is an mCblk
@@ -397,7 +393,7 @@
 
 /*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
 {
-    result.append("   Name Client Type Fmt Chn mask   Session StpCnt fCount S M F SRate  "
+    result.append("   Name Client Type Fmt Chn mask   Session StpCnt fCount S F SRate  "
                   "L dB  R dB    Server      User     Main buf    Aux Buf  Flags Underruns\n");
 }
 
@@ -461,7 +457,7 @@
         nowInUnderrun = '?';
         break;
     }
-    snprintf(&buffer[7], size-7, " %6d %4u %3u 0x%08x %7u %6u %6u %1c %1d %1d %5u %5.2g %5.2g  "
+    snprintf(&buffer[7], size-7, " %6d %4u %3u 0x%08x %7u %6u %6u %1c %1d %5u %5.2g %5.2g  "
             "0x%08x 0x%08x 0x%08x 0x%08x %#5x %9u%c\n",
             (mClient == 0) ? getpid_cached : mClient->pid(),
             mStreamType,
@@ -471,7 +467,6 @@
             mStepCount,
             mFrameCount,
             stateChar,
-            mMute,
             mFillingUpStatus,
             mCblk->sampleRate,
             20.0 * log10((vlr & 0xFFFF) / 4096.0),
@@ -708,11 +703,6 @@
     }
 }
 
-void AudioFlinger::PlaybackThread::Track::mute(bool muted)
-{
-    mMute = muted;
-}
-
 status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
 {
     status_t status = DEAD_OBJECT;
@@ -845,6 +835,14 @@
     return true;
 }
 
+void AudioFlinger::PlaybackThread::Track::invalidate()
+{
+    // FIXME should use proxy
+    android_atomic_or(CBLK_INVALID, &mCblk->flags);
+    mCblk->cv.signal();
+    mIsInvalid = true;
+}
+
 // ----------------------------------------------------------------------------
 
 sp<AudioFlinger::PlaybackThread::TimedTrack>
diff --git a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
index af3e40d..d45d697 100644
--- a/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
+++ b/services/audioflinger/audio-resampler/AudioResamplerCoefficients.cpp
@@ -15,7 +15,7 @@
  */
 
 #define LOG_TAG "ResamplerCoefficients"
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 
 #include <utils/Log.h>
 
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 5a7bb48..70bf0ac 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -183,37 +183,37 @@
 
     result.append("    White balance mode: ");
     switch (p.wbMode) {
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_AUTO)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_INCANDESCENT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_FLUORESCENT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_DAYLIGHT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_TWILIGHT)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_SHADE)
         default: result.append("UNKNOWN\n");
     }
 
     result.append("    Effect mode: ");
     switch (p.effectMode) {
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_OFF)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_MONO)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_NEGATIVE)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_SOLARIZE)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_SEPIA)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_POSTERIZE)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_AQUA)
         default: result.append("UNKNOWN\n");
     }
 
     result.append("    Antibanding mode: ");
     switch (p.antibandingMode) {
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
-        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ)
+        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ)
         default: result.append("UNKNOWN\n");
     }
 
@@ -497,7 +497,7 @@
 }
 
 status_t Camera2Client::setPreviewTexture(
-        const sp<ISurfaceTexture>& surfaceTexture) {
+        const sp<IGraphicBufferProducer>& bufferProducer) {
     ATRACE_CALL();
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mICameraLock);
@@ -506,9 +506,9 @@
 
     sp<IBinder> binder;
     sp<ANativeWindow> window;
-    if (surfaceTexture != 0) {
-        binder = surfaceTexture->asBinder();
-        window = new SurfaceTextureClient(surfaceTexture);
+    if (bufferProducer != 0) {
+        binder = bufferProducer->asBinder();
+        window = new SurfaceTextureClient(bufferProducer);
     }
     return setPreviewWindowL(binder, window);
 }
@@ -1260,7 +1260,7 @@
     }
     // Ignoring type
     if (l.mParameters.fastInfo.bestFaceDetectMode ==
-            ANDROID_STATS_FACE_DETECTION_OFF) {
+            ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
         ALOGE("%s: Camera %d: Face detection not supported",
                 __FUNCTION__, mCameraId);
         return INVALID_OPERATION;
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 55ead02..4669958 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -49,7 +49,7 @@
     virtual status_t        unlock();
     virtual status_t        setPreviewDisplay(const sp<Surface>& surface);
     virtual status_t        setPreviewTexture(
-        const sp<ISurfaceTexture>& surfaceTexture);
+        const sp<IGraphicBufferProducer>& bufferProducer);
     virtual void            setPreviewCallbackFlag(int flag);
     virtual status_t        startPreview();
     virtual void            stopPreview();
diff --git a/services/camera/libcameraservice/CameraClient.cpp b/services/camera/libcameraservice/CameraClient.cpp
index 006a9c9..f9cee0d 100644
--- a/services/camera/libcameraservice/CameraClient.cpp
+++ b/services/camera/libcameraservice/CameraClient.cpp
@@ -307,17 +307,17 @@
     return setPreviewWindow(binder, window);
 }
 
-// set the SurfaceTexture that the preview will use
+// set the SurfaceTextureClient that the preview will use
 status_t CameraClient::setPreviewTexture(
-        const sp<ISurfaceTexture>& surfaceTexture) {
-    LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
+        const sp<IGraphicBufferProducer>& bufferProducer) {
+    LOG1("setPreviewTexture(%p) (pid %d)", bufferProducer.get(),
             getCallingPid());
 
     sp<IBinder> binder;
     sp<ANativeWindow> window;
-    if (surfaceTexture != 0) {
-        binder = surfaceTexture->asBinder();
-        window = new SurfaceTextureClient(surfaceTexture);
+    if (bufferProducer != 0) {
+        binder = bufferProducer->asBinder();
+        window = new SurfaceTextureClient(bufferProducer);
     }
     return setPreviewWindow(binder, window);
 }
diff --git a/services/camera/libcameraservice/CameraClient.h b/services/camera/libcameraservice/CameraClient.h
index 2f31c4e..7da3da7 100644
--- a/services/camera/libcameraservice/CameraClient.h
+++ b/services/camera/libcameraservice/CameraClient.h
@@ -33,7 +33,7 @@
     virtual status_t        lock();
     virtual status_t        unlock();
     virtual status_t        setPreviewDisplay(const sp<Surface>& surface);
-    virtual status_t        setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture);
+    virtual status_t        setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer);
     virtual void            setPreviewCallbackFlag(int flag);
     virtual status_t        startPreview();
     virtual void            stopPreview();
@@ -124,7 +124,7 @@
 
     // Ensures atomicity among the public methods
     mutable Mutex                   mLock;
-    // This is a binder of Surface or SurfaceTexture.
+    // This is a binder of Surface or SurfaceTextureClient.
     sp<IBinder>                     mSurface;
     sp<ANativeWindow>               mPreviewWindow;
 
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 4dab340..41365a0 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -81,7 +81,7 @@
         virtual status_t      lock() = 0;
         virtual status_t      unlock() = 0;
         virtual status_t      setPreviewDisplay(const sp<Surface>& surface) = 0;
-        virtual status_t      setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture) = 0;
+        virtual status_t      setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)=0;
         virtual void          setPreviewCallbackFlag(int flag) = 0;
         virtual status_t      startPreview() = 0;
         virtual void          stopPreview() = 0;
diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.cpp b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
index e032522..8ee5de7 100644
--- a/services/camera/libcameraservice/camera2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
@@ -177,7 +177,7 @@
         SharedParameters::Lock l(client->getParameters());
         enableFaceDetect = l.mParameters.enableFaceDetect;
     }
-    entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE);
+    entry = frame.find(ANDROID_STATISTICS_FACE_DETECT_MODE);
 
     // TODO: This should be an error once implementations are compliant
     if (entry.count == 0) {
@@ -190,9 +190,9 @@
     Vector<camera_face_t> faces;
     metadata.number_of_faces = 0;
 
-    if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
+    if (enableFaceDetect && faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
         SharedParameters::Lock l(client->getParameters());
-        entry = frame.find(ANDROID_STATS_FACE_RECTANGLES);
+        entry = frame.find(ANDROID_STATISTICS_FACE_RECTANGLES);
         if (entry.count == 0) {
             // No faces this frame
             /* warning: locks SharedCameraClient */
@@ -209,7 +209,7 @@
         }
         const int32_t *faceRects = entry.data.i32;
 
-        entry = frame.find(ANDROID_STATS_FACE_SCORES);
+        entry = frame.find(ANDROID_STATISTICS_FACE_SCORES);
         if (entry.count == 0) {
             ALOGE("%s: Camera %d: Unable to read face scores",
                     __FUNCTION__, client->getCameraId());
@@ -220,8 +220,8 @@
         const int32_t *faceLandmarks = NULL;
         const int32_t *faceIds = NULL;
 
-        if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
-            entry = frame.find(ANDROID_STATS_FACE_LANDMARKS);
+        if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
+            entry = frame.find(ANDROID_STATISTICS_FACE_LANDMARKS);
             if (entry.count == 0) {
                 ALOGE("%s: Camera %d: Unable to read face landmarks",
                         __FUNCTION__, client->getCameraId());
@@ -229,7 +229,7 @@
             }
             faceLandmarks = entry.data.i32;
 
-            entry = frame.find(ANDROID_STATS_FACE_IDS);
+            entry = frame.find(ANDROID_STATISTICS_FACE_IDS);
 
             if (entry.count == 0) {
                 ALOGE("%s: Camera %d: Unable to read face IDs",
@@ -256,7 +256,7 @@
             face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]);
 
             face.score = faceScores[i];
-            if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
+            if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
                 face.id = faceIds[i];
                 face.left_eye[0] =
                         l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]);
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
index 93927e6..6ab19b1 100644
--- a/services/camera/libcameraservice/camera2/Parameters.cpp
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -278,7 +278,7 @@
     gpsProcessingMethod = "unknown";
     // GPS fields in CameraParameters are not set by implementation
 
-    wbMode = ANDROID_CONTROL_AWB_AUTO;
+    wbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
     params.set(CameraParameters::KEY_WHITE_BALANCE,
             CameraParameters::WHITE_BALANCE_AUTO);
 
@@ -291,40 +291,40 @@
             if (addComma) supportedWhiteBalance += ",";
             addComma = true;
             switch (availableWhiteBalanceModes.data.u8[i]) {
-            case ANDROID_CONTROL_AWB_AUTO:
+            case ANDROID_CONTROL_AWB_MODE_AUTO:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_AUTO;
                 break;
-            case ANDROID_CONTROL_AWB_INCANDESCENT:
+            case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_INCANDESCENT;
                 break;
-            case ANDROID_CONTROL_AWB_FLUORESCENT:
+            case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_FLUORESCENT;
                 break;
-            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
+            case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
                 break;
-            case ANDROID_CONTROL_AWB_DAYLIGHT:
+            case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_DAYLIGHT;
                 break;
-            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
+            case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
                 break;
-            case ANDROID_CONTROL_AWB_TWILIGHT:
+            case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_TWILIGHT;
                 break;
-            case ANDROID_CONTROL_AWB_SHADE:
+            case ANDROID_CONTROL_AWB_MODE_SHADE:
                 supportedWhiteBalance +=
                     CameraParameters::WHITE_BALANCE_SHADE;
                 break;
             // Skipping values not mappable to v1 API
-            case ANDROID_CONTROL_AWB_OFF:
+            case ANDROID_CONTROL_AWB_MODE_OFF:
                 addComma = false;
                 break;
             default:
@@ -339,7 +339,7 @@
                 supportedWhiteBalance);
     }
 
-    effectMode = ANDROID_CONTROL_EFFECT_OFF;
+    effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
     params.set(CameraParameters::KEY_EFFECT,
             CameraParameters::EFFECT_NONE);
 
@@ -353,39 +353,39 @@
             if (addComma) supportedEffects += ",";
             addComma = true;
             switch (availableEffects.data.u8[i]) {
-                case ANDROID_CONTROL_EFFECT_OFF:
+                case ANDROID_CONTROL_EFFECT_MODE_OFF:
                     supportedEffects +=
                         CameraParameters::EFFECT_NONE;
                     break;
-                case ANDROID_CONTROL_EFFECT_MONO:
+                case ANDROID_CONTROL_EFFECT_MODE_MONO:
                     supportedEffects +=
                         CameraParameters::EFFECT_MONO;
                     break;
-                case ANDROID_CONTROL_EFFECT_NEGATIVE:
+                case ANDROID_CONTROL_EFFECT_MODE_NEGATIVE:
                     supportedEffects +=
                         CameraParameters::EFFECT_NEGATIVE;
                     break;
-                case ANDROID_CONTROL_EFFECT_SOLARIZE:
+                case ANDROID_CONTROL_EFFECT_MODE_SOLARIZE:
                     supportedEffects +=
                         CameraParameters::EFFECT_SOLARIZE;
                     break;
-                case ANDROID_CONTROL_EFFECT_SEPIA:
+                case ANDROID_CONTROL_EFFECT_MODE_SEPIA:
                     supportedEffects +=
                         CameraParameters::EFFECT_SEPIA;
                     break;
-                case ANDROID_CONTROL_EFFECT_POSTERIZE:
+                case ANDROID_CONTROL_EFFECT_MODE_POSTERIZE:
                     supportedEffects +=
                         CameraParameters::EFFECT_POSTERIZE;
                     break;
-                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
+                case ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD:
                     supportedEffects +=
                         CameraParameters::EFFECT_WHITEBOARD;
                     break;
-                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
+                case ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD:
                     supportedEffects +=
                         CameraParameters::EFFECT_BLACKBOARD;
                     break;
-                case ANDROID_CONTROL_EFFECT_AQUA:
+                case ANDROID_CONTROL_EFFECT_MODE_AQUA:
                     supportedEffects +=
                         CameraParameters::EFFECT_AQUA;
                     break;
@@ -399,7 +399,7 @@
         params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
     }
 
-    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
+    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
     params.set(CameraParameters::KEY_ANTIBANDING,
             CameraParameters::ANTIBANDING_AUTO);
 
@@ -413,19 +413,19 @@
             if (addComma) supportedAntibanding += ",";
             addComma = true;
             switch (availableAntibandingModes.data.u8[i]) {
-                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
+                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF:
                     supportedAntibanding +=
                         CameraParameters::ANTIBANDING_OFF;
                     break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
+                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ:
                     supportedAntibanding +=
                         CameraParameters::ANTIBANDING_50HZ;
                     break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
+                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ:
                     supportedAntibanding +=
                         CameraParameters::ANTIBANDING_60HZ;
                     break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
+                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO:
                     supportedAntibanding +=
                         CameraParameters::ANTIBANDING_AUTO;
                     break;
@@ -538,7 +538,7 @@
     }
 
     camera_metadata_ro_entry_t flashAvailable =
-        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
+        staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 1, 1);
     if (!flashAvailable.count) return NO_INIT;
 
     camera_metadata_ro_entry_t availableAeModes =
@@ -557,7 +557,7 @@
             "," + CameraParameters::FLASH_MODE_TORCH;
         for (size_t i=0; i < availableAeModes.count; i++) {
             if (availableAeModes.data.u8[i] ==
-                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
+                    ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
                 supportedFlashModes = supportedFlashModes + "," +
                     CameraParameters::FLASH_MODE_RED_EYE;
                 break;
@@ -574,7 +574,7 @@
     }
 
     camera_metadata_ro_entry_t minFocusDistance =
-        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
+        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 1, 1);
     if (!minFocusDistance.count) return NO_INIT;
 
     camera_metadata_ro_entry_t availableAfModes =
@@ -599,28 +599,28 @@
             if (addComma) supportedFocusModes += ",";
             addComma = true;
             switch (availableAfModes.data.u8[i]) {
-                case ANDROID_CONTROL_AF_AUTO:
+                case ANDROID_CONTROL_AF_MODE_AUTO:
                     supportedFocusModes +=
                         CameraParameters::FOCUS_MODE_AUTO;
                     break;
-                case ANDROID_CONTROL_AF_MACRO:
+                case ANDROID_CONTROL_AF_MODE_MACRO:
                     supportedFocusModes +=
                         CameraParameters::FOCUS_MODE_MACRO;
                     break;
-                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
+                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
                     supportedFocusModes +=
                         CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
                     break;
-                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
+                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
                     supportedFocusModes +=
                         CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
                     break;
-                case ANDROID_CONTROL_AF_EDOF:
+                case ANDROID_CONTROL_AF_MODE_EDOF:
                     supportedFocusModes +=
                         CameraParameters::FOCUS_MODE_EDOF;
                     break;
                 // Not supported in old API
-                case ANDROID_CONTROL_AF_OFF:
+                case ANDROID_CONTROL_AF_MODE_OFF:
                     addComma = false;
                     break;
                 default:
@@ -651,14 +651,14 @@
     focusingAreas.add(Parameters::Area(0,0,0,0,0));
 
     camera_metadata_ro_entry_t availableFocalLengths =
-        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
+        staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
     if (!availableFocalLengths.count) return NO_INIT;
 
     float minFocalLength = availableFocalLengths.data.f[0];
     params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
 
     camera_metadata_ro_entry_t sensorSize =
-        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
+        staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
     if (!sensorSize.count) return NO_INIT;
 
     // The fields of view here assume infinity focus, maximum wide angle
@@ -674,7 +674,7 @@
                 exposureCompensation);
 
     camera_metadata_ro_entry_t exposureCompensationRange =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
+        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE, 2, 2);
     if (!exposureCompensationRange.count) return NO_INIT;
 
     params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
@@ -683,7 +683,7 @@
             exposureCompensationRange.data.i32[0]);
 
     camera_metadata_ro_entry_t exposureCompensationStep =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
+        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_STEP, 1, 1);
     if (!exposureCompensationStep.count) return NO_INIT;
 
     params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
@@ -713,7 +713,7 @@
     params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
 
     camera_metadata_ro_entry_t maxDigitalZoom =
-        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, /*minCount*/1, /*maxCount*/1);
+        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, /*minCount*/1, /*maxCount*/1);
     if (!maxDigitalZoom.count) return NO_INIT;
 
     {
@@ -811,31 +811,31 @@
 status_t Parameters::buildFastInfo() {
 
     camera_metadata_ro_entry_t activeArraySize =
-        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
+        staticInfo(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 2, 2);
     if (!activeArraySize.count) return NO_INIT;
     int32_t arrayWidth = activeArraySize.data.i32[0];
     int32_t arrayHeight = activeArraySize.data.i32[1];
 
     camera_metadata_ro_entry_t availableFaceDetectModes =
-        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
+        staticInfo(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
     if (!availableFaceDetectModes.count) return NO_INIT;
 
     uint8_t bestFaceDetectMode =
-        ANDROID_STATS_FACE_DETECTION_OFF;
+        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
     for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
         switch (availableFaceDetectModes.data.u8[i]) {
-            case ANDROID_STATS_FACE_DETECTION_OFF:
+            case ANDROID_STATISTICS_FACE_DETECT_MODE_OFF:
                 break;
-            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
+            case ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE:
                 if (bestFaceDetectMode !=
-                        ANDROID_STATS_FACE_DETECTION_FULL) {
+                        ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
                     bestFaceDetectMode =
-                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
+                        ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE;
                 }
                 break;
-            case ANDROID_STATS_FACE_DETECTION_FULL:
+            case ANDROID_STATISTICS_FACE_DETECT_MODE_FULL:
                 bestFaceDetectMode =
-                    ANDROID_STATS_FACE_DETECTION_FULL;
+                    ANDROID_STATISTICS_FACE_DETECT_MODE_FULL;
                 break;
             default:
                 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
@@ -846,7 +846,7 @@
     }
 
     camera_metadata_ro_entry_t maxFacesDetected =
-        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
+        staticInfo(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 1, 1);
     if (!maxFacesDetected.count) return NO_INIT;
 
     int32_t maxFaces = maxFacesDetected.data.i32[0];
@@ -856,7 +856,7 @@
     camera_metadata_ro_entry_t sceneModeOverrides =
         staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES);
     camera_metadata_ro_entry_t minFocusDistance =
-        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
+        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
     bool fixedLens = (minFocusDistance.data.f[0] == 0);
 
     if (sceneModeOverrides.count > 0) {
@@ -877,16 +877,16 @@
             uint8_t aeMode =
                     sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
             switch(aeMode) {
-                case ANDROID_CONTROL_AE_ON:
+                case ANDROID_CONTROL_AE_MODE_ON:
                     modes.flashMode = FLASH_MODE_OFF;
                     break;
-                case ANDROID_CONTROL_AE_ON_AUTO_FLASH:
+                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
                     modes.flashMode = FLASH_MODE_AUTO;
                     break;
-                case ANDROID_CONTROL_AE_ON_ALWAYS_FLASH:
+                case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
                     modes.flashMode = FLASH_MODE_ON;
                     break;
-                case ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE:
+                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
                     modes.flashMode = FLASH_MODE_RED_EYE;
                     break;
                 default:
@@ -900,15 +900,15 @@
             uint8_t afMode =
                     sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
             switch(afMode) {
-                case ANDROID_CONTROL_AF_OFF:
+                case ANDROID_CONTROL_AF_MODE_OFF:
                     modes.focusMode = fixedLens ?
                             FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
                     break;
-                case ANDROID_CONTROL_AF_AUTO:
-                case ANDROID_CONTROL_AF_MACRO:
-                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
-                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
-                case ANDROID_CONTROL_AF_EDOF:
+                case ANDROID_CONTROL_AF_MODE_AUTO:
+                case ANDROID_CONTROL_AF_MODE_MACRO:
+                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                case ANDROID_CONTROL_AF_MODE_EDOF:
                     modes.focusMode = static_cast<focusMode_t>(afMode);
                     break;
                 default:
@@ -1363,7 +1363,7 @@
 
     if (validatedParams.flashMode != flashMode) {
         camera_metadata_ro_entry_t flashAvailable =
-            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
+            staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 1, 1);
         if (!flashAvailable.data.u8[0] &&
                 validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
             ALOGE("%s: Requested flash mode \"%s\" is not supported: "
@@ -1400,9 +1400,9 @@
                 fastInfo.sceneModeOverrides.
                         valueFor(validatedParams.sceneMode).wbMode;
     } else {
-        validatedParams.wbMode = ANDROID_CONTROL_AWB_OFF;
+        validatedParams.wbMode = ANDROID_CONTROL_AWB_MODE_OFF;
     }
-    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_OFF) {
+    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_MODE_OFF) {
         validatedParams.wbMode = wbModeStringToEnum(
             newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
     }
@@ -1439,7 +1439,7 @@
         validatedParams.currentAfTriggerId = -1;
         if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
             camera_metadata_ro_entry_t minFocusDistance =
-                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
+                staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
             if (minFocusDistance.data.f[0] == 0) {
                 ALOGE("%s: Requested focus mode \"%s\" is not available: "
                         "fixed focus lens",
@@ -1489,7 +1489,7 @@
     validatedParams.exposureCompensation =
         newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
     camera_metadata_ro_entry_t exposureCompensationRange =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
+        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE);
     if ((validatedParams.exposureCompensation <
             exposureCompensationRange.data.i32[0]) ||
         (validatedParams.exposureCompensation >
@@ -1585,7 +1585,7 @@
     ATRACE_CALL();
     status_t res;
 
-    uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
+    uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
     res = request->update(ANDROID_REQUEST_METADATA_MODE,
             &metadataMode, 1);
     if (res != OK) return res;
@@ -1612,9 +1612,9 @@
     // to the other.
     bool sceneModeActive =
             sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
-    uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
+    uint8_t reqControlMode = ANDROID_CONTROL_MODE_AUTO;
     if (enableFaceDetect || sceneModeActive) {
-        reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
+        reqControlMode = ANDROID_CONTROL_MODE_USE_SCENE_MODE;
     }
     res = request->update(ANDROID_CONTROL_MODE,
             &reqControlMode, 1);
@@ -1628,21 +1628,21 @@
             &reqSceneMode, 1);
     if (res != OK) return res;
 
-    uint8_t reqFlashMode = ANDROID_FLASH_OFF;
-    uint8_t reqAeMode = ANDROID_CONTROL_AE_OFF;
+    uint8_t reqFlashMode = ANDROID_FLASH_MODE_OFF;
+    uint8_t reqAeMode = ANDROID_CONTROL_AE_MODE_OFF;
     switch (flashMode) {
         case Parameters::FLASH_MODE_OFF:
-            reqAeMode = ANDROID_CONTROL_AE_ON; break;
+            reqAeMode = ANDROID_CONTROL_AE_MODE_ON; break;
         case Parameters::FLASH_MODE_AUTO:
-            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
+            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; break;
         case Parameters::FLASH_MODE_ON:
-            reqAeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
+            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH; break;
         case Parameters::FLASH_MODE_TORCH:
-            reqAeMode = ANDROID_CONTROL_AE_ON;
-            reqFlashMode = ANDROID_FLASH_TORCH;
+            reqAeMode = ANDROID_CONTROL_AE_MODE_ON;
+            reqFlashMode = ANDROID_FLASH_MODE_TORCH;
             break;
         case Parameters::FLASH_MODE_RED_EYE:
-            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
+            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; break;
         default:
             ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
                     cameraId, flashMode);
@@ -1666,7 +1666,7 @@
     if (res != OK) return res;
 
     float reqFocusDistance = 0; // infinity focus in diopters
-    uint8_t reqFocusMode = ANDROID_CONTROL_AF_OFF;
+    uint8_t reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
     switch (focusMode) {
         case Parameters::FOCUS_MODE_AUTO:
         case Parameters::FOCUS_MODE_MACRO:
@@ -1677,7 +1677,7 @@
             break;
         case Parameters::FOCUS_MODE_INFINITY:
         case Parameters::FOCUS_MODE_FIXED:
-            reqFocusMode = ANDROID_CONTROL_AF_OFF;
+            reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
             break;
         default:
                 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
@@ -1716,7 +1716,7 @@
     if (res != OK) return res;
     delete[] reqFocusingAreas;
 
-    res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
+    res = request->update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
             &exposureCompensation, 1);
     if (res != OK) return res;
 
@@ -1758,16 +1758,16 @@
     if (res != OK) return res;
 
     uint8_t reqVstabMode = videoStabilization ?
-            ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
-            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
+            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON :
+            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
     res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
             &reqVstabMode, 1);
     if (res != OK) return res;
 
     uint8_t reqFaceDetectMode = enableFaceDetect ?
             fastInfo.bestFaceDetectMode :
-            (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
-    res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
+            (uint8_t)ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+    res = request->update(ANDROID_STATISTICS_FACE_DETECT_MODE,
             &reqFaceDetectMode, 1);
     if (res != OK) return res;
 
@@ -1891,43 +1891,43 @@
 int Parameters::wbModeStringToEnum(const char *wbMode) {
     return
         !wbMode ?
-            ANDROID_CONTROL_AWB_AUTO :
+            ANDROID_CONTROL_AWB_MODE_AUTO :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
-            ANDROID_CONTROL_AWB_AUTO :
+            ANDROID_CONTROL_AWB_MODE_AUTO :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
-            ANDROID_CONTROL_AWB_INCANDESCENT :
+            ANDROID_CONTROL_AWB_MODE_INCANDESCENT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
-            ANDROID_CONTROL_AWB_FLUORESCENT :
+            ANDROID_CONTROL_AWB_MODE_FLUORESCENT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
-            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
+            ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
-            ANDROID_CONTROL_AWB_DAYLIGHT :
+            ANDROID_CONTROL_AWB_MODE_DAYLIGHT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
-            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
+            ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
-            ANDROID_CONTROL_AWB_TWILIGHT :
+            ANDROID_CONTROL_AWB_MODE_TWILIGHT :
         !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
-            ANDROID_CONTROL_AWB_SHADE :
+            ANDROID_CONTROL_AWB_MODE_SHADE :
         -1;
 }
 
 const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
     switch (wbMode) {
-        case ANDROID_CONTROL_AWB_AUTO:
+        case ANDROID_CONTROL_AWB_MODE_AUTO:
             return CameraParameters::WHITE_BALANCE_AUTO;
-        case ANDROID_CONTROL_AWB_INCANDESCENT:
+        case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
             return CameraParameters::WHITE_BALANCE_INCANDESCENT;
-        case ANDROID_CONTROL_AWB_FLUORESCENT:
+        case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
             return CameraParameters::WHITE_BALANCE_FLUORESCENT;
-        case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
+        case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
             return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
-        case ANDROID_CONTROL_AWB_DAYLIGHT:
+        case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
             return CameraParameters::WHITE_BALANCE_DAYLIGHT;
-        case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
+        case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
             return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
-        case ANDROID_CONTROL_AWB_TWILIGHT:
+        case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
             return CameraParameters::WHITE_BALANCE_TWILIGHT;
-        case ANDROID_CONTROL_AWB_SHADE:
+        case ANDROID_CONTROL_AWB_MODE_SHADE:
             return CameraParameters::WHITE_BALANCE_SHADE;
         default:
             ALOGE("%s: Unknown AWB mode enum: %d",
@@ -1939,40 +1939,40 @@
 int Parameters::effectModeStringToEnum(const char *effectMode) {
     return
         !effectMode ?
-            ANDROID_CONTROL_EFFECT_OFF :
+            ANDROID_CONTROL_EFFECT_MODE_OFF :
         !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
-            ANDROID_CONTROL_EFFECT_OFF :
+            ANDROID_CONTROL_EFFECT_MODE_OFF :
         !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
-            ANDROID_CONTROL_EFFECT_MONO :
+            ANDROID_CONTROL_EFFECT_MODE_MONO :
         !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
-            ANDROID_CONTROL_EFFECT_NEGATIVE :
+            ANDROID_CONTROL_EFFECT_MODE_NEGATIVE :
         !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
-            ANDROID_CONTROL_EFFECT_SOLARIZE :
+            ANDROID_CONTROL_EFFECT_MODE_SOLARIZE :
         !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
-            ANDROID_CONTROL_EFFECT_SEPIA :
+            ANDROID_CONTROL_EFFECT_MODE_SEPIA :
         !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
-            ANDROID_CONTROL_EFFECT_POSTERIZE :
+            ANDROID_CONTROL_EFFECT_MODE_POSTERIZE :
         !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
-            ANDROID_CONTROL_EFFECT_WHITEBOARD :
+            ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD :
         !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
-            ANDROID_CONTROL_EFFECT_BLACKBOARD :
+            ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD :
         !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
-            ANDROID_CONTROL_EFFECT_AQUA :
+            ANDROID_CONTROL_EFFECT_MODE_AQUA :
         -1;
 }
 
 int Parameters::abModeStringToEnum(const char *abMode) {
     return
         !abMode ?
-            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
         !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
         !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF :
         !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ :
         !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ :
         -1;
 }
 
@@ -2329,7 +2329,7 @@
     // chosen to maximize its area on the sensor
 
     camera_metadata_ro_entry_t maxDigitalZoom =
-            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
+            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
     // For each zoom step by how many pixels more do we change the zoom
     float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
             (NUM_ZOOM_STEPS-1);
diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h
index 6d32bf6..4192e97 100644
--- a/services/camera/libcameraservice/camera2/Parameters.h
+++ b/services/camera/libcameraservice/camera2/Parameters.h
@@ -73,16 +73,16 @@
         FLASH_MODE_AUTO,
         FLASH_MODE_ON,
         FLASH_MODE_TORCH,
-        FLASH_MODE_RED_EYE = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE,
+        FLASH_MODE_RED_EYE = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
         FLASH_MODE_INVALID = -1
     } flashMode;
 
     enum focusMode_t {
-        FOCUS_MODE_AUTO = ANDROID_CONTROL_AF_AUTO,
-        FOCUS_MODE_MACRO = ANDROID_CONTROL_AF_MACRO,
-        FOCUS_MODE_CONTINUOUS_VIDEO = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO,
-        FOCUS_MODE_CONTINUOUS_PICTURE = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
-        FOCUS_MODE_EDOF = ANDROID_CONTROL_AF_EDOF,
+        FOCUS_MODE_AUTO = ANDROID_CONTROL_AF_MODE_AUTO,
+        FOCUS_MODE_MACRO = ANDROID_CONTROL_AF_MODE_MACRO,
+        FOCUS_MODE_CONTINUOUS_VIDEO = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
+        FOCUS_MODE_CONTINUOUS_PICTURE = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+        FOCUS_MODE_EDOF = ANDROID_CONTROL_AF_MODE_EDOF,
         FOCUS_MODE_INFINITY,
         FOCUS_MODE_FIXED,
         FOCUS_MODE_INVALID = -1
@@ -179,7 +179,7 @@
             focusMode_t focusMode;
             OverrideModes():
                     flashMode(FLASH_MODE_INVALID),
-                    wbMode(ANDROID_CONTROL_AWB_OFF),
+                    wbMode(ANDROID_CONTROL_AWB_MODE_OFF),
                     focusMode(FOCUS_MODE_INVALID) {
             }
         };