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();
}
}
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);
}
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);
}
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);
}
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);
}
Aggregations