use of com.google.android.exoplayer2.decoder.DecoderException in project ExoPlayer by google.
the class DecoderAudioRenderer method maybeInitDecoder.
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
CryptoConfig cryptoConfig = null;
if (decoderDrmSession != null) {
cryptoConfig = decoderDrmSession.getCryptoConfig();
if (cryptoConfig == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if a new input format causes the
// session to be replaced without it having been used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, cryptoConfig);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (DecoderException e) {
Log.e(TAG, "Audio codec error", e);
eventDispatcher.audioCodecError(e);
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
} catch (OutOfMemoryError e) {
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
}
}
use of com.google.android.exoplayer2.decoder.DecoderException in project ExoPlayer by google.
the class DecoderAudioRenderer method render.
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (outputStreamEnded) {
try {
audioSink.playToEndOfStream();
} catch (AudioSink.WriteException e) {
throw createRendererException(e, e.format, e.isRecoverable, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED);
}
return;
}
// Try and read a format if we don't have one already.
if (inputFormat == null) {
// We don't have a format yet, so try and read one.
FormatHolder formatHolder = getFormatHolder();
flagsOnlyBuffer.clear();
@ReadDataResult int result = readSource(formatHolder, flagsOnlyBuffer, FLAG_REQUIRE_FORMAT);
if (result == C.RESULT_FORMAT_READ) {
onInputFormatChanged(formatHolder);
} else if (result == C.RESULT_BUFFER_READ) {
// End of stream read having not read a format.
Assertions.checkState(flagsOnlyBuffer.isEndOfStream());
inputStreamEnded = true;
try {
processEndOfStream();
} catch (AudioSink.WriteException e) {
throw createRendererException(e, /* format= */
null, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED);
}
return;
} else {
// We still don't have a format and can't make progress without one.
return;
}
}
// If we don't have a decoder yet, we need to instantiate one.
maybeInitDecoder();
if (decoder != null) {
try {
// Rendering loop.
TraceUtil.beginSection("drainAndFeed");
while (drainOutputBuffer()) {
}
while (feedInputBuffer()) {
}
TraceUtil.endSection();
} catch (DecoderException e) {
// Can happen with dequeueOutputBuffer, dequeueInputBuffer, queueInputBuffer
Log.e(TAG, "Audio codec error", e);
eventDispatcher.audioCodecError(e);
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODING_FAILED);
} catch (AudioSink.ConfigurationException e) {
throw createRendererException(e, e.format, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED);
} catch (AudioSink.InitializationException e) {
throw createRendererException(e, e.format, e.isRecoverable, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED);
} catch (AudioSink.WriteException e) {
throw createRendererException(e, e.format, e.isRecoverable, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED);
}
decoderCounters.ensureUpdated();
}
}
use of com.google.android.exoplayer2.decoder.DecoderException in project ExoPlayer by google.
the class DecoderAudioRenderer method feedInputBuffer.
private boolean feedInputBuffer() throws DecoderException, ExoPlaybackException {
if (decoder == null || decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM || inputStreamEnded) {
// We need to reinitialize the decoder or the input stream has ended.
return false;
}
if (inputBuffer == null) {
inputBuffer = decoder.dequeueInputBuffer();
if (inputBuffer == null) {
return false;
}
}
if (decoderReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
inputBuffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
decoder.queueInputBuffer(inputBuffer);
inputBuffer = null;
decoderReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
return false;
}
FormatHolder formatHolder = getFormatHolder();
switch(readSource(formatHolder, inputBuffer, /* readFlags= */
0)) {
case C.RESULT_NOTHING_READ:
return false;
case C.RESULT_FORMAT_READ:
onInputFormatChanged(formatHolder);
return true;
case C.RESULT_BUFFER_READ:
if (inputBuffer.isEndOfStream()) {
inputStreamEnded = true;
decoder.queueInputBuffer(inputBuffer);
inputBuffer = null;
return false;
}
inputBuffer.flip();
inputBuffer.format = inputFormat;
onQueueInputBuffer(inputBuffer);
decoder.queueInputBuffer(inputBuffer);
decoderReceivedBuffers = true;
decoderCounters.queuedInputBufferCount++;
inputBuffer = null;
return true;
default:
throw new IllegalStateException();
}
}
use of com.google.android.exoplayer2.decoder.DecoderException in project ExoPlayer by google.
the class DecoderVideoRenderer method processOutputBuffer.
/**
* Processes {@link #outputBuffer} by rendering it, skipping it or doing nothing, and returns
* whether it may be possible to process another output buffer.
*
* @param positionUs The player's current position.
* @param elapsedRealtimeUs {@link android.os.SystemClock#elapsedRealtime()} in microseconds,
* measured at the start of the current iteration of the rendering loop.
* @return Whether it may be possible to drain another output buffer.
* @throws ExoPlaybackException If an error occurs processing the output buffer.
*/
private boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException, DecoderException {
if (initialPositionUs == C.TIME_UNSET) {
initialPositionUs = positionUs;
}
long earlyUs = outputBuffer.timeUs - positionUs;
if (!hasOutput()) {
// Skip frames in sync with playback, so we'll be at the right frame if the mode changes.
if (isBufferLate(earlyUs)) {
skipOutputBuffer(outputBuffer);
return true;
}
return false;
}
long presentationTimeUs = outputBuffer.timeUs - outputStreamOffsetUs;
Format format = formatQueue.pollFloor(presentationTimeUs);
if (format != null) {
outputFormat = format;
}
long elapsedRealtimeNowUs = SystemClock.elapsedRealtime() * 1000;
long elapsedSinceLastRenderUs = elapsedRealtimeNowUs - lastRenderTimeUs;
boolean isStarted = getState() == STATE_STARTED;
boolean shouldRenderFirstFrame = !renderedFirstFrameAfterEnable ? (isStarted || mayRenderFirstFrameAfterEnableIfNotStarted) : !renderedFirstFrameAfterReset;
// TODO: We shouldn't force render while we are joining an ongoing playback.
if (shouldRenderFirstFrame || (isStarted && shouldForceRenderOutputBuffer(earlyUs, elapsedSinceLastRenderUs))) {
renderOutputBuffer(outputBuffer, presentationTimeUs, outputFormat);
return true;
}
if (!isStarted || positionUs == initialPositionUs) {
return false;
}
// TODO: Treat dropped buffers as skipped while we are joining an ongoing playback.
if (shouldDropBuffersToKeyframe(earlyUs, elapsedRealtimeUs) && maybeDropBuffersToKeyframe(positionUs)) {
return false;
} else if (shouldDropOutputBuffer(earlyUs, elapsedRealtimeUs)) {
dropOutputBuffer(outputBuffer);
return true;
}
if (earlyUs < 30000) {
renderOutputBuffer(outputBuffer, presentationTimeUs, outputFormat);
return true;
}
return false;
}
use of com.google.android.exoplayer2.decoder.DecoderException in project ExoPlayer by google.
the class DecoderVideoRenderer method maybeInitDecoder.
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
CryptoConfig cryptoConfig = null;
if (decoderDrmSession != null) {
cryptoConfig = decoderDrmSession.getCryptoConfig();
if (cryptoConfig == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if a new input format causes the
// session to be replaced without it having been used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long decoderInitializingTimestamp = SystemClock.elapsedRealtime();
decoder = createDecoder(inputFormat, cryptoConfig);
setDecoderOutputMode(outputMode);
long decoderInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), decoderInitializedTimestamp, decoderInitializedTimestamp - decoderInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (DecoderException e) {
Log.e(TAG, "Video codec error", e);
eventDispatcher.videoCodecError(e);
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
} catch (OutOfMemoryError e) {
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
}
}
Aggregations