Merge "Prevent notifications from muting accessibility prompts" into mnc-dev
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index b96a88f..46bcc1d 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -289,6 +289,17 @@
         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
         return BAD_VALUE;
     }
+    // Safety check - ensure that data isn't pointing to this metadata, since
+    // that would get invalidated if a resize is needed
+    size_t bufferSize = get_camera_metadata_size(mBuffer);
+    uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
+    uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
+    if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
+        ALOGE("%s: Update attempted with data from the same metadata buffer!",
+                __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
     size_t data_size = calculate_camera_metadata_entry_data_size(type,
             data_count);
 
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index b621b9c..c10963d 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -61,11 +61,15 @@
         CB_RESOURCE_RECLAIMED = 5,
     };
 
+    static const pid_t kNoPid = -1;
+
     static sp<MediaCodec> CreateByType(
-            const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL);
+            const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL,
+            pid_t pid = kNoPid);
 
     static sp<MediaCodec> CreateByComponentName(
-            const sp<ALooper> &looper, const char *name, status_t *err = NULL);
+            const sp<ALooper> &looper, const char *name, status_t *err = NULL,
+            pid_t pid = kNoPid);
 
     static sp<PersistentSurface> CreatePersistentInputSurface();
 
@@ -251,7 +255,7 @@
     };
 
     struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
-        ResourceManagerServiceProxy();
+        ResourceManagerServiceProxy(pid_t pid);
         ~ResourceManagerServiceProxy();
 
         void init();
@@ -271,7 +275,7 @@
     private:
         Mutex mLock;
         sp<IResourceManagerService> mService;
-        int mPid;
+        pid_t mPid;
     };
 
     State mState;
@@ -333,7 +337,7 @@
     bool mHaveInputSurface;
     bool mHavePendingInputBuffers;
 
-    MediaCodec(const sp<ALooper> &looper);
+    MediaCodec(const sp<ALooper> &looper, pid_t pid);
 
     static status_t PostAndAwaitResponse(
             const sp<AMessage> &msg, sp<AMessage> *response);
diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h
index 4b5cd05..ef8cb23 100644
--- a/include/media/stagefright/MediaSync.h
+++ b/include/media/stagefright/MediaSync.h
@@ -135,8 +135,7 @@
 
 private:
     enum {
-        kWhatDrainVideo          = 'dVid',
-        kWhatCheckFrameAvailable = 'cFrA',
+        kWhatDrainVideo = 'dVid',
     };
 
     // This is a thin wrapper class that lets us listen to
@@ -248,9 +247,8 @@
     // onBufferReleasedByOutput releases a buffer back to the input.
     void onFrameAvailableFromInput();
 
-    // Send |bufferItem| to the output for rendering. If this is not the only
-    // buffer sent for rendering, check for any dropped frames in |checkInUs| us.
-    void renderOneBufferItem_l(const BufferItem &bufferItem, int64_t checkInUs);
+    // Send |bufferItem| to the output for rendering.
+    void renderOneBufferItem_l(const BufferItem &bufferItem);
 
     // This implements the onBufferReleased callback from IProducerListener.
     // It gets called from an OutputListener.
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index e8d495b..d5d12f7 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -135,7 +135,8 @@
 sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
         player_type playerType,
         void* cookie,
-        notify_callback_f notifyFunc) {
+        notify_callback_f notifyFunc,
+        pid_t pid) {
     sp<MediaPlayerBase> p;
     IFactory* factory;
     status_t init_result;
@@ -149,7 +150,7 @@
 
     factory = sFactoryMap.valueFor(playerType);
     CHECK(NULL != factory);
-    p = factory->createPlayer();
+    p = factory->createPlayer(pid);
 
     if (p == NULL) {
         ALOGE("Failed to create player object of type %d, create failed",
@@ -217,7 +218,7 @@
         return 0.0;
     }
 
-    virtual sp<MediaPlayerBase> createPlayer() {
+    virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
         ALOGV(" create StagefrightPlayer");
         return new StagefrightPlayer();
     }
@@ -279,9 +280,9 @@
         return 1.0;
     }
 
-    virtual sp<MediaPlayerBase> createPlayer() {
+    virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
         ALOGV(" create NuPlayer");
-        return new NuPlayerDriver;
+        return new NuPlayerDriver(pid);
     }
 };
 
@@ -297,7 +298,7 @@
         return 0.0;
     }
 
-    virtual sp<MediaPlayerBase> createPlayer() {
+    virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
         ALOGV("Create Test Player stub");
         return new TestPlayerStub();
     }
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index 7f9b3b5..e22a56f 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -47,7 +47,7 @@
                                    const sp<DataSource> &/*source*/,
                                    float /*curScore*/) { return 0.0; }
 
-        virtual sp<MediaPlayerBase> createPlayer() = 0;
+        virtual sp<MediaPlayerBase> createPlayer(pid_t pid) = 0;
     };
 
     static status_t registerFactory(IFactory* factory,
@@ -66,7 +66,8 @@
 
     static sp<MediaPlayerBase> createPlayer(player_type playerType,
                                             void* cookie,
-                                            notify_callback_f notifyFunc);
+                                            notify_callback_f notifyFunc,
+                                            pid_t pid);
 
     static void registerBuiltinFactories();
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index abbbc20..d49ba93 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -633,7 +633,7 @@
         p.clear();
     }
     if (p == NULL) {
-        p = MediaPlayerFactory::createPlayer(playerType, this, notify);
+        p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
     }
 
     if (p != NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 2fdc196..8e3e460 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -166,8 +166,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-NuPlayer::NuPlayer()
+NuPlayer::NuPlayer(pid_t pid)
     : mUIDValid(false),
+      mPID(pid),
       mSourceFlags(0),
       mOffloadAudio(false),
       mAudioDecoderGeneration(0),
@@ -1525,7 +1526,7 @@
             format->setInt32("has-video", hasVideo);
             *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
         } else {
-            *decoder = new Decoder(notify, mSource, mRenderer);
+            *decoder = new Decoder(notify, mSource, mPID, mRenderer);
         }
     } else {
         sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
@@ -1533,7 +1534,7 @@
         notify->setInt32("generation", mVideoDecoderGeneration);
 
         *decoder = new Decoder(
-                notify, mSource, mRenderer, mSurface, mCCDecoder);
+                notify, mSource, mPID, mRenderer, mSurface, mCCDecoder);
 
         // enable FRC if high-quality AV sync is requested, even if not
         // directly queuing to display, as this will even improve textureview
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 9f4c462..9456d5d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -33,7 +33,7 @@
 struct NuPlayerDriver;
 
 struct NuPlayer : public AHandler {
-    NuPlayer();
+    NuPlayer(pid_t pid);
 
     void setUID(uid_t uid);
 
@@ -139,6 +139,7 @@
     wp<NuPlayerDriver> mDriver;
     bool mUIDValid;
     uid_t mUID;
+    pid_t mPID;
     sp<Source> mSource;
     uint32_t mSourceFlags;
     sp<Surface> mSurface;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index dcc28c4..3646828 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -48,6 +48,7 @@
 NuPlayer::Decoder::Decoder(
         const sp<AMessage> &notify,
         const sp<Source> &source,
+        pid_t pid,
         const sp<Renderer> &renderer,
         const sp<Surface> &surface,
         const sp<CCDecoder> &ccDecoder)
@@ -56,6 +57,7 @@
       mSource(source),
       mRenderer(renderer),
       mCCDecoder(ccDecoder),
+      mPid(pid),
       mSkipRenderingUntilMediaTimeUs(-1ll),
       mNumFramesTotal(0ll),
       mNumInputFramesDropped(0ll),
@@ -249,7 +251,8 @@
     mComponentName.append(" decoder");
     ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
 
-    mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
+    mCodec = MediaCodec::CreateByType(
+            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid);
     int32_t secure = 0;
     if (format->findInt32("secure", &secure) && secure != 0) {
         if (mCodec != NULL) {
@@ -258,7 +261,7 @@
             mCodec->release();
             ALOGI("[%s] creating", mComponentName.c_str());
             mCodec = MediaCodec::CreateByComponentName(
-                    mCodecLooper, mComponentName.c_str());
+                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid);
         }
     }
     if (mCodec == NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index ed0be62..eeb4af4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -26,6 +26,7 @@
 struct NuPlayer::Decoder : public DecoderBase {
     Decoder(const sp<AMessage> &notify,
             const sp<Source> &source,
+            pid_t pid,
             const sp<Renderer> &renderer = NULL,
             const sp<Surface> &surface = NULL,
             const sp<CCDecoder> &ccDecoder = NULL);
@@ -77,6 +78,7 @@
     Vector<MediaBuffer *> mMediaBuffers;
     Vector<size_t> mDequeuedInputBuffers;
 
+    const pid_t mPid;
     int64_t mSkipRenderingUntilMediaTimeUs;
     int64_t mNumFramesTotal;
     int64_t mNumInputFramesDropped;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 3882dcd..7370224 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -33,7 +33,7 @@
 
 namespace android {
 
-NuPlayerDriver::NuPlayerDriver()
+NuPlayerDriver::NuPlayerDriver(pid_t pid)
     : mState(STATE_IDLE),
       mIsAsyncPrepare(false),
       mAsyncResult(UNKNOWN_ERROR),
@@ -55,7 +55,7 @@
             true,  /* canCallJava */
             PRIORITY_AUDIO);
 
-    mPlayer = new NuPlayer;
+    mPlayer = new NuPlayer(pid);
     mLooper->registerHandler(mPlayer);
 
     mPlayer->setDriver(this);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 9da7fc1..d009fd7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -24,7 +24,7 @@
 struct NuPlayer;
 
 struct NuPlayerDriver : public MediaPlayerInterface {
-    NuPlayerDriver();
+    NuPlayerDriver(pid_t pid);
 
     virtual status_t initCheck();
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index cebd577..4e1f094 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1400,7 +1400,7 @@
         ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
                 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
                 mDequeueCounter - oldest->mDequeuedAt,
-                grallocMeta->pHandle,
+                (void *)(uintptr_t)grallocMeta->pHandle,
                 oldest->mGraphicBuffer->handle, oldest->mData->base());
     } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
         VideoNativeMetadata *nativeMeta =
@@ -1408,7 +1408,7 @@
         ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
                 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
                 mDequeueCounter - oldest->mDequeuedAt,
-                nativeMeta->pBuffer,
+                (void *)(uintptr_t)nativeMeta->pBuffer,
                 oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
     }
 
@@ -4034,7 +4034,7 @@
                                             sizeof(describeParams.sMediaImage)));
 
                             MediaImage *img = &describeParams.sMediaImage;
-                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
+                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%u+%u @%u+%u+%u @%u+%u+%u }",
                                     mComponentName.c_str(), img->mWidth, img->mHeight,
                                     img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
                                     img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
@@ -5144,10 +5144,15 @@
                 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
                 if (info->mData->size() >= sizeof(grallocMeta)
                         && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
-                    handle = (native_handle_t *)grallocMeta.pHandle;
+                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
                 } else if (info->mData->size() >= sizeof(nativeMeta)
                         && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
+#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
+                    handle = NULL;
+#else
                     handle = (native_handle_t *)nativeMeta.pBuffer->handle;
+#endif
                 }
                 info->mData->meta()->setPointer("handle", handle);
                 info->mData->meta()->setInt32("rangeOffset", rangeOffset);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index b444687..cd59709 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -104,8 +104,11 @@
     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
 };
 
-MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy()
-        : mPid(IPCThreadState::self()->getCallingPid()) {
+MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
+        : mPid(pid) {
+    if (mPid == MediaCodec::kNoPid) {
+        mPid = IPCThreadState::self()->getCallingPid();
+    }
 }
 
 MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
@@ -161,8 +164,8 @@
 
 // static
 sp<MediaCodec> MediaCodec::CreateByType(
-        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
-    sp<MediaCodec> codec = new MediaCodec(looper);
+        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err, pid_t pid) {
+    sp<MediaCodec> codec = new MediaCodec(looper, pid);
 
     const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
     if (err != NULL) {
@@ -173,8 +176,8 @@
 
 // static
 sp<MediaCodec> MediaCodec::CreateByComponentName(
-        const sp<ALooper> &looper, const char *name, status_t *err) {
-    sp<MediaCodec> codec = new MediaCodec(looper);
+        const sp<ALooper> &looper, const char *name, status_t *err, pid_t pid) {
+    sp<MediaCodec> codec = new MediaCodec(looper, pid);
 
     const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
     if (err != NULL) {
@@ -232,7 +235,7 @@
     return new PersistentSurface(bufferProducer, bufferConsumer);
 }
 
-MediaCodec::MediaCodec(const sp<ALooper> &looper)
+MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid)
     : mState(UNINITIALIZED),
       mReleasedByResourceManager(false),
       mLooper(looper),
@@ -242,7 +245,7 @@
       mStickyError(OK),
       mSoftRenderer(NULL),
       mResourceManagerClient(new ResourceManagerClient(this)),
-      mResourceManagerService(new ResourceManagerServiceProxy()),
+      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
       mBatteryStatNotified(false),
       mIsVideo(false),
       mVideoWidth(0),
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index 0df3ec9..3a45e25 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -558,8 +558,7 @@
 
         // adjust video frame PTS based on vsync
         itemRealUs = mFrameScheduler->schedule(itemRealUs * 1000) / 1000;
-        int64_t oneVsyncUs = (mFrameScheduler->getVsyncPeriod() / 1000);
-        int64_t twoVsyncsUs = oneVsyncUs * 2;
+        int64_t twoVsyncsUs = 2 * (mFrameScheduler->getVsyncPeriod() / 1000);
 
         // post 2 display refreshes before rendering is due
         if (itemRealUs <= nowUs + twoVsyncsUs) {
@@ -570,7 +569,7 @@
 
             if (mHasAudio) {
                 if (nowUs - itemRealUs <= kMaxAllowedVideoLateTimeUs) {
-                    renderOneBufferItem_l(*bufferItem, nowUs + oneVsyncUs - itemRealUs);
+                    renderOneBufferItem_l(*bufferItem);
                 } else {
                     // too late.
                     returnBufferToInput_l(
@@ -579,7 +578,7 @@
                 }
             } else {
                 // always render video buffer in video-only mode.
-                renderOneBufferItem_l(*bufferItem, nowUs + oneVsyncUs - itemRealUs);
+                renderOneBufferItem_l(*bufferItem);
 
                 // smooth out videos >= 10fps
                 mMediaClock->updateAnchor(
@@ -613,7 +612,7 @@
     while (mNumOutstandingBuffers > mMaxAcquiredBufferCount
             && !mIsAbandoned && !mReturnPendingInputFrame) {
         if (mReleaseCondition.waitRelative(mMutex, kAcquireWaitTimeout) != OK) {
-            ALOGI("still waiting to release a buffer before acquire");
+            ALOGI_IF(mPlaybackRate != 0.f, "still waiting to release a buffer before acquire");
         }
 
         // If the sync is abandoned while we are waiting, the release
@@ -670,7 +669,7 @@
     }
 }
 
-void MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem, int64_t checkInUs) {
+void MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem) {
     IGraphicBufferProducer::QueueBufferInput queueInput(
             bufferItem.mTimestamp,
             bufferItem.mIsAutoTimestamp,
@@ -710,12 +709,6 @@
     mBuffersSentToOutput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer);
 
     ALOGV("queued buffer %#llx to output", (long long)bufferItem.mGraphicBuffer->getId());
-
-    // If we have already queued more than one buffer, check for any free buffers in case
-    // one of them were dropped - as BQ does not signal onBufferReleased in that case.
-    if (mBuffersSentToOutput.size() > 1) {
-        (new AMessage(kWhatCheckFrameAvailable, this))->post(checkInUs);
-    }
 }
 
 void MediaSync::onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output) {
@@ -727,38 +720,32 @@
 
     sp<GraphicBuffer> buffer;
     sp<Fence> fence;
-    status_t status;
-    // NOTE: This is a workaround for a BufferQueue bug where onBufferReleased is
-    // called only for released buffers, but not for buffers that were dropped during
-    // acquire. Dropped buffers can still be detached as they are on the free list.
-    // TODO: remove if released callback happens also for dropped buffers
-    while ((status = mOutput->detachNextBuffer(&buffer, &fence)) != NO_MEMORY) {
-        ALOGE_IF(status != NO_ERROR, "detaching buffer from output failed (%d)", status);
+    status_t status = mOutput->detachNextBuffer(&buffer, &fence);
+    ALOGE_IF(status != NO_ERROR, "detaching buffer from output failed (%d)", status);
 
-        if (status == NO_INIT) {
-            // If the output has been abandoned, we can't do anything else,
-            // since buffer is invalid.
-            onAbandoned_l(false /* isInput */);
-            return;
-        }
-
-        ALOGV("detached buffer %#llx from output", (long long)buffer->getId());
-
-        // If we've been abandoned, we can't return the buffer to the input, so just
-        // move on.
-        if (mIsAbandoned) {
-            return;
-        }
-
-        ssize_t ix = mBuffersSentToOutput.indexOfKey(buffer->getId());
-        if (ix < 0) {
-            // The buffer is unknown, maybe leftover, ignore.
-            return;
-        }
-        mBuffersSentToOutput.removeItemsAt(ix);
-
-        returnBufferToInput_l(buffer, fence);
+    if (status == NO_INIT) {
+        // If the output has been abandoned, we can't do anything else,
+        // since buffer is invalid.
+        onAbandoned_l(false /* isInput */);
+        return;
     }
+
+    ALOGV("detached buffer %#llx from output", (long long)buffer->getId());
+
+    // If we've been abandoned, we can't return the buffer to the input, so just
+    // move on.
+    if (mIsAbandoned) {
+        return;
+    }
+
+    ssize_t ix = mBuffersSentToOutput.indexOfKey(buffer->getId());
+    if (ix < 0) {
+        // The buffer is unknown, maybe leftover, ignore.
+        return;
+    }
+    mBuffersSentToOutput.removeItemsAt(ix);
+
+    returnBufferToInput_l(buffer, fence);
 }
 
 void MediaSync::returnBufferToInput_l(
@@ -829,12 +816,6 @@
             break;
         }
 
-        case kWhatCheckFrameAvailable:
-        {
-            onBufferReleasedByOutput(mOutput);
-            break;
-        }
-
         default:
             TRESPASS();
             break;
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index aab3af7..8e7a277 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -526,6 +526,8 @@
     const uint32_t oldHeight = mHeight;
     OMX_ERRORTYPE ret = SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
     if (mWidth != oldWidth || mHeight != oldHeight) {
+        mNewWidth = mWidth;
+        mNewHeight = mHeight;
         status_t err = reInitDecoder(mNewWidth, mNewHeight);
         if (err != OK) {
             notify(OMX_EventError, OMX_ErrorUnsupportedSetting, err, NULL);
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/libstagefright/foundation/ABuffer.cpp
index b214870..a5b81a8 100644
--- a/media/libstagefright/foundation/ABuffer.cpp
+++ b/media/libstagefright/foundation/ABuffer.cpp
@@ -25,12 +25,17 @@
 
 ABuffer::ABuffer(size_t capacity)
     : mMediaBufferBase(NULL),
-      mData(malloc(capacity)),
-      mCapacity(capacity),
       mRangeOffset(0),
-      mRangeLength(capacity),
       mInt32Data(0),
       mOwnsData(true) {
+    mData = malloc(capacity);
+    if (mData == NULL) {
+        mCapacity = 0;
+        mRangeLength = 0;
+    } else {
+        mCapacity = capacity;
+        mRangeLength = capacity;
+    }
 }
 
 ABuffer::ABuffer(void *data, size_t capacity)
@@ -47,6 +52,9 @@
 sp<ABuffer> ABuffer::CreateAsCopy(const void *data, size_t capacity)
 {
     sp<ABuffer> res = new ABuffer(capacity);
+    if (res->base() == NULL) {
+        return NULL;
+    }
     memcpy(res->data(), data, capacity);
     return res;
 }
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 70d2c69..e8bd432 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -21,6 +21,7 @@
 #include "MatroskaExtractor.h"
 
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBuffer.h>
@@ -620,7 +621,12 @@
                     TRESPASS();
             }
 
-            if (srcOffset + mNALSizeLen + NALsize > srcSize) {
+            if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) {
+                frame->release();
+                frame = NULL;
+
+                return ERROR_MALFORMED;
+            } else if (srcOffset + mNALSizeLen + NALsize > srcSize) {
                 break;
             }