Merge "Add memory heap checks for mediaserver and audioserver" into nyc-dev
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index f8b2f68..9aa0156 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -215,7 +215,7 @@
     enc_meta->setInt32("width", width);
     enc_meta->setInt32("height", height);
     enc_meta->setInt32("sample-rate", kFramerate);
-    enc_meta->setInt32("bit-rate", kVideoBitRate);
+    enc_meta->setInt32("bitrate", kVideoBitRate);
     // enc_meta->setInt32("stride", width);
     // enc_meta->setInt32("slice-height", height);
     enc_meta->setInt32("i-frame-interval", kIFramesIntervalSec);
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 585ef59..2e6646a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -238,6 +238,7 @@
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
                                     audio_session_t session,
+                                    pid_t pid,
                                     uid_t uid,
                                     uint32_t samplingRate,
                                     audio_format_t format,
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 1ade4ba..984bc02 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -73,6 +73,7 @@
                                 // reference and will release it when the track is destroyed.
                                 // However on failure, the client is responsible for release.
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -89,6 +90,7 @@
                                 const String16& callingPackage,
                                 size_t *pFrameCount,
                                 track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                 int clientUid,
                                 audio_session_t *sessionId,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 80437dc..0e9e3bc 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -81,6 +81,7 @@
     virtual status_t  getInputForAttr(const audio_attributes_t *attr,
                               audio_io_handle_t *input,
                               audio_session_t session,
+                              pid_t pid,
                               uid_t uid,
                               uint32_t samplingRate,
                               audio_format_t format,
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 3074910..8fc410d 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -38,7 +38,9 @@
             const String16 &opPackageName,
             uint32_t sampleRate,
             uint32_t channels,
-            uint32_t outSampleRate = 0);
+            uint32_t outSampleRate = 0,
+            uid_t uid = -1,
+            pid_t pid = -1);
 
     status_t initCheck() const;
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index ba375a2..7b43f87 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -52,6 +52,8 @@
     kKeyPcmEncoding       = 'PCMe',  // int32_t (audio encoding enum)
     kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
     kKeyBitRate           = 'brte',  // int32_t (bps)
+    kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
+    kKeyStreamHeader      = 'stHd',  // raw data
     kKeyESDS              = 'esds',  // raw data
     kKeyAACProfile        = 'aacp',  // int32_t
     kKeyAVCC              = 'avcc',  // raw data
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
index 6606c58..03e2185 100644
--- a/include/media/stagefright/NuMediaExtractor.h
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -44,6 +44,11 @@
         SAMPLE_FLAG_ENCRYPTED   = 2,
     };
 
+    // identical to IMediaExtractor::GetTrackMetaDataFlags
+    enum GetTrackFormatFlags {
+        kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
+    };
+
     NuMediaExtractor();
 
     status_t setDataSource(
@@ -56,7 +61,7 @@
     status_t setDataSource(const sp<DataSource> &datasource);
 
     size_t countTracks() const;
-    status_t getTrackFormat(size_t index, sp<AMessage> *format) const;
+    status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
 
     status_t getFileFormat(sp<AMessage> *format) const;
 
diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h
index 17631a0..01b3e3f 100644
--- a/include/media/stagefright/Utils.h
+++ b/include/media/stagefright/Utils.h
@@ -48,6 +48,11 @@
 void convertMessageToMetaData(
         const sp<AMessage> &format, sp<MetaData> &meta);
 
+// Returns a pointer to the next NAL start code in buffer of size |length| starting at |data|, or
+// a pointer to the end of the buffer if the start code is not found.
+// TODO: combine this with avc_utils::getNextNALUnit
+const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length);
+
 AString MakeUserAgent();
 
 // Convert a MIME type to a AudioSystem::audio_format
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 2976a5c..d9bb856 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -533,7 +533,8 @@
     status = AudioSystem::getInputForAttr(&mAttributes, &input,
                                         mSessionId,
                                         // FIXME compare to AudioTrack
-                                        IPCThreadState::self()->getCallingUid(),
+                                        mClientPid,
+                                        mClientUid,
                                         mSampleRate, mFormat, mChannelMask,
                                         mFlags, mSelectedDeviceId);
 
@@ -615,6 +616,7 @@
                                                        opPackageName,
                                                        &temp,
                                                        &trackFlags,
+                                                       mClientPid,
                                                        tid,
                                                        mClientUid,
                                                        &mSessionId,
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index bbdf65e..808b3ab 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -836,6 +836,7 @@
 status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
                                 audio_io_handle_t *input,
                                 audio_session_t session,
+                                pid_t pid,
                                 uid_t uid,
                                 uint32_t samplingRate,
                                 audio_format_t format,
@@ -846,7 +847,8 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getInputForAttr(
-            attr, input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId);
+            attr, input, session, pid, uid,
+            samplingRate, format, channelMask, flags, selectedDeviceId);
 }
 
 status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 22a5acd..f206f5c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1401,6 +1401,7 @@
                                                       &trackFlags,
                                                       mSharedBuffer,
                                                       output,
+                                                      mClientPid,
                                                       tid,
                                                       &mSessionId,
                                                       mClientUid,
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index aa75188..92e65e4 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -104,6 +104,7 @@
                                 track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -128,6 +129,7 @@
             data.writeInt32(false);
         }
         data.writeInt32((int32_t) output);
+        data.writeInt32((int32_t) pid);
         data.writeInt32((int32_t) tid);
         audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
         if (sessionId != NULL) {
@@ -179,6 +181,7 @@
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
                                 track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,
                                 int clientUid,
                                 audio_session_t *sessionId,
@@ -199,6 +202,7 @@
         data.writeInt64(frameCount);
         track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
         data.writeInt32(lFlags);
+        data.writeInt32((int32_t) pid);
         data.writeInt32((int32_t) tid);
         data.writeInt32((int32_t) clientUid);
         audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
@@ -950,6 +954,7 @@
                 buffer = interface_cast<IMemory>(data.readStrongBinder());
             }
             audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
+            pid_t pid = (pid_t) data.readInt32();
             pid_t tid = (pid_t) data.readInt32();
             audio_session_t sessionId = (audio_session_t) data.readInt32();
             int clientUid = data.readInt32();
@@ -962,7 +967,7 @@
             } else {
                 track = createTrack(
                         (audio_stream_type_t) streamType, sampleRate, format,
-                        channelMask, &frameCount, &flags, buffer, output, tid,
+                        channelMask, &frameCount, &flags, buffer, output, pid, tid,
                         &sessionId, clientUid, &status);
                 LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
             }
@@ -982,6 +987,7 @@
             const String16& opPackageName = data.readString16();
             size_t frameCount = data.readInt64();
             track_flags_t flags = (track_flags_t) data.readInt32();
+            pid_t pid = (pid_t) data.readInt32();
             pid_t tid = (pid_t) data.readInt32();
             int clientUid = data.readInt32();
             audio_session_t sessionId = (audio_session_t) data.readInt32();
@@ -990,8 +996,9 @@
             sp<IMemory> buffers;
             status_t status = NO_ERROR;
             sp<IAudioRecord> record = openRecord(input,
-                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid,
-                    clientUid, &sessionId, &notificationFrames, cblk, buffers, &status);
+                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
+                    pid, tid, clientUid, &sessionId, &notificationFrames, cblk, buffers,
+                    &status);
             LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
             reply->writeInt64(frameCount);
             reply->writeInt32(flags);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 4ea67da..6405d6d 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -280,6 +280,7 @@
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
                                      audio_session_t session,
+                                     pid_t pid,
                                      uid_t uid,
                                      uint32_t samplingRate,
                                      audio_format_t format,
@@ -299,6 +300,7 @@
         }
         data.write(attr, sizeof(audio_attributes_t));
         data.writeInt32(session);
+        data.writeInt32(pid);
         data.writeInt32(uid);
         data.writeInt32(samplingRate);
         data.writeInt32(static_cast <uint32_t>(format));
@@ -959,6 +961,7 @@
             audio_attributes_t attr;
             data.read(&attr, sizeof(audio_attributes_t));
             audio_session_t session = (audio_session_t)data.readInt32();
+            pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
             uint32_t samplingRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
@@ -966,7 +969,7 @@
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
             audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-            status_t status = getInputForAttr(&attr, &input, session, uid,
+            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
                                               samplingRate, format, channelMask,
                                               flags, selectedDeviceId);
             reply->writeInt32(status);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6114af8..97ba76b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -934,7 +934,9 @@
                 mOpPackageName,
                 sourceSampleRate,
                 mAudioChannels,
-                mSampleRate);
+                mSampleRate,
+                mClientUid,
+                mClientPid);
 
     status_t err = audioSource->initCheck();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1fbb957..87d64cd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -192,7 +192,6 @@
       mSourceStarted(false),
       mPaused(false),
       mPausedByClient(true),
-      mPendingBufferingFlag(PENDING_BUFFERING_FLAG_NONE),
       mPausedForBuffering(false) {
     clearFlushComplete();
 }
@@ -723,10 +722,6 @@
                 onStart();
             }
             mPausedByClient = false;
-            if (mPendingBufferingFlag != PENDING_BUFFERING_FLAG_NONE) {
-                notifyListener(MEDIA_INFO, mPendingBufferingFlag, 0);
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-            }
             break;
         }
 
@@ -1218,8 +1213,6 @@
                 break;
             }
 
-            mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-
             mDeferredActions.push_back(
                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
                                            FLUSH_CMD_FLUSH /* video */));
@@ -1961,7 +1954,6 @@
     }
     mPreviousSeekTimeUs = seekTimeUs;
     mSource->seekTo(seekTimeUs);
-    mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
     ++mTimedTextGeneration;
 
     // everything's flushed, continue playback.
@@ -2207,12 +2199,7 @@
 
         case Source::kWhatBufferingStart:
         {
-            if (mPausedByClient) {
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_START;
-            } else {
-                notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-            }
+            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
             break;
         }
 
@@ -2235,7 +2222,6 @@
         case Source::kWhatBufferingEnd:
         {
             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
-            mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
             break;
         }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index e896ac6..7431532 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -183,12 +183,6 @@
         FLUSH_CMD_SHUTDOWN,
     };
 
-    enum PendingBufferingFlag {
-        PENDING_BUFFERING_FLAG_NONE = MEDIA_INFO_UNKNOWN,
-        PENDING_BUFFERING_FLAG_START = MEDIA_INFO_BUFFERING_START,
-        PENDING_BUFFERING_FLAG_END = MEDIA_INFO_BUFFERING_END,
-    };
-
     // Status of flush responses from the decoder and renderer.
     bool mFlushComplete[2][2];
 
@@ -215,9 +209,6 @@
     // still become true, when we pause internally due to buffering.
     bool mPausedByClient;
 
-    // Pending buffering flag which is not sent to client due to being paused.
-    PendingBufferingFlag mPendingBufferingFlag;
-
     // Pause state as requested by source (internally) due to buffering
     bool mPausedForBuffering;
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 4ae8e82..e59a498 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1770,7 +1770,7 @@
                     mime.c_str(), audioFormat);
 
             int avgBitRate = -1;
-            format->findInt32("bit-rate", &avgBitRate);
+            format->findInt32("bitrate", &avgBitRate);
 
             int32_t aacProfile = -1;
             if (audioFormat == AUDIO_FORMAT_AAC
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index c8b61ca..790c6da 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -51,7 +51,8 @@
 
 AudioSource::AudioSource(
         audio_source_t inputSource, const String16 &opPackageName,
-        uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate)
+        uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
+        uid_t uid, pid_t pid)
     : mStarted(false),
       mSampleRate(sampleRate),
       mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -91,7 +92,12 @@
                     (size_t) (bufCount * frameCount),
                     AudioRecordCallbackFunction,
                     this,
-                    frameCount /*notificationFrames*/);
+                    frameCount /*notificationFrames*/,
+                    AUDIO_SESSION_ALLOCATE,
+                    AudioRecord::TRANSFER_DEFAULT,
+                    AUDIO_INPUT_FLAG_NONE,
+                    uid,
+                    pid);
         mInitCheck = mRecord->initCheck();
         if (mInitCheck != OK) {
             mRecord.clear();
diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp
index 8fbb57c..c31720d 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/libstagefright/ESDS.cpp
@@ -18,6 +18,8 @@
 #define LOG_TAG "ESDS"
 #include <utils/Log.h>
 
+#include <media/stagefright/Utils.h>
+
 #include "include/ESDS.h"
 
 #include <string.h>
@@ -194,12 +196,25 @@
     return err;
 }
 
+status_t ESDS::getBitRate(uint32_t *brateMax, uint32_t *brateAvg) const {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    *brateMax = mBitRateMax;
+    *brateAvg = mBitRateAvg;
+
+    return OK;
+};
+
 status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
     if (size < 13) {
         return ERROR_MALFORMED;
     }
 
     mObjectTypeIndication = mData[offset];
+    mBitRateMax = U32_AT(mData + offset + 5);
+    mBitRateAvg = U32_AT(mData + offset + 9);
 
     offset += 13;
     size -= 13;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f296d9a..f29ec11 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -51,6 +51,11 @@
 
 namespace android {
 
+enum {
+    // max track header chunk to return
+    kMaxTrackHeaderSize = 32,
+};
+
 class MPEG4Source : public MediaSource {
 public:
     // Caller retains ownership of both "dataSource" and "sampleTable".
@@ -476,6 +481,22 @@
                             ((int64_t)sampleTime * 1000000) / track->timescale);
                 }
             }
+
+            // MPEG2 tracks do not provide CSD, so read the stream header
+            if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
+                off64_t offset;
+                size_t size;
+                if (track->sampleTable->getMetaDataForSample(
+                            0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
+                    if (size > kMaxTrackHeaderSize) {
+                        size = kMaxTrackHeaderSize;
+                    }
+                    uint8_t header[kMaxTrackHeaderSize];
+                    if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
+                        track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
+                    }
+                }
+            }
         }
     }
 
@@ -536,6 +557,10 @@
     }
     if (psshsize > 0 && psshsize <= UINT32_MAX) {
         char *buf = (char*)malloc(psshsize);
+        if (!buf) {
+            ALOGE("b/28471206");
+            return NO_MEMORY;
+        }
         char *ptr = buf;
         for (size_t i = 0; i < mPssh.size(); i++) {
             memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
@@ -1738,12 +1763,42 @@
             break;
         }
 
+        case FOURCC('b', 't', 'r', 't'):
+        {
+            *offset += chunk_size;
+
+            uint8_t buffer[12];
+            if (chunk_data_size != sizeof(buffer)) {
+                return ERROR_MALFORMED;
+            }
+
+            if (mDataSource->readAt(
+                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
+                return ERROR_IO;
+            }
+
+            uint32_t maxBitrate = U32_AT(&buffer[4]);
+            uint32_t avgBitrate = U32_AT(&buffer[8]);
+            if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
+                mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
+            }
+            if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
+                mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
+            }
+            break;
+        }
+
         case FOURCC('a', 'v', 'c', 'C'):
         {
             *offset += chunk_size;
 
             sp<ABuffer> buffer = new ABuffer(chunk_data_size);
 
+            if (buffer->data() == NULL) {
+                ALOGE("b/28471206");
+                return NO_MEMORY;
+            }
+
             if (mDataSource->readAt(
                         data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
                 return ERROR_IO;
@@ -1761,6 +1816,11 @@
         {
             sp<ABuffer> buffer = new ABuffer(chunk_data_size);
 
+            if (buffer->data() == NULL) {
+                ALOGE("b/28471206");
+                return NO_MEMORY;
+            }
+
             if (mDataSource->readAt(
                         data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
                 return ERROR_IO;
@@ -2094,6 +2154,10 @@
                     return ERROR_MALFORMED;
                 }
                 sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
+                if (buffer->data() == NULL) {
+                    ALOGE("b/28471206");
+                    return NO_MEMORY;
+                }
                 if (mDataSource->readAt(
                     data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
                     return ERROR_IO;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index db20590..46a32fb 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1929,22 +1929,6 @@
     *type = (byte & 0x1F);
 }
 
-static const uint8_t *findNextStartCode(
-        const uint8_t *data, size_t length) {
-
-    ALOGV("findNextStartCode: %p %zu", data, length);
-
-    size_t bytesLeft = length;
-    while (bytesLeft > 4  &&
-            memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) {
-        --bytesLeft;
-    }
-    if (bytesLeft <= 4) {
-        bytesLeft = 0; // Last parameter set
-    }
-    return &data[length - bytesLeft];
-}
-
 const uint8_t *MPEG4Writer::Track::parseParamSet(
         const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
 
@@ -1952,7 +1936,7 @@
     CHECK(type == kNalUnitTypeSeqParamSet ||
           type == kNalUnitTypePicParamSet);
 
-    const uint8_t *nextStartCode = findNextStartCode(data, length);
+    const uint8_t *nextStartCode = findNextNalStartCode(data, length);
     *paramSetLen = nextStartCode - data;
     if (*paramSetLen == 0) {
         ALOGE("Param set is malformed, since its length is 0");
@@ -2198,10 +2182,7 @@
     const uint8_t *nextStartCode = data;
     size_t bytesLeft = size;
     while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
-        nextStartCode = findNextStartCode(tmp + 4, bytesLeft - 4);
-        if (nextStartCode == NULL) {
-            return ERROR_MALFORMED;
-        }
+        nextStartCode = findNextNalStartCode(tmp + 4, bytesLeft - 4);
         status_t err = paramSets.addNalUnit(tmp + 4, (nextStartCode - tmp) - 4);
         if (err != OK) {
             return ERROR_MALFORMED;
@@ -3057,11 +3038,14 @@
     mOwner->writeInt8(0x15);   // streamType AudioStream
 
     mOwner->writeInt16(0x03);  // XXX
-    mOwner->writeInt8(0x00);   // buffer size 24-bit
-    int32_t bitRate;
-    bool success = mMeta->findInt32(kKeyBitRate, &bitRate);
-    mOwner->writeInt32(success ? bitRate : 96000); // max bit rate
-    mOwner->writeInt32(success ? bitRate : 96000); // avg bit rate
+    mOwner->writeInt8(0x00);   // buffer size 24-bit (0x300)
+
+    int32_t avgBitrate = 256000;
+    (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
+    int32_t maxBitrate = avgBitrate;
+    (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
+    mOwner->writeInt32(maxBitrate);
+    mOwner->writeInt32(avgBitrate);
 
     mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
     mOwner->writeInt8(mCodecSpecificDataSize);
@@ -3095,12 +3079,17 @@
     mOwner->writeInt8(0x11);  // streamType VisualStream
 
     static const uint8_t kData[] = {
-        0x01, 0x77, 0x00,
-        0x00, 0x03, 0xe8, 0x00,
-        0x00, 0x03, 0xe8, 0x00
+        0x01, 0x77, 0x00, // buffer size 96000 bytes
     };
     mOwner->write(kData, sizeof(kData));
 
+    int32_t avgBitrate = 256000;
+    (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
+    int32_t maxBitrate = avgBitrate;
+    (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
+    mOwner->writeInt32(maxBitrate);
+    mOwner->writeInt32(avgBitrate);
+
     mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
 
     mOwner->writeInt8(mCodecSpecificDataSize);
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 271c69b..a669dca 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -232,7 +232,7 @@
 }
 
 status_t NuMediaExtractor::getTrackFormat(
-        size_t index, sp<AMessage> *format) const {
+        size_t index, sp<AMessage> *format, uint32_t flags) const {
     Mutex::Autolock autoLock(mLock);
 
     *format = NULL;
@@ -245,7 +245,7 @@
         return -ERANGE;
     }
 
-    sp<MetaData> meta = mImpl->getTrackMetaData(index);
+    sp<MetaData> meta = mImpl->getTrackMetaData(index, flags);
     // Extractors either support trackID-s or not, so either all tracks have trackIDs or none.
     // Generate trackID if missing.
     int32_t trackID;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 3e1badf..aa64d22 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -157,9 +157,14 @@
         msg->setInt64("durationUs", durationUs);
     }
 
-    int avgBitRate;
+    int32_t avgBitRate;
     if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
-        msg->setInt32("bit-rate", avgBitRate);
+        msg->setInt32("bitrate", avgBitRate);
+    }
+
+    int32_t maxBitRate;
+    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)) {
+        msg->setInt32("max-bitrate", maxBitRate);
     }
 
     int32_t isSync;
@@ -465,6 +470,18 @@
         buffer->meta()->setInt32("csd", true);
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
+
+        uint32_t maxBitrate, avgBitrate;
+        if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
+            if (!meta->hasData(kKeyMaxBitRate)
+                    && maxBitrate > 0 && maxBitrate <= INT32_MAX) {
+                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
+            }
+            if (!meta->hasData(kKeyBitRate)
+                    && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
+                msg->setInt32("bitrate", (int32_t)avgBitrate);
+            }
+        }
     } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
         if (buffer.get() == NULL || buffer->base() == NULL) {
@@ -551,12 +568,20 @@
     return OK;
 }
 
-static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
+const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
+    uint8_t *res = NULL;
+    if (length > 4) {
+        // minus 1 as to not match NAL start code at end
+        res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
+    }
+    return res != NULL && res < data + length - 4 ? res : &data[length];
+}
 
+static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
     avcc[0] = 1;        // version
-    avcc[1] = 0x64;     // profile
-    avcc[2] = 0;        // unused (?)
-    avcc[3] = 0xd;      // level
+    avcc[1] = 0x64;     // profile (default to high)
+    avcc[2] = 0;        // constraints (default to none)
+    avcc[3] = 0xd;      // level (default to 1.3)
     avcc[4] = 0xff;     // reserved+size
 
     size_t i = 0;
@@ -564,26 +589,28 @@
     int lastparamoffset = 0;
     int avccidx = 6;
     do {
-        if (i >= csd0->size() - 4 ||
-                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
-            if (i >= csd0->size() - 4) {
-                // there can't be another param here, so use all the rest
-                i = csd0->size();
+        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
+        ALOGV("block at %zu, last was %d", i, lastparamoffset);
+        if (lastparamoffset > 0) {
+            const uint8_t *lastparam = csd0->data() + lastparamoffset;
+            int size = i - lastparamoffset;
+            if (size > 3) {
+                if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
+                    ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
+                            avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
+                } else if (!numparams) {
+                    // fill in profile, constraints and level
+                    memcpy(avcc + 1, lastparam + 1, 3);
+                }
             }
-            ALOGV("block at %zu, last was %d", i, lastparamoffset);
-            if (lastparamoffset > 0) {
-                int size = i - lastparamoffset;
-                avcc[avccidx++] = size >> 8;
-                avcc[avccidx++] = size & 0xff;
-                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
-                avccidx += size;
-                numparams++;
-            }
-            i += 4;
-            lastparamoffset = i;
-        } else {
-            i++;
+            avcc[avccidx++] = size >> 8;
+            avcc[avccidx++] = size & 0xff;
+            memcpy(avcc+avccidx, lastparam, size);
+            avccidx += size;
+            numparams++;
         }
+        i += 4;
+        lastparamoffset = i;
     } while(i < csd0->size());
     ALOGV("csd0 contains %d params", numparams);
 
@@ -595,26 +622,18 @@
     int numpicparamsoffset = avccidx;
     avccidx++;
     do {
-        if (i >= csd1->size() - 4 ||
-                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
-            if (i >= csd1->size() - 4) {
-                // there can't be another param here, so use all the rest
-                i = csd1->size();
-            }
-            ALOGV("block at %zu, last was %d", i, lastparamoffset);
-            if (lastparamoffset > 0) {
-                int size = i - lastparamoffset;
-                avcc[avccidx++] = size >> 8;
-                avcc[avccidx++] = size & 0xff;
-                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
-                avccidx += size;
-                numparams++;
-            }
-            i += 4;
-            lastparamoffset = i;
-        } else {
-            i++;
+        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
+        ALOGV("block at %zu, last was %d", i, lastparamoffset);
+        if (lastparamoffset > 0) {
+            int size = i - lastparamoffset;
+            avcc[avccidx++] = size >> 8;
+            avcc[avccidx++] = size & 0xff;
+            memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
+            avccidx += size;
+            numparams++;
         }
+        i += 4;
+        lastparamoffset = i;
     } while(i < csd1->size());
     avcc[numpicparamsoffset] = numparams;
     return avccidx;
@@ -638,15 +657,16 @@
     esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
     esds[12] = (configdescriptorsize & 0x7f);
     esds[13] = 0x40; // objectTypeIndication
-    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
-    esds[15] = 0x00; // but the actual values here were taken from a real file.
+    // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
+    esds[14] = 0x15; // streamType(5), upStream(0),
+    esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
     esds[16] = 0x18;
     esds[17] = 0x00;
-    esds[18] = 0x00;
+    esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
     esds[19] = 0x00;
     esds[20] = 0xfa;
     esds[21] = 0x00;
-    esds[22] = 0x00;
+    esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
     esds[23] = 0x00;
     esds[24] = 0xfa;
     esds[25] = 0x00;
@@ -657,7 +677,6 @@
     esds[30] = (csd0size & 0x7f);
     memcpy((void*)&esds[31], csd0->data(), csd0size);
     // data following this is ignored, so don't bother appending it
-
 }
 
 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
@@ -1059,7 +1078,7 @@
     int32_t brate = -1;
     if (!meta->findInt32(kKeyBitRate, &brate)) {
         ALOGV("track of type '%s' does not publish bitrate", mime);
-     }
+    }
     info.bit_rate = brate;
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/libstagefright/codecs/amrwbenc/src/convolve.c
index 9b8b3aa..8c24414 100644
--- a/media/libstagefright/codecs/amrwbenc/src/convolve.c
+++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c
@@ -47,48 +47,53 @@
         s = vo_mult32((*tmpX++), (*tmpH--));i--;
         while(i>0)
         {
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
             i -= 4;
         }
-        y[n] = ((s<<1) + 0x8000)>>16;
+        y[n] = voround(L_shl(s, 1));
         n++;
 
         tmpH = h+n;
         tmpX = x;
         i=n+1;
-        s =  vo_mult32((*tmpX++), (*tmpH--));i--;
-        s += vo_mult32((*tmpX++), (*tmpH--));i--;
+        s =  vo_mult32((*tmpX++), (*tmpH--));
+        i--;
+        s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+        i--;
 
         while(i>0)
         {
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
             i -= 4;
         }
-        y[n] = ((s<<1) + 0x8000)>>16;
+        y[n] = voround(L_shl(s, 1));
         n++;
 
         tmpH = h+n;
         tmpX = x;
         i=n+1;
-        s =  vo_mult32((*tmpX++), (*tmpH--));i--;
-        s += vo_mult32((*tmpX++), (*tmpH--));i--;
-        s += vo_mult32((*tmpX++), (*tmpH--));i--;
+        s =  vo_mult32((*tmpX++), (*tmpH--));
+        i--;
+        s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+        i--;
+        s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+        i--;
 
         while(i>0)
         {
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
             i -= 4;
         }
-        y[n] = ((s<<1) + 0x8000)>>16;
+        y[n] = voround(L_shl(s, 1));
         n++;
 
         s = 0;
@@ -97,13 +102,13 @@
         i=n+1;
         while(i>0)
         {
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
-            s += vo_mult32((*tmpX++), (*tmpH--));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+            s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
             i -= 4;
         }
-        y[n] = ((s<<1) + 0x8000)>>16;
+        y[n] = voround(L_shl(s, 1));
         n++;
     }
     return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
index de2a221..b453b25 100644
--- a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
+++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
@@ -84,8 +84,8 @@
 
     /* Find interval to compute normalized correlation */
 
-    t_min = t0_min - L_INTERPOL1;
-    t_max = t0_max + L_INTERPOL1;
+    t_min = L_sub(t0_min, L_INTERPOL1);
+    t_max = L_add(t0_max, L_INTERPOL1);
     corr = &corr_v[-t_min];
     /* Compute normalized correlation between target and filtered excitation */
 #ifdef ASM_OPT               /* asm optimization branch */
@@ -188,15 +188,15 @@
     L_tmp = 0;
     for (i = 0; i < 64; i+=4)
     {
-        L_tmp += (xn[i] * xn[i]);
-        L_tmp += (xn[i+1] * xn[i+1]);
-        L_tmp += (xn[i+2] * xn[i+2]);
-        L_tmp += (xn[i+3] * xn[i+3]);
+        L_tmp = L_add(L_tmp, (xn[i] * xn[i]));
+        L_tmp = L_add(L_tmp, (xn[i+1] * xn[i+1]));
+        L_tmp = L_add(L_tmp, (xn[i+2] * xn[i+2]));
+        L_tmp = L_add(L_tmp, (xn[i+3] * xn[i+3]));
     }
 
-    L_tmp = (L_tmp << 1) + 1;
+    L_tmp = L_add(L_shl(L_tmp, 1), 1);
     exp = norm_l(L_tmp);
-    exp = (32 - exp);
+    exp = L_sub(32, exp);
     //exp = exp + 2;                     /* energy of xn[] x 2 + rounded up     */
     scale = -(exp >> 1);           /* (1<<scale) < 1/sqrt(energy rounded) */
 
@@ -209,36 +209,36 @@
         L_tmp1 = 0;
         for (i = 0; i < 64; i+=4)
         {
-            L_tmp  += (xn[i] * excf[i]);
-            L_tmp1 += (excf[i] * excf[i]);
-            L_tmp  += (xn[i+1] * excf[i+1]);
-            L_tmp1 += (excf[i+1] * excf[i+1]);
-            L_tmp  += (xn[i+2] * excf[i+2]);
-            L_tmp1 += (excf[i+2] * excf[i+2]);
-            L_tmp  += (xn[i+3] * excf[i+3]);
-            L_tmp1 += (excf[i+3] * excf[i+3]);
+            L_tmp = L_add(L_tmp, (xn[i] * excf[i]));
+            L_tmp1 = L_add(L_tmp1, (excf[i] * excf[i]));
+            L_tmp = L_add(L_tmp, (xn[i+1] * excf[i+1]));
+            L_tmp1 = L_add(L_tmp1, (excf[i+1] * excf[i+1]));
+            L_tmp = L_add(L_tmp, (xn[i+2] * excf[i+2]));
+            L_tmp1 = L_add(L_tmp1, (excf[i+2] * excf[i+2]));
+            L_tmp = L_add(L_tmp, (xn[i+3] * excf[i+3]));
+            L_tmp1 = L_add(L_tmp1, (excf[i+3] * excf[i+3]));
         }
 
-        L_tmp = (L_tmp << 1) + 1;
-        L_tmp1 = (L_tmp1 << 1) + 1;
+        L_tmp = L_add(L_shl(L_tmp, 1), 1);
+        L_tmp1 = L_add(L_shl(L_tmp1, 1), 1);
 
         exp = norm_l(L_tmp);
-        L_tmp = (L_tmp << exp);
-        exp_corr = (30 - exp);
+        L_tmp = L_shl(L_tmp, exp);
+        exp_corr = L_sub(30, exp);
         corr = extract_h(L_tmp);
 
         exp = norm_l(L_tmp1);
-        L_tmp = (L_tmp1 << exp);
-        exp_norm = (30 - exp);
+        L_tmp = L_shl(L_tmp1, exp);
+        exp_norm = L_sub(30, exp);
 
         Isqrt_n(&L_tmp, &exp_norm);
         norm = extract_h(L_tmp);
 
         /* Normalize correlation = correlation * (1/sqrt(energy)) */
 
-        L_tmp = vo_L_mult(corr, norm);
+        L_tmp = L_mult(corr, norm);
 
-        L_tmp2 = exp_corr + exp_norm + scale;
+        L_tmp2 = L_add(exp_corr, exp_norm + scale);
         if(L_tmp2 < 0)
         {
             L_tmp2 = -L_tmp2;
@@ -246,10 +246,10 @@
         }
         else
         {
-            L_tmp = L_tmp << L_tmp2;
+            L_tmp = L_shl(L_tmp, L_tmp2);
         }
 
-        corr_norm[t] = vo_round(L_tmp);
+        corr_norm[t] = voround(L_tmp);
         /* modify the filtered excitation excf[] for the next iteration */
 
         if(t != t_max)
@@ -310,13 +310,13 @@
     ptr = &(inter4_1[k][0]);
 
     L_sum  = vo_mult32(x[0], (*ptr++));
-    L_sum += vo_mult32(x[1], (*ptr++));
-    L_sum += vo_mult32(x[2], (*ptr++));
-    L_sum += vo_mult32(x[3], (*ptr++));
-    L_sum += vo_mult32(x[4], (*ptr++));
-    L_sum += vo_mult32(x[5], (*ptr++));
-    L_sum += vo_mult32(x[6], (*ptr++));
-    L_sum += vo_mult32(x[7], (*ptr++));
+    L_sum = L_add(L_sum, vo_mult32(x[1], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[2], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[3], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[4], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[5], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[6], (*ptr++)));
+    L_sum = L_add(L_sum, vo_mult32(x[7], (*ptr++)));
 
     sum = extract_h(L_add(L_shl2(L_sum, 2), 0x8000));
     return (sum);
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index d59f129..b908ff8 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -810,10 +810,10 @@
             vo_p2 = vo_p0-1;
             for (j = 1; j <= M/4; j++)
             {
-                L_tmp -= *vo_p1++ * *vo_p2--;
-                L_tmp -= *vo_p1++ * *vo_p2--;
-                L_tmp -= *vo_p1++ * *vo_p2--;
-                L_tmp -= *vo_p1++ * *vo_p2--;
+                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+                L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
             }
             *vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
         }
@@ -1205,7 +1205,7 @@
          *------------------------------------------------------*/
 
         /* y2 in Q9, gain_pit in Q14 */
-        L_tmp = (gain_code * y2[L_SUBFR - 1])<<1;
+        L_tmp = L_mult(gain_code, y2[L_SUBFR - 1]);
         L_tmp = L_shl(L_tmp, (5 + shift));
         L_tmp = L_negate(L_tmp);
         L_tmp += (xn[L_SUBFR - 1] * 16384)<<1;
@@ -1220,8 +1220,8 @@
         {
             Word32 tmp;
             /* code in Q9, gain_pit in Q14 */
-            L_tmp = (gain_code * code[i])<<1;
-            L_tmp = (L_tmp << 5);
+            L_tmp = L_mult(gain_code, code[i]);
+            L_tmp = L_shl(L_tmp, 5);
             tmp = L_mult(exc[i + i_subfr], gain_pit); // (exc[i + i_subfr] * gain_pit)<<1
             L_tmp = L_add(L_tmp, tmp);
             L_tmp = L_shl2(L_tmp, 1);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 75998ef..d2fee81 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -579,6 +579,7 @@
         IAudioFlinger::track_flags_t *flags,
         const sp<IMemory>& sharedBuffer,
         audio_io_handle_t output,
+        pid_t pid,
         pid_t tid,
         audio_session_t *sessionId,
         int clientUid,
@@ -590,6 +591,15 @@
     status_t lStatus;
     audio_session_t lSessionId;
 
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (pid == -1 || !isTrustedCallingUid(callingUid)) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != -1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
+    }
+
     // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
     // but if someone uses binder directly they could bypass that and cause us to crash
     if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
@@ -634,7 +644,6 @@
             goto Exit;
         }
 
-        pid_t pid = IPCThreadState::self()->getCallingPid();
         client = registerPid(pid);
 
         PlaybackThread *effectThread = NULL;
@@ -1455,6 +1464,7 @@
         const String16& opPackageName,
         size_t *frameCount,
         IAudioFlinger::track_flags_t *flags,
+        pid_t pid,
         pid_t tid,
         int clientUid,
         audio_session_t *sessionId,
@@ -1472,11 +1482,21 @@
     cblk.clear();
     buffers.clear();
 
+    bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!isTrustedCallingUid(callingUid)) {
         ALOGW_IF((uid_t)clientUid != callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
         clientUid = callingUid;
+        updatePid = true;
+    }
+
+    if (updatePid) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != -1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
     }
 
     // check calling permissions
@@ -1516,7 +1536,6 @@
             goto Exit;
         }
 
-        pid_t pid = IPCThreadState::self()->getCallingPid();
         client = registerPid(pid);
 
         if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 96d38d0..59ad688 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -107,6 +107,7 @@
                                 IAudioFlinger::track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -120,6 +121,7 @@
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
                                 IAudioFlinger::track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,
                                 int clientUid,
                                 audio_session_t *sessionId,
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index afc2440..3c73543 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -105,11 +105,10 @@
     return true;
 }
 
-bool captureAudioOutputAllowed() {
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
     if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
-    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-    bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);
+    bool ok = checkPermission(sCaptureAudioOutput, pid, uid);
     if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
     return ok;
 }
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index 1e79553..8b1bc00 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,7 +21,7 @@
 extern pid_t getpid_cached;
 bool isTrustedCallingUid(uid_t uid);
 bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool captureAudioOutputAllowed();
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
 bool captureHotwordAllowed();
 bool settingsAllowed();
 bool modifyAudioRoutingAllowed();
diff --git a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
index 09a931f..151d066 100644
--- a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
@@ -190,7 +190,8 @@
     }
 
     if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX)
-            && !captureAudioOutputAllowed()) {
+            && !captureAudioOutputAllowed(IPCThreadState::self()->getCallingPid(),
+                                          IPCThreadState::self()->getCallingUid())) {
         ALOGE("open_input() permission denied: capture not allowed");
         return AUDIO_IO_HANDLE_NONE;
     }
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 92a1285..02603b8 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -260,6 +260,7 @@
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
                                              audio_session_t session,
+                                             pid_t pid,
                                              uid_t uid,
                                              uint32_t samplingRate,
                                              audio_format_t format,
@@ -282,11 +283,22 @@
     sp<AudioPolicyEffects>audioPolicyEffects;
     status_t status;
     AudioPolicyInterface::input_type_t inputType;
+
+    bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
-        ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+    if (!isTrustedCallingUid(callingUid)) {
+        ALOGW_IF(uid != -1 && uid != (int)callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
         uid = callingUid;
+        updatePid = true;
+    }
+
+    if (updatePid) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != -1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
     }
 
     {
@@ -306,7 +318,7 @@
             case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                 // FIXME: use the same permission as for remote submix for now.
             case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
-                if (!captureAudioOutputAllowed()) {
+                if (!captureAudioOutputAllowed(pid, uid)) {
                     ALOGE("getInputForAttr() permission denied: capture not allowed");
                     status = PERMISSION_DENIED;
                 }
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index c830454..7c9315d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -234,6 +234,7 @@
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
                                              audio_session_t session,
+                                             pid_t pid __unused,
                                              uid_t uid __unused,
                                              uint32_t samplingRate,
                                              audio_format_t format,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 2710ac7..0b2cb35 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -99,6 +99,7 @@
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
                                      audio_session_t session,
+                                     pid_t pid,
                                      uid_t uid,
                                      uint32_t samplingRate,
                                      audio_format_t format,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0e4e244..c0de95a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2967,19 +2967,28 @@
 }
 
 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
-    Mutex::Autolock l(mRequestLock);
-    // Check all streams needed by repeating requests are still valid. Otherwise, stop
-    // repeating requests.
-    for (const auto& request : mRepeatingRequests) {
-        for (const auto& s : request->mOutputStreams) {
-            if (s->isAbandoned()) {
-                int64_t lastFrameNumber = 0;
-                clearRepeatingRequestsLocked(&lastFrameNumber);
-                mListener->notifyRepeatingRequestError(lastFrameNumber);
-                return;
+    bool surfaceAbandoned = false;
+    int64_t lastFrameNumber = 0;
+    {
+        Mutex::Autolock l(mRequestLock);
+        // Check all streams needed by repeating requests are still valid. Otherwise, stop
+        // repeating requests.
+        for (const auto& request : mRepeatingRequests) {
+            for (const auto& s : request->mOutputStreams) {
+                if (s->isAbandoned()) {
+                    surfaceAbandoned = true;
+                    clearRepeatingRequestsLocked(&lastFrameNumber);
+                    break;
+                }
+            }
+            if (surfaceAbandoned) {
+                break;
             }
         }
     }
+    if (surfaceAbandoned) {
+        mListener->notifyRepeatingRequestError(lastFrameNumber);
+    }
 }
 
 bool Camera3Device::RequestThread::threadLoop() {