diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java index 3b9e840fa9f..9a23bbffad8 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java @@ -419,7 +419,7 @@ private static String buildCustomDiagnosticInfo(int errorCode) { // MIREGO: added the following field and 2 functions to log and debug a specific issue (rendering pipleine stall) // MIREGO: once the issue is solved, we should get rid of that code - private boolean hasReportedRenderingStall = false; + protected boolean hasReportedRenderingStall = false; void saveFeedInputBufferStep(int stepIndex) { if (getTrackType() == TRACK_TYPE_AUDIO) { @@ -2110,6 +2110,10 @@ private void drainAndReinitializeCodec() throws ExoPlaybackException { int dequeuedOutputCount = 0; // MIREGO for logging + protected void detectRendererStallMirego(boolean hasDequeuedBuffer) { + // NOOP + } + /** * @return Whether it may be possible to drain more output data. * @throws ExoPlaybackException If an error occurs draining the output buffer. @@ -2141,22 +2145,12 @@ private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs) outputIndex = codec.dequeueOutputBufferIndex(outputBufferInfo); } - if (outputIndex < 0) { + // MIREGO video renderer stall detection + if (getTrackType() == TRACK_TYPE_VIDEO) { + detectRendererStallMirego(outputIndex >= 0); + } - // MIREGO video renderer stall detection - if (getTrackType() == TRACK_TYPE_VIDEO) { - - if (Util.currentProcessedOutputBuffers < Util.currentQueuedInputBuffers) { - // waiting for a decoded buffer to be available from the codec - long currentTimeMs = System.currentTimeMillis(); - if (Util.waitingForDecodedVideoBufferTimeMs == 0) { - Util.waitingForDecodedVideoBufferTimeMs = currentTimeMs; // starting to wait for the decoded buffer - } else if (!hasReportedRenderingStall && currentTimeMs > Util.waitingForDecodedVideoBufferTimeMs + 7000) { // been waiting for an arbitrary while, send an error to the app - Log.e(TAG, new PlaybackException("Video codec may be stalled error", new RuntimeException(), PlaybackException.ERROR_CODE_VIDEO_CODEC_STALLED)); - hasReportedRenderingStall = true; - } - } - } + if (outputIndex < 0) { // MIREGO Log.v(Log.LOG_LEVEL_VERBOSE2, TAG, "drainOutputBuffer(type:%d) Failed dequeueOutputBufferIndex res: %d (dequeuedOutputCount: %d)", @@ -2176,11 +2170,6 @@ private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs) return false; } - // MIREGO video renderer stall detection - if (getTrackType() == TRACK_TYPE_VIDEO) { - Util.waitingForDecodedVideoBufferTimeMs = 0; // we got a decoded buffer, reset the wait time - } - // MIREGO START dequeuedOutputCount++; Log.v(Log.LOG_LEVEL_VERBOSE3, TAG, "drainOutputBuffer(type:%d) presentationTime: %d dequeuedOutputCount: %d outputIndex: %d", diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index a342daf67e1..36cef30e2fe 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java @@ -16,6 +16,7 @@ package androidx.media3.exoplayer.video; import static android.view.Display.DEFAULT_DISPLAY; +import static androidx.media3.common.C.TRACK_TYPE_VIDEO; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkStateNotNull; @@ -1607,6 +1608,31 @@ private void detectTunnelingDroppedFrames(long presentationTimeUs) { lastRenderedTunneledBufferPresentationTimeUs = presentationTimeUs; } + protected void detectRendererStallMirego(boolean hasDequeuedBuffer) { + if (tunneling) { + return; + } + + if (hasDequeuedBuffer) { + Util.waitingForDecodedVideoBufferTimeMs = 0; // we got a decoded buffer, reset the wait time + } else { + if (Util.currentProcessedOutputBuffers < Util.currentQueuedInputBuffers) { + // waiting for a decoded buffer to be available from the codec + long currentTimeMs = System.currentTimeMillis(); + if (Util.waitingForDecodedVideoBufferTimeMs == 0) { + Util.waitingForDecodedVideoBufferTimeMs = currentTimeMs; // starting to wait for the decoded buffer + } else if (!hasReportedRenderingStall && currentTimeMs + > Util.waitingForDecodedVideoBufferTimeMs + + 7000) { // been waiting for an arbitrary while, send an error to the app + Log.e(TAG, + new PlaybackException("Video codec may be stalled error", new RuntimeException(), + PlaybackException.ERROR_CODE_VIDEO_CODEC_STALLED)); + hasReportedRenderingStall = true; + } + } + } + } + /** Called when a output EOS was received in tunneling mode. */ private void onProcessedTunneledEndOfStream() { setPendingOutputEndOfStream();