mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Propagate AudioTrack errors.
This commit is contained in:
parent
a96a7fe782
commit
d906e405a1
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user