DO NOT MERGE - ACodec: Save and use the previous crop rectangle.

When the surface changes, set the crop rectangle for the new native
window using the previous crop rectangle if available.

Also prevent null pointer dereferencing in debug mode.

Bug: 30690174

Change-Id: I7a707d661ced5a87fcaa8568cbb903fbc26ea346
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 8b5b862..8b9e93e 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -240,6 +240,9 @@
     bool mShutdownInProgress;
     bool mExplicitShutdown;
 
+    bool mHasLastCrop;
+    android_native_rect_t mLastCrop;
+
     // If "mKeepComponentAllocated" we only transition back to Loaded state
     // and do not release the component instance.
     bool mKeepComponentAllocated;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 6399b79..d25e99d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -500,6 +500,8 @@
       mFatalError(false),
       mShutdownInProgress(false),
       mExplicitShutdown(false),
+      mHasLastCrop(false),
+      mLastCrop{0, 0, 0, 0},
       mEncoderDelay(0),
       mEncoderPadding(0),
       mRotationDegrees(0),
@@ -716,7 +718,8 @@
         if (storingMetadataInDecodedBuffers()
                 && !mLegacyAdaptiveExperiment
                 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
-            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
+            ALOGV("skipping buffer %p", info.mGraphicBuffer == NULL ?
+                    NULL : info.mGraphicBuffer->getNativeBuffer());
             continue;
         }
         ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
@@ -724,7 +727,8 @@
         err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
         if (err != OK) {
             ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
-                    info.mGraphicBuffer->getNativeBuffer(),
+                    info.mGraphicBuffer == NULL ?
+                    NULL : info.mGraphicBuffer->getNativeBuffer(),
                     strerror(-err), -err);
             return err;
         }
@@ -756,6 +760,12 @@
         pushBlankBuffersToNativeWindow(mNativeWindow.get());
     }
 
+    // Restore the crop rectangle using past information if available
+    if (mHasLastCrop) {
+        status_t err = native_window_set_crop(nativeWindow, &mLastCrop);
+        ALOGW_IF(err != NO_ERROR, "failed to restore crop: %d", err);
+    }
+
     mNativeWindow = nativeWindow;
     mNativeWindowUsageBits = usageBits;
     return OK;
@@ -5242,6 +5252,9 @@
     if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
         status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
         ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
+        // Save the crop rectangle to be used when the surface changes
+        mCodec->mHasLastCrop = true;
+        mCodec->mLastCrop = crop;
     }
 
     int32_t render;