Search in sources :

Example 11 with FormatHolder

use of androidx.media3.exoplayer.FormatHolder in project media by androidx.

the class DecoderVideoRenderer method render.

// BaseRenderer implementation.
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
    if (outputStreamEnded) {
        return;
    }
    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;
            outputStreamEnded = true;
            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(positionUs, elapsedRealtimeUs)) {
            }
            while (feedInputBuffer()) {
            }
            TraceUtil.endSection();
        } catch (DecoderException e) {
            Log.e(TAG, "Video codec error", e);
            eventDispatcher.videoCodecError(e);
            throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODING_FAILED);
        }
        decoderCounters.ensureUpdated();
    }
}
Also used : DecoderException(androidx.media3.decoder.DecoderException) ReadDataResult(androidx.media3.exoplayer.source.SampleStream.ReadDataResult) FormatHolder(androidx.media3.exoplayer.FormatHolder)

Example 12 with FormatHolder

use of androidx.media3.exoplayer.FormatHolder in project media by androidx.

the class MergingMediaPeriodTest method selectTracks_createsSampleStreamsFromChildPeriods.

@Test
public void selectTracks_createsSampleStreamsFromChildPeriods() throws Exception {
    MergingMediaPeriod mergingMediaPeriod = prepareMergingPeriod(new MergingPeriodDefinition(/* timeOffsetUs= */
    0, /* singleSampleTimeUs= */
    0, childFormat11, childFormat12), new MergingPeriodDefinition(/* timeOffsetUs= */
    0, /* singleSampleTimeUs= */
    0, childFormat21, childFormat22));
    ExoTrackSelection selectionForChild1 = new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(1), /* track= */
    0);
    ExoTrackSelection selectionForChild2 = new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */
    0);
    SampleStream[] streams = new SampleStream[4];
    mergingMediaPeriod.selectTracks(/* selections= */
    new ExoTrackSelection[] { null, selectionForChild1, selectionForChild2, null }, /* mayRetainStreamFlags= */
    new boolean[] { false, false, false, false }, streams, /* streamResetFlags= */
    new boolean[] { false, false, false, false }, /* positionUs= */
    0);
    mergingMediaPeriod.continueLoading(/* positionUs= */
    0);
    assertThat(streams[0]).isNull();
    assertThat(streams[3]).isNull();
    FormatHolder formatHolder = new FormatHolder();
    DecoderInputBuffer inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
    assertThat(streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT)).isEqualTo(C.RESULT_FORMAT_READ);
    assertThat(formatHolder.format).isEqualTo(childFormat12);
    assertThat(streams[2].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT)).isEqualTo(C.RESULT_FORMAT_READ);
    assertThat(formatHolder.format).isEqualTo(childFormat21);
}
Also used : ExoTrackSelection(androidx.media3.exoplayer.trackselection.ExoTrackSelection) DecoderInputBuffer(androidx.media3.decoder.DecoderInputBuffer) FormatHolder(androidx.media3.exoplayer.FormatHolder) FixedTrackSelection(androidx.media3.exoplayer.trackselection.FixedTrackSelection) Test(org.junit.Test)

Example 13 with FormatHolder

use of androidx.media3.exoplayer.FormatHolder in project media by androidx.

the class MergingMediaPeriodTest method selectTracks_withPeriodOffsets_selectTracksWithOffset_andCreatesSampleStreamsCorrectingOffset.

@Test
public void selectTracks_withPeriodOffsets_selectTracksWithOffset_andCreatesSampleStreamsCorrectingOffset() throws Exception {
    MergingMediaPeriod mergingMediaPeriod = prepareMergingPeriod(new MergingPeriodDefinition(/* timeOffsetUs= */
    0, /* singleSampleTimeUs= */
    123_000, childFormat11, childFormat12), new MergingPeriodDefinition(/* timeOffsetUs= */
    -3000, /* singleSampleTimeUs= */
    456_000, childFormat21, childFormat22));
    ExoTrackSelection selectionForChild1 = new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(0), /* track= */
    0);
    ExoTrackSelection selectionForChild2 = new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */
    0);
    SampleStream[] streams = new SampleStream[2];
    mergingMediaPeriod.selectTracks(/* selections= */
    new ExoTrackSelection[] { selectionForChild1, selectionForChild2 }, /* mayRetainStreamFlags= */
    new boolean[] { false, false }, streams, /* streamResetFlags= */
    new boolean[] { false, false }, /* positionUs= */
    0);
    mergingMediaPeriod.continueLoading(/* positionUs= */
    0);
    FormatHolder formatHolder = new FormatHolder();
    DecoderInputBuffer inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
    streams[0].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
    streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
    FakeMediaPeriodWithSelectTracksPosition childMediaPeriod1 = (FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(0);
    assertThat(childMediaPeriod1.selectTracksPositionUs).isEqualTo(0);
    assertThat(streams[0].readData(formatHolder, inputBuffer, /* readFlags= */
    0)).isEqualTo(C.RESULT_BUFFER_READ);
    assertThat(inputBuffer.timeUs).isEqualTo(123_000L);
    FakeMediaPeriodWithSelectTracksPosition childMediaPeriod2 = (FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(1);
    assertThat(childMediaPeriod2.selectTracksPositionUs).isEqualTo(3000L);
    assertThat(streams[1].readData(formatHolder, inputBuffer, /* readFlags= */
    0)).isEqualTo(C.RESULT_BUFFER_READ);
    assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000);
}
Also used : ExoTrackSelection(androidx.media3.exoplayer.trackselection.ExoTrackSelection) DecoderInputBuffer(androidx.media3.decoder.DecoderInputBuffer) FormatHolder(androidx.media3.exoplayer.FormatHolder) FixedTrackSelection(androidx.media3.exoplayer.trackselection.FixedTrackSelection) Test(org.junit.Test)

Example 14 with FormatHolder

use of androidx.media3.exoplayer.FormatHolder in project media by androidx.

the class SampleQueueTest method assertReadSample.

/**
 * Asserts {@link SampleQueue#read} returns {@link C#RESULT_BUFFER_READ} and that the buffer is
 * filled with the specified sample data.
 *
 * @param timeUs The expected buffer timestamp.
 * @param isKeyFrame The expected keyframe flag.
 * @param isDecodeOnly The expected decodeOnly flag.
 * @param isEncrypted The expected encrypted flag.
 * @param sampleData An array containing the expected sample data.
 * @param offset The offset in {@code sampleData} of the expected sample data.
 * @param length The length of the expected sample data.
 */
private void assertReadSample(long timeUs, boolean isKeyFrame, boolean isDecodeOnly, boolean isEncrypted, byte[] sampleData, int offset, int length) {
    // Check that peek whilst omitting data yields the expected values.
    formatHolder.format = null;
    DecoderInputBuffer flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
    int result = sampleQueue.read(formatHolder, flagsOnlyBuffer, FLAG_OMIT_SAMPLE_DATA | FLAG_PEEK, /* loadingFinished= */
    false);
    assertSampleBufferReadResult(flagsOnlyBuffer, result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted);
    // Check that peek yields the expected values.
    clearFormatHolderAndInputBuffer();
    result = sampleQueue.read(formatHolder, inputBuffer, FLAG_PEEK, /* loadingFinished= */
    false);
    assertSampleBufferReadResult(result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted, sampleData, offset, length);
    // Check that read yields the expected values.
    clearFormatHolderAndInputBuffer();
    result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
    0, /* loadingFinished= */
    false);
    assertSampleBufferReadResult(result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted, sampleData, offset, length);
}
Also used : DecoderInputBuffer(androidx.media3.decoder.DecoderInputBuffer)

Example 15 with FormatHolder

use of androidx.media3.exoplayer.FormatHolder in project media by androidx.

the class SampleQueueTest method trailingCryptoInfoInitializationVectorBytesZeroed.

@Test
public void trailingCryptoInfoInitializationVectorBytesZeroed() {
    when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
    DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
    when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
    mockDrmSessionManager.mockPlaceholderDrmSession = mockPlaceholderDrmSession;
    writeFormat(ENCRYPTED_SAMPLE_FORMATS[0]);
    byte[] sampleData = new byte[] { 0, 1, 2 };
    byte[] initializationVector = new byte[] { 7, 6, 5, 4, 3, 2, 1, 0 };
    byte[] encryptedSampleData = Bytes.concat(new byte[] { // subsampleEncryption = false (1 bit), ivSize = 8 (7 bits).
    0x08 }, initializationVector, sampleData);
    writeSample(encryptedSampleData, /* timestampUs= */
    0, BUFFER_FLAG_KEY_FRAME | BUFFER_FLAG_ENCRYPTED);
    int result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
    0, /* loadingFinished= */
    false);
    assertThat(result).isEqualTo(RESULT_FORMAT_READ);
    // Fill cryptoInfo.iv with non-zero data. When the 8 byte initialization vector is written into
    // it, we expect the trailing 8 bytes to be zeroed.
    inputBuffer.cryptoInfo.iv = new byte[16];
    Arrays.fill(inputBuffer.cryptoInfo.iv, (byte) 1);
    result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
    0, /* loadingFinished= */
    false);
    assertThat(result).isEqualTo(RESULT_BUFFER_READ);
    // Assert cryptoInfo.iv contains the 8-byte initialization vector and that the trailing 8 bytes
    // have been zeroed.
    byte[] expectedInitializationVector = Arrays.copyOf(initializationVector, 16);
    assertArrayEquals(expectedInitializationVector, inputBuffer.cryptoInfo.iv);
}
Also used : DrmSession(androidx.media3.exoplayer.drm.DrmSession) Test(org.junit.Test)

Aggregations

FormatHolder (androidx.media3.exoplayer.FormatHolder)16 Test (org.junit.Test)13 ReadDataResult (androidx.media3.exoplayer.source.SampleStream.ReadDataResult)11 Format (androidx.media3.common.Format)9 EventStream (androidx.media3.exoplayer.dash.manifest.EventStream)9 EventMessage (androidx.media3.extractor.metadata.emsg.EventMessage)8 Nullable (androidx.annotation.Nullable)7 DecoderReuseEvaluation (androidx.media3.exoplayer.DecoderReuseEvaluation)5 DecoderInputBuffer (androidx.media3.decoder.DecoderInputBuffer)4 DrmSession (androidx.media3.exoplayer.drm.DrmSession)4 CallSuper (androidx.annotation.CallSuper)2 DecoderException (androidx.media3.decoder.DecoderException)2 ExoTrackSelection (androidx.media3.exoplayer.trackselection.ExoTrackSelection)2 FixedTrackSelection (androidx.media3.exoplayer.trackselection.FixedTrackSelection)2 Before (org.junit.Before)2 CryptoException (android.media.MediaCodec.CryptoException)1 MediaCryptoException (android.media.MediaCryptoException)1 MediaFormat (android.media.MediaFormat)1 DrmInitData (androidx.media3.common.DrmInitData)1 Metadata (androidx.media3.common.Metadata)1