From f0159a742f39fe746053430a04b844ef2ead0770 Mon Sep 17 00:00:00 2001 From: Alex Glaznev Date: Thu, 8 Oct 2015 12:59:21 -0700 Subject: [PATCH] Allow to print Java stack traces in Android camera, renderer and media codec. R=wzh@webrtc.org Review URL: https://codereview.webrtc.org/1396873002 . Cr-Commit-Position: refs/heads/master@{#10227} --- .../org/webrtc/VideoCapturerAndroid.java | 13 ++++++- .../android/org/webrtc/VideoRendererGui.java | 34 +++++++++++++++++-- .../org/webrtc/MediaCodecVideoDecoder.java | 17 +++++++--- .../org/webrtc/MediaCodecVideoEncoder.java | 15 ++++++-- .../src/org/webrtc/PeerConnectionFactory.java | 26 +++++++------- 5 files changed, 84 insertions(+), 21 deletions(-) diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java index 7ec86b005b..9fdd41af9a 100644 --- a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java +++ b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java @@ -35,7 +35,6 @@ import android.opengl.EGLContext; import android.os.Handler; import android.os.HandlerThread; import android.os.SystemClock; -import android.text.StaticLayout; import android.view.Surface; import android.view.WindowManager; @@ -217,6 +216,18 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba return capturer; } + public void printStackTrace() { + if (cameraThread != null) { + StackTraceElement[] cameraStackTraces = cameraThread.getStackTrace(); + if (cameraStackTraces.length > 0) { + Logging.d(TAG, "VideoCapturerAndroid stacks trace:"); + for (StackTraceElement stackTrace : cameraStackTraces) { + Logging.d(TAG, stackTrace.toString()); + } + } + } + } + // Switch camera to the next valid camera id. This can only be called while // the camera is running. public void switchCamera(final CameraSwitchHandler handler) { diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java index afaebf6f2e..1d413b8ece 100644 --- a/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java +++ b/talk/app/webrtc/java/android/org/webrtc/VideoRendererGui.java @@ -36,12 +36,10 @@ import javax.microedition.khronos.opengles.GL10; import android.annotation.SuppressLint; import android.graphics.Point; import android.graphics.Rect; -import android.graphics.SurfaceTexture; import android.opengl.EGL14; import android.opengl.EGLContext; import android.opengl.GLES20; import android.opengl.GLSurfaceView; -import android.opengl.Matrix; import org.webrtc.Logging; import org.webrtc.VideoRenderer.I420Frame; @@ -77,6 +75,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { // Current SDK version. private static final int CURRENT_SDK_VERSION = android.os.Build.VERSION.SDK_INT; + // Render and draw threads. + private static Thread renderFrameThread; + private static Thread drawThread; private VideoRendererGui(GLSurfaceView surface) { this.surface = surface; @@ -372,6 +373,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { VideoRenderer.renderFrameDone(frame); return; } + if (renderFrameThread == null) { + renderFrameThread = Thread.currentThread(); + } if (!seenFrame && rendererEvents != null) { Logging.d(TAG, "ID: " + id + ". Reporting first rendered frame."); rendererEvents.onFirstFrameRendered(); @@ -394,6 +398,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { // Skip rendering of this frame if previous frame was not rendered yet. framesDropped++; VideoRenderer.renderFrameDone(frame); + seenFrame = true; return; } pendingFrame = frame; @@ -430,6 +435,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { } instance.yuvImageRenderers.clear(); } + renderFrameThread = null; + drawThread = null; instance.surface = null; eglContext = null; eglContextReady = null; @@ -565,6 +572,26 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { } } + private static void printStackTrace(Thread thread, String threadName) { + if (thread != null) { + StackTraceElement[] stackTraces = thread.getStackTrace(); + if (stackTraces.length > 0) { + Logging.d(TAG, threadName + " stacks trace:"); + for (StackTraceElement stackTrace : stackTraces) { + Logging.d(TAG, stackTrace.toString()); + } + } + } + } + + public static synchronized void printStackTraces() { + if (instance == null) { + return; + } + printStackTrace(renderFrameThread, "Render frame thread"); + printStackTrace(drawThread, "Draw thread"); + } + @SuppressLint("NewApi") @Override public void onSurfaceCreated(GL10 unused, EGLConfig config) { @@ -613,6 +640,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer { @Override public void onDrawFrame(GL10 unused) { + if (drawThread == null) { + drawThread = Thread.currentThread(); + } GLES20.glViewport(0, 0, screenWidth, screenHeight); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); synchronized (yuvImageRenderers) { diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java index 5312fe39a8..f6dcf15b35 100644 --- a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java +++ b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java @@ -32,9 +32,6 @@ import android.media.MediaCodecInfo; import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecList; import android.media.MediaFormat; -import android.opengl.EGLContext; -import android.opengl.GLES11Ext; -import android.opengl.GLES20; import android.os.Build; import android.view.Surface; @@ -65,7 +62,7 @@ public class MediaCodecVideoDecoder { } private static final int DEQUEUE_INPUT_TIMEOUT = 500000; // 500 ms timeout. - private Thread mediaCodecThread; + private static Thread mediaCodecThread; private MediaCodec mediaCodec; private ByteBuffer[] inputBuffers; private ByteBuffer[] outputBuffers; @@ -173,6 +170,18 @@ public class MediaCodecVideoDecoder { return findDecoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null; } + public static void printStackTrace() { + if (mediaCodecThread != null) { + StackTraceElement[] mediaCodecStackTraces = mediaCodecThread.getStackTrace(); + if (mediaCodecStackTraces.length > 0) { + Logging.d(TAG, "MediaCodecVideoDecoder stacks trace:"); + for (StackTraceElement stackTrace : mediaCodecStackTraces) { + Logging.d(TAG, stackTrace.toString()); + } + } + } + } + private void checkOnMediaCodecThread() throws IllegalStateException { if (mediaCodecThread.getId() != Thread.currentThread().getId()) { throw new IllegalStateException( diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java index dfff8f2691..705dcd1a35 100644 --- a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java +++ b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java @@ -25,7 +25,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - package org.webrtc; import android.media.MediaCodec; @@ -62,7 +61,7 @@ public class MediaCodecVideoEncoder { } private static final int DEQUEUE_TIMEOUT = 0; // Non-blocking, no wait. - private Thread mediaCodecThread; + private static Thread mediaCodecThread; private MediaCodec mediaCodec; private ByteBuffer[] outputBuffers; private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8"; @@ -197,6 +196,18 @@ public class MediaCodecVideoEncoder { } } + public static void printStackTrace() { + if (mediaCodecThread != null) { + StackTraceElement[] mediaCodecStackTraces = mediaCodecThread.getStackTrace(); + if (mediaCodecStackTraces.length > 0) { + Logging.d(TAG, "MediaCodecVideoEncoder stacks trace:"); + for (StackTraceElement stackTrace : mediaCodecStackTraces) { + Logging.d(TAG, stackTrace.toString()); + } + } + } + } + static MediaCodec createByCodecName(String codecName) { try { // In the L-SDK this call can throw IOException so in order to work in diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java index 6bc8189cd8..0460624aa7 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java @@ -148,19 +148,21 @@ public class PeerConnectionFactory { nativeThreadsCallbacks(nativeFactory); } + private static void printStackTrace(Thread thread, String threadName) { + if (thread != null) { + StackTraceElement[] stackTraces = thread.getStackTrace(); + if (stackTraces.length > 0) { + Logging.d(TAG, threadName + " stacks trace:"); + for (StackTraceElement stackTrace : stackTraces) { + Logging.d(TAG, stackTrace.toString()); + } + } + } + } + public static void printStackTraces() { - if (workerThread != null) { - Logging.d(TAG, "Worker thread stacks trace:"); - for (StackTraceElement stackTrace : workerThread.getStackTrace()) { - Logging.d(TAG, stackTrace.toString()); - } - } - if (signalingThread != null) { - Logging.d(TAG, "Signaling thread stacks trace:"); - for (StackTraceElement stackTrace : signalingThread.getStackTrace()) { - Logging.d(TAG, stackTrace.toString()); - } - } + printStackTrace(workerThread, "Worker thread"); + printStackTrace(signalingThread, "Signaling thread"); } private static void onWorkerThreadReady() {