Propagate AudioTrack errors.

This commit is contained in:
Oliver Woodman 2015-01-02 17:35:57 +00:00
parent a96a7fe782
commit d906e405a1
6 changed files with 91 additions and 11 deletions

View File

@ -153,6 +153,11 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
printInternalError("audioTrackInitializationError", e);
}
@Override
public void onAudioTrackWriteError(AudioTrack.WriteException e) {
printInternalError("audioTrackWriteError", e);
}
@Override
public void onCryptoError(CryptoException e) {
printInternalError("cryptoError", e);

View File

@ -108,6 +108,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
public interface InternalErrorListener {
void onRendererInitializationError(Exception e);
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
void onAudioTrackWriteError(AudioTrack.WriteException e);
void onDecoderInitializationError(DecoderInitializationException e);
void onCryptoError(CryptoException e);
void onUpstreamError(int sourceId, IOException e);
@ -434,6 +435,13 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
}
@Override
public void onAudioTrackWriteError(AudioTrack.WriteException e) {
if (internalErrorListener != null) {
internalErrorListener.onAudioTrackWriteError(e);
}
}
@Override
public void onCryptoError(CryptoException e) {
if (internalErrorListener != null) {

View File

@ -51,6 +51,13 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
*/
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
/**
* Invoked when an {@link AudioTrack} write fails.
*
* @param e The corresponding exception.
*/
void onAudioTrackWriteError(AudioTrack.WriteException e);
}
/**
@ -188,7 +195,7 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
}
}
private void feedInputBuffer() throws IOException {
private void feedInputBuffer() throws IOException, ExoPlaybackException {
if (!audioTrack.isInitialized() || inputStreamEnded) {
return;
}
@ -212,8 +219,14 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
shouldReadInputBuffer = false;
}
int handleBufferResult =
audioTrack.handleBuffer(sampleHolder.data, 0, sampleHolder.size, sampleHolder.timeUs);
int handleBufferResult;
try {
handleBufferResult =
audioTrack.handleBuffer(sampleHolder.data, 0, sampleHolder.size, sampleHolder.timeUs);
} catch (AudioTrack.WriteException e) {
notifyAudioTrackWriteError(e);
throw new ExoPlaybackException(e);
}
// If we are out of sync, allow currentPositionUs to jump backwards.
if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
@ -308,4 +321,15 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
}
}
private void notifyAudioTrackWriteError(final AudioTrack.WriteException e) {
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onAudioTrackWriteError(e);
}
});
}
}
}

View File

@ -190,7 +190,8 @@ public final class FrameworkSampleSource implements SampleSource {
if (bufferedDurationUs == -1) {
return TrackRenderer.UNKNOWN_TIME_US;
} else {
return extractor.getSampleTime() + bufferedDurationUs;
long sampleTime = extractor.getSampleTime();
return sampleTime == -1 ? TrackRenderer.END_OF_TRACK_US : sampleTime + bufferedDurationUs;
}
}

View File

@ -47,6 +47,13 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
*/
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
/**
* Invoked when an {@link AudioTrack} write fails.
*
* @param e The corresponding exception.
*/
void onAudioTrackWriteError(AudioTrack.WriteException e);
}
/**
@ -303,8 +310,14 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
}
}
int handleBufferResult = audioTrack.handleBuffer(
buffer, bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs);
int handleBufferResult;
try {
handleBufferResult = audioTrack.handleBuffer(
buffer, bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs);
} catch (AudioTrack.WriteException e) {
notifyAudioTrackWriteError(e);
throw new ExoPlaybackException(e);
}
// If we are out of sync, allow currentPositionUs to jump backwards.
if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
@ -341,4 +354,15 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
}
}
private void notifyAudioTrackWriteError(final AudioTrack.WriteException e) {
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onAudioTrackWriteError(e);
}
});
}
}
}

View File

@ -66,6 +66,21 @@ public final class AudioTrack {
}
/**
* Thrown when a failure occurs writing to an {@link android.media.AudioTrack}.
*/
public static class WriteException extends Exception {
/** The value returned from {@link android.media.AudioTrack#write(byte[], int, int)}. */
public final int errorCode;
public WriteException(int errorCode) {
super("AudioTrack write failed: " + errorCode);
this.errorCode = errorCode;
}
}
/** Returned in the result of {@link #handleBuffer} if the buffer was discontinuous. */
public static final int RESULT_POSITION_DISCONTINUITY = 1;
/** Returned in the result of {@link #handleBuffer} if the buffer can be released. */
@ -359,8 +374,10 @@ public final class AudioTrack {
* @return A bit field with {@link #RESULT_BUFFER_CONSUMED} if the buffer can be released, and
* {@link #RESULT_POSITION_DISCONTINUITY} if the buffer was not contiguous with previously
* written data.
* @throws WriteException If an error occurs writing the audio data.
*/
public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs) {
public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs)
throws WriteException {
if (size == 0) {
return RESULT_BUFFER_CONSUMED;
}
@ -422,9 +439,7 @@ public final class AudioTrack {
if (bytesToWrite > 0) {
bytesToWrite = Math.min(temporaryBufferSize, bytesToWrite);
bytesWritten = audioTrack.write(temporaryBuffer, temporaryBufferOffset, bytesToWrite);
if (bytesWritten < 0) {
Log.w(TAG, "AudioTrack.write returned error code: " + bytesWritten);
} else {
if (bytesWritten >= 0) {
temporaryBufferOffset += bytesWritten;
}
}
@ -432,12 +447,15 @@ public final class AudioTrack {
bytesWritten = writeNonBlockingV21(audioTrack, buffer, temporaryBufferSize);
}
if (bytesWritten < 0) {
throw new WriteException(bytesWritten);
}
temporaryBufferSize -= bytesWritten;
submittedBytes += bytesWritten;
if (temporaryBufferSize == 0) {
result |= RESULT_BUFFER_CONSUMED;
}
return result;
}