OSDN Git Service

Bug 4099084 native window data locator
authorGlenn Kasten <gkasten@google.com>
Tue, 15 Mar 2011 23:32:17 +0000 (16:32 -0700)
committerGlenn Kasten <gkasten@google.com>
Wed, 16 Mar 2011 00:29:57 +0000 (17:29 -0700)
Change-Id: I03cac7501c3f185a2f95395b140b52b695081c4b

wilhelm/src/Android.mk
wilhelm/src/data.c
wilhelm/src/objects/CMediaPlayer.c
wilhelm/tests/native-media/jni/native-media-jni.c

index d85d736..38a0d30 100644 (file)
@@ -145,7 +145,8 @@ LOCAL_SHARED_LIBRARIES :=         \
         libbinder                 \
         libstagefright            \
         libstagefright_foundation \
-        libcutils
+        libcutils                 \
+        libgui
 
 ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
         LOCAL_LDLIBS += -lpthread -ldl
index 3a23ee2..399d4db 100644 (file)
@@ -170,12 +170,14 @@ static SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *
 
         case XA_DATALOCATOR_NATIVEDISPLAY:
             pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator;
-            // if hDisplay is NULL, then hWindow is NDK C ANativeWindow *
-            // if hDisplay is non-NULL, then:
-            //   hWindow is JNI jobject Surface or SurfaceTexture
-            //   hDisplay is JNIENV *
+            // hWindow is NDK C ANativeWindow * and hDisplay must be NULL
             if (pDataLocator->mNativeDisplay.hWindow == NULL) {
-                SL_LOGE("%s: hWindow must be non-NULL", name);
+                SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name);
+                result = SL_RESULT_PARAMETER_INVALID;
+            }
+            if (pDataLocator->mNativeDisplay.hDisplay != NULL) {
+                SL_LOGE("%s: hDisplay must be NULL, but is %p", name,
+                        pDataLocator->mNativeDisplay.hDisplay);
                 result = SL_RESULT_PARAMETER_INVALID;
             }
             break;
index ea9ad5d..5d3e690 100644 (file)
@@ -28,6 +28,7 @@
 #include <media/IMediaPlayerService.h>
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
 
 #include <fcntl.h>
 #endif
@@ -56,34 +57,39 @@ XAresult CMediaPlayer_Realize(void *self, XAboolean async)
         // if there is a video sink
         if (XA_DATALOCATOR_NATIVEDISPLAY ==
                 thiz->mImageVideoSink.mLocator.mLocatorType) {
-            JNIEnv *env = (JNIEnv *) thiz->mImageVideoSink.mLocator.mNativeDisplay.hDisplay;
-            if (env != NULL) {
-                // FIXME this is a temporary hack because ANativeWindow is not Binderable yet
-                jobject object = (jobject) thiz->mImageVideoSink.mLocator.mNativeDisplay.hWindow;
-                assert(object != NULL);
-                jclass surfaceClass = env->FindClass("android/view/Surface");
-                jclass surfaceTextureClass = env->FindClass("android/graphics/SurfaceTexture");
-                jclass objectClass = env->GetObjectClass(object);
-                if (thiz->mAVPlayer != 0) {
-                    // initialize display surface
-                    android::GenericMediaPlayer* avp =
-                            (android::GenericMediaPlayer*)(thiz->mAVPlayer.get());
-                    if (objectClass == surfaceClass) {
-                        sp<Surface> nativeSurface((Surface *) env->GetIntField(object,
-                                env->GetFieldID(surfaceClass, "mNativeSurface", "I")));
-                        result = android_Player_setVideoSurface(avp, nativeSurface);
-                    } else if (objectClass == surfaceTextureClass) {
-                        sp<ISurfaceTexture> nativeSurfaceTexture((ISurfaceTexture *)
-                                env->GetIntField(object, env->GetFieldID(surfaceTextureClass,
-                                "mSurfaceTexture", "I")));
-                        result = android_Player_setVideoSurfaceTexture(avp, nativeSurfaceTexture);
-                    }
-                }
+            ANativeWindow *nativeWindow = (ANativeWindow *)
+                    thiz->mImageVideoSink.mLocator.mNativeDisplay.hWindow;
+            // we already verified earlier that hWindow is non-NULL
+            assert(nativeWindow != NULL);
+            int err;
+            int value;
+            // this could crash if app passes in a bad parameter, but that's OK
+            err = (*nativeWindow->query)(nativeWindow, NATIVE_WINDOW_CONCRETE_TYPE, &value);
+            if (0 != err) {
+                SL_LOGE("Query NATIVE_WINDOW_CONCRETE_TYPE on ANativeWindow * %p failed; "
+                        "errno %d", nativeWindow, err);
             } else {
-                ANativeWindow *nativeWindow = (ANativeWindow *)
-                        thiz->mImageVideoSink.mLocator.mNativeDisplay.hWindow;
-                assert(nativeWindow != NULL);
-                // FIXME here is where to implement ANativeWindow support
+                android::GenericMediaPlayer* avp =
+                        static_cast<android::GenericMediaPlayer *>(thiz->mAVPlayer.get());
+                switch (value) {
+                case NATIVE_WINDOW_SURFACE: {                // Surface
+                    sp<Surface> nativeSurface(static_cast<Surface *>(nativeWindow));
+                    result = android_Player_setVideoSurface(avp, nativeSurface);
+                    } break;
+                case NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT: { // SurfaceTextureClient
+                    sp<SurfaceTextureClient> surfaceTextureClient(
+                            static_cast<SurfaceTextureClient *>(nativeWindow));
+                    sp<ISurfaceTexture> nativeSurfaceTexture(
+                            surfaceTextureClient->getISurfaceTexture());
+                    result = android_Player_setVideoSurfaceTexture(avp, nativeSurfaceTexture);
+                    } break;
+                case NATIVE_WINDOW_FRAMEBUFFER:              // FramebufferNativeWindow
+                    // fall through
+                default:
+                    SL_LOGE("ANativeWindow * %p has unknown or unsupported concrete type %d",
+                            nativeWindow, value);
+                    break;
+                }
             }
         }
     }
index fe087fc..285dca3 100644 (file)
@@ -27,9 +27,6 @@
 
 #include <android/native_window_jni.h>
 
-// define as 1 if ANativeWindow * is not supported as a video sink
-#define NO_NATIVE_WINDOW 1
-
 // engine interfaces
 static XAObjectItf engineObject = NULL;
 static XAEngineItf engineEngine;
@@ -46,12 +43,8 @@ static XAVolumeItf             playerVolItf;
 // number of required interfaces for the MediaPlayer creation
 #define NB_MAXAL_INTERFACES 3 // XAAndroidBufferQueueItf, XAStreamInformationItf and XAPlayItf
 
-// cached surface where the video display happens
-#if NO_NATIVE_WINDOW
-static jobject theSurfaceOrSurfaceTexture;
-#else
+// video sink for the player
 static ANativeWindow* theNativeWindow;
-#endif
 
 // number of buffers in our buffer queue
 #define NB_BUFFERS 16
@@ -229,15 +222,10 @@ jboolean Java_com_example_nativemedia_NativeMedia_createStreamingMediaPlayer(JNI
     // configure image video sink
     XADataLocator_NativeDisplay loc_nd = {
             XA_DATALOCATOR_NATIVEDISPLAY,        // locatorType
-#if NO_NATIVE_WINDOW
-            (void *) theSurfaceOrSurfaceTexture, // jobject
-            (void *) env                         // JNIEnv *env
-#else
-            // later the video sink can be an ANativeWindow created from a Surface or SurfaceTexture
+            // the video sink must be an ANativeWindow created from a Surface or SurfaceTexture
             (void*)theNativeWindow,              // hWindow
             // must be NULL
             NULL                                 // hDisplay
-#endif
     };
     XADataSink imageVideoSink = {&loc_nd, NULL};
 
@@ -366,25 +354,19 @@ void Java_com_example_nativemedia_NativeMedia_shutdown(JNIEnv* env, jclass clazz
         file = NULL;
     }
 
-#if !NO_NATIVE_WINDOW
     // make sure we don't leak native windows
     if (theNativeWindow != NULL) {
         ANativeWindow_release(theNativeWindow);
         theNativeWindow = NULL;
     }
-#endif
 }
 
 
 // set the surface
 void Java_com_example_nativemedia_NativeMedia_setSurface(JNIEnv *env, jclass clazz, jobject surface)
 {
-#if NO_NATIVE_WINDOW
-    theSurfaceOrSurfaceTexture = surface;
-#else
     // obtain a native window from a Java surface
     theNativeWindow = ANativeWindow_fromSurface(env, surface);
-#endif
 }
 
 
@@ -392,10 +374,6 @@ void Java_com_example_nativemedia_NativeMedia_setSurface(JNIEnv *env, jclass cla
 void Java_com_example_nativemedia_NativeMedia_setSurfaceTexture(JNIEnv *env, jclass clazz,
         jobject surfaceTexture)
 {
-#if NO_NATIVE_WINDOW
-    theSurfaceOrSurfaceTexture = surfaceTexture;
-#else
     // obtain a native window from a Java surface texture
     theNativeWindow = ANativeWindow_fromSurfaceTexture(env, surfaceTexture);
-#endif
 }