Ensure non-fatal errors are logged to logcat.

We already report these errors through callbacks to interested listeners.
However, to ease debugging with bugreports and local error detection,
it's helpful to also log these non-fatal execptions to logcat. Otherwise
nothing in logcat indicates that the player recovered from an exception.

Issue: #6384
PiperOrigin-RevId: 357923899
This commit is contained in:
tonihei 2021-02-17 12:57:36 +00:00 committed by kim-vde
parent f191000e20
commit 7830eb7ae5
8 changed files with 25 additions and 4 deletions

View File

@ -242,6 +242,11 @@ public interface AudioSink {
*/
public UnexpectedDiscontinuityException(
long actualPresentationTimeUs, long expectedPresentationTimeUs) {
super(
"Unexpected audio track timestamp discontinuity: expected "
+ expectedPresentationTimeUs
+ ", got "
+ actualPresentationTimeUs);
this.actualPresentationTimeUs = actualPresentationTimeUs;
this.expectedPresentationTimeUs = expectedPresentationTimeUs;
}

View File

@ -47,6 +47,7 @@ import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaClock;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil;
@ -82,6 +83,8 @@ public abstract class DecoderAudioRenderer<
Decoder<DecoderInputBuffer, ? extends SimpleOutputBuffer, ? extends DecoderException>>
extends BaseRenderer implements MediaClock {
private static final String TAG = "DecoderAudioRenderer";
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
@ -300,6 +303,7 @@ public abstract class DecoderAudioRenderer<
while (feedInputBuffer()) {}
TraceUtil.endSection();
} catch (DecoderException e) {
Log.e(TAG, "Audio codec error", e);
eventDispatcher.audioCodecError(e);
throw createRendererException(e, inputFormat);
} catch (AudioSink.ConfigurationException e) {
@ -620,6 +624,7 @@ public abstract class DecoderAudioRenderer<
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (DecoderException e) {
Log.e(TAG, "Audio codec error", e);
eventDispatcher.audioCodecError(e);
throw createRendererException(e, inputFormat);
} catch (OutOfMemoryError e) {
@ -739,6 +744,7 @@ public abstract class DecoderAudioRenderer<
@Override
public void onAudioSinkError(Exception audioSinkError) {
Log.e(TAG, "Audio sink error", audioSinkError);
eventDispatcher.audioSinkError(audioSinkError);
}
}

View File

@ -49,6 +49,7 @@ import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaClock;
import com.google.android.exoplayer2.util.MediaFormatUtil;
import com.google.android.exoplayer2.util.MimeTypes;
@ -416,6 +417,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onCodecError(Exception codecError) {
Log.e(TAG, "Audio codec error", codecError);
eventDispatcher.audioCodecError(codecError);
}
@ -853,6 +855,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
public void onAudioSinkError(Exception audioSinkError) {
Log.e(TAG, "Audio sink error", audioSinkError);
eventDispatcher.audioSinkError(audioSinkError);
}
}

View File

@ -446,7 +446,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
mediaDrm.restoreKeys(sessionId, offlineLicenseKeySetId);
return true;
} catch (Exception e) {
Log.e(TAG, "Error trying to restore keys.", e);
onError(e);
}
return false;
@ -522,6 +521,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private void onError(final Exception e) {
lastException = new DrmSessionException(e);
Log.e(TAG, "DRM session error", e);
dispatchEvent(eventDispatcher -> eventDispatcher.drmSessionManagerError(e));
if (state != STATE_OPENED_WITH_KEYS) {
state = STATE_ERROR;

View File

@ -489,6 +489,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
schemeDatas = getSchemeDatas(Assertions.checkNotNull(format.drmInitData), uuid, false);
if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
Log.e(TAG, "DRM error", error);
if (eventDispatcher != null) {
eventDispatcher.drmSessionManagerError(error);
}

View File

@ -435,24 +435,24 @@ public final class Loader implements LoaderErrorThrower {
}
} catch (Exception e) {
// This should never happen, but handle it anyway.
Log.e(TAG, "Unexpected exception loading stream", e);
if (!released) {
Log.e(TAG, "Unexpected exception loading stream", e);
obtainMessage(MSG_IO_EXCEPTION, new UnexpectedLoaderException(e)).sendToTarget();
}
} catch (OutOfMemoryError e) {
// This can occur if a stream is malformed in a way that causes an extractor to think it
// needs to allocate a large amount of memory. We don't want the process to die in this
// case, but we do want the playback to fail.
Log.e(TAG, "OutOfMemory error loading stream", e);
if (!released) {
Log.e(TAG, "OutOfMemory error loading stream", e);
obtainMessage(MSG_IO_EXCEPTION, new UnexpectedLoaderException(e)).sendToTarget();
}
} catch (Error e) {
// We'd hope that the platform would shut down the process if an Error is thrown here, but
// the executor may catch the error (b/20616433). Throw it here, but also pass and throw it
// from the handler thread so the process dies even if the executor behaves in this way.
Log.e(TAG, "Unexpected error loading stream", e);
if (!released) {
Log.e(TAG, "Unexpected error loading stream", e);
obtainMessage(MSG_FATAL_ERROR, e).sendToTarget();
}
throw e;

View File

@ -43,6 +43,7 @@ import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.TimedValueQueue;
import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.video.VideoRendererEventListener.EventDispatcher;
@ -69,6 +70,8 @@ import java.lang.annotation.RetentionPolicy;
*/
public abstract class DecoderVideoRenderer extends BaseRenderer {
private static final String TAG = "DecoderVideoRenderer";
/** Decoder reinitialization states. */
@Documented
@Retention(RetentionPolicy.SOURCE)
@ -206,6 +209,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
while (feedInputBuffer()) {}
TraceUtil.endSection();
} catch (DecoderException e) {
Log.e(TAG, "Video codec error", e);
eventDispatcher.videoCodecError(e);
throw createRendererException(e, inputFormat);
}
@ -709,6 +713,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
decoderInitializedTimestamp - decoderInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (DecoderException e) {
Log.e(TAG, "Video codec error", e);
eventDispatcher.videoCodecError(e);
throw createRendererException(e, inputFormat);
} catch (OutOfMemoryError e) {

View File

@ -692,6 +692,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override
protected void onCodecError(Exception codecError) {
Log.e(TAG, "Video codec error", codecError);
eventDispatcher.videoCodecError(codecError);
}