summaryrefslogtreecommitdiffstats
path: root/media/jni
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2011-02-08 17:26:17 -0800
committerGlenn Kasten <gkasten@google.com>2011-02-23 15:02:56 -0800
commitcc562a3576a6a8096626387472e05e8bee03352a (patch)
tree86b53d7654e5e4a57d623dd616df57aa05801616 /media/jni
parent1beb48055208bca57c6bf9d26676f86386e3a5dc (diff)
downloadframeworks_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.cpp75
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},