下面列出了android.graphics.SurfaceTexture#setOnFrameAvailableListener ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 映像入力用SurfaceTexture/Surfaceを再生成する
*/
@SuppressLint("NewApi")
@WorkerThread
protected void handleReCreateInputSurface() {
if (DEBUG) Log.v(TAG, "handleReCreateInputSurface:");
synchronized (mSync) {
mEglTask.makeCurrent();
handleReleaseInputSurface();
mEglTask.makeCurrent();
if (isOES3()) {
mTexId = com.serenegiant.glutils.es3.GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE0, GLES30.GL_NEAREST);
} else {
mTexId = com.serenegiant.glutils.es2.GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE0, GLES20.GL_NEAREST);
}
mInputTexture = new SurfaceTexture(mTexId);
mInputSurface = new Surface(mInputTexture);
if (BuildCheck.isAndroid4_1()) {
// XXX getIntrinsicWidth/getIntrinsicHeightの代わりにmImageWidth/mImageHeightを使うべきかも?
mInputTexture.setDefaultBufferSize(getIntrinsicWidth(), getIntrinsicHeight());
}
mInputTexture.setOnFrameAvailableListener(mOnFrameAvailableListener);
}
onCreateSurface(mInputSurface);
}
/**
* Handles the surface-created callback from SurfaceView. Prepares GLES and the Surface.
*/
private void surfaceAvailable(SurfaceHolder holder, boolean newSurface) {
Surface surface = holder.getSurface();
mWindowSurface = new WindowSurface(mEglCore, surface, false);
mWindowSurface.makeCurrent();
// Create and configure the SurfaceTexture, which will receive frames from the
// camera. We set the textured rect's program to render from it.
mTexProgram = new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT);
int textureId = mTexProgram.createTextureObject();
mCameraTexture = new SurfaceTexture(textureId);
mRect.setTexture(textureId);
if (!newSurface) {
// This Surface was established on a previous run, so no surfaceChanged()
// message is forthcoming. Finish the surface setup now.
//
// We could also just call this unconditionally, and perhaps do an unnecessary
// bit of reallocating if a surface-changed message arrives.
mWindowSurfaceWidth = mWindowSurface.getWidth();
mWindowSurfaceHeight = mWindowSurface.getHeight();
finishSurfaceSetup();
}
mCameraTexture.setOnFrameAvailableListener(this);
}
private void initSurfaceTexture() {
Log.d(LOGTAG, "initSurfaceTexture");
deleteSurfaceTexture();
initTexOES(texCamera);
mSTexture = new SurfaceTexture(texCamera[0]);
mSTexture.setOnFrameAvailableListener(this);
}
private void setup() {
mTextureRender = new TextureRenderer(rotateRender);
mTextureRender.surfaceCreated();
mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
mSurfaceTexture.setOnFrameAvailableListener(this);
mSurface = new Surface(mSurfaceTexture);
}
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
super.init();
/*
* Create the SurfaceTexture that will feed this textureID, and pass
* it to the MediaPlayer
*/
mSurface = new SurfaceTexture(getTexture());
mSurface.setOnFrameAvailableListener(this);
Surface surface = new Surface(mSurface);
mMediaPlayer.setSurface(surface);
mMediaPlayer.setScreenOnWhilePlaying(true);
surface.release();
if (!isMediaPlayerPrepared) {
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
isMediaPlayerPrepared = true;
}
synchronized (this) {
updateSurface = false;
}
mMediaPlayer.start();
}
private void initSurfaceTexture() {
Log.d(LOGTAG, "initSurfaceTexture");
deleteSurfaceTexture();
initTexOES(texCamera);
mSTexture = new SurfaceTexture(texCamera[0]);
mSTexture.setOnFrameAvailableListener(this);
}
/**
* Creates an OutputSurface using the current EGL context. Creates a Surface that can be
* passed to MediaCodec.setMediaFormat().
*
* @param eglUtil
*/
public OutputSurface(IEglUtil eglUtil) {
this.eglUtil = eglUtil;
textureRender = new TextureRenderer(this.eglUtil);
textureRender.surfaceCreated();
// Even if we don't access the SurfaceTexture after the constructor returns, we
// still need to keep a reference to it. The Surface doesn't retain a reference
// at the Java level, so if we don't either then the object can get GCed, which
// causes the native finalizer to run.
//if (VERBOSE) //Log.d(TAG, "textureID=" + mTextureRender.getTextureId());
textureId = this.eglUtil.createTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
surfaceTexture = new SurfaceTexture(textureId);
// This doesn't work if OutputSurface is created on the thread that CTS started for
// these test cases.
//
// The CTS-created thread has a Looper, and the SurfaceTexture constructor will
// create a Handler that uses it. The "frame available" message is delivered
// there, but since we're not a Looper-based thread we'll never see it. For
// this to do anything useful, OutputSurface must be created on a thread without
// a Looper, so that SurfaceTexture uses the main application Looper instead.
//
// Java language note: passing "this" out of a constructor is generally unwise,
// but we should be able to get away with it here.
surfaceTexture.setOnFrameAvailableListener(this);
surface = new Surface(surfaceTexture);
}
/**
* Creates instances of TextureRender and SurfaceTexture, and a Surface associated
* with the SurfaceTexture.
*/
private void setup() {
mTextureRender = new TextureRender();
mTextureRender.surfaceCreated();
// Even if we don't access the SurfaceTexture after the constructor returns, we
// still need to keep a reference to it. The Surface doesn't retain a reference
// at the Java level, so if we don't either then the object can get GCed, which
// causes the native finalizer to run.
if (VERBOSE) Log.d(TAG, "textureID=" + mTextureRender.getTextureId());
mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
// This doesn't work if OutputSurface is created on the thread that CTS started for
// these test cases.
//
// The CTS-created thread has a Looper, and the SurfaceTexture constructor will
// create a Handler that uses it. The "frame available" message is delivered
// there, but since we're not a Looper-based thread we'll never see it. For
// this to do anything useful, OutputSurface must be created on a thread without
// a Looper, so that SurfaceTexture uses the main application Looper instead.
//
// Java language note: passing "this" out of a constructor is generally unwise,
// but we should be able to get away with it here.
mSurfaceTexture.setOnFrameAvailableListener(this);
mSurface = new Surface(mSurfaceTexture);
}
private void initSurfaceTexture() {
Log.d(LOGTAG, "initSurfaceTexture");
deleteSurfaceTexture();
initTexOES(texCamera);
mSTexture = new SurfaceTexture(texCamera[0]);
mSTexture.setOnFrameAvailableListener(this);
}
private void initSurfaceTexture() {
Log.d(LOGTAG, "initSurfaceTexture");
deleteSurfaceTexture();
initTexOES(texCamera);
mSTexture = new SurfaceTexture(texCamera[0]);
mSTexture.setOnFrameAvailableListener(this);
}
/**
* Connects the SurfaceTexture to the Camera preview output, and starts the preview.
*/
private void handleSetSurfaceTexture(SurfaceTexture st) {
st.setOnFrameAvailableListener(this);
try {
mCamera.setPreviewTexture(st);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
mCamera.startPreview();
}
private void setup() {
mTextureRender = new TextureRenderer(rotateRender);
mTextureRender.surfaceCreated();
mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
mSurfaceTexture.setOnFrameAvailableListener(this);
mSurface = new Surface(mSurfaceTexture);
}
/**
* Initializes required EGL parameters and creates the {@link SurfaceTexture}.
*
* @param secureMode The {@link SecureMode} to be used for EGL surface.
*/
public void init(@SecureMode int secureMode) {
display = getDefaultDisplay();
EGLConfig config = chooseEGLConfig(display);
context = createEGLContext(display, config, secureMode);
surface = createEGLSurface(display, config, context, secureMode);
generateTextureIds(textureIdHolder);
texture = new SurfaceTexture(textureIdHolder[0]);
texture.setOnFrameAvailableListener(this);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Create OES texture for storing camera preview data(YUV format)
GLES20.glGenTextures(1, camTextureId, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
surfaceTexture = new SurfaceTexture(camTextureId[0]);
surfaceTexture.setOnFrameAvailableListener(this);
// Prepare vertex and texture coordinates
int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexCoordsBuffer.put(vertexCoords).position(0);
textureCoordsBuffer.put(textureCoords).position(0);
// Create vertex and fragment shaders
// camTextureId->fboTexureId
progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcCam2FBO);
GLES20.glEnableVertexAttribArray(tcCam2FBO);
// fboTexureId/drawTexureId -> screen
progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcTex2Screen);
GLES20.glEnableVertexAttribArray(tcTex2Screen);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Create OES texture for storing camera preview data(YUV format)
GLES20.glGenTextures(1, camTextureId, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
surfaceTexture = new SurfaceTexture(camTextureId[0]);
surfaceTexture.setOnFrameAvailableListener(this);
// Prepare vertex and texture coordinates
int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexCoordsBuffer.put(vertexCoords).position(0);
textureCoordsBuffer.put(textureCoords).position(0);
// Create vertex and fragment shaders
// camTextureId->fboTexureId
progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcCam2FBO);
GLES20.glEnableVertexAttribArray(tcCam2FBO);
// fboTexureId/drawTexureId -> screen
progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcTex2Screen);
GLES20.glEnableVertexAttribArray(tcTex2Screen);
}
/**
* Initializes required EGL parameters and creates the {@link SurfaceTexture}.
*
* @param secureMode The {@link SecureMode} to be used for EGL surface.
*/
public void init(@SecureMode int secureMode) {
display = getDefaultDisplay();
EGLConfig config = chooseEGLConfig(display);
context = createEGLContext(display, config, secureMode);
surface = createEGLSurface(display, config, context, secureMode);
generateTextureIds(textureIdHolder);
texture = new SurfaceTexture(textureIdHolder[0]);
texture.setOnFrameAvailableListener(this);
}
private void initSurfaceTexture() {
Log.d(LOGTAG, "initSurfaceTexture");
deleteSurfaceTexture();
initTexOES(texCamera);
mSTexture = new SurfaceTexture(texCamera[0]);
mSTexture.setOnFrameAvailableListener(this);
}
public GlSurfaceTexture(final int texName) {
surfaceTexture = new SurfaceTexture(texName);
surfaceTexture.setOnFrameAvailableListener(this);
}
@CalledByNative
private static void setFrameAvailableCallback(SurfaceTexture surfaceTexture,
int nativeSurfaceTextureListener) {
surfaceTexture.setOnFrameAvailableListener(
new SurfaceTextureListener(nativeSurfaceTextureListener));
}
@Override
protected void initWithGLContext() {
ready = false;
try {
player = MediaPlayer.create(context, id);
} catch (Exception e) {
Log.e("VideoPlayer", "Failed to load video");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.e("VideoPlayer", sw.toString());
player.release();
}
setRenderSize(player.getVideoWidth(), player.getVideoHeight());
super.initWithGLContext();
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
texture_in = textures[0];
videoTex = new SurfaceTexture(texture_in);
videoTex.setOnFrameAvailableListener(this);
Surface surface = new Surface(videoTex);
player.setSurface(surface);
ready = true;
if(startWhenReady) {
player.start();
}
}