OSDN Git Service

DO NOT MERGE - ACodec: Save and use the previous crop rectangle.
authorPawin Vongmasa <pawin@google.com>
Fri, 12 Aug 2016 01:51:24 +0000 (18:51 -0700)
committerPawin Vongmasa <pawin@google.com>
Fri, 12 Aug 2016 02:16:07 +0000 (02:16 +0000)
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

include/media/stagefright/ACodec.h
media/libstagefright/ACodec.cpp

index 8b5b862..8b9e93e 100644 (file)
@@ -240,6 +240,9 @@ private:
     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;
index 6399b79..d25e99d 100644 (file)
@@ -500,6 +500,8 @@ ACodec::ACodec()
       mFatalError(false),
       mShutdownInProgress(false),
       mExplicitShutdown(false),
+      mHasLastCrop(false),
+      mLastCrop{0, 0, 0, 0},
       mEncoderDelay(0),
       mEncoderPadding(0),
       mRotationDegrees(0),
@@ -716,7 +718,8 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
         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 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
         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 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
         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 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
     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;