diff options
author | Glenn Kasten <gkasten@google.com> | 2011-02-08 17:26:17 -0800 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2011-02-23 15:02:56 -0800 |
commit | cc562a3576a6a8096626387472e05e8bee03352a (patch) | |
tree | 86b53d7654e5e4a57d623dd616df57aa05801616 /media/jni | |
parent | 1beb48055208bca57c6bf9d26676f86386e3a5dc (diff) | |
download | frameworks_base-cc562a3576a6a8096626387472e05e8bee03352a.zip frameworks_base-cc562a3576a6a8096626387472e05e8bee03352a.tar.gz frameworks_base-cc562a3576a6a8096626387472e05e8bee03352a.tar.bz2 |
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
Diffstat (limited to 'media/jni')
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index ca54432..6d074e9 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -35,6 +35,8 @@ #include "utils/String8.h" #include "android_util_Binder.h" #include <binder/Parcel.h> +#include <gui/SurfaceTexture.h> +#include <gui/ISurfaceTexture.h> #include <surfaceflinger/Surface.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -48,8 +50,11 @@ using namespace android; struct fields_t { jfieldID context; jfieldID surface; + jfieldID surfaceTexture; /* actually in android.view.Surface XXX */ jfieldID surface_native; + // actually in android.graphics.SurfaceTexture + jfieldID surfaceTexture_native; jmethodID post_event; }; @@ -110,6 +115,13 @@ static Surface* get_surface(JNIEnv* env, jobject clazz) return (Surface*)env->GetIntField(clazz, fields.surface_native); } +sp<ISurfaceTexture> getSurfaceTexture(JNIEnv* env, jobject clazz) +{ + sp<ISurfaceTexture> surfaceTexture( + (ISurfaceTexture*)env->GetIntField(clazz, fields.surfaceTexture_native)); + return surfaceTexture; +} + static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz) { Mutex::Autolock l(sLock); @@ -288,26 +300,40 @@ android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fil process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." ); } -static void setVideoSurface(const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz) +static void setVideoSurfaceOrSurfaceTexture( + const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz, const char *prefix) { + // The Java MediaPlayer class makes sure that at most one of mSurface and + // mSurfaceTexture is non-null. But just in case, we give priority to + // mSurface over mSurfaceTexture. jobject surface = env->GetObjectField(thiz, fields.surface); if (surface != NULL) { - const sp<Surface> native_surface = get_surface(env, surface); - LOGV("prepare: surface=%p (id=%d)", + sp<Surface> native_surface(get_surface(env, surface)); + LOGV("%s: surface=%p (id=%d)", prefix, native_surface.get(), native_surface->getIdentity()); mp->setVideoSurface(native_surface); + } else { + jobject surfaceTexture = env->GetObjectField(thiz, fields.surfaceTexture); + if (surfaceTexture != NULL) { + sp<ISurfaceTexture> native_surfaceTexture( + getSurfaceTexture(env, surfaceTexture)); + LOGV("%s: texture=%p (id=%d)", prefix, + native_surfaceTexture.get(), native_surfaceTexture->getIdentity()); + mp->setVideoSurfaceTexture(native_surfaceTexture); + } } } static void -android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz) +android_media_MediaPlayer_setVideoSurfaceOrSurfaceTexture(JNIEnv *env, jobject thiz) { sp<MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); return; } - setVideoSurface(mp, env, thiz); + setVideoSurfaceOrSurfaceTexture(mp, env, thiz, + "_setVideoSurfaceOrSurfaceTexture"); } static void @@ -318,7 +344,7 @@ android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz) jniThrowException(env, "java/lang/IllegalStateException", NULL); return; } - setVideoSurface(mp, env, thiz); + setVideoSurfaceOrSurfaceTexture(mp, env, thiz, "prepare"); process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." ); } @@ -330,13 +356,7 @@ android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz) jniThrowException(env, "java/lang/IllegalStateException", NULL); return; } - jobject surface = env->GetObjectField(thiz, fields.surface); - if (surface != NULL) { - const sp<Surface> native_surface = get_surface(env, surface); - LOGV("prepareAsync: surface=%p (id=%d)", - native_surface.get(), native_surface->getIdentity()); - mp->setVideoSurface(native_surface); - } + setVideoSurfaceOrSurfaceTexture(mp, env, thiz, "prepareAsync"); process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." ); } @@ -640,9 +660,34 @@ android_media_MediaPlayer_native_init(JNIEnv *env) fields.surface_native = env->GetFieldID(surface, ANDROID_VIEW_SURFACE_JNI_ID, "I"); if (fields.surface_native == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface"); + jniThrowException(env, "java/lang/RuntimeException", + "Can't find Surface." ANDROID_VIEW_SURFACE_JNI_ID); return; } + + fields.surfaceTexture = env->GetFieldID(clazz, "mSurfaceTexture", + "Landroid/graphics/SurfaceTexture;"); + if (fields.surfaceTexture == NULL) { + jniThrowException(env, "java/lang/RuntimeException", + "Can't find MediaPlayer.mSurfaceTexture"); + return; + } + + jclass surfaceTexture = env->FindClass("android/graphics/SurfaceTexture"); + if (surfaceTexture == NULL) { + jniThrowException(env, "java/lang/RuntimeException", + "Can't find android/graphics/SurfaceTexture"); + return; + } + + fields.surfaceTexture_native = env->GetFieldID(surfaceTexture, + ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); + if (fields.surfaceTexture_native == NULL) { + jniThrowException(env, "java/lang/RuntimeException", + "Can't find SurfaceTexture." ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID); + return; + } + } static void @@ -746,7 +791,7 @@ static JNINativeMethod gMethods[] = { {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource}, {"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders}, {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD}, - {"_setVideoSurface", "()V", (void *)android_media_MediaPlayer_setVideoSurface}, + {"_setVideoSurfaceOrSurfaceTexture", "()V", (void *)android_media_MediaPlayer_setVideoSurfaceOrSurfaceTexture}, {"prepare", "()V", (void *)android_media_MediaPlayer_prepare}, {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync}, {"_start", "()V", (void *)android_media_MediaPlayer_start}, |