mirror of
https://github.com/androidx/media.git
synced 2025-05-03 21:57:46 +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);
|
printInternalError("audioTrackInitializationError", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioTrackWriteError(AudioTrack.WriteException e) {
|
||||||
|
printInternalError("audioTrackWriteError", e);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCryptoError(CryptoException e) {
|
public void onCryptoError(CryptoException e) {
|
||||||
printInternalError("cryptoError", e);
|
printInternalError("cryptoError", e);
|
||||||
|
@ -108,6 +108,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
|
|||||||
public interface InternalErrorListener {
|
public interface InternalErrorListener {
|
||||||
void onRendererInitializationError(Exception e);
|
void onRendererInitializationError(Exception e);
|
||||||
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
|
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
|
||||||
|
void onAudioTrackWriteError(AudioTrack.WriteException e);
|
||||||
void onDecoderInitializationError(DecoderInitializationException e);
|
void onDecoderInitializationError(DecoderInitializationException e);
|
||||||
void onCryptoError(CryptoException e);
|
void onCryptoError(CryptoException e);
|
||||||
void onUpstreamError(int sourceId, IOException 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
|
@Override
|
||||||
public void onCryptoError(CryptoException e) {
|
public void onCryptoError(CryptoException e) {
|
||||||
if (internalErrorListener != null) {
|
if (internalErrorListener != null) {
|
||||||
|
@ -51,6 +51,13 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
|
|||||||
*/
|
*/
|
||||||
void onAudioTrackInitializationError(AudioTrack.InitializationException e);
|
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) {
|
if (!audioTrack.isInitialized() || inputStreamEnded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -212,8 +219,14 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
|
|||||||
shouldReadInputBuffer = false;
|
shouldReadInputBuffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handleBufferResult =
|
int handleBufferResult;
|
||||||
audioTrack.handleBuffer(sampleHolder.data, 0, sampleHolder.size, sampleHolder.timeUs);
|
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 we are out of sync, allow currentPositionUs to jump backwards.
|
||||||
if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
|
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) {
|
if (bufferedDurationUs == -1) {
|
||||||
return TrackRenderer.UNKNOWN_TIME_US;
|
return TrackRenderer.UNKNOWN_TIME_US;
|
||||||
} else {
|
} 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);
|
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(
|
int handleBufferResult;
|
||||||
buffer, bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs);
|
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 we are out of sync, allow currentPositionUs to jump backwards.
|
||||||
if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
|
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. */
|
/** Returned in the result of {@link #handleBuffer} if the buffer was discontinuous. */
|
||||||
public static final int RESULT_POSITION_DISCONTINUITY = 1;
|
public static final int RESULT_POSITION_DISCONTINUITY = 1;
|
||||||
/** Returned in the result of {@link #handleBuffer} if the buffer can be released. */
|
/** 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
|
* @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
|
* {@link #RESULT_POSITION_DISCONTINUITY} if the buffer was not contiguous with previously
|
||||||
* written data.
|
* 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) {
|
if (size == 0) {
|
||||||
return RESULT_BUFFER_CONSUMED;
|
return RESULT_BUFFER_CONSUMED;
|
||||||
}
|
}
|
||||||
@ -422,9 +439,7 @@ public final class AudioTrack {
|
|||||||
if (bytesToWrite > 0) {
|
if (bytesToWrite > 0) {
|
||||||
bytesToWrite = Math.min(temporaryBufferSize, bytesToWrite);
|
bytesToWrite = Math.min(temporaryBufferSize, bytesToWrite);
|
||||||
bytesWritten = audioTrack.write(temporaryBuffer, temporaryBufferOffset, bytesToWrite);
|
bytesWritten = audioTrack.write(temporaryBuffer, temporaryBufferOffset, bytesToWrite);
|
||||||
if (bytesWritten < 0) {
|
if (bytesWritten >= 0) {
|
||||||
Log.w(TAG, "AudioTrack.write returned error code: " + bytesWritten);
|
|
||||||
} else {
|
|
||||||
temporaryBufferOffset += bytesWritten;
|
temporaryBufferOffset += bytesWritten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,12 +447,15 @@ public final class AudioTrack {
|
|||||||
bytesWritten = writeNonBlockingV21(audioTrack, buffer, temporaryBufferSize);
|
bytesWritten = writeNonBlockingV21(audioTrack, buffer, temporaryBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytesWritten < 0) {
|
||||||
|
throw new WriteException(bytesWritten);
|
||||||
|
}
|
||||||
|
|
||||||
temporaryBufferSize -= bytesWritten;
|
temporaryBufferSize -= bytesWritten;
|
||||||
submittedBytes += bytesWritten;
|
submittedBytes += bytesWritten;
|
||||||
if (temporaryBufferSize == 0) {
|
if (temporaryBufferSize == 0) {
|
||||||
result |= RESULT_BUFFER_CONSUMED;
|
result |= RESULT_BUFFER_CONSUMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user