handle rotation in NuPlayer

Bug: 16653284
Change-Id: I54165041da5a13498d627eee1b3ec59ef3c923b0
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 42a03bb..7f92671 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -190,6 +190,7 @@
 
     int32_t mEncoderDelay;
     int32_t mEncoderPadding;
+    int32_t mRotationDegrees;
 
     bool mChannelMaskPresent;
     int32_t mChannelMask;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d144af1..adc5f33 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -860,8 +860,23 @@
                               displayWidth, displayHeight);
                     }
 
-                    notifyListener(
-                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
+                    int32_t rotationDegrees;
+                    if (!videoInputFormat->findInt32(
+                            "rotation-degrees", &rotationDegrees)) {
+                        rotationDegrees = 0;
+                    }
+
+                    if (rotationDegrees == 90 || rotationDegrees == 270) {
+                        notifyListener(
+                                MEDIA_SET_VIDEO_SIZE,
+                                displayHeight,
+                                displayWidth);
+                    } else {
+                        notifyListener(
+                                MEDIA_SET_VIDEO_SIZE,
+                                displayWidth,
+                                displayHeight);
+                    }
                 }
             } else if (what == Decoder::kWhatShutdownCompleted) {
                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 1b1d7a9..3fb174d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -368,6 +368,7 @@
       mExplicitShutdown(false),
       mEncoderDelay(0),
       mEncoderPadding(0),
+      mRotationDegrees(0),
       mChannelMaskPresent(false),
       mChannelMask(0),
       mDequeueCounter(0),
@@ -591,6 +592,27 @@
         return err;
     }
 
+    if (mRotationDegrees != 0) {
+        uint32_t transform = 0;
+        switch (mRotationDegrees) {
+            case 0: transform = 0; break;
+            case 90: transform = HAL_TRANSFORM_ROT_90; break;
+            case 180: transform = HAL_TRANSFORM_ROT_180; break;
+            case 270: transform = HAL_TRANSFORM_ROT_270; break;
+            default: transform = 0; break;
+        }
+
+        if (transform > 0) {
+            err = native_window_set_buffers_transform(
+                    mNativeWindow.get(), transform);
+            if (err != 0) {
+                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
+                        strerror(-err), -err);
+                return err;
+            }
+        }
+    }
+
     // Set up the native window.
     OMX_U32 usage = 0;
     err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
@@ -1232,6 +1254,13 @@
                 && push != 0) {
             mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
         }
+
+        int32_t rotationDegrees;
+        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
+            mRotationDegrees = rotationDegrees;
+        } else {
+            mRotationDegrees = 0;
+        }
     }
 
     if (video) {
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 750bff0..587e264 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -142,6 +142,11 @@
         msg->setInt32("max-input-size", maxInputSize);
     }
 
+    int32_t rotationDegrees;
+    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
+        msg->setInt32("rotation-degrees", rotationDegrees);
+    }
+
     uint32_t type;
     const void *data;
     size_t size;