| Index: talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
|
| diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
|
| index 4809cf65b29b13d7d59b0bf623b4b657f489a7c6..8c1293c47286ea68a38aa1e3acbe2088c31797f8 100644
|
| --- a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
|
| +++ b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java
|
| @@ -27,7 +27,6 @@
|
|
|
| package org.webrtc;
|
|
|
| -import android.graphics.SurfaceTexture;
|
| import android.media.MediaCodec;
|
| import android.media.MediaCodecInfo;
|
| import android.media.MediaCodecInfo.CodecCapabilities;
|
| @@ -47,7 +46,8 @@ import java.nio.ByteBuffer;
|
| // This class is an implementation detail of the Java PeerConnection API.
|
| // MediaCodec is thread-hostile so this class must be operated on a single
|
| // thread.
|
| -public class MediaCodecVideoDecoder {
|
| +public class MediaCodecVideoDecoder
|
| + implements SurfaceTextureHelper.OnTextureFrameAvailableListener {
|
| // This class is constructed, operated, and destroyed by its C++ incarnation,
|
| // so the class and its methods have non-public visibility. The API this
|
| // class exposes aims to mimic the webrtc::VideoDecoder API as closely as
|
| @@ -91,11 +91,11 @@ public class MediaCodecVideoDecoder {
|
| private int height;
|
| private int stride;
|
| private int sliceHeight;
|
| + // |nativeDecoder| is a webrc_jni::MediaCodecVideoDecoder* pointer to the parent.
|
| + private long nativeDecoder;
|
| private boolean useSurface;
|
| - private int textureID = -1;
|
| - private SurfaceTexture surfaceTexture = null;
|
| - private Surface surface = null;
|
| - private EglBase eglBase;
|
| + private Surface surface;
|
| + private SurfaceTextureHelper surfaceTextureHelper;
|
|
|
| private MediaCodecVideoDecoder() { }
|
|
|
| @@ -180,10 +180,12 @@ public class MediaCodecVideoDecoder {
|
| }
|
|
|
| // Pass null in |sharedContext| to configure the codec for ByteBuffer output.
|
| - private boolean initDecode(VideoCodecType type, int width, int height, EGLContext sharedContext) {
|
| + private boolean initDecode(long nativeDecoder, VideoCodecType type, int width, int height,
|
| + EGLContext sharedContext) {
|
| if (mediaCodecThread != null) {
|
| throw new RuntimeException("Forgot to release()?");
|
| }
|
| + this.nativeDecoder = nativeDecoder;
|
| useSurface = (sharedContext != null);
|
| String mime = null;
|
| String[] supportedCodecPrefixes = null;
|
| @@ -208,24 +210,14 @@ public class MediaCodecVideoDecoder {
|
| }
|
| mediaCodecThread = Thread.currentThread();
|
| try {
|
| - Surface decodeSurface = null;
|
| this.width = width;
|
| this.height = height;
|
| stride = width;
|
| sliceHeight = height;
|
|
|
| if (useSurface) {
|
| - // Create shared EGL context.
|
| - eglBase = new EglBase(sharedContext, EglBase.ConfigType.PIXEL_BUFFER);
|
| - eglBase.createDummyPbufferSurface();
|
| - eglBase.makeCurrent();
|
| -
|
| - // Create output surface
|
| - textureID = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
| - Logging.d(TAG, "Video decoder TextureID = " + textureID);
|
| - surfaceTexture = new SurfaceTexture(textureID);
|
| - surface = new Surface(surfaceTexture);
|
| - decodeSurface = surface;
|
| + surfaceTextureHelper = new SurfaceTextureHelper(sharedContext, this);
|
| + surface = new Surface(surfaceTextureHelper.getSurfaceTexture());
|
| }
|
|
|
| MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
|
| @@ -238,7 +230,7 @@ public class MediaCodecVideoDecoder {
|
| if (mediaCodec == null) {
|
| return false;
|
| }
|
| - mediaCodec.configure(format, decodeSurface, null, 0);
|
| + mediaCodec.configure(format, surface, null, 0);
|
| mediaCodec.start();
|
| colorFormat = properties.colorFormat;
|
| outputBuffers = mediaCodec.getOutputBuffers();
|
| @@ -265,16 +257,22 @@ public class MediaCodecVideoDecoder {
|
| mediaCodecThread = null;
|
| if (useSurface) {
|
| surface.release();
|
| - if (textureID != 0) {
|
| - Logging.d(TAG, "Delete video decoder TextureID " + textureID);
|
| - GLES20.glDeleteTextures(1, new int[] {textureID}, 0);
|
| - textureID = 0;
|
| - }
|
| - eglBase.release();
|
| - eglBase = null;
|
| + surface = null;
|
| + surfaceTextureHelper.disconnect();
|
| + surfaceTextureHelper = null;
|
| }
|
| }
|
|
|
| + @Override
|
| + public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) {
|
| + // Forward to JNI class.
|
| + nativeOnTextureFrame(nativeDecoder, width, height, oesTextureId, transformMatrix, timestampNs);
|
| + }
|
| +
|
| + public void returnTextureFrame() {
|
| + surfaceTextureHelper.returnTextureFrame();
|
| + }
|
| +
|
| // Dequeue an input buffer and return its index, -1 if no input buffer is
|
| // available, or -2 if the codec is no longer operative.
|
| private int dequeueInputBuffer() {
|
| @@ -387,4 +385,7 @@ public class MediaCodecVideoDecoder {
|
| return false;
|
| }
|
| }
|
| +
|
| + private static native void nativeOnTextureFrame(long nativeDecoder, int width, int height,
|
| + int oesTextureId, float[] transformMatrix, long timestampNs);
|
| }
|
|
|