From b44de0d2509abfb39a15b343957a7d4338e08d26 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Thu, 23 Jul 2015 13:14:06 +0100 Subject: [PATCH] Improve sniffer error reporting. - Make UnrecognizedInputFormatException public so the app can more easily handle it when it is propagated to onPlayerError. - Format the description using the simple class names for the extractors. - Don't retry loading after it's thrown, but just throw immediately. --- .../extractor/ExtractorSampleSource.java | 35 ++++++++++++------- .../google/android/exoplayer/util/Util.java | 23 ++++++++++-- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java index 016f800e44..3a6a4b14e7 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java @@ -32,6 +32,7 @@ import com.google.android.exoplayer.upstream.DefaultAllocator; import com.google.android.exoplayer.upstream.Loader; import com.google.android.exoplayer.upstream.Loader.Loadable; import com.google.android.exoplayer.util.Assertions; +import com.google.android.exoplayer.util.Util; import android.net.Uri; import android.os.SystemClock; @@ -40,7 +41,6 @@ import android.util.SparseArray; import java.io.EOFException; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -70,6 +70,18 @@ import java.util.List; public class ExtractorSampleSource implements SampleSource, SampleSourceReader, ExtractorOutput, Loader.Callback { + /** + * Thrown if the input format could not recognized. + */ + public static final class UnrecognizedInputFormatException extends ParserException { + + public UnrecognizedInputFormatException(Extractor[] extractors) { + super("None of the available extractors (" + + Util.getCommaDelimitedSimpleClassNames(extractors) + ") could read the stream."); + } + + } + /** * The default minimum number of times to retry loading prior to failing for on-demand streams. */ @@ -401,6 +413,9 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader, if (currentLoadableException == null) { return; } + if (isCurrentLoadableExceptionFatal()) { + throw currentLoadableException; + } int minLoadableRetryCountForMedia; if (minLoadableRetryCount != MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA) { minLoadableRetryCountForMedia = minLoadableRetryCount; @@ -545,6 +560,9 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader, } if (currentLoadableException != null) { + if (isCurrentLoadableExceptionFatal()) { + return; + } Assertions.checkState(loadable != null); long elapsedMillis = SystemClock.elapsedRealtime() - currentLoadableExceptionTimestamp; if (elapsedMillis >= getRetryDelayMillis(currentLoadableExceptionCount)) { @@ -642,6 +660,10 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader, return pendingResetPositionUs != NO_RESET_PENDING; } + private boolean isCurrentLoadableExceptionFatal() { + return currentLoadableException instanceof UnrecognizedInputFormatException; + } + private long getRetryDelayMillis(long errorCount) { return Math.min((errorCount - 1) * 1000, 5000); } @@ -791,15 +813,4 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader, } - /** - * Thrown if the input format could not recognized by {@link Extractor#sniff(ExtractorInput)}. - */ - private static final class UnrecognizedInputFormatException extends ParserException { - - public UnrecognizedInputFormatException(Extractor[] extractors) { - super("None of the extractors " + Arrays.toString(extractors) + " could read the stream."); - } - - } - } diff --git a/library/src/main/java/com/google/android/exoplayer/util/Util.java b/library/src/main/java/com/google/android/exoplayer/util/Util.java index 2e90c4abba..c3b449034d 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/Util.java +++ b/library/src/main/java/com/google/android/exoplayer/util/Util.java @@ -577,11 +577,28 @@ public final class Util { * @return A string containing the hex representation of the data provided. */ public static String getHexStringFromBytes(byte[] data, int beginIndex, int endIndex) { - StringBuffer dataStringBuffer = new StringBuffer(endIndex - beginIndex); + StringBuilder dataStringBuilder = new StringBuilder(endIndex - beginIndex); for (int i = beginIndex; i < endIndex; i++) { - dataStringBuffer.append(String.format(Locale.US, "%02X", data[i])); + dataStringBuilder.append(String.format(Locale.US, "%02X", data[i])); } - return dataStringBuffer.toString(); + return dataStringBuilder.toString(); + } + + /** + * Returns a string with comma delimited simple names of each object's class. + * + * @param objects The objects whose simple class names should be comma delimited and returned. + * @return A string with comma delimited simple names of each object's class. + */ + public static String getCommaDelimitedSimpleClassNames(T[] objects) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < objects.length; i++) { + stringBuilder.append(objects[i].getClass().getSimpleName()); + if (i < objects.length - 1) { + stringBuilder.append(", "); + } + } + return stringBuilder.toString(); } /**