Bug 3438258 Add SurfaceTexture as MediaPlayer sink

This change enables the use of a SurfaceTexture in place of a Surface
as the video sink for an android.media.MediaPlayer. The new API
MediaPlayer.setTexture is currently hidden.

This includes:
 - New Java and C++ interfaces
 - C++ plumbing and implementation (JNI, Binder)
 - Stagefright AwesomePlayer and NuPlayer use ANativeWindow
   (either Surface or SurfaceTextureClient)

Change-Id: I2b568bee143d9eaf3dfc6cc4533c1bebbd5afc51
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1fcf92b..48b517e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -37,6 +37,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
@@ -76,8 +77,16 @@
 }
 
 void NuPlayer::setVideoSurface(const sp<Surface> &surface) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, id());
-    msg->setObject("surface", surface);
+    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
+    msg->setObject("native-window", new NativeWindowWrapper(surface));
+    msg->post();
+}
+
+void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
+    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
+                new SurfaceTextureClient(surfaceTexture) : NULL);
+    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
     msg->post();
 }
 
@@ -144,14 +153,14 @@
             break;
         }
 
-        case kWhatSetVideoSurface:
+        case kWhatSetVideoNativeWindow:
         {
-            LOGV("kWhatSetVideoSurface");
+            LOGV("kWhatSetVideoNativeWindow");
 
             sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
+            CHECK(msg->findObject("native-window", &obj));
 
-            mSurface = static_cast<Surface *>(obj.get());
+            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
             break;
         }
 
@@ -529,7 +538,8 @@
         new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
                      id());
 
-    *decoder = new Decoder(notify, audio ? NULL : mSurface);
+    *decoder = audio ? new Decoder(notify) :
+                       new Decoder(notify, mNativeWindow);
     looper()->registerHandler(*decoder);
 
     (*decoder)->configure(meta);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index bb65162..e7c6a42 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -20,6 +20,9 @@
 
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/NativeWindowWrapper.h>
+#include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/Surface.h>
 
 namespace android {
 
@@ -38,6 +41,7 @@
             const char *url, const KeyedVector<String8, String8> *headers);
 
     void setVideoSurface(const sp<Surface> &surface);
+    void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
     void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
     void start();
 
@@ -65,7 +69,7 @@
 
     enum {
         kWhatSetDataSource,
-        kWhatSetVideoSurface,
+        kWhatSetVideoNativeWindow,
         kWhatSetAudioSink,
         kWhatMoreDataQueued,
         kWhatStart,
@@ -81,7 +85,7 @@
 
     wp<NuPlayerDriver> mDriver;
     sp<Source> mSource;
-    sp<Surface> mSurface;
+    sp<NativeWindowWrapper> mNativeWindow;
     sp<MediaPlayerBase::AudioSink> mAudioSink;
     sp<Decoder> mVideoDecoder;
     sp<Decoder> mAudioDecoder;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 761dfa4..517acc9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -31,13 +31,15 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
 NuPlayer::Decoder::Decoder(
-        const sp<AMessage> &notify, const sp<Surface> &surface)
+        const sp<AMessage> &notify,
+        const sp<NativeWindowWrapper> &nativeWindow)
     : mNotify(notify),
-      mSurface(surface) {
+      mNativeWindow(nativeWindow) {
 }
 
 NuPlayer::Decoder::~Decoder() {
@@ -55,8 +57,8 @@
 
     sp<AMessage> format = makeFormat(meta);
 
-    if (mSurface != NULL) {
-        format->setObject("surface", mSurface);
+    if (mNativeWindow != NULL) {
+        format->setObject("native-window", mNativeWindow);
     }
 
     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 3874cfe..732f090 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -28,7 +28,8 @@
 struct DecoderWrapper;
 
 struct NuPlayer::Decoder : public AHandler {
-    Decoder(const sp<AMessage> &notify, const sp<Surface> &surface = NULL);
+    Decoder(const sp<AMessage> &notify,
+            const sp<NativeWindowWrapper> &nativeWindow = NULL);
 
     void configure(const sp<MetaData> &meta);
 
@@ -47,7 +48,7 @@
     };
 
     sp<AMessage> mNotify;
-    sp<Surface> mSurface;
+    sp<NativeWindowWrapper> mNativeWindow;
 
     sp<ACodec> mCodec;
     sp<DecoderWrapper> mWrapper;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index ac19a2f..0eca958 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -86,6 +86,13 @@
     return OK;
 }
 
+status_t NuPlayerDriver::setVideoSurfaceTexture(
+        const sp<ISurfaceTexture> &surfaceTexture) {
+    mPlayer->setVideoSurfaceTexture(surfaceTexture);
+
+    return OK;
+}
+
 status_t NuPlayerDriver::prepare() {
     return OK;
 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index e3a5de4..67d0f3e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -36,6 +36,8 @@
     virtual status_t setDataSource(const sp<IStreamSource> &source);
 
     virtual status_t setVideoSurface(const sp<Surface> &surface);
+    virtual status_t setVideoSurfaceTexture(
+            const sp<ISurfaceTexture> &surfaceTexture);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();