Don't kill the process if SimpleDecoder.decode throws.
Issue: #3645 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=180659855
This commit is contained in:
parent
d3ba207a4b
commit
7b9f71b44d
@ -69,18 +69,23 @@ import java.util.List;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderInputBuffer createInputBuffer() {
|
||||
protected DecoderInputBuffer createInputBuffer() {
|
||||
return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleOutputBuffer createOutputBuffer() {
|
||||
protected SimpleOutputBuffer createOutputBuffer() {
|
||||
return new SimpleOutputBuffer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FfmpegDecoderException decode(DecoderInputBuffer inputBuffer,
|
||||
SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
protected FfmpegDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new FfmpegDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FfmpegDecoderException decode(
|
||||
DecoderInputBuffer inputBuffer, SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
if (reset) {
|
||||
nativeContext = ffmpegReset(nativeContext, extraData);
|
||||
if (nativeContext == 0) {
|
||||
|
@ -26,4 +26,7 @@ public final class FfmpegDecoderException extends AudioDecoderException {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/* package */ FfmpegDecoderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
@ -70,18 +70,23 @@ import java.util.List;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderInputBuffer createInputBuffer() {
|
||||
protected DecoderInputBuffer createInputBuffer() {
|
||||
return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleOutputBuffer createOutputBuffer() {
|
||||
protected SimpleOutputBuffer createOutputBuffer() {
|
||||
return new SimpleOutputBuffer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlacDecoderException decode(DecoderInputBuffer inputBuffer,
|
||||
SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
protected FlacDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new FlacDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FlacDecoderException decode(
|
||||
DecoderInputBuffer inputBuffer, SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
if (reset) {
|
||||
decoderJni.flush();
|
||||
}
|
||||
|
@ -26,4 +26,7 @@ public final class FlacDecoderException extends AudioDecoderException {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/* package */ FlacDecoderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
@ -135,18 +135,23 @@ import java.util.List;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderInputBuffer createInputBuffer() {
|
||||
protected DecoderInputBuffer createInputBuffer() {
|
||||
return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleOutputBuffer createOutputBuffer() {
|
||||
protected SimpleOutputBuffer createOutputBuffer() {
|
||||
return new SimpleOutputBuffer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpusDecoderException decode(DecoderInputBuffer inputBuffer,
|
||||
SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
protected OpusDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new OpusDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OpusDecoderException decode(
|
||||
DecoderInputBuffer inputBuffer, SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
if (reset) {
|
||||
opusReset(nativeDecoderContext);
|
||||
// When seeking to 0, skip number of samples as specified in opus header. When seeking to
|
||||
|
@ -99,6 +99,11 @@ import java.nio.ByteBuffer;
|
||||
super.releaseOutputBuffer(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VpxDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new VpxDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VpxDecoderException decode(VpxInputBuffer inputBuffer, VpxOutputBuffer outputBuffer,
|
||||
boolean reset) {
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.ext.vp9;
|
||||
|
||||
/**
|
||||
* Thrown when a libvpx decoder error occurs.
|
||||
*/
|
||||
public class VpxDecoderException extends Exception {
|
||||
/** Thrown when a libvpx decoder error occurs. */
|
||||
public final class VpxDecoderException extends Exception {
|
||||
|
||||
/* package */ VpxDecoderException(String message) {
|
||||
super(message);
|
||||
|
@ -15,27 +15,21 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.audio;
|
||||
|
||||
/**
|
||||
* Thrown when an audio decoder error occurs.
|
||||
*/
|
||||
public abstract class AudioDecoderException extends Exception {
|
||||
/** Thrown when an audio decoder error occurs. */
|
||||
public class AudioDecoderException extends Exception {
|
||||
|
||||
/**
|
||||
* @param detailMessage The detail message for this exception.
|
||||
*/
|
||||
public AudioDecoderException(String detailMessage) {
|
||||
super(detailMessage);
|
||||
/** @param message The detail message for this exception. */
|
||||
public AudioDecoderException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param detailMessage The detail message for this exception.
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @param message The detail message for this exception.
|
||||
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).
|
||||
* A <tt>null</tt> value is permitted, and indicates that the cause is nonexistent or unknown.
|
||||
*/
|
||||
public AudioDecoderException(String detailMessage, Throwable cause) {
|
||||
super(detailMessage, cause);
|
||||
public AudioDecoderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,11 +55,9 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
*/
|
||||
public static final class InvalidAudioTrackTimestampException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* @param detailMessage The detail message for this exception.
|
||||
*/
|
||||
public InvalidAudioTrackTimestampException(String detailMessage) {
|
||||
super(detailMessage);
|
||||
/** @param message The detail message for this exception. */
|
||||
public InvalidAudioTrackTimestampException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -219,7 +219,18 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
|
||||
if (inputBuffer.isDecodeOnly()) {
|
||||
outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
try {
|
||||
exception = decode(inputBuffer, outputBuffer, resetDecoder);
|
||||
} catch (RuntimeException e) {
|
||||
// This can occur if a sample is malformed in a way that the decoder is not robust against.
|
||||
// We don't want the process to die in this case, but we do want to propagate the error.
|
||||
exception = createUnexpectedDecodeException(e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
// This can occur if a sample is malformed in a way that causes the decoder 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 to propagate the error.
|
||||
exception = createUnexpectedDecodeException(e);
|
||||
}
|
||||
if (exception != null) {
|
||||
// Memory barrier to ensure that the decoder exception is visible from the playback thread.
|
||||
synchronized (lock) {}
|
||||
@ -269,6 +280,14 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
|
||||
*/
|
||||
protected abstract O createOutputBuffer();
|
||||
|
||||
/**
|
||||
* Creates an exception to propagate for an unexpected decode error.
|
||||
*
|
||||
* @param error The unexpected decode error.
|
||||
* @return The exception to propagate.
|
||||
*/
|
||||
protected abstract E createUnexpectedDecodeException(Throwable error);
|
||||
|
||||
/**
|
||||
* Decodes the {@code inputBuffer} and stores any decoded output in {@code outputBuffer}.
|
||||
*
|
||||
|
@ -57,6 +57,11 @@ public abstract class SimpleSubtitleDecoder extends
|
||||
return new SimpleSubtitleOutputBuffer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final SubtitleDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new SubtitleDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void releaseOutputBuffer(SubtitleOutputBuffer buffer) {
|
||||
super.releaseOutputBuffer(buffer);
|
||||
|
@ -124,6 +124,11 @@ public class SimpleDecoderAudioRendererTest {
|
||||
return new SimpleOutputBuffer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AudioDecoderException createUnexpectedDecodeException(Throwable error) {
|
||||
return new AudioDecoderException("Unexpected decode error", error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AudioDecoderException decode(DecoderInputBuffer inputBuffer,
|
||||
SimpleOutputBuffer outputBuffer, boolean reset) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user