/** * Invoked when a new format is read from the upstream {@link SampleSource}. * * @param formatHolder Holds the new format. * @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}. */ protected void onInputFormatChanged(MediaFormatHolder formatHolder) throws ExoPlaybackException { MediaFormat oldFormat = format; format = formatHolder.format; drmInitData = formatHolder.drmInitData; if (codec != null && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) { codecReconfigured = true; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; } else { if (codecHasQueuedBuffers) { // Signal end of stream and wait for any final output buffers before re-initialization. codecReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM; } else { // There aren't any final output buffers, so perform re-initialization immediately. releaseCodec(); maybeInitCodec(); } } }
@Override protected void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { sourceState = continueBufferingSource(positionUs) ? (sourceState == SOURCE_STATE_NOT_READY ? SOURCE_STATE_READY : sourceState) : SOURCE_STATE_NOT_READY; checkForDiscontinuity(positionUs); if (format == null) { readFormat(positionUs); } if (codec == null && shouldInitCodec()) { maybeInitCodec(); } if (codec != null) { TraceUtil.beginSection("drainAndFeed"); while (drainOutputBuffer(positionUs, elapsedRealtimeUs)) {} if (feedInputBuffer(positionUs, true)) { while (feedInputBuffer(positionUs, false)) {} } TraceUtil.endSection(); } codecCounters.ensureUpdated(); }
private void checkForDiscontinuity(long positionUs) throws ExoPlaybackException { if (codec == null) { return; } int result = readSource(positionUs, formatHolder, sampleHolder, true); if (result == SampleSource.DISCONTINUITY_READ) { flushCodec(); } }
@SuppressWarnings("deprecation") protected final void maybeInitCodec() throws ExoPlaybackException { if (!shouldInitCodec()) { return; decoderInfo = getDecoderInfo(mimeType, requiresSecureDecoder); } catch (DecoderQueryException e) { notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e, DecoderInitializationException.DECODER_QUERY_ERROR)); notifyAndThrowDecoderInitError(new DecoderInitializationException(format, null, DecoderInitializationException.NO_SUITABLE_DECODER_ERROR)); codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(decoderName); codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(decoderName); try { long codecInitializingTimestamp = SystemClock.elapsedRealtime(); TraceUtil.endSection(); TraceUtil.beginSection("configureCodec"); configureCodec(codec, decoderName, format.getFrameworkMediaFormatV16(), mediaCrypto); TraceUtil.endSection(); TraceUtil.beginSection("codec.start()"); TraceUtil.endSection(); long codecInitializedTimestamp = SystemClock.elapsedRealtime(); notifyDecoderInitialized(decoderName, codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp); inputBuffers = codec.getInputBuffers(); outputBuffers = codec.getOutputBuffers();
result = readSource(positionUs, formatHolder, sampleHolder, false); if (firstFeed && sourceState == SOURCE_STATE_READY && result == SampleSource.NOTHING_READ) { sourceState = SOURCE_STATE_READY_READ_MAY_FAIL; flushCodec(); return true; onInputFormatChanged(formatHolder); return true; processEndOfStream(); return false; notifyCryptoError(e); throw new ExoPlaybackException(e); waitingForKeys = shouldWaitForKeys(sampleEncrypted); if (waitingForKeys) { return false; MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(sampleHolder, adaptiveReconfigurationBytes); codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0); codecReconfigurationState = RECONFIGURATION_STATE_NONE; } catch (CryptoException e) { notifyCryptoError(e); throw new ExoPlaybackException(e);
outputIndex = codec.dequeueOutputBuffer(outputBufferInfo, getDequeueOutputBufferTimeoutUs()); onOutputFormatChanged(codec.getOutputFormat()); codecCounters.outputFormatChangedCount++; return true; if (codecNeedsEosPropagationWorkaround && (inputStreamEnded || codecReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM)) { processEndOfStream(); return true; processEndOfStream(); return false; int decodeOnlyIndex = getDecodeOnlyIndex(outputBufferInfo.presentationTimeUs); if (processOutputBuffer(positionUs, elapsedRealtimeUs, codec, outputBuffers[outputIndex], outputBufferInfo, outputIndex, decodeOnlyIndex != -1)) { if (decodeOnlyIndex != -1) {