Merge "Enable extended precision PCM output in AudioFlinger"
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 3c0c7ec..0f729a3 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -211,28 +211,28 @@
                 int32_t what;
                 CHECK(msg->findInt32("what", &what));
 
-                if (what == ACodec::kWhatFillThisBuffer) {
+                if (what == CodecBase::kWhatFillThisBuffer) {
                     onFillThisBuffer(msg);
-                } else if (what == ACodec::kWhatDrainThisBuffer) {
+                } else if (what == CodecBase::kWhatDrainThisBuffer) {
                     if ((mNumOutputBuffersReceived++ % 16) == 0) {
                         printf(".");
                         fflush(stdout);
                     }
 
                     onDrainThisBuffer(msg);
-                } else if (what == ACodec::kWhatEOS
-                        || what == ACodec::kWhatError) {
-                    printf((what == ACodec::kWhatEOS) ? "$\n" : "E\n");
+                } else if (what == CodecBase::kWhatEOS
+                        || what == CodecBase::kWhatError) {
+                    printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n");
 
                     printStatistics();
                     (new AMessage(kWhatStop, id()))->post();
-                } else if (what == ACodec::kWhatFlushCompleted) {
+                } else if (what == CodecBase::kWhatFlushCompleted) {
                     mSeekState = SEEK_FLUSH_COMPLETED;
                     mCodec->signalResume();
 
                     (new AMessage(kWhatSeek, id()))->post(5000000ll);
-                } else if (what == ACodec::kWhatOutputFormatChanged) {
-                } else if (what == ACodec::kWhatShutdownCompleted) {
+                } else if (what == CodecBase::kWhatOutputFormatChanged) {
+                } else if (what == CodecBase::kWhatShutdownCompleted) {
                     mDecodeLooper->unregisterHandler(mCodec->id());
 
                     if (mDecodeLooper != looper()) {
@@ -240,12 +240,6 @@
                     }
 
                     looper()->stop();
-                } else if (what == ACodec::kWhatError) {
-                    ALOGE("something went wrong, codec reported an error.");
-
-                    printf("E\n");
-
-                    (new AMessage(kWhatStop, id()))->post();
                 }
                 break;
             }
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 84b6bab..142b7cb 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -22,6 +22,7 @@
 #include <android/native_window.h>
 #include <media/IOMX.h>
 #include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+#include <media/stagefright/CodecBase.h>
 #include <media/stagefright/SkipCutBuffer.h>
 #include <OMX_Audio.h>
 
@@ -32,42 +33,32 @@
 struct ABuffer;
 struct MemoryDealer;
 
-struct ACodec : public AHierarchicalStateMachine {
-    enum {
-        kWhatFillThisBuffer      = 'fill',
-        kWhatDrainThisBuffer     = 'drai',
-        kWhatEOS                 = 'eos ',
-        kWhatShutdownCompleted   = 'scom',
-        kWhatFlushCompleted      = 'fcom',
-        kWhatOutputFormatChanged = 'outC',
-        kWhatError               = 'erro',
-        kWhatComponentAllocated  = 'cAll',
-        kWhatComponentConfigured = 'cCon',
-        kWhatInputSurfaceCreated = 'isfc',
-        kWhatSignaledInputEOS    = 'seos',
-        kWhatBuffersAllocated    = 'allc',
-        kWhatOMXDied             = 'OMXd',
-    };
-
+struct ACodec : public AHierarchicalStateMachine, public CodecBase {
     ACodec();
 
-    void setNotificationMessage(const sp<AMessage> &msg);
+    virtual void setNotificationMessage(const sp<AMessage> &msg);
+
     void initiateSetup(const sp<AMessage> &msg);
-    void signalFlush();
-    void signalResume();
-    void initiateShutdown(bool keepComponentAllocated = false);
 
-    void signalSetParameters(const sp<AMessage> &msg);
-    void signalEndOfInputStream();
+    virtual void initiateAllocateComponent(const sp<AMessage> &msg);
+    virtual void initiateConfigureComponent(const sp<AMessage> &msg);
+    virtual void initiateCreateInputSurface();
+    virtual void initiateStart();
+    virtual void initiateShutdown(bool keepComponentAllocated = false);
 
-    void initiateAllocateComponent(const sp<AMessage> &msg);
-    void initiateConfigureComponent(const sp<AMessage> &msg);
-    void initiateCreateInputSurface();
-    void initiateStart();
+    virtual void signalFlush();
+    virtual void signalResume();
 
-    void signalRequestIDRFrame();
+    virtual void signalSetParameters(const sp<AMessage> &msg);
+    virtual void signalEndOfInputStream();
+    virtual void signalRequestIDRFrame();
 
-    struct PortDescription : public RefBase {
+    // AHierarchicalStateMachine implements the message handling
+    virtual void onMessageReceived(const sp<AMessage> &msg) {
+        handleMessage(msg);
+    }
+
+    struct PortDescription : public CodecBase::PortDescription {
         size_t countBuffers();
         IOMX::buffer_id bufferIDAt(size_t index) const;
         sp<ABuffer> bufferAt(size_t index) const;
@@ -117,6 +108,7 @@
         kWhatRequestIDRFrame         = 'ridr',
         kWhatSetParameters           = 'setP',
         kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
+        kWhatOMXDied                 = 'OMXd',
     };
 
     enum {
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
new file mode 100644
index 0000000..1bf27a6
--- /dev/null
+++ b/include/media/stagefright/CodecBase.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC_BASE_H_
+
+#define CODEC_BASE_H_
+
+#include <stdint.h>
+#include <media/IOMX.h>
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct ABuffer;
+
+struct CodecBase : public AHandler {
+    enum {
+        kWhatFillThisBuffer      = 'fill',
+        kWhatDrainThisBuffer     = 'drai',
+        kWhatEOS                 = 'eos ',
+        kWhatShutdownCompleted   = 'scom',
+        kWhatFlushCompleted      = 'fcom',
+        kWhatOutputFormatChanged = 'outC',
+        kWhatError               = 'erro',
+        kWhatComponentAllocated  = 'cAll',
+        kWhatComponentConfigured = 'cCon',
+        kWhatInputSurfaceCreated = 'isfc',
+        kWhatSignaledInputEOS    = 'seos',
+        kWhatBuffersAllocated    = 'allc',
+    };
+
+    virtual void setNotificationMessage(const sp<AMessage> &msg) = 0;
+
+    virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
+    virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
+    virtual void initiateCreateInputSurface() = 0;
+    virtual void initiateStart() = 0;
+    virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
+
+    // require an explicit message handler
+    virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
+
+    virtual void signalFlush() = 0;
+    virtual void signalResume() = 0;
+
+    virtual void signalRequestIDRFrame() = 0;
+    virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
+    virtual void signalEndOfInputStream() = 0;
+
+    struct PortDescription : public RefBase {
+        virtual size_t countBuffers() = 0;
+        virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
+        virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+
+    protected:
+        PortDescription();
+        virtual ~PortDescription();
+
+    private:
+        DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
+    };
+
+protected:
+    CodecBase();
+    virtual ~CodecBase();
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
+};
+
+}  // namespace android
+
+#endif  // CODEC_BASE_H_
+
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index a1e32c9..3e6eefb 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -26,9 +26,9 @@
 namespace android {
 
 struct ABuffer;
-struct ACodec;
 struct AMessage;
 struct AString;
+struct CodecBase;
 struct ICrypto;
 struct SoftwareRenderer;
 struct Surface;
@@ -195,7 +195,7 @@
     State mState;
     sp<ALooper> mLooper;
     sp<ALooper> mCodecLooper;
-    sp<ACodec> mCodec;
+    sp<CodecBase> mCodec;
     AString mComponentName;
     uint32_t mReplyID;
     uint32_t mFlags;
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index 5510b12..c3bf0ff 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -25,8 +25,10 @@
 
 namespace android {
 
-struct ABitReader {
+class ABitReader {
+public:
     ABitReader(const uint8_t *data, size_t size);
+    virtual ~ABitReader();
 
     uint32_t getBits(size_t n);
     void skipBits(size_t n);
@@ -37,18 +39,32 @@
 
     const uint8_t *data() const;
 
-private:
+protected:
     const uint8_t *mData;
     size_t mSize;
 
     uint32_t mReservoir;  // left-aligned bits
     size_t mNumBitsLeft;
 
-    void fillReservoir();
+    virtual void fillReservoir();
 
     DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
 };
 
+class NALBitReader : public ABitReader {
+public:
+    NALBitReader(const uint8_t *data, size_t size);
+
+    bool atLeastNumBitsLeft(size_t n) const;
+
+private:
+    int32_t mNumZeros;
+
+    virtual void fillReservoir();
+
+    DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
+};
+
 }  // namespace android
 
 #endif  // A_BIT_READER_H_
diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
index d2e6b28..3bb7d75 100644
--- a/include/media/stagefright/foundation/AHierarchicalStateMachine.h
+++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
@@ -43,13 +43,13 @@
     DISALLOW_EVIL_CONSTRUCTORS(AState);
 };
 
-struct AHierarchicalStateMachine : public AHandler {
+struct AHierarchicalStateMachine {
     AHierarchicalStateMachine();
 
 protected:
     virtual ~AHierarchicalStateMachine();
 
-    virtual void onMessageReceived(const sp<AMessage> &msg);
+    virtual void handleMessage(const sp<AMessage> &msg);
 
     // Only to be called in response to a message.
     void changeState(const sp<AState> &state);
diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h
index 622028e..0edaa1c 100644
--- a/include/media/stagefright/foundation/AString.h
+++ b/include/media/stagefright/foundation/AString.h
@@ -77,6 +77,8 @@
 
     bool startsWith(const char *prefix) const;
     bool endsWith(const char *suffix) const;
+    bool startsWithIgnoreCase(const char *prefix) const;
+    bool endsWithIgnoreCase(const char *suffix) const;
 
     void tolower();
 
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 695767d..38ee82b 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -163,7 +163,7 @@
 
 extern "C" int EffectCreate(const effect_uuid_t *uuid,
                             int32_t             sessionId,
-                            int32_t             ioId,
+                            int32_t             ioId __unused,
                             effect_handle_t  *pHandle){
     int ret = 0;
     int sessionNo;
@@ -1360,7 +1360,7 @@
 //  pLow:       lower band range
 //  pLow:       upper band range
 //----------------------------------------------------------------------------
-int32_t EqualizerGetBandFreqRange(EffectContext *pContext, int32_t band, uint32_t *pLow,
+int32_t EqualizerGetBandFreqRange(EffectContext *pContext __unused, int32_t band, uint32_t *pLow,
                                   uint32_t *pHi){
     *pLow = bandFreqRange[band][0];
     *pHi  = bandFreqRange[band][1];
@@ -1384,7 +1384,7 @@
 //  pLow:       lower band range
 //  pLow:       upper band range
 //----------------------------------------------------------------------------
-int32_t EqualizerGetBand(EffectContext *pContext, uint32_t targetFreq){
+int32_t EqualizerGetBand(EffectContext *pContext __unused, uint32_t targetFreq){
     int band = 0;
 
     if(targetFreq < bandFreqRange[0][0]){
@@ -1884,7 +1884,6 @@
     int status = 0;
     int32_t *pParamTemp = (int32_t *)pParam;
     int32_t param = *pParamTemp++;
-    int32_t param2;
     char *name;
 
     //ALOGV("\tVirtualizer_getParameter start");
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 5cf9238..388f77a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -272,7 +272,9 @@
 
             if (seeking) {
                 track->mPackets->queueDiscontinuity(
-                        ATSParser::DISCONTINUITY_SEEK, NULL);
+                        ATSParser::DISCONTINUITY_SEEK,
+                        NULL,
+                        true /* discard */);
             }
 
             track->mPackets->queueAccessUnit(buffer);
@@ -280,7 +282,9 @@
         } else if (err == INFO_FORMAT_CHANGED) {
 #if 0
             track->mPackets->queueDiscontinuity(
-                    ATSParser::DISCONTINUITY_FORMATCHANGE, NULL);
+                    ATSParser::DISCONTINUITY_FORMATCHANGE,
+                    NULL,
+                    false /* discard */);
 #endif
         } else {
             track->mPackets->signalEOS(err);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5abfb71..dd73cc4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -674,9 +674,9 @@
 
     bool hasCC = false;
 
-    ABitReader br(sei->data() + 1, sei->size() - 1);
+    NALBitReader br(sei->data() + 1, sei->size() - 1);
     // sei_message()
-    while (br.numBitsLeft() >= 16) { // at least 16-bit for sei_message()
+    while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
         uint32_t payload_type = 0;
         size_t payload_size = 0;
         uint8_t last_byte;
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 94800ba..2338b23 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -505,7 +505,10 @@
             TrackInfo *info = &mTracks.editItemAt(trackIndex);
             sp<AnotherPacketSource> source = info->mSource;
             if (source != NULL) {
-                source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
+                source->queueDiscontinuity(
+                        ATSParser::DISCONTINUITY_SEEK,
+                        NULL,
+                        true /* discard */);
             }
 
             break;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2a583d0..9c64d72 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -547,7 +547,7 @@
     }
 
     sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
+    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
 
     notify->setInt32("portIndex", portIndex);
 
@@ -3005,7 +3005,7 @@
 
 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
     sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatError);
+    notify->setInt32("what", CodecBase::kWhatError);
     notify->setInt32("omx-error", error);
     notify->setInt32("err", internalError);
     notify->post();
@@ -3398,7 +3398,7 @@
     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
 
     sp<AMessage> notify = mCodec->mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
+    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
     notify->setInt32("buffer-id", info->mBufferID);
 
     info->mData->meta()->clear();
@@ -3693,7 +3693,7 @@
             info->mData->meta()->setInt64("timeUs", timeUs);
 
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
+            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
             notify->setInt32("buffer-id", info->mBufferID);
             notify->setBuffer("buffer", info->mData);
             notify->setInt32("flags", flags);
@@ -3710,7 +3710,7 @@
                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
 
                 sp<AMessage> notify = mCodec->mNotify->dup();
-                notify->setInt32("what", ACodec::kWhatEOS);
+                notify->setInt32("what", CodecBase::kWhatEOS);
                 notify->setInt32("err", mCodec->mInputEOSResult);
                 notify->post();
 
@@ -3891,7 +3891,7 @@
                      "cannot keep component allocated on shutdown in Uninitialized state");
 
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
             notify->post();
 
             handled = true;
@@ -3901,7 +3901,7 @@
         case ACodec::kWhatFlush:
         {
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatFlushCompleted);
+            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
             notify->post();
 
             handled = true;
@@ -4023,7 +4023,7 @@
 
     {
         sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatComponentAllocated);
+        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
         notify->setString("componentName", mCodec->mComponentName.c_str());
         notify->post();
     }
@@ -4073,7 +4073,7 @@
 
     if (mCodec->mExplicitShutdown) {
         sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
         notify->post();
         mCodec->mExplicitShutdown = false;
     }
@@ -4120,7 +4120,7 @@
         case ACodec::kWhatFlush:
         {
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatFlushCompleted);
+            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
             notify->post();
 
             handled = true;
@@ -4169,7 +4169,7 @@
 
     {
         sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatComponentConfigured);
+        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
         notify->setMessage("input-format", mCodec->mInputFormat);
         notify->setMessage("output-format", mCodec->mOutputFormat);
         notify->post();
@@ -4183,7 +4183,7 @@
     ALOGV("onCreateInputSurface");
 
     sp<AMessage> notify = mCodec->mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
+    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
 
     sp<IGraphicBufferProducer> bufferProducer;
     status_t err;
@@ -4337,7 +4337,7 @@
         {
             // We haven't even started yet, so we're flushed alright...
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatFlushCompleted);
+            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
             notify->post();
             return true;
         }
@@ -4398,7 +4398,7 @@
         {
             // We haven't even started yet, so we're flushed alright...
             sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatFlushCompleted);
+            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
             notify->post();
 
             return true;
@@ -4701,7 +4701,7 @@
 
 void ACodec::onSignalEndOfInputStream() {
     sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
+    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
 
     status_t err = mOMX->signalEndOfInputStream(mNode);
     if (err != OK) {
@@ -5131,7 +5131,7 @@
         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
 
         sp<AMessage> notify = mCodec->mNotify->dup();
-        notify->setInt32("what", ACodec::kWhatFlushCompleted);
+        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
         notify->post();
 
         mCodec->mPortEOS[kPortIndexInput] =
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 11c5970..99c8e9f 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -15,6 +15,7 @@
         CameraSource.cpp                  \
         CameraSourceTimeLapse.cpp         \
         ClockEstimator.cpp                \
+        CodecBase.cpp                     \
         DataSource.cpp                    \
         DataURISource.cpp                 \
         DRMExtractor.cpp                  \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 63799e1..cd05c54 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2949,6 +2949,7 @@
 
     sp<IMediaHTTPService> savedHTTPService = mHTTPService;
 
+    bool wasLooping = mFlags & LOOPING;
     // Reset and recreate
     reset_l();
 
@@ -2967,6 +2968,9 @@
         // a MEDIA_ERROR to the client and abort the prepare
         mFlags |= PREPARE_CANCELLED;
     }
+    if (wasLooping) {
+        mFlags |= LOOPING;
+    }
 
     mAudioTearDown = true;
     mIsAsyncPrepare = true;
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
new file mode 100644
index 0000000..f729d4d
--- /dev/null
+++ b/media/libstagefright/CodecBase.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecBase"
+
+#include <inttypes.h>
+
+#include <media/stagefright/CodecBase.h>
+
+namespace android {
+
+CodecBase::CodecBase() {
+}
+
+CodecBase::~CodecBase() {
+}
+
+CodecBase::PortDescription::PortDescription() {
+}
+
+CodecBase::PortDescription::~PortDescription() {
+}
+
+}  // namespace android
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 14c8028..6e3d6f8 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -67,7 +67,7 @@
 MediaCodec::MediaCodec(const sp<ALooper> &looper)
     : mState(UNINITIALIZED),
       mLooper(looper),
-      mCodec(new ACodec),
+      mCodec(NULL),
       mReplyID(0),
       mFlags(0),
       mSoftRenderer(NULL),
@@ -103,6 +103,7 @@
     // quickly, violating the OpenMAX specs, until that is remedied
     // we need to invest in an extra looper to free the main event
     // queue.
+    mCodec = new ACodec;
     bool needDedicatedLooper = false;
     if (nameIsType && !strncasecmp(name, "video/", 6)) {
         needDedicatedLooper = true;
@@ -541,7 +542,7 @@
             CHECK(msg->findInt32("what", &what));
 
             switch (what) {
-                case ACodec::kWhatError:
+                case CodecBase::kWhatError:
                 {
                     int32_t omxError, internalError;
                     CHECK(msg->findInt32("omx-error", &omxError));
@@ -638,7 +639,7 @@
                     break;
                 }
 
-                case ACodec::kWhatComponentAllocated:
+                case CodecBase::kWhatComponentAllocated:
                 {
                     CHECK_EQ(mState, INITIALIZING);
                     setState(INITIALIZED);
@@ -661,7 +662,7 @@
                     break;
                 }
 
-                case ACodec::kWhatComponentConfigured:
+                case CodecBase::kWhatComponentConfigured:
                 {
                     CHECK_EQ(mState, CONFIGURING);
                     setState(CONFIGURED);
@@ -676,9 +677,9 @@
                     break;
                 }
 
-                case ACodec::kWhatInputSurfaceCreated:
+                case CodecBase::kWhatInputSurfaceCreated:
                 {
-                    // response to ACodec::kWhatCreateInputSurface
+                    // response to initiateCreateInputSurface()
                     status_t err = NO_ERROR;
                     sp<AMessage> response = new AMessage();
                     if (!msg->findInt32("err", &err)) {
@@ -694,9 +695,9 @@
                     break;
                 }
 
-                case ACodec::kWhatSignaledInputEOS:
+                case CodecBase::kWhatSignaledInputEOS:
                 {
-                    // response to ACodec::kWhatSignalEndOfInputStream
+                    // response to signalEndOfInputStream()
                     sp<AMessage> response = new AMessage();
                     status_t err;
                     if (msg->findInt32("err", &err)) {
@@ -707,7 +708,7 @@
                 }
 
 
-                case ACodec::kWhatBuffersAllocated:
+                case CodecBase::kWhatBuffersAllocated:
                 {
                     int32_t portIndex;
                     CHECK(msg->findInt32("portIndex", &portIndex));
@@ -725,8 +726,8 @@
                     sp<RefBase> obj;
                     CHECK(msg->findObject("portDesc", &obj));
 
-                    sp<ACodec::PortDescription> portDesc =
-                        static_cast<ACodec::PortDescription *>(obj.get());
+                    sp<CodecBase::PortDescription> portDesc =
+                        static_cast<CodecBase::PortDescription *>(obj.get());
 
                     size_t numBuffers = portDesc->countBuffers();
 
@@ -759,7 +760,7 @@
                     break;
                 }
 
-                case ACodec::kWhatOutputFormatChanged:
+                case CodecBase::kWhatOutputFormatChanged:
                 {
                     ALOGV("codec output format changed");
 
@@ -810,7 +811,7 @@
                     break;
                 }
 
-                case ACodec::kWhatFillThisBuffer:
+                case CodecBase::kWhatFillThisBuffer:
                 {
                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
 
@@ -857,7 +858,7 @@
                     break;
                 }
 
-                case ACodec::kWhatDrainThisBuffer:
+                case CodecBase::kWhatDrainThisBuffer:
                 {
                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
 
@@ -908,14 +909,14 @@
                     break;
                 }
 
-                case ACodec::kWhatEOS:
+                case CodecBase::kWhatEOS:
                 {
                     // We already notify the client of this by using the
                     // corresponding flag in "onOutputBufferReady".
                     break;
                 }
 
-                case ACodec::kWhatShutdownCompleted:
+                case CodecBase::kWhatShutdownCompleted:
                 {
                     if (mState == STOPPING) {
                         setState(INITIALIZED);
@@ -928,7 +929,7 @@
                     break;
                 }
 
-                case ACodec::kWhatFlushCompleted:
+                case CodecBase::kWhatFlushCompleted:
                 {
                     CHECK_EQ(mState, FLUSHING);
                     setState(STARTED);
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index e25709d..42c9956 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -721,7 +721,7 @@
             vin.uChan = vin.yChan + vin.height * vin.pitch;
             vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
 
-            unsigned long modTimeMs = 0;
+            ULong modTimeMs = 0;
             int32_t nLayer = 0;
             MP4HintTrack hintTrack;
             if (!PVEncodeVideoFrame(mHandle, &vin, &vout,
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index a54fd8b..9451479 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -29,7 +29,7 @@
 typedef unsigned short UShort;
 typedef short Short;
 typedef unsigned int Bool;
-typedef unsigned long ULong;
+typedef uint32_t ULong;
 
 #define PV_CODEC_INIT  0
 #define PV_CODEC_STOP  1
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
index 06e8926..9a967c2 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
@@ -363,7 +363,7 @@
     /* initialize offset to adjust pixel counter */
     /*    the next row; full-pel resolution      */
 
-    tmp = (ULong)prev & 0x3;
+    tmp = (uintptr_t)prev & 0x3;
 
     if (tmp == 0)  /* word-aligned */
     {
@@ -466,7 +466,7 @@
     /* Branch based on pixel location (half-pel or full-pel) for x and y */
     rec -= 12; /* preset */
 
-    tmp = (ULong)prev & 3;
+    tmp = (uintptr_t)prev & 3;
     mask = 254;
     mask |= (mask << 8);
     mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -791,7 +791,7 @@
     /* Branch based on pixel location (half-pel or full-pel) for x and y */
     rec -= 12; /* preset */
 
-    tmp = (ULong)prev & 3;
+    tmp = (uintptr_t)prev & 3;
     mask = 254;
     mask |= (mask << 8);
     mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -1140,7 +1140,7 @@
     mask |= (mask << 8);
     mask |= (mask << 16); /* 0x3f3f3f3f */
 
-    tmp = (ULong)prev & 3;
+    tmp = (uintptr_t)prev & 3;
 
     rec -= 4; /* preset */
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
index 0d5a3e8..2d44482 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
@@ -60,7 +60,7 @@
 typedef short Short;
 typedef short int SInt;
 typedef unsigned int Bool;
-typedef unsigned long   ULong;
+typedef uint32_t ULong;
 typedef void Void;
 
 #define PV_CODEC_INIT       0
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 5499c32..beb5cc0 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -27,6 +27,9 @@
       mNumBitsLeft(0) {
 }
 
+ABitReader::~ABitReader() {
+}
+
 void ABitReader::fillReservoir() {
     CHECK_GT(mSize, 0u);
 
@@ -99,4 +102,69 @@
     return mData - (mNumBitsLeft + 7) / 8;
 }
 
+NALBitReader::NALBitReader(const uint8_t *data, size_t size)
+    : ABitReader(data, size),
+      mNumZeros(0) {
+}
+
+bool NALBitReader::atLeastNumBitsLeft(size_t n) const {
+    // check against raw size and reservoir bits first
+    size_t numBits = numBitsLeft();
+    if (n > numBits) {
+        return false;
+    }
+
+    ssize_t numBitsRemaining = n - mNumBitsLeft;
+
+    size_t size = mSize;
+    const uint8_t *data = mData;
+    int32_t numZeros = mNumZeros;
+    while (size > 0 && numBitsRemaining > 0) {
+        bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3);
+
+        if (*data == 0) {
+            ++numZeros;
+        } else {
+            numZeros = 0;
+        }
+
+        if (!isEmulationPreventionByte) {
+            numBitsRemaining -= 8;
+        }
+
+        ++data;
+        --size;
+    }
+
+    return (numBitsRemaining <= 0);
+}
+
+void NALBitReader::fillReservoir() {
+    CHECK_GT(mSize, 0u);
+
+    mReservoir = 0;
+    size_t i = 0;
+    while (mSize > 0 && i < 4) {
+        bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3);
+
+        if (*mData == 0) {
+            ++mNumZeros;
+        } else {
+            mNumZeros = 0;
+        }
+
+        // skip emulation_prevention_three_byte
+        if (!isEmulationPreventionByte) {
+            mReservoir = (mReservoir << 8) | *mData;
+            ++i;
+        }
+
+        ++mData;
+        --mSize;
+    }
+
+    mNumBitsLeft = 8 * i;
+    mReservoir <<= 32 - mNumBitsLeft;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp b/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
index f7a00d8..5f7c70d 100644
--- a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
+++ b/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
@@ -51,7 +51,7 @@
 AHierarchicalStateMachine::~AHierarchicalStateMachine() {
 }
 
-void AHierarchicalStateMachine::onMessageReceived(const sp<AMessage> &msg) {
+void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
     sp<AState> save = mState;
 
     sp<AState> cur = mState;
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index f2d501e..894f65c 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -328,6 +328,20 @@
     return !strcmp(mData + mSize - suffixLen, suffix);
 }
 
+bool AString::startsWithIgnoreCase(const char *prefix) const {
+    return !strncasecmp(mData, prefix, strlen(prefix));
+}
+
+bool AString::endsWithIgnoreCase(const char *suffix) const {
+    size_t suffixLen = strlen(suffix);
+
+    if (mSize < suffixLen) {
+        return false;
+    }
+
+    return !strcasecmp(mData + mSize - suffixLen, suffix);
+}
+
 AString StringPrintf(const char *format, ...) {
     va_list ap;
     va_start(ap, format);
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 2af0998..10437c9 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -588,7 +588,10 @@
 void PlaylistFetcher::queueDiscontinuity(
         ATSParser::DiscontinuityType type, const sp<AMessage> &extra) {
     for (size_t i = 0; i < mPacketSources.size(); ++i) {
-        mPacketSources.valueAt(i)->queueDiscontinuity(type, extra);
+        // do not discard buffer upon #EXT-X-DISCONTINUITY tag
+        // (seek will discard buffer by abandoning old fetchers)
+        mPacketSources.valueAt(i)->queueDiscontinuity(
+                type, extra, false /* discard */);
     }
 }
 
@@ -723,8 +726,7 @@
         firstSeqNumberInPlaylist = 0;
     }
 
-    bool seekDiscontinuity = false;
-    bool explicitDiscontinuity = false;
+    bool discontinuity = false;
 
     const int32_t lastSeqNumberInPlaylist =
         firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
@@ -792,7 +794,7 @@
             if (mSeqNumber < firstSeqNumberInPlaylist) {
                 mSeqNumber = firstSeqNumberInPlaylist;
             }
-            explicitDiscontinuity = true;
+            discontinuity = true;
 
             // fall through
         } else {
@@ -817,7 +819,7 @@
 
     int32_t val;
     if (itemMeta->findInt32("discontinuity", &val) && val != 0) {
-        explicitDiscontinuity = true;
+        discontinuity = true;
     }
 
     int64_t range_offset, range_length;
@@ -877,7 +879,7 @@
             return;
         }
 
-        if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
+        if (mStartup || discontinuity) {
             // Signal discontinuity.
 
             if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
@@ -887,18 +889,14 @@
                 mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
             }
 
-            if (seekDiscontinuity || explicitDiscontinuity) {
-                ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
-                     seekDiscontinuity, explicitDiscontinuity);
+            if (discontinuity) {
+                ALOGI("queueing discontinuity (explicit=%d)", discontinuity);
 
                 queueDiscontinuity(
-                        explicitDiscontinuity
-                            ? ATSParser::DISCONTINUITY_FORMATCHANGE
-                            : ATSParser::DISCONTINUITY_SEEK,
+                        ATSParser::DISCONTINUITY_FORMATCHANGE,
                         NULL /* extra */);
 
-                seekDiscontinuity = false;
-                explicitDiscontinuity = false;
+                discontinuity = false;
             }
         }
 
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 338e899..3d241e0 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -669,7 +669,7 @@
     }
 
     if (mSource != NULL) {
-        mSource->queueDiscontinuity(type, extra);
+        mSource->queueDiscontinuity(type, extra, true);
     }
 }
 
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 021b640..871824a 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -217,22 +217,25 @@
 
 void AnotherPacketSource::queueDiscontinuity(
         ATSParser::DiscontinuityType type,
-        const sp<AMessage> &extra) {
+        const sp<AMessage> &extra,
+        bool discard) {
     Mutex::Autolock autoLock(mLock);
 
-    // Leave only discontinuities in the queue.
-    List<sp<ABuffer> >::iterator it = mBuffers.begin();
-    while (it != mBuffers.end()) {
-        sp<ABuffer> oldBuffer = *it;
+    if (discard) {
+        // Leave only discontinuities in the queue.
+        List<sp<ABuffer> >::iterator it = mBuffers.begin();
+        while (it != mBuffers.end()) {
+            sp<ABuffer> oldBuffer = *it;
 
-        int32_t oldDiscontinuityType;
-        if (!oldBuffer->meta()->findInt32(
-                    "discontinuity", &oldDiscontinuityType)) {
-            it = mBuffers.erase(it);
-            continue;
+            int32_t oldDiscontinuityType;
+            if (!oldBuffer->meta()->findInt32(
+                        "discontinuity", &oldDiscontinuityType)) {
+                it = mBuffers.erase(it);
+                continue;
+            }
+
+            ++it;
         }
-
-        ++it;
     }
 
     mEOSResult = OK;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 9b193a2..06c49bd 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -54,7 +54,9 @@
     void queueAccessUnit(const sp<ABuffer> &buffer);
 
     void queueDiscontinuity(
-            ATSParser::DiscontinuityType type, const sp<AMessage> &extra);
+            ATSParser::DiscontinuityType type,
+            const sp<AMessage> &extra,
+            bool discard);
 
     void signalEOS(status_t result);
 
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index af312c4..4dbbc43 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -763,21 +763,9 @@
                     quality = AudioResampler::DEFAULT_QUALITY;
                 }
 
-                int bits;
-                switch (mMixerInFormat) {
-                case AUDIO_FORMAT_PCM_16_BIT:
-                    bits = 16;
-                    break;
-                case AUDIO_FORMAT_PCM_FLOAT:
-                    bits = 32; // 32 bits to the AudioResampler::create() indicates float.
-                    break;
-                default:
-                    LOG_ALWAYS_FATAL("Invalid mMixerInFormat: %#x", mMixerInFormat);
-                    break;
-                }
                 ALOGVV("Creating resampler with %d bits\n", bits);
                 resampler = AudioResampler::create(
-                        bits,
+                        mMixerInFormat,
                         // the resampler sees the number of channels after the downmixer, if any
                         (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
                         devSampleRate, quality);
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index b8a0357..38c9061 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -40,8 +40,8 @@
 
 class AudioResamplerOrder1 : public AudioResampler {
 public:
-    AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
-        AudioResampler(bitDepth, inChannelCount, sampleRate, LOW_QUALITY), mX0L(0), mX0R(0) {
+    AudioResamplerOrder1(int inChannelCount, int32_t sampleRate) :
+        AudioResampler(inChannelCount, sampleRate, LOW_QUALITY), mX0L(0), mX0R(0) {
     }
     virtual void resample(int32_t* out, size_t outFrameCount,
             AudioBufferProvider* provider);
@@ -145,7 +145,7 @@
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static uint32_t currentMHz = 0;
 
-AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
+AudioResampler* AudioResampler::create(audio_format_t format, int inChannelCount,
         int32_t sampleRate, src_quality quality) {
 
     bool atFinalQuality;
@@ -216,33 +216,40 @@
     default:
     case LOW_QUALITY:
         ALOGV("Create linear Resampler");
-        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+        LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+        resampler = new AudioResamplerOrder1(inChannelCount, sampleRate);
         break;
     case MED_QUALITY:
         ALOGV("Create cubic Resampler");
-        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+        LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+        resampler = new AudioResamplerCubic(inChannelCount, sampleRate);
         break;
     case HIGH_QUALITY:
         ALOGV("Create HIGH_QUALITY sinc Resampler");
-        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+        LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+        resampler = new AudioResamplerSinc(inChannelCount, sampleRate);
         break;
     case VERY_HIGH_QUALITY:
         ALOGV("Create VERY_HIGH_QUALITY sinc Resampler = %d", quality);
-        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate, quality);
+        LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+        resampler = new AudioResamplerSinc(inChannelCount, sampleRate, quality);
         break;
     case DYN_LOW_QUALITY:
     case DYN_MED_QUALITY:
     case DYN_HIGH_QUALITY:
         ALOGV("Create dynamic Resampler = %d", quality);
-        if (bitDepth == 32) { /* bitDepth == 32 signals float precision */
-            resampler = new AudioResamplerDyn<float, float, float>(bitDepth, inChannelCount,
-                    sampleRate, quality);
-        } else if (quality == DYN_HIGH_QUALITY) {
-            resampler = new AudioResamplerDyn<int32_t, int16_t, int32_t>(bitDepth, inChannelCount,
+        if (format == AUDIO_FORMAT_PCM_FLOAT) {
+            resampler = new AudioResamplerDyn<float, float, float>(inChannelCount,
                     sampleRate, quality);
         } else {
-            resampler = new AudioResamplerDyn<int16_t, int16_t, int32_t>(bitDepth, inChannelCount,
-                    sampleRate, quality);
+            LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+            if (quality == DYN_HIGH_QUALITY) {
+                resampler = new AudioResamplerDyn<int32_t, int16_t, int32_t>(inChannelCount,
+                        sampleRate, quality);
+            } else {
+                resampler = new AudioResamplerDyn<int16_t, int16_t, int32_t>(inChannelCount,
+                        sampleRate, quality);
+            }
         }
         break;
     }
@@ -252,18 +259,17 @@
     return resampler;
 }
 
-AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
+AudioResampler::AudioResampler(int inChannelCount,
         int32_t sampleRate, src_quality quality) :
-    mBitDepth(bitDepth), mChannelCount(inChannelCount),
-            mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
-            mPhaseFraction(0), mLocalTimeFreq(0),
-            mPTS(AudioBufferProvider::kInvalidPTS), mQuality(quality) {
-    // sanity check on format
-    if ((bitDepth != 16 && (quality < DYN_LOW_QUALITY || bitDepth != 32))
-            || inChannelCount < 1
+        mChannelCount(inChannelCount),
+        mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
+        mPhaseFraction(0), mLocalTimeFreq(0),
+        mPTS(AudioBufferProvider::kInvalidPTS), mQuality(quality) {
+
+    if (inChannelCount < 1
             || inChannelCount > (quality < DYN_LOW_QUALITY ? 2 : 8)) {
-        LOG_ALWAYS_FATAL("Unsupported sample format %d quality %d bits, %d channels",
-                quality, bitDepth, inChannelCount);
+        LOG_ALWAYS_FATAL("Unsupported sample format %d quality %d channels",
+                quality, inChannelCount);
     }
     if (sampleRate <= 0) {
         LOG_ALWAYS_FATAL("Unsupported sample rate %d Hz", sampleRate);
@@ -272,7 +278,6 @@
     // initialize common members
     mVolume[0] = mVolume[1] = 0;
     mBuffer.frameCount = 0;
-
 }
 
 AudioResampler::~AudioResampler() {
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index b84567e..be747f6 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -22,6 +22,7 @@
 #include <cutils/compiler.h>
 
 #include <media/AudioBufferProvider.h>
+#include <system/audio.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -46,7 +47,7 @@
         DYN_HIGH_QUALITY=7,
     };
 
-    static AudioResampler* create(int bitDepth, int inChannelCount,
+    static AudioResampler* create(audio_format_t format, int inChannelCount,
             int32_t sampleRate, src_quality quality=DEFAULT_QUALITY);
 
     virtual ~AudioResampler();
@@ -86,7 +87,7 @@
     // multiplier to calculate fixed point phase increment
     static const double kPhaseMultiplier;
 
-    AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate, src_quality quality);
+    AudioResampler(int inChannelCount, int32_t sampleRate, src_quality quality);
 
     // prevent copying
     AudioResampler(const AudioResampler&);
@@ -94,7 +95,6 @@
 
     int64_t calculateOutputPTS(int outputFrameIndex);
 
-    const int32_t mBitDepth;
     const int32_t mChannelCount;
     const int32_t mSampleRate;
     int32_t mInSampleRate;
diff --git a/services/audioflinger/AudioResamplerCubic.h b/services/audioflinger/AudioResamplerCubic.h
index 203b933..b315da5 100644
--- a/services/audioflinger/AudioResamplerCubic.h
+++ b/services/audioflinger/AudioResamplerCubic.h
@@ -28,8 +28,8 @@
 
 class AudioResamplerCubic : public AudioResampler {
 public:
-    AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
-        AudioResampler(bitDepth, inChannelCount, sampleRate, MED_QUALITY) {
+    AudioResamplerCubic(int inChannelCount, int32_t sampleRate) :
+        AudioResampler(inChannelCount, sampleRate, MED_QUALITY) {
     }
     virtual void resample(int32_t* out, size_t outFrameCount,
             AudioBufferProvider* provider);
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index 7ca10c1..043c803 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -162,9 +162,9 @@
 }
 
 template<typename TC, typename TI, typename TO>
-AudioResamplerDyn<TC, TI, TO>::AudioResamplerDyn(int bitDepth,
+AudioResamplerDyn<TC, TI, TO>::AudioResamplerDyn(
         int inChannelCount, int32_t sampleRate, src_quality quality)
-    : AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
+    : AudioResampler(inChannelCount, sampleRate, quality),
       mResampleFunc(0), mFilterSampleRate(0), mFilterQuality(DEFAULT_QUALITY),
     mCoefBuffer(NULL)
 {
diff --git a/services/audioflinger/AudioResamplerDyn.h b/services/audioflinger/AudioResamplerDyn.h
index 3dced8a..3044bfb 100644
--- a/services/audioflinger/AudioResamplerDyn.h
+++ b/services/audioflinger/AudioResamplerDyn.h
@@ -41,7 +41,7 @@
 template<typename TC, typename TI, typename TO>
 class AudioResamplerDyn: public AudioResampler {
 public:
-    AudioResamplerDyn(int bitDepth, int inChannelCount,
+    AudioResamplerDyn(int inChannelCount,
             int32_t sampleRate, src_quality quality);
 
     virtual ~AudioResamplerDyn();
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 35553ef..60ff88e 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -452,9 +452,9 @@
 
 // ----------------------------------------------------------------------------
 
-AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
+AudioResamplerSinc::AudioResamplerSinc(
         int inChannelCount, int32_t sampleRate, src_quality quality)
-    : AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
+    : AudioResampler(inChannelCount, sampleRate, quality),
     mState(0), mImpulse(0), mRingFull(0), mFirCoefs(0)
 {
     /*
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 1ea4474..97ae3d0 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -34,7 +34,7 @@
 
 class AudioResamplerSinc : public AudioResampler {
 public:
-    AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate,
+    AudioResamplerSinc(int inChannelCount, int32_t sampleRate,
             src_quality quality = HIGH_QUALITY);
 
     virtual ~AudioResamplerSinc();
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 4fbb973..0ef9fe5 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1895,7 +1895,8 @@
     if (thread->mSampleRate != sampleRate && thread->mChannelCount <= FCC_2 &&
             channelCount <= FCC_2) {
         // sink SR
-        mResampler = AudioResampler::create(16, thread->mChannelCount, sampleRate);
+        mResampler = AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT,
+                thread->mChannelCount, sampleRate);
         // source SR
         mResampler->setSampleRate(thread->mSampleRate);
         mResampler->setVolume(AudioMixer::UNITY_GAIN_INT, AudioMixer::UNITY_GAIN_INT);
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
index e14b4ae..78c9927 100644
--- a/services/audioflinger/test-resample.cpp
+++ b/services/audioflinger/test-resample.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include "AudioResampler.h"
-#include <media/AudioBufferProvider.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,6 +28,8 @@
 #include <audio_utils/primitives.h>
 #include <audio_utils/sndfile.h>
 #include <utils/Vector.h>
+#include <media/AudioBufferProvider.h>
+#include "AudioResampler.h"
 
 using namespace android;
 
@@ -329,7 +329,7 @@
         printf("%zu input frames\n", input_frames);
     }
 
-    int bit_depth = useFloat ? 32 : 16;
+    audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
     int output_channels = channels > 2 ? channels : 2; // output is at least stereo samples
     size_t output_framesize = output_channels * (useFloat ? sizeof(float) : sizeof(int32_t));
     size_t output_frames = ((int64_t) input_frames * output_freq) / input_freq;
@@ -342,7 +342,7 @@
         //
         // On fast devices, filters should be generated between 0.1ms - 1ms.
         // (single threaded).
-        AudioResampler* resampler = AudioResampler::create(bit_depth, channels,
+        AudioResampler* resampler = AudioResampler::create(format, channels,
                 8000, quality);
         int looplimit = 100;
         timespec start, end;
@@ -380,7 +380,7 @@
     }
 
     void* output_vaddr = malloc(output_size);
-    AudioResampler* resampler = AudioResampler::create(bit_depth, channels,
+    AudioResampler* resampler = AudioResampler::create(format, channels,
             output_freq, quality);
 
 
diff --git a/services/audioflinger/tests/resampler_tests.cpp b/services/audioflinger/tests/resampler_tests.cpp
index d76c376..987162c 100644
--- a/services/audioflinger/tests/resampler_tests.cpp
+++ b/services/audioflinger/tests/resampler_tests.cpp
@@ -69,7 +69,7 @@
         unsigned inputFreq, unsigned outputFreq,
         enum android::AudioResampler::src_quality quality)
 {
-    const int bits = useFloat ? 32 : 16;
+    const audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
     // create the provider
     std::vector<int> inputIncr;
     SignalProvider provider;
@@ -92,7 +92,7 @@
     const int volumePrecision = 12; /* typical unity gain */
     android::AudioResampler* resampler;
 
-    resampler = android::AudioResampler::create(bits, channels, outputFreq, quality);
+    resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
     resampler->setSampleRate(inputFreq);
     resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
 
@@ -109,7 +109,7 @@
     resampler->reset();
 #else
     delete resampler;
-    resampler = android::AudioResampler::create(bits, channels, outputFreq, quality);
+    resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
     resampler->setSampleRate(inputFreq);
     resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
 #endif
@@ -174,7 +174,8 @@
     const int volumePrecision = 12; /* typical unity gain */
     android::AudioResampler* resampler;
 
-    resampler = android::AudioResampler::create(16, channels, outputFreq, quality);
+    resampler = android::AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT,
+            channels, outputFreq, quality);
     resampler->setSampleRate(inputFreq);
     resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
 
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 95179b7..bb3bce8 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -101,6 +101,7 @@
     STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
 };
 
 const StringToEnum sFlagNameToEnumTable[] = {
@@ -4104,7 +4105,7 @@
 
 const AudioPolicyManager::VolumeCurvePoint
     AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -56.0f}, {20, -34.0f}, {86, -10.0f}, {100, 0.0f}
+    {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
 };
 
 const AudioPolicyManager::VolumeCurvePoint
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 99abced..911f55a 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -89,8 +89,26 @@
 
     Mutex::Autolock m(mMutex);
     if (mPreviewRequest.entryCount() == 0) {
-        res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                &mPreviewRequest);
+        sp<Camera2Client> client = mClient.promote();
+        if (client == 0) {
+            ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
+            return INVALID_OPERATION;
+        }
+
+        // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
+        if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
+            if (params.zslMode && !params.recordingHint) {
+                res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
+                        &mPreviewRequest);
+            } else {
+                res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
+                        &mPreviewRequest);
+            }
+        } else {
+            res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
+                    &mPreviewRequest);
+        }
+
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to create default preview request: "
                     "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index ae537e2..79f75a5 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -290,18 +290,45 @@
         uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
         res = request.update(ANDROID_REQUEST_TYPE,
                 &requestType, 1);
+        if (res != OK) {
+            ALOGE("%s: Unable to update request type",
+                  __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
         int32_t inputStreams[1] =
                 { mZslStreamId };
-        if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
+        res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
                 inputStreams, 1);
+        if (res != OK) {
+            ALOGE("%s: Unable to update request input streams",
+                  __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
+        uint8_t captureIntent =
+                static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+        res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
+                &captureIntent, 1);
+        if (res != OK ) {
+            ALOGE("%s: Unable to update request capture intent",
+                  __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
         // TODO: Shouldn't we also update the latest preview frame?
         int32_t outputStreams[1] =
                 { client->getCaptureStreamId() };
-        if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
+        res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
                 outputStreams, 1);
+        if (res != OK) {
+            ALOGE("%s: Unable to update request output streams",
+                  __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
         res = request.update(ANDROID_REQUEST_ID,
                 &requestId, 1);
-
         if (res != OK ) {
             ALOGE("%s: Unable to update frame to a reprocess request",
                   __FUNCTION__);
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 7597b10..c7bd886 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -26,6 +26,7 @@
 
 #include <camera/camera2/ICameraDeviceCallbacks.h>
 #include "hardware/camera2.h"
+#include "hardware/camera3.h"
 #include "camera/CameraMetadata.h"
 #include "camera/CaptureResult.h"
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index bbb1e1c..6ceb9d4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1929,11 +1929,11 @@
                 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
                       "  its stream:%s (%d)",  __FUNCTION__,
                       frameNumber, strerror(-res), res);
-           } else {
-               ALOGW("%s: Input buffer should be NULL if there is no input"
-                       " buffer sent in the request",
-                       __FUNCTION__);
-           }
+            }
+        } else {
+            ALOGW("%s: Input buffer should be NULL if there is no input"
+                    " buffer sent in the request, skipping input buffer return.",
+                    __FUNCTION__);
         }
     }
 
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index fa59388..747af79 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -377,7 +377,7 @@
 }
 
 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
-                                  const sp<IMemory>& dataMemory)
+                                 const sp<IMemory>& dataMemory)
 {
     ALOGV("startRecognition() model handle %d", handle);
 
@@ -391,28 +391,25 @@
     if (model == 0) {
         return BAD_VALUE;
     }
+    if ((dataMemory == 0) ||
+            (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
+        return BAD_VALUE;
+    }
 
     if (model->mState == Model::STATE_ACTIVE) {
         return INVALID_OPERATION;
     }
     model->mState = Model::STATE_ACTIVE;
 
-    char *data = NULL;
-    unsigned int data_size = 0;
-    if (dataMemory != 0 && dataMemory->size() != 0) {
-        data_size = (unsigned int)dataMemory->size();
-        data = (char *)dataMemory->pointer();
-        ALOGV("startRecognition() data size %d data %d - %d",
-                      data_size, data[0], data[data_size - 1]);
-    }
+    struct sound_trigger_recognition_config *config =
+            (struct sound_trigger_recognition_config *)dataMemory->pointer();
 
     //TODO: get capture handle and device from audio policy service
-    audio_io_handle_t capture_handle = 0;
-    return mHwDevice->start_recognition(mHwDevice, handle, capture_handle, AUDIO_DEVICE_NONE,
+    config->capture_handle = AUDIO_IO_HANDLE_NONE;
+    config->capture_device = AUDIO_DEVICE_NONE;
+    return mHwDevice->start_recognition(mHwDevice, handle, config,
                                         SoundTriggerHwService::recognitionCallback,
-                                        this,
-                                        data_size,
-                                        data);
+                                        this);
 }
 
 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)