Merge "Added Tunneled video playback support to ACodec" into lmp-dev
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index e756368..2442219 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -172,7 +172,8 @@
     INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3,
     INVOKE_ID_SELECT_TRACK = 4,
     INVOKE_ID_UNSELECT_TRACK = 5,
-    INVOKE_ID_SET_VIDEO_SCALING_MODE = 6
+    INVOKE_ID_SET_VIDEO_SCALING_MODE = 6,
+    INVOKE_ID_GET_SELECTED_TRACK = 7
 };
 
 // Keep MEDIA_TRACK_TYPE_* in sync with MediaPlayer.java.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6f6c9d9..55fd708 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -427,6 +427,31 @@
             break;
         }
 
+        case kWhatGetSelectedTrack:
+        {
+            status_t err = INVALID_OPERATION;
+            if (mSource != NULL) {
+                err = OK;
+
+                int32_t type32;
+                CHECK(msg->findInt32("type", (int32_t*)&type32));
+                media_track_type type = (media_track_type)type32;
+                ssize_t selectedTrack = mSource->getSelectedTrack(type);
+
+                Parcel* reply;
+                CHECK(msg->findPointer("reply", (void**)&reply));
+                reply->writeInt32(selectedTrack);
+            }
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+            response->postReply(replyID);
+            break;
+        }
+
         case kWhatSelectTrack:
         {
             uint32_t replyID;
@@ -1495,6 +1520,19 @@
     return err;
 }
 
+status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
+    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
+    msg->setPointer("reply", reply);
+    msg->setInt32("type", type);
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+    if (err == OK && response != NULL) {
+        CHECK(response->findInt32("err", &err));
+    }
+    return err;
+}
+
 status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
     sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
     msg->setSize("trackIndex", trackIndex);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 486b7cc..fc456a4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -63,6 +63,7 @@
 
     status_t setVideoScalingMode(int32_t mode);
     status_t getTrackInfo(Parcel* reply) const;
+    status_t getSelectedTrack(int32_t type, Parcel* reply) const;
     status_t selectTrack(size_t trackIndex, bool select);
 
 protected:
@@ -109,6 +110,7 @@
         kWhatPollDuration               = 'polD',
         kWhatSourceNotify               = 'srcN',
         kWhatGetTrackInfo               = 'gTrI',
+        kWhatGetSelectedTrack           = 'gSel',
         kWhatSelectTrack                = 'selT',
     };
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 4748546..e33e647 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -422,6 +422,12 @@
             return mPlayer->selectTrack(trackIndex, false /* select */);
         }
 
+        case INVOKE_ID_GET_SELECTED_TRACK:
+        {
+            int32_t type = request.readInt32();
+            return mPlayer->getSelectedTrack(type, reply);
+        }
+
         default:
         {
             return INVALID_OPERATION;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 06bbbec..74892b6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -22,6 +22,7 @@
 
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MetaData.h>
+#include <media/mediaplayer.h>
 #include <utils/Vector.h>
 
 namespace android {
@@ -86,6 +87,10 @@
         return NULL;
     }
 
+    virtual ssize_t getSelectedTrack(media_track_type /* type */) const {
+        return INVALID_OPERATION;
+    }
+
     virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */) {
         return INVALID_OPERATION;
     }
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 7124fd3..a4a651d 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -439,6 +439,10 @@
         maxBytesToRead = maxBytesAvailable;
     }
 
+    // read only integral amounts of audio unit frames.
+    const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8;
+    maxBytesToRead -= maxBytesToRead % inputUnitFrameSize;
+
     if (mWaveFormat == WAVE_FORMAT_MSGSM) {
         // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames,
         // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 67dfcd2..0c5527a 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -112,6 +112,17 @@
                 bufHeight,
                 halFormat));
 
+    // NOTE: native window uses extended right-bottom coordinate
+    android_native_rect_t crop;
+    crop.left = mCropLeft;
+    crop.top = mCropTop;
+    crop.right = mCropRight + 1;
+    crop.bottom = mCropBottom + 1;
+    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
+          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);
+
+    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));
+
     uint32_t transform;
     switch (rotationDegrees) {
         case 0: transform = 0; break;