SampleQueue implements TrackOutput { @CallSuper public int read( FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired, boolean loadingFinished, long decodeOnlyUntilUs) { int result = readSampleMetadata( formatHolder, buffer, formatRequired, loadingFinished, decodeOnlyUntilUs, extrasHolder); if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream() && !buffer.isFlagsOnly()) { sampleDataQueue.readToBuffer(buffer, extrasHolder); } return result; } SampleQueue(Allocator allocator, DrmSessionManager<?> drmSessionManager); @CallSuper void release(); final void reset(); @CallSuper void reset(boolean resetUpstreamFormat); final void sourceId(int sourceId); final void splice(); final int getWriteIndex(); final void discardUpstreamSamples(int discardFromIndex); @CallSuper void preRelease(); @CallSuper void maybeThrowError(); final int getFirstIndex(); final int getReadIndex(); final synchronized int peekSourceId(); final synchronized Format getUpstreamFormat(); final synchronized long getLargestQueuedTimestampUs(); final synchronized boolean isLastSampleQueued(); final synchronized long getFirstTimestampUs(); @SuppressWarnings("ReferenceEquality") // See comments in setUpstreamFormat @CallSuper synchronized boolean isReady(boolean loadingFinished); @CallSuper int read(
      FormatHolder formatHolder,
      DecoderInputBuffer buffer,
      boolean formatRequired,
      boolean loadingFinished,
      long decodeOnlyUntilUs); final synchronized boolean seekTo(int sampleIndex); final synchronized boolean seekTo(long timeUs, boolean allowTimeBeyondBuffer); final synchronized int advanceTo(long timeUs); final synchronized int advanceToEnd(); final void discardTo(long timeUs, boolean toKeyframe, boolean stopAtReadPosition); final void discardToRead(); final void discardToEnd(); final void setSampleOffsetUs(long sampleOffsetUs); final void setUpstreamFormatChangeListener(UpstreamFormatChangedListener listener); @Override final void format(Format unadjustedUpstreamFormat); @Override final int sampleData(ExtractorInput input, int length, boolean allowEndOfInput); @Override final void sampleData(ParsableByteArray buffer, int length); @Override final void sampleMetadata(
      long timeUs,
      @C.BufferFlags int flags,
      int size,
      int offset,
      @Nullable CryptoData cryptoData); synchronized long discardSampleMetadataToRead();  }
@Test public void testReadEncryptedSectionsPopulatesDrmSession() { when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS); writeTestDataWithEncryptedSections(); int result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample( 0); assertReadEncryptedSample( 1); formatHolder.clear(); assertThat(formatHolder.drmSession).isNull(); result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isNull(); assertReadEncryptedSample( 2); result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); }
@Test @SuppressWarnings("unchecked") public void testAllowPlaceholderSessionPopulatesDrmSession() { when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS); DrmSession<ExoMediaCrypto> mockPlaceholderDrmSession = (DrmSession<ExoMediaCrypto>) Mockito.mock(DrmSession.class); when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS); when(mockDrmSessionManager.acquirePlaceholderSession( ArgumentMatchers.any(), ArgumentMatchers.anyInt())) .thenReturn(mockPlaceholderDrmSession); writeTestDataWithEncryptedSections(); int result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample( 0); assertReadEncryptedSample( 1); formatHolder.clear(); assertThat(formatHolder.drmSession).isNull(); result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockPlaceholderDrmSession); assertReadEncryptedSample( 2); result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample( 3); }
@Test @SuppressWarnings("unchecked") public void testTrailingCryptoInfoInitializationVectorBytesZeroed() { when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS); DrmSession<ExoMediaCrypto> mockPlaceholderDrmSession = (DrmSession<ExoMediaCrypto>) Mockito.mock(DrmSession.class); when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS); when(mockDrmSessionManager.acquirePlaceholderSession( ArgumentMatchers.any(), ArgumentMatchers.anyInt())) .thenReturn(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 = TestUtil.joinByteArrays( new byte[] { 0x08, }, initializationVector, sampleData); writeSample( encryptedSampleData, 0, BUFFER_FLAG_KEY_FRAME | BUFFER_FLAG_ENCRYPTED); int result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_FORMAT_READ); inputBuffer.cryptoInfo.iv = new byte[16]; Arrays.fill(inputBuffer.cryptoInfo.iv, (byte) 1); result = sampleQueue.read( formatHolder, inputBuffer, false, false, 0); assertThat(result).isEqualTo(RESULT_BUFFER_READ); byte[] expectedInitializationVector = Arrays.copyOf(initializationVector, 16); assertArrayEquals(expectedInitializationVector, inputBuffer.cryptoInfo.iv); }