Search in sources :

Example 1 with FormatHolder

use of com.google.android.exoplayer2.FormatHolder in project ExoPlayer by google.

the class MediaCodecRenderer method readSourceOmittingSampleData.

/**
 * Reads from the source when sample data is not required. If a format or an end of stream buffer
 * is read, it will be handled before the call returns.
 *
 * @param readFlags Additional {@link ReadFlags}. {@link SampleStream#FLAG_OMIT_SAMPLE_DATA} is
 *     added internally, and so does not need to be passed.
 * @return Whether a format was read and processed.
 */
private boolean readSourceOmittingSampleData(@SampleStream.ReadFlags int readFlags) throws ExoPlaybackException {
    FormatHolder formatHolder = getFormatHolder();
    noDataBuffer.clear();
    @ReadDataResult int result = readSource(formatHolder, noDataBuffer, readFlags | FLAG_OMIT_SAMPLE_DATA);
    if (result == C.RESULT_FORMAT_READ) {
        onInputFormatChanged(formatHolder);
        return true;
    } else if (result == C.RESULT_BUFFER_READ && noDataBuffer.isEndOfStream()) {
        inputStreamEnded = true;
        processEndOfStream();
    }
    return false;
}
Also used : ReadDataResult(com.google.android.exoplayer2.source.SampleStream.ReadDataResult) FormatHolder(com.google.android.exoplayer2.FormatHolder)

Example 2 with FormatHolder

use of com.google.android.exoplayer2.FormatHolder in project ExoPlayer by google.

the class DecoderAudioRenderer method onInputFormatChanged.

private void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
    Format newFormat = Assertions.checkNotNull(formatHolder.format);
    setSourceDrmSession(formatHolder.drmSession);
    Format oldFormat = inputFormat;
    inputFormat = newFormat;
    encoderDelay = newFormat.encoderDelay;
    encoderPadding = newFormat.encoderPadding;
    if (decoder == null) {
        maybeInitDecoder();
        eventDispatcher.inputFormatChanged(inputFormat, /* decoderReuseEvaluation= */
        null);
        return;
    }
    DecoderReuseEvaluation evaluation;
    if (sourceDrmSession != decoderDrmSession) {
        evaluation = new DecoderReuseEvaluation(decoder.getName(), oldFormat, newFormat, REUSE_RESULT_NO, DISCARD_REASON_DRM_SESSION_CHANGED);
    } else {
        evaluation = canReuseDecoder(decoder.getName(), oldFormat, newFormat);
    }
    if (evaluation.result == REUSE_RESULT_NO) {
        if (decoderReceivedBuffers) {
            // Signal end of stream and wait for any final output buffers before re-initialization.
            decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
        } else {
            // There aren't any final output buffers, so release the decoder immediately.
            releaseDecoder();
            maybeInitDecoder();
            audioTrackNeedsConfigure = true;
        }
    }
    eventDispatcher.inputFormatChanged(inputFormat, evaluation);
}
Also used : Format(com.google.android.exoplayer2.Format) DecoderReuseEvaluation(com.google.android.exoplayer2.decoder.DecoderReuseEvaluation)

Example 3 with FormatHolder

use of com.google.android.exoplayer2.FormatHolder 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();
    }
}
Also used : DecoderException(com.google.android.exoplayer2.decoder.DecoderException) ReadDataResult(com.google.android.exoplayer2.source.SampleStream.ReadDataResult) FormatHolder(com.google.android.exoplayer2.FormatHolder)

Example 4 with FormatHolder

use of com.google.android.exoplayer2.FormatHolder 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();
    }
}
Also used : FormatHolder(com.google.android.exoplayer2.FormatHolder)

Example 5 with FormatHolder

use of com.google.android.exoplayer2.FormatHolder in project ExoPlayer by google.

the class MediaCodecAudioRenderer method onInputFormatChanged.

@Override
@Nullable
protected DecoderReuseEvaluation onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
    @Nullable DecoderReuseEvaluation evaluation = super.onInputFormatChanged(formatHolder);
    eventDispatcher.inputFormatChanged(formatHolder.format, evaluation);
    return evaluation;
}
Also used : DecoderReuseEvaluation(com.google.android.exoplayer2.decoder.DecoderReuseEvaluation) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Aggregations

FormatHolder (com.google.android.exoplayer2.FormatHolder)16 Test (org.junit.Test)13 ReadDataResult (com.google.android.exoplayer2.source.SampleStream.ReadDataResult)11 Format (com.google.android.exoplayer2.Format)10 EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)9 EventMessage (com.google.android.exoplayer2.metadata.emsg.EventMessage)8 Nullable (androidx.annotation.Nullable)7 DecoderReuseEvaluation (com.google.android.exoplayer2.decoder.DecoderReuseEvaluation)5 DecoderInputBuffer (com.google.android.exoplayer2.decoder.DecoderInputBuffer)4 DrmSession (com.google.android.exoplayer2.drm.DrmSession)4 CallSuper (androidx.annotation.CallSuper)2 DecoderException (com.google.android.exoplayer2.decoder.DecoderException)2 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)2 FixedTrackSelection (com.google.android.exoplayer2.trackselection.FixedTrackSelection)2 Before (org.junit.Before)2 CryptoException (android.media.MediaCodec.CryptoException)1 MediaCryptoException (android.media.MediaCryptoException)1 MediaFormat (android.media.MediaFormat)1 InsufficientCapacityException (com.google.android.exoplayer2.decoder.DecoderInputBuffer.InsufficientCapacityException)1 DecoderDiscardReasons (com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DecoderDiscardReasons)1