Support for setting a ParcelSurfaceTexture as the MediaPlayer sink.

This adds support for setting a SurfaceTexture as the MediaPlayer video
sink by using a ParcelSurfaceTexture object. The goal is to enable a
SurfaceTexture to pass through Binder (via ParcelSurfaceTexture) and then
be set on the MediaPlayer.

Change-Id: Ife5689ce673eb4bee1c377019db761685217b71d
This commit is contained in:
tedbo
2011-06-10 13:05:32 -07:00
parent 8aec83eb15
commit cc5278a3e2
6 changed files with 48 additions and 70 deletions

View File

@ -19,6 +19,7 @@
#include <gui/SurfaceTextureClient.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <utils/Log.h>
@ -27,7 +28,6 @@
#include "android_util_Binder.h"
#include "jni.h"
#include "JNIHelp.h"
#include "SurfaceTexture.h"
// ----------------------------------------------------------------------------
@ -59,7 +59,7 @@ static void ParcelSurfaceTexture_setISurfaceTexture(
env->SetIntField(thiz, fields.iSurfaceTexture, (int)iSurfaceTexture.get());
}
static sp<ISurfaceTexture> ParcelSurfaceTexture_getISurfaceTexture(
sp<ISurfaceTexture> ParcelSurfaceTexture_getISurfaceTexture(
JNIEnv* env, jobject thiz)
{
sp<ISurfaceTexture> iSurfaceTexture(

View File

@ -1,31 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_GRAPHICS_SURFACETEXTURE_H
#define _ANDROID_GRAPHICS_SURFACETEXTURE_H
#include <gui/SurfaceTexture.h>
#include <utils/StrongPointer.h>
#include "jni.h"
namespace android {
/* Gets the underlying SurfaceTexture from a SurfaceTexture Java object. */
sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz);
} // namespace android
#endif // _ANDROID_GRAPHICS_SURFACETEXTURE_H

View File

@ -23,10 +23,15 @@
namespace android {
class ISurfaceTexture;
extern sp<ANativeWindow> android_ParcelSurfaceTexture_getNativeWindow(
JNIEnv* env, jobject thiz);
extern bool android_ParcelSurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);
/* Gets the underlying ISurfaceTexture from a ParcelSurfaceTexture Java object. */
extern sp<ISurfaceTexture> ParcelSurfaceTexture_getISurfaceTexture(JNIEnv* env, jobject thiz);
} // namespace android
#endif // _ANDROID_GRAPHICS_PARCELSURFACETEXTURE_H

View File

@ -23,10 +23,14 @@
namespace android {
class SurfaceTexture;
extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
JNIEnv* env, jobject thiz);
extern bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);
/* Gets the underlying SurfaceTexture from a SurfaceTexture Java object. */
extern sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz);
} // namespace android

View File

@ -30,6 +30,7 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.graphics.Bitmap;
import android.graphics.ParcelSurfaceTexture;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
@ -509,7 +510,7 @@ public class MediaPlayer
private int mListenerContext; // accessed by native methods
private Surface mSurface; // accessed by native methods
private SurfaceHolder mSurfaceHolder;
private SurfaceTexture mSurfaceTexture; // accessed by native methods
private ParcelSurfaceTexture mParcelSurfaceTexture; // accessed by native methods
private EventHandler mEventHandler;
private PowerManager.WakeLock mWakeLock = null;
private boolean mScreenOnWhilePlaying;
@ -541,7 +542,7 @@ public class MediaPlayer
/*
* Update the MediaPlayer ISurface and ISurfaceTexture.
* Call after updating mSurface and/or mSurfaceTexture.
* Call after updating mSurface and/or mParcelSurfaceTexture.
*/
private native void _setVideoSurfaceOrSurfaceTexture();
@ -607,7 +608,7 @@ public class MediaPlayer
} else {
mSurface = null;
}
mSurfaceTexture = null;
mParcelSurfaceTexture = null;
_setVideoSurfaceOrSurfaceTexture();
updateSurfaceScreenOn();
}
@ -630,12 +631,32 @@ public class MediaPlayer
* program.
*/
public void setTexture(SurfaceTexture st) {
if (mScreenOnWhilePlaying && st != null && mSurfaceTexture == null) {
ParcelSurfaceTexture pst = null;
if (st != null) {
pst = ParcelSurfaceTexture.fromSurfaceTexture(st);
}
setParcelSurfaceTexture(pst);
}
/**
* Sets the {@link ParcelSurfaceTexture} to be used as the sink for the video portion of
* the media. This is similar to {@link #setTexture(SurfaceTexture)}, but supports using
* a {@link ParcelSurfaceTexture} to transport the texture to be used via Binder. Setting
* a parceled surface texture will un-set any surface or surface texture that was previously
* set. See {@link #setTexture(SurfaceTexture)} for more details.
*
* @param pst The {@link ParcelSurfaceTexture} to be used as the sink for
* the video portion of the media.
*
* @hide Pending review by API council.
*/
public void setParcelSurfaceTexture(ParcelSurfaceTexture pst) {
if (mScreenOnWhilePlaying && pst != null && mParcelSurfaceTexture == null) {
Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for SurfaceTexture");
}
mSurfaceHolder = null;
mSurface = null;
mSurfaceTexture = st;
mParcelSurfaceTexture = pst;
_setVideoSurfaceOrSurfaceTexture();
updateSurfaceScreenOn();
}
@ -962,7 +983,7 @@ public class MediaPlayer
*/
public void setScreenOnWhilePlaying(boolean screenOn) {
if (mScreenOnWhilePlaying != screenOn) {
if (screenOn && mSurfaceTexture != null) {
if (screenOn && mParcelSurfaceTexture != null) {
Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for SurfaceTexture");
}
mScreenOnWhilePlaying = screenOn;

View File

@ -30,6 +30,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/android_graphics_ParcelSurfaceTexture.h"
#include "utils/Errors.h" // for status_t
#include "utils/KeyedVector.h"
#include "utils/String8.h"
@ -37,7 +38,6 @@
#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>
@ -52,11 +52,9 @@ using namespace android;
struct fields_t {
jfieldID context;
jfieldID surface;
jfieldID surfaceTexture;
jfieldID parcelSurfaceTexture;
/* actually in android.view.Surface XXX */
jfieldID surface_native;
// actually in android.graphics.SurfaceTexture
jfieldID surfaceTexture_native;
jmethodID post_event;
};
@ -130,13 +128,6 @@ 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);
@ -257,8 +248,8 @@ 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.
// mParcelSurfaceTexture is non-null. But just in case, we give priority to
// mSurface over mParcelSurfaceTexture.
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
sp<Surface> native_surface(get_surface(env, surface));
@ -266,10 +257,10 @@ static void setVideoSurfaceOrSurfaceTexture(
native_surface.get(), native_surface->getIdentity());
mp->setVideoSurface(native_surface);
} else {
jobject surfaceTexture = env->GetObjectField(thiz, fields.surfaceTexture);
if (surfaceTexture != NULL) {
jobject parcelSurfaceTexture = env->GetObjectField(thiz, fields.parcelSurfaceTexture);
if (parcelSurfaceTexture != NULL) {
sp<ISurfaceTexture> native_surfaceTexture(
getSurfaceTexture(env, surfaceTexture));
ParcelSurfaceTexture_getISurfaceTexture(env, parcelSurfaceTexture));
LOGV("%s: texture=%p", prefix, native_surfaceTexture.get());
mp->setVideoSurfaceTexture(native_surfaceTexture);
}
@ -610,23 +601,11 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
return;
}
fields.surfaceTexture = env->GetFieldID(clazz, "mSurfaceTexture",
"Landroid/graphics/SurfaceTexture;");
if (fields.surfaceTexture == NULL) {
fields.parcelSurfaceTexture = env->GetFieldID(clazz, "mParcelSurfaceTexture",
"Landroid/graphics/ParcelSurfaceTexture;");
if (fields.parcelSurfaceTexture == NULL) {
return;
}
jclass surfaceTexture = env->FindClass("android/graphics/SurfaceTexture");
if (surfaceTexture == NULL) {
return;
}
fields.surfaceTexture_native = env->GetFieldID(surfaceTexture,
ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
if (fields.surfaceTexture_native == NULL) {
return;
}
}
static void