Chromium Code Reviews| 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() { |
|
perkj_webrtc
2015/09/22 12:40:37
checkOnMediaCodecThread();
|
| + surfaceTextureHelper.returnTextureFrame(); |
|
perkj_webrtc
2015/09/22 12:40:37
What guarantees that this object is alive when the
|
| + } |
| + |
| // 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); |
| } |