Merge "Camera: Use physical camera's capability for physical stream check"
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index e3da259..a721b65 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -18,6 +18,8 @@
 #define LOG_TAG "FLACExtractor"
 #include <utils/Log.h>
 
+#include <stdint.h>
+
 #include "FLACExtractor.h"
 // libFLAC parser
 #include "FLAC/stream_decoder.h"
@@ -124,7 +126,7 @@
     // media buffers
     size_t mMaxBufferSize;
     MediaBufferGroup *mGroup;
-    void (*mCopy)(short *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
+    void (*mCopy)(int16_t *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
 
     // handle to underlying libFLAC parser
     FLAC__StreamDecoder *mDecoder;
@@ -383,7 +385,7 @@
 // These are candidates for optimization if needed.
 
 static void copyMono8(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -393,7 +395,7 @@
 }
 
 static void copyStereo8(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -403,7 +405,7 @@
     }
 }
 
-static void copyMultiCh8(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
+static void copyMultiCh8(int16_t *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
 {
     for (unsigned i = 0; i < nSamples; ++i) {
         for (unsigned c = 0; c < nChannels; ++c) {
@@ -413,7 +415,7 @@
 }
 
 static void copyMono16(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -423,7 +425,7 @@
 }
 
 static void copyStereo16(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -433,7 +435,7 @@
     }
 }
 
-static void copyMultiCh16(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
+static void copyMultiCh16(int16_t *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
 {
     for (unsigned i = 0; i < nSamples; ++i) {
         for (unsigned c = 0; c < nChannels; ++c) {
@@ -445,7 +447,7 @@
 // 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
 
 static void copyMono24(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -455,7 +457,7 @@
 }
 
 static void copyStereo24(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACParser::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -465,7 +467,7 @@
     }
 }
 
-static void copyMultiCh24(short *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
+static void copyMultiCh24(int16_t *dst, const int * src[FLACParser::kMaxChannels], unsigned nSamples, unsigned nChannels)
 {
     for (unsigned i = 0; i < nSamples; ++i) {
         for (unsigned c = 0; c < nChannels; ++c) {
@@ -475,7 +477,7 @@
 }
 
 static void copyTrespass(
-        short * /* dst */,
+        int16_t * /* dst */,
         const int *[FLACParser::kMaxChannels] /* src */,
         unsigned /* nSamples */,
         unsigned /* nChannels */) {
@@ -592,7 +594,7 @@
         static const struct {
             unsigned mChannels;
             unsigned mBitsPerSample;
-            void (*mCopy)(short *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
+            void (*mCopy)(int16_t *dst, const int * src[kMaxChannels], unsigned nSamples, unsigned nChannels);
         } table[] = {
             { 1,  8, copyMono8    },
             { 2,  8, copyStereo8  },
@@ -635,7 +637,7 @@
 {
     CHECK(mGroup == NULL);
     mGroup = new MediaBufferGroup;
-    mMaxBufferSize = getMaxBlockSize() * getChannels() * sizeof(short);
+    mMaxBufferSize = getMaxBlockSize() * getChannels() * sizeof(int16_t);
     mGroup->add_buffer(MediaBufferBase::Create(mMaxBufferSize));
 }
 
@@ -688,9 +690,9 @@
     if (err != OK) {
         return NULL;
     }
-    size_t bufferSize = blocksize * getChannels() * sizeof(short);
+    size_t bufferSize = blocksize * getChannels() * sizeof(int16_t);
     CHECK(bufferSize <= mMaxBufferSize);
-    short *data = (short *) buffer->data();
+    int16_t *data = (int16_t *) buffer->data();
     buffer->set_range(0, bufferSize);
     // copy PCM from FLAC write buffer to our media buffer, with interleaving
     (*mCopy)(data, mWriteBuffer, blocksize, getChannels());
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 7b3b81d..5331ba8 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -66,6 +66,8 @@
     kMaxAtomSize = 64 * 1024 * 1024,
 };
 
+static const size_t  kMaxPcmFrameSize = 8192;
+
 class MPEG4Source : public MediaTrack {
 public:
     // Caller retains ownership of both "dataSource" and "sampleTable".
@@ -125,6 +127,7 @@
 
     bool mIsAVC;
     bool mIsHEVC;
+    bool mIsPcm;
     size_t mNALLengthSize;
 
     bool mStarted;
@@ -324,6 +327,11 @@
         case FOURCC('h', 'v', 'c', '1'):
         case FOURCC('h', 'e', 'v', '1'):
             return MEDIA_MIMETYPE_VIDEO_HEVC;
+
+        case FOURCC('t', 'w', 'o', 's'):
+        case FOURCC('s', 'o', 'w', 't'):
+            return MEDIA_MIMETYPE_AUDIO_RAW;
+
         default:
             ALOGW("Unknown fourcc: %c%c%c%c",
                    (fourcc >> 24) & 0xff,
@@ -467,8 +475,15 @@
             if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
                     __builtin_add_overflow(delay, halfscale, &delay) ||
                     (delay /= mHeaderTimescale, false) ||
-                    delay > INT32_MAX ||
-                    delay < INT32_MIN) {
+                    /* the calculated delay should be small, but some apps
+                     * appear to write a bogus edit list that causes a really
+                     * large delay, resulting in playback problems.
+                     * Ignore such edit lists.
+                     * (4096 is enough to drop 4 full samples)
+                     */
+                    delay > 4096 ||
+                    delay < 0) {
+                ALOGW("ignoring edit list with bogus values");
                 return;
             }
             ALOGV("delay = %" PRId64, delay);
@@ -1473,6 +1488,8 @@
         case FOURCC('e', 'n', 'c', 'a'):
         case FOURCC('s', 'a', 'm', 'r'):
         case FOURCC('s', 'a', 'w', 'b'):
+        case FOURCC('t', 'w', 'o', 's'):
+        case FOURCC('s', 'o', 'w', 't'):
         {
             if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
                     && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
@@ -1542,6 +1559,13 @@
                 // if the chunk type is enca, we'll get the type from the frma box later
                 mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
                 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
+
+                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, FourCC2MIME(chunk_type))) {
+                    mLastTrack->meta.setInt32(kKeyBitsPerSample, sample_size);
+                    if (chunk_type == FOURCC('t', 'w', 'o', 's')) {
+                        mLastTrack->meta.setInt32(kKeyPcmBigEndian, 1);
+                    }
+                }
             }
             ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                    chunk, num_channels, sample_size, sample_rate);
@@ -3857,6 +3881,7 @@
       mCurrentSampleInfoOffsets(NULL),
       mIsAVC(false),
       mIsHEVC(false),
+      mIsPcm(false),
       mNALLengthSize(0),
       mStarted(false),
       mGroup(NULL),
@@ -3918,6 +3943,27 @@
         mNALLengthSize = 1 + (ptr[14 + 7] & 3);
     }
 
+    mIsPcm = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW);
+
+    if (mIsPcm) {
+        int32_t numChannels = 0;
+        int32_t bitsPerSample = 0;
+        CHECK(mFormat.findInt32(kKeyBitsPerSample, &bitsPerSample));
+        CHECK(mFormat.findInt32(kKeyChannelCount, &numChannels));
+
+        int32_t bytesPerSample = bitsPerSample >> 3;
+        int32_t pcmSampleSize = bytesPerSample * numChannels;
+
+        size_t maxSampleSize;
+        status_t err = mSampleTable->getMaxSampleSize(&maxSampleSize);
+        if (err != OK || maxSampleSize != static_cast<size_t>(pcmSampleSize) || bitsPerSample != 16) {
+            // Not supported
+            mIsPcm = false;
+        } else {
+            mFormat.setInt32(kKeyMaxInputSize, pcmSampleSize * kMaxPcmFrameSize);
+        }
+    }
+
     CHECK(format.findInt32(kKeyTrackID, &mTrackId));
 
 }
@@ -4832,34 +4878,78 @@
 
     if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
         if (newBuffer) {
-            ssize_t num_bytes_read =
-                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
+            if (mIsPcm) {
+                // The twos' PCM block reader assumes that all samples has the same size.
 
-            if (num_bytes_read < (ssize_t)size) {
-                mBuffer->release();
-                mBuffer = NULL;
+                uint32_t samplesToRead = mSampleTable->getLastSampleIndexInChunk()
+                                                      - mCurrentSampleIndex + 1;
+                if (samplesToRead > kMaxPcmFrameSize) {
+                    samplesToRead = kMaxPcmFrameSize;
+                }
 
-                return ERROR_IO;
-            }
+                ALOGV("Reading %d PCM frames of size %zu at index %d to stop of chunk at %d",
+                      samplesToRead, size, mCurrentSampleIndex,
+                      mSampleTable->getLastSampleIndexInChunk());
 
-            CHECK(mBuffer != NULL);
-            mBuffer->set_range(0, size);
-            mBuffer->meta_data().clear();
-            mBuffer->meta_data().setInt64(
-                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
-            mBuffer->meta_data().setInt64(
-                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+                size_t totalSize = samplesToRead * size;
+                uint8_t* buf = (uint8_t *)mBuffer->data();
+                ssize_t bytesRead = mDataSource->readAt(offset, buf, totalSize);
+                if (bytesRead < (ssize_t)totalSize) {
+                    mBuffer->release();
+                    mBuffer = NULL;
 
-            if (targetSampleTimeUs >= 0) {
-                mBuffer->meta_data().setInt64(
-                        kKeyTargetTime, targetSampleTimeUs);
-            }
+                    return ERROR_IO;
+                }
 
-            if (isSyncSample) {
+                mBuffer->meta_data().clear();
+                mBuffer->meta_data().setInt64(kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
                 mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
-            }
 
-            ++mCurrentSampleIndex;
+                int32_t byteOrder;
+                mFormat.findInt32(kKeyPcmBigEndian, &byteOrder);
+
+                if (byteOrder == 1) {
+                    // Big-endian -> little-endian
+                    uint16_t *dstData = (uint16_t *)buf;
+                    uint16_t *srcData = (uint16_t *)buf;
+
+                    for (size_t j = 0; j < bytesRead / sizeof(uint16_t); j++) {
+                         dstData[j] = ntohs(srcData[j]);
+                    }
+                }
+
+                mCurrentSampleIndex += samplesToRead;
+                mBuffer->set_range(0, totalSize);
+            } else {
+                ssize_t num_bytes_read =
+                    mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
+
+                if (num_bytes_read < (ssize_t)size) {
+                    mBuffer->release();
+                    mBuffer = NULL;
+
+                    return ERROR_IO;
+                }
+
+                CHECK(mBuffer != NULL);
+                mBuffer->set_range(0, size);
+                mBuffer->meta_data().clear();
+                mBuffer->meta_data().setInt64(
+                        kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+                mBuffer->meta_data().setInt64(
+                        kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+
+                if (targetSampleTimeUs >= 0) {
+                    mBuffer->meta_data().setInt64(
+                            kKeyTargetTime, targetSampleTimeUs);
+                }
+
+                if (isSyncSample) {
+                    mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+                }
+
+                ++mCurrentSampleIndex;
+            }
         }
 
         if (!mIsAVC && !mIsHEVC) {
diff --git a/media/extractors/mp4/SampleIterator.h b/media/extractors/mp4/SampleIterator.h
index 6a3fd3b..6e4f60e 100644
--- a/media/extractors/mp4/SampleIterator.h
+++ b/media/extractors/mp4/SampleIterator.h
@@ -36,6 +36,11 @@
     uint32_t getSampleTime() const { return mCurrentSampleTime; }
     uint32_t getSampleDuration() const { return mCurrentSampleDuration; }
 
+    uint32_t getLastSampleIndexInChunk() const {
+        return mCurrentSampleIndex + mSamplesPerChunk -
+                ((mCurrentSampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk) - 1;
+    }
+
     status_t getSampleSizeDirect(
             uint32_t sampleIndex, size_t *size);
 
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp
index 81c353e..28fe717 100644
--- a/media/extractors/mp4/SampleTable.cpp
+++ b/media/extractors/mp4/SampleTable.cpp
@@ -946,6 +946,11 @@
             sampleIndex, sampleSize);
 }
 
+uint32_t SampleTable::getLastSampleIndexInChunk() {
+    Mutex::Autolock autoLock(mLock);
+    return mSampleIterator->getLastSampleIndexInChunk();
+}
+
 status_t SampleTable::getMetaDataForSample(
         uint32_t sampleIndex,
         off64_t *offset,
diff --git a/media/extractors/mp4/SampleTable.h b/media/extractors/mp4/SampleTable.h
index e4e974b..dd68860 100644
--- a/media/extractors/mp4/SampleTable.h
+++ b/media/extractors/mp4/SampleTable.h
@@ -69,6 +69,9 @@
             bool *isSyncSample = NULL,
             uint32_t *sampleDuration = NULL);
 
+    // call only after getMetaDataForSample has been called successfully.
+    uint32_t getLastSampleIndexInChunk();
+
     enum {
         kFlagBefore,
         kFlagAfter,
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index b1cb0e7..b40f0db 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -52,6 +52,7 @@
                 )
     : mStatus(NO_INIT), mOpPackageName(opPackageName)
 {
+    AutoMutex lock(mConstructLock);
     mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
 }
 
@@ -85,6 +86,7 @@
         }
     }
 
+    AutoMutex lock(mConstructLock);
     mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
 }
 
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f9df5b1..e2de8e7 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -865,9 +865,9 @@
     } else if (waitCount == 0) {
         requested = &ClientProxy::kNonBlocking;
     } else if (waitCount > 0) {
-        long long ms = WAIT_PERIOD_MS * (long long) waitCount;
+        time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
         timeout.tv_sec = ms / 1000;
-        timeout.tv_nsec = (int) (ms % 1000) * 1000000;
+        timeout.tv_nsec = (long) (ms % 1000) * 1000000;
         requested = &timeout;
     } else {
         ALOGE("%s invalid waitCount %d", __func__, waitCount);
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index ab9efe8..76c9bfb 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -706,6 +706,13 @@
         // force refresh of remaining frames by processAudioBuffer() as last
         // write before stop could be partial.
         mRefreshRemaining = true;
+
+        // for static track, clear the old flags when starting from stopped state
+        if (mSharedBuffer != 0) {
+            android_atomic_and(
+            ~(CBLK_LOOP_CYCLE | CBLK_LOOP_FINAL | CBLK_BUFFER_END),
+            &mCblk->mFlags);
+        }
     }
     mNewPosition = mPosition + mUpdatePeriod;
     int32_t flags = android_atomic_and(~(CBLK_STREAM_END_DONE | CBLK_DISABLED), &mCblk->mFlags);
@@ -1634,9 +1641,9 @@
     } else if (waitCount == 0) {
         requested = &ClientProxy::kNonBlocking;
     } else if (waitCount > 0) {
-        long long ms = WAIT_PERIOD_MS * (long long) waitCount;
+        time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
         timeout.tv_sec = ms / 1000;
-        timeout.tv_nsec = (int) (ms % 1000) * 1000000;
+        timeout.tv_nsec = (long) (ms % 1000) * 1000000;
         requested = &timeout;
     } else {
         ALOGE("%s invalid waitCount %d", __func__, waitCount);
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index dced3c4..d40f193 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -286,7 +286,8 @@
                 struct timespec after;
                 clock_gettime(CLOCK_MONOTONIC, &after);
                 total.tv_sec += after.tv_sec - before.tv_sec;
-                long deltaNs = after.tv_nsec - before.tv_nsec;
+                // Use auto instead of long to avoid the google-runtime-int warning.
+                auto deltaNs = after.tv_nsec - before.tv_nsec;
                 if (deltaNs < 0) {
                     deltaNs += 1000000000;
                     total.tv_sec--;
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 5716727..5e979e0 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1136,13 +1136,13 @@
             // This is needed in case of cold start of the output stream.
             if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) {
                 time_t sec = stopTime.tv_sec - mStartTime.tv_sec;
-                long nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
+                auto nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
                 if (nsec < 0) {
                     --sec;
                     nsec += 1000000000;
                 }
 
-                if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) {
+                if ((sec + 1) > ((time_t)(INT_MAX / mSamplingRate))) {
                     mMaxSmp = sec * mSamplingRate;
                 } else {
                     // mSamplingRate is always > 1000
@@ -1257,8 +1257,8 @@
 
     AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
     ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user);
-    short *lpOut = buffer->i16;
-    unsigned int lNumSmp = buffer->size/sizeof(short);
+    int16_t *lpOut = buffer->i16;
+    unsigned int lNumSmp = buffer->size/sizeof(int16_t);
     const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc;
 
     if (buffer->size == 0) return;
@@ -1329,7 +1329,7 @@
             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
                 lWaveCmd = WaveGenerator::WAVEGEN_STOP;
                 unsigned int lFreqIdx = 0;
-                unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
+                uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
 
                 while (lFrequency != 0) {
                     WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
@@ -1415,7 +1415,7 @@
         if (lGenSmp) {
             // If samples must be generated, call all active wave generators and acumulate waves in lpOut
             unsigned int lFreqIdx = 0;
-            unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
+            uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
 
             while (lFrequency != 0) {
                 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
@@ -1654,17 +1654,17 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 ToneGenerator::WaveGenerator::WaveGenerator(uint32_t samplingRate,
-        unsigned short frequency, float volume) {
+        uint16_t frequency, float volume) {
     double d0;
     double F_div_Fs;  // frequency / samplingRate
 
     F_div_Fs = frequency / (double)samplingRate;
     d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs);
-    mS2_0 = (short)d0;
+    mS2_0 = (int16_t)d0;
     mS1 = 0;
     mS2 = mS2_0;
 
-    mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP);
+    mAmplitude_Q15 = (int16_t)(32767. * 32767. * volume / GEN_AMP);
     // take some margin for amplitude fluctuation
     if (mAmplitude_Q15 > 32500)
         mAmplitude_Q15 = 32500;
@@ -1672,7 +1672,7 @@
     d0 = 32768.0 * cos(2 * M_PI * F_div_Fs);  // Q14*2*cos()
     if (d0 > 32767)
         d0 = 32767;
-    mA1_Q14 = (short) d0;
+    mA1_Q14 = (int16_t) d0;
 
     ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d",
             mA1_Q14, mS2_0, mAmplitude_Q15);
@@ -1710,7 +1710,7 @@
 //        none
 //
 ////////////////////////////////////////////////////////////////////////////////
-void ToneGenerator::WaveGenerator::getSamples(short *outBuffer,
+void ToneGenerator::WaveGenerator::getSamples(int16_t *outBuffer,
         unsigned int count, unsigned int command) {
     long lS1, lS2;
     long lA1, lAmplitude;
@@ -1741,7 +1741,7 @@
             lS2 = lS1;
             lS1 = Sample;
             Sample = ((lAmplitude>>16) * Sample) >> S_Q15;
-            *(outBuffer++) += (short)Sample;  // put result in buffer
+            *(outBuffer++) += (int16_t)Sample;  // put result in buffer
             lAmplitude -= dec;
         }
     } else {
@@ -1753,7 +1753,7 @@
             lS2 = lS1;
             lS1 = Sample;
             Sample = (lAmplitude * Sample) >> S_Q15;
-            *(outBuffer++) += (short)Sample;  // put result in buffer
+            *(outBuffer++) += (int16_t)Sample;  // put result in buffer
         }
     }
 
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index bfc068b..324bcb9 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -414,6 +414,7 @@
      effect_descriptor_t     mDescriptor;        // effect descriptor
      int32_t                 mId;                // system wide unique effect engine instance ID
      Mutex                   mLock;              // Mutex for mEnabled access
+     Mutex                   mConstructLock;     // Mutex for integrality construction
 
      String16                mOpPackageName;     // The package name used for app op checks.
 
@@ -440,12 +441,22 @@
         virtual void controlStatusChanged(bool controlGranted) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->controlStatusChanged(controlGranted);
             }
         }
         virtual void enableStatusChanged(bool enabled) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->enableStatusChanged(enabled);
             }
         }
@@ -456,6 +467,11 @@
                                      void *pReplyData) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->commandExecuted(
                     cmdCode, cmdSize, pCmdData, replySize, pReplyData);
             }
@@ -465,6 +481,11 @@
         virtual void binderDied(const wp<IBinder>& /*who*/) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->binderDied();
             }
         }
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index cf446a5..806280a 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -85,7 +85,7 @@
 
         union {
             void*       raw;
-            short*      i16;        // signed 16-bit
+            int16_t*    i16;        // signed 16-bit
             int8_t*     i8;         // unsigned 8-bit, offset by 0x80
                                     // input to obtainBuffer(): unused, output: pointer to buffer
         };
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 3eb627d..59c6f4c 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -102,7 +102,7 @@
 
         union {
             void*       raw;
-            short*      i16;      // signed 16-bit
+            int16_t*    i16;      // signed 16-bit
             int8_t*     i8;       // unsigned 8-bit, offset by 0x80
         };                        // input to obtainBuffer(): unused, output: pointer to buffer
     };
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 247703f..e0e3bb1 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -256,9 +256,9 @@
     class ToneSegment {
     public:
         unsigned int duration;
-        unsigned short waveFreq[TONEGEN_MAX_WAVES+1];
-        unsigned short loopCnt;
-        unsigned short loopIndx;
+        uint16_t waveFreq[TONEGEN_MAX_WAVES+1];
+        uint16_t loopCnt;
+        uint16_t loopIndx;
     };
 
     class ToneDescriptor {
@@ -279,14 +279,14 @@
     unsigned int mMaxSmp;  // Maximum number of audio samples played (maximun tone duration)
     int mDurationMs;  // Maximum tone duration in ms
 
-    unsigned short mCurSegment;  // Current segment index in ToneDescriptor segments[]
-    unsigned short mCurCount;  // Current sequence repeat count
-    volatile unsigned short mState;  // ToneGenerator state (tone_state)
-    unsigned short mRegion;
+    uint16_t mCurSegment;  // Current segment index in ToneDescriptor segments[]
+    uint16_t mCurCount;  // Current sequence repeat count
+    volatile uint16_t mState;  // ToneGenerator state (tone_state)
+    uint16_t mRegion;
     const ToneDescriptor *mpToneDesc;  // pointer to active tone descriptor
     const ToneDescriptor *mpNewToneDesc;  // pointer to next active tone descriptor
 
-    unsigned short mLoopCounter; // Current tone loopback count
+    uint16_t mLoopCounter; // Current tone loopback count
 
     uint32_t mSamplingRate;  // AudioFlinger Sampling rate
     sp<AudioTrack> mpAudioTrack;  // Pointer to audio track used for playback
@@ -314,26 +314,26 @@
             WAVEGEN_STOP  // Stop wave on zero crossing
         };
 
-        WaveGenerator(uint32_t samplingRate, unsigned short frequency,
+        WaveGenerator(uint32_t samplingRate, uint16_t frequency,
                 float volume);
         ~WaveGenerator();
 
-        void getSamples(short *outBuffer, unsigned int count,
+        void getSamples(int16_t *outBuffer, unsigned int count,
                 unsigned int command);
 
     private:
-        static const short GEN_AMP = 32000;  // amplitude of generator
-        static const short S_Q14 = 14;  // shift for Q14
-        static const short S_Q15 = 15;  // shift for Q15
+        static const int16_t GEN_AMP = 32000;  // amplitude of generator
+        static const int16_t S_Q14 = 14;  // shift for Q14
+        static const int16_t S_Q15 = 15;  // shift for Q15
 
-        short mA1_Q14;  // Q14 coefficient
+        int16_t mA1_Q14;  // Q14 coefficient
         // delay line of full amplitude generator
         long mS1, mS2;  // delay line S2 oldest
-        short mS2_0;  // saved value for reinitialisation
-        short mAmplitude_Q15;  // Q15 amplitude
+        int16_t mS2_0;  // saved value for reinitialisation
+        int16_t mAmplitude_Q15;  // Q15 amplitude
     };
 
-    KeyedVector<unsigned short, WaveGenerator *> mWaveGens;  // list of active wave generators.
+    KeyedVector<uint16_t, WaveGenerator *> mWaveGens;  // list of active wave generators.
 };
 
 }
diff --git a/media/libaudiohal/2.0/StreamHalHidl.cpp b/media/libaudiohal/2.0/StreamHalHidl.cpp
index 9869cd2..22cbd45 100644
--- a/media/libaudiohal/2.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/2.0/StreamHalHidl.cpp
@@ -178,6 +178,13 @@
                     if (handle->numFds > 0) {
                         info->shared_memory_fd = handle->data[0];
                         info->buffer_size_frames = hidlInfo.bufferSizeFrames;
+                        // Negative buffer size frame was a hack in O and P to
+                        // indicate that the buffer is shareable to applications
+                        if (info->buffer_size_frames < 0) {
+                            info->buffer_size_frames *= -1;
+                            info->flags = audio_mmap_buffer_flag(
+                                    info->flags | AUDIO_MMAP_APPLICATION_SHAREABLE);
+                        }
                         info->burst_size_frames = hidlInfo.burstSizeFrames;
                         // info->shared_memory_address is not needed in HIDL context
                         info->shared_memory_address = NULL;
diff --git a/media/libaudiohal/4.0/StreamHalHidl.cpp b/media/libaudiohal/4.0/StreamHalHidl.cpp
index 1c2fdb0..da2f5f6 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/4.0/StreamHalHidl.cpp
@@ -188,7 +188,15 @@
                     const native_handle *handle = hidlInfo.sharedMemory.handle();
                     if (handle->numFds > 0) {
                         info->shared_memory_fd = handle->data[0];
+                        info->flags = audio_mmap_buffer_flag(hidlInfo.flags);
                         info->buffer_size_frames = hidlInfo.bufferSizeFrames;
+                        // Negative buffer size frame was a hack in O and P to
+                        // indicate that the buffer is shareable to applications
+                        if (info->buffer_size_frames < 0) {
+                            info->buffer_size_frames *= -1;
+                            info->flags = audio_mmap_buffer_flag(
+                                    info->flags | AUDIO_MMAP_APPLICATION_SHAREABLE);
+                        }
                         info->burst_size_frames = hidlInfo.burstSizeFrames;
                         // info->shared_memory_address is not needed in HIDL context
                         info->shared_memory_address = NULL;
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp
index 39f8d6e..d197b3f 100644
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ b/media/libmediaextractor/MediaBuffer.cpp
@@ -39,7 +39,7 @@
       mRangeOffset(0),
       mRangeLength(size),
       mOwnsData(false),
-      mMetaData(new MetaData),
+      mMetaData(new MetaDataBase),
       mOriginal(NULL) {
 }
 
@@ -51,7 +51,7 @@
       mRangeOffset(0),
       mRangeLength(size),
       mOwnsData(true),
-      mMetaData(new MetaData),
+      mMetaData(new MetaDataBase),
       mOriginal(NULL) {
     if (size < kSharedMemThreshold
             || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
@@ -84,7 +84,7 @@
       mRangeLength(mSize),
       mBuffer(buffer),
       mOwnsData(false),
-      mMetaData(new MetaData),
+      mMetaData(new MetaDataBase),
       mOriginal(NULL) {
 }
 
@@ -96,7 +96,7 @@
         return;
     }
 
-    int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
+    int prevCount = mRefCount.fetch_sub(1);
     if (prevCount == 1) {
         if (mObserver == NULL) {
             delete this;
@@ -110,13 +110,13 @@
 
 void MediaBuffer::claim() {
     CHECK(mObserver != NULL);
-    CHECK_EQ(mRefCount, 1);
+    CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
 
-    mRefCount = 0;
+    mRefCount.store(0, std::memory_order_relaxed);
 }
 
 void MediaBuffer::add_ref() {
-    (void) __sync_fetch_and_add(&mRefCount, 1);
+    (void) mRefCount.fetch_add(1);
 }
 
 void *MediaBuffer::data() const {
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
index f944d51..5a25965 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
@@ -86,12 +86,14 @@
     virtual MediaBufferBase *clone();
 
     // sum of localRefcount() and remoteRefcount()
+    // Result should be treated as approximate unless the result precludes concurrent accesses.
     virtual int refcount() const {
         return localRefcount() + remoteRefcount();
     }
 
+    // Result should be treated as approximate unless the result precludes concurrent accesses.
     virtual int localRefcount() const {
-        return mRefCount;
+        return mRefCount.load(std::memory_order_relaxed);
     }
 
     virtual int remoteRefcount() const {
@@ -146,7 +148,7 @@
     void claim();
 
     MediaBufferObserver *mObserver;
-    int mRefCount;
+    std::atomic<int> mRefCount;
 
     void *mData;
     size_t mSize, mRangeOffset, mRangeLength;
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
index dfe34e8..9d35568 100644
--- a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
@@ -53,6 +53,7 @@
     kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
     kKeyBitRate           = 'brte',  // int32_t (bps)
     kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
+    kKeyBitsPerSample     = 'bits',  // int32_t (bits per sample)
     kKeyStreamHeader      = 'stHd',  // raw data
     kKeyESDS              = 'esds',  // raw data
     kKeyAACProfile        = 'aacp',  // int32_t
@@ -225,6 +226,8 @@
     kKeyExifOffset       = 'exof', // int64_t, Exif data offset
     kKeyExifSize         = 'exsz', // int64_t, Exif data size
     kKeyIsExif           = 'exif', // bool (int32_t) buffer contains exif data block
+
+    kKeyPcmBigEndian     = 'pcmb', // bool (int32_t)
 };
 
 enum {
diff --git a/media/libstagefright/http/HTTPHelper.cpp b/media/libstagefright/http/HTTPHelper.cpp
index 77845e2..b895f03 100644
--- a/media/libstagefright/http/HTTPHelper.cpp
+++ b/media/libstagefright/http/HTTPHelper.cpp
@@ -42,11 +42,11 @@
             env, env->FindClass("android/media/MediaHTTPService"));
     CHECK(clazz.get() != NULL);
 
-    jmethodID constructID = env->GetMethodID(clazz.get(), "<init>", "()V");
+    jmethodID constructID = env->GetMethodID(clazz.get(), "<init>", "(Ljava/util/List;)V");
     CHECK(constructID != NULL);
 
     ScopedLocalRef<jobject> httpServiceObj(
-            env, env->NewObject(clazz.get(), constructID));
+            env, env->NewObject(clazz.get(), constructID, NULL));
 
     sp<IMediaHTTPService> httpService;
     if (httpServiceObj.get() != NULL) {
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 2047dfd..20c9d37 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -50,6 +50,8 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
+#define DEFAULT_OUTPUT_SAMPLE_RATE 48000
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -263,7 +265,9 @@
         }
         break;
     case STOPPING:
-        if (stop_l() == NO_ERROR) {
+        // volume control for offload and direct threads must take effect immediately.
+        if (stop_l() == NO_ERROR
+            && !(isVolumeControl() && isOffloadedOrDirect())) {
             mDisableWaitCnt = mMaxDisableWaitCnt;
         } else {
             mDisableWaitCnt = 1; // will cause immediate transition to IDLE
@@ -547,7 +551,14 @@
 
     mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT;
     mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT;
-    mConfig.inputCfg.samplingRate = thread->sampleRate();
+
+    // Don't use sample rate for thread if effect isn't offloadable.
+    if ((thread->type() == ThreadBase::OFFLOAD) && !isOffloaded()) {
+        mConfig.inputCfg.samplingRate = DEFAULT_OUTPUT_SAMPLE_RATE;
+        ALOGV("Overriding effect input as 48kHz");
+    } else {
+        mConfig.inputCfg.samplingRate = thread->sampleRate();
+    }
     mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
     mConfig.inputCfg.bufferProvider.cookie = NULL;
     mConfig.inputCfg.bufferProvider.getBuffer = NULL;
@@ -778,6 +789,16 @@
     }
     status_t cmdStatus = NO_ERROR;
     uint32_t size = sizeof(status_t);
+
+    if (isVolumeControl() && isOffloadedOrDirect()) {
+        sp<EffectChain>chain = mChain.promote();
+        // We have the EffectChain and EffectModule lock, permit a reentrant call to setVolume:
+        // resetVolume_l --> setVolume_l --> EffectModule::setVolume
+        mSetVolumeReentrantTid = gettid();
+        chain->resetVolume_l();
+        mSetVolumeReentrantTid = INVALID_PID;
+    }
+
     status_t status = mEffectInterface->command(EFFECT_CMD_DISABLE,
                                                 0,
                                                 NULL,
@@ -993,6 +1014,16 @@
     }
 }
 
+bool AudioFlinger::EffectModule::isOffloadedOrDirect() const
+{
+    return (mThreadType == ThreadBase::OFFLOAD || mThreadType == ThreadBase::DIRECT);
+}
+
+bool AudioFlinger::EffectModule::isVolumeControlEnabled() const
+{
+    return (isVolumeControl() && (isOffloadedOrDirect() ? isEnabled() : isProcessEnabled()));
+}
+
 void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
     ALOGVV("setInBuffer %p",(&buffer));
 
@@ -1091,7 +1122,7 @@
 
 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
 {
-    Mutex::Autolock _l(mLock);
+    AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1122,6 +1153,18 @@
     return status;
 }
 
+void AudioFlinger::EffectChain::setVolumeForOutput_l(uint32_t left, uint32_t right)
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0 &&
+        (thread->type() == ThreadBase::OFFLOAD || thread->type() == ThreadBase::DIRECT)) {
+        PlaybackThread *t = (PlaybackThread *)thread.get();
+        float vol_l = (float)left / (1 << 24);
+        float vol_r = (float)right / (1 << 24);
+        t->setVolumeForOutput_l(vol_l, vol_r);
+    }
+}
+
 status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
 {
     if (device == AUDIO_DEVICE_NONE) {
@@ -2200,8 +2243,7 @@
 
     // first update volume controller
     for (size_t i = size; i > 0; i--) {
-        if (mEffects[i - 1]->isProcessEnabled() &&
-            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
+        if (mEffects[i - 1]->isVolumeControlEnabled()) {
             ctrlIdx = i - 1;
             hasControl = true;
             break;
@@ -2247,6 +2289,8 @@
     *left = newLeft;
     *right = newRight;
 
+    setVolumeForOutput_l(*left, *right);
+
     return hasControl;
 }
 
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 2327bb9..e04ee8e 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -85,6 +85,8 @@
     status_t    setEnabled_l(bool enabled);
     bool isEnabled() const;
     bool isProcessEnabled() const;
+    bool isOffloadedOrDirect() const;
+    bool isVolumeControlEnabled() const;
 
     void        setInBuffer(const sp<EffectBufferHalInterface>& buffer);
     int16_t     *inBuffer() const {
@@ -95,7 +97,8 @@
         return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL;
     }
     void        setChain(const wp<EffectChain>& chain) { mChain = chain; }
-    void        setThread(const wp<ThreadBase>& thread) { mThread = thread; }
+    void        setThread(const wp<ThreadBase>& thread)
+                    { mThread = thread; mThreadType = thread.promote()->type(); }
     const wp<ThreadBase>& thread() { return mThread; }
 
     status_t addHandle(EffectHandle *handle);
@@ -128,6 +131,9 @@
                         { return (mDescriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0; }
     bool             isProcessImplemented() const
                         { return (mDescriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0; }
+    bool             isVolumeControl() const
+                        { return (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK)
+                            == EFFECT_FLAG_VOLUME_CTRL; }
     status_t         setOffloaded(bool offloaded, audio_io_handle_t io);
     bool             isOffloaded() const;
     void             addEffectToHal_l();
@@ -150,6 +156,7 @@
 
 mutable Mutex               mLock;      // mutex for process, commands and handles list protection
     wp<ThreadBase>      mThread;    // parent thread
+    ThreadBase::type_t  mThreadType; // parent thread type
     wp<EffectChain>     mChain;     // parent effect chain
     const int           mId;        // this instance unique ID
     const audio_session_t mSessionId; // audio session ID
@@ -176,6 +183,24 @@
     uint32_t mInChannelCountRequested;
     uint32_t mOutChannelCountRequested;
 #endif
+
+    class AutoLockReentrant {
+    public:
+        AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
+            : mMutex(gettid() == allowedTid ? nullptr : &mutex)
+        {
+            if (mMutex != nullptr) mMutex->lock();
+        }
+        ~AutoLockReentrant() {
+            if (mMutex != nullptr) mMutex->unlock();
+        }
+    private:
+        Mutex * const mMutex;
+    };
+
+    static constexpr pid_t INVALID_PID = (pid_t)-1;
+    // this tid is allowed to call setVolume() without acquiring the mutex.
+    pid_t mSetVolumeReentrantTid = INVALID_PID;
 };
 
 // The EffectHandle class implements the IEffect interface. It provides resources
@@ -403,6 +428,8 @@
 
     void setThread(const sp<ThreadBase>& thread);
 
+    void setVolumeForOutput_l(uint32_t left, uint32_t right);
+
              wp<ThreadBase> mThread;     // parent mixer thread
     mutable  Mutex mLock;        // mutex protecting effect list
              Vector< sp<EffectModule> > mEffects; // list of effect modules
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dcad866..4ca50d7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2286,6 +2286,11 @@
     return mStreamTypes[stream].volume;
 }
 
+void AudioFlinger::PlaybackThread::setVolumeForOutput_l(float left, float right) const
+{
+    mOutput->stream->setVolume(left, right);
+}
+
 // addTrack_l() must be called with ThreadBase::mLock held
 status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
 {
@@ -5142,20 +5147,20 @@
             mLeftVolFloat = left;
             mRightVolFloat = right;
 
-            // Convert volumes from float to 8.24
-            uint32_t vl = (uint32_t)(left * (1 << 24));
-            uint32_t vr = (uint32_t)(right * (1 << 24));
-
             // Delegate volume control to effect in track effect chain if needed
             // only one effect chain can be present on DirectOutputThread, so if
             // there is one, the track is connected to it
             if (!mEffectChains.isEmpty()) {
-                mEffectChains[0]->setVolume_l(&vl, &vr);
-                left = (float)vl / (1 << 24);
-                right = (float)vr / (1 << 24);
+                // if effect chain exists, volume is handled by it.
+                // Convert volumes from float to 8.24
+                uint32_t vl = (uint32_t)(left * (1 << 24));
+                uint32_t vr = (uint32_t)(right * (1 << 24));
+                // Direct/Offload effect chains set output volume in setVolume_l().
+                (void)mEffectChains[0]->setVolume_l(&vl, &vr);
+            } else {
+                // otherwise we directly set the volume.
+                setVolumeForOutput_l(left, right);
             }
-            status_t result = mOutput->stream->setVolume(left, right);
-            ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result);
         }
     }
 }
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 28d4482..ea29455 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -712,6 +712,8 @@
     virtual     void        setStreamMute(audio_stream_type_t stream, bool muted);
     virtual     float       streamVolume(audio_stream_type_t stream) const;
 
+                void        setVolumeForOutput_l(float left, float right) const;
+
                 sp<Track>   createTrack_l(
                                 const sp<AudioFlinger::Client>& client,
                                 audio_stream_type_t streamType,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index baf051a..84428c2 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1682,9 +1682,12 @@
 
     // WORKAROUND: HAL refuses to disconnect while there's streams in flight
     {
-        mDevice->clearStreamingRequest();
-
+        int64_t lastFrameNumber;
         status_t code;
+        if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
+            ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
+        }
+
         if ((code = mDevice->waitUntilDrained()) != OK) {
             ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
                   code);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index b3c3717..2c020a2 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -564,7 +564,7 @@
 
             // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
             // let prepareNextBuffer handle the error.)
-            if (res == NO_INIT && mState == STATE_CONFIGURED) {
+            if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
                 mState = STATE_ABANDONED;
             }
 
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index f9e21fb..f30f9bb 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -189,6 +189,7 @@
         minSizeFrames = AAUDIO_BUFFER_CAPACITY_MIN;
     }
     status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
+    bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE;
     if (status != OK) {
         ALOGE("%s() - createMmapBuffer() failed with status %d %s",
               __func__, status, strerror(-status));
@@ -198,18 +199,13 @@
         ALOGD("%s() createMmapBuffer() returned = %d, buffer_size = %d, burst_size %d"
                       ", Sharable FD: %s",
               __func__, status,
-              abs(mMmapBufferinfo.buffer_size_frames),
+              mMmapBufferinfo.buffer_size_frames,
               mMmapBufferinfo.burst_size_frames,
-              mMmapBufferinfo.buffer_size_frames < 0 ? "Yes" : "No");
+              isBufferShareable ? "Yes" : "No");
     }
 
     setBufferCapacity(mMmapBufferinfo.buffer_size_frames);
-    // The audio HAL indicates if the shared memory fd can be shared outside of audioserver
-    // by returning a negative buffer size
-    if (getBufferCapacity() < 0) {
-        // Exclusive mode can be used by client or service.
-        setBufferCapacity(-getBufferCapacity());
-    } else {
+    if (!isBufferShareable) {
         // Exclusive mode can only be used by the service because the FD cannot be shared.
         uid_t audioServiceUid = getuid();
         if ((mMmapClient.clientUid != audioServiceUid) &&