Search in sources :

Example 26 with DecoderInputBuffer

use of com.google.android.exoplayer2.decoder.DecoderInputBuffer in project ExoPlayer by google.

the class OpusDecoder method decode.

@Override
@Nullable
protected OpusDecoderException decode(DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) {
    if (reset) {
        opusReset(nativeDecoderContext);
        // When seeking to 0, skip number of samples as specified in opus header. When seeking to
        // any other time, skip number of samples as specified by seek preroll.
        skipSamples = (inputBuffer.timeUs == 0) ? preSkipSamples : seekPreRollSamples;
    }
    ByteBuffer inputData = Util.castNonNull(inputBuffer.data);
    CryptoInfo cryptoInfo = inputBuffer.cryptoInfo;
    int result = inputBuffer.isEncrypted() ? opusSecureDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(), outputBuffer, SAMPLE_RATE, cryptoConfig, cryptoInfo.mode, Assertions.checkNotNull(cryptoInfo.key), Assertions.checkNotNull(cryptoInfo.iv), cryptoInfo.numSubSamples, cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData) : opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(), outputBuffer);
    if (result < 0) {
        if (result == DRM_ERROR) {
            String message = "Drm error: " + opusGetErrorMessage(nativeDecoderContext);
            CryptoException cause = new CryptoException(opusGetErrorCode(nativeDecoderContext), message);
            return new OpusDecoderException(message, cause);
        } else {
            return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
        }
    }
    ByteBuffer outputData = Util.castNonNull(outputBuffer.data);
    outputData.position(0);
    outputData.limit(result);
    if (skipSamples > 0) {
        int bytesPerSample = samplesToBytes(1, channelCount, outputFloat);
        int skipBytes = skipSamples * bytesPerSample;
        if (result <= skipBytes) {
            skipSamples -= result / bytesPerSample;
            outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
            outputData.position(result);
        } else {
            skipSamples = 0;
            outputData.position(skipBytes);
        }
    }
    return null;
}
Also used : CryptoInfo(com.google.android.exoplayer2.decoder.CryptoInfo) CryptoException(com.google.android.exoplayer2.decoder.CryptoException) ByteBuffer(java.nio.ByteBuffer) Nullable(androidx.annotation.Nullable)

Example 27 with DecoderInputBuffer

use of com.google.android.exoplayer2.decoder.DecoderInputBuffer in project ExoPlayer by google.

the class SampleQueueTest method setUp.

@Before
public void setUp() {
    allocator = new DefaultAllocator(false, ALLOCATION_SIZE);
    mockDrmSession = Mockito.mock(DrmSession.class);
    mockDrmSessionManager = new MockDrmSessionManager(mockDrmSession);
    eventDispatcher = new DrmSessionEventListener.EventDispatcher();
    sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
    formatHolder = new FormatHolder();
    inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
}
Also used : DrmSession(com.google.android.exoplayer2.drm.DrmSession) DecoderInputBuffer(com.google.android.exoplayer2.decoder.DecoderInputBuffer) FormatHolder(com.google.android.exoplayer2.FormatHolder) DefaultAllocator(com.google.android.exoplayer2.upstream.DefaultAllocator) DrmSessionEventListener(com.google.android.exoplayer2.drm.DrmSessionEventListener) Before(org.junit.Before)

Example 28 with DecoderInputBuffer

use of com.google.android.exoplayer2.decoder.DecoderInputBuffer in project ExoPlayer by google.

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(com.google.android.exoplayer2.decoder.DecoderInputBuffer)

Example 29 with DecoderInputBuffer

use of com.google.android.exoplayer2.decoder.DecoderInputBuffer in project ExoPlayer by google.

the class SampleDataQueue method readEncryptionData.

/**
 * Reads encryption data for the sample described by {@code extrasHolder}.
 *
 * <p>The encryption data is written into {@link DecoderInputBuffer#cryptoInfo}, and {@link
 * SampleExtrasHolder#size} is adjusted to subtract the number of bytes that were read. The same
 * value is added to {@link SampleExtrasHolder#offset}.
 *
 * @param allocationNode The first {@link AllocationNode} containing data yet to be read.
 * @param buffer The buffer into which the encryption data should be written.
 * @param extrasHolder The extras holder whose offset should be read and subsequently adjusted.
 * @param scratch A scratch {@link ParsableByteArray}.
 * @return The first {@link AllocationNode} that contains unread bytes after this method returns.
 */
private static AllocationNode readEncryptionData(AllocationNode allocationNode, DecoderInputBuffer buffer, SampleExtrasHolder extrasHolder, ParsableByteArray scratch) {
    long offset = extrasHolder.offset;
    // Read the signal byte.
    scratch.reset(1);
    allocationNode = readData(allocationNode, offset, scratch.getData(), 1);
    offset++;
    byte signalByte = scratch.getData()[0];
    boolean subsampleEncryption = (signalByte & 0x80) != 0;
    int ivSize = signalByte & 0x7F;
    // Read the initialization vector.
    CryptoInfo cryptoInfo = buffer.cryptoInfo;
    if (cryptoInfo.iv == null) {
        cryptoInfo.iv = new byte[16];
    } else {
        // Zero out cryptoInfo.iv so that if ivSize < 16, the remaining bytes are correctly set to 0.
        Arrays.fill(cryptoInfo.iv, (byte) 0);
    }
    allocationNode = readData(allocationNode, offset, cryptoInfo.iv, ivSize);
    offset += ivSize;
    // Read the subsample count, if present.
    int subsampleCount;
    if (subsampleEncryption) {
        scratch.reset(2);
        allocationNode = readData(allocationNode, offset, scratch.getData(), 2);
        offset += 2;
        subsampleCount = scratch.readUnsignedShort();
    } else {
        subsampleCount = 1;
    }
    // Write the clear and encrypted subsample sizes.
    @Nullable int[] clearDataSizes = cryptoInfo.numBytesOfClearData;
    if (clearDataSizes == null || clearDataSizes.length < subsampleCount) {
        clearDataSizes = new int[subsampleCount];
    }
    @Nullable int[] encryptedDataSizes = cryptoInfo.numBytesOfEncryptedData;
    if (encryptedDataSizes == null || encryptedDataSizes.length < subsampleCount) {
        encryptedDataSizes = new int[subsampleCount];
    }
    if (subsampleEncryption) {
        int subsampleDataLength = 6 * subsampleCount;
        scratch.reset(subsampleDataLength);
        allocationNode = readData(allocationNode, offset, scratch.getData(), subsampleDataLength);
        offset += subsampleDataLength;
        scratch.setPosition(0);
        for (int i = 0; i < subsampleCount; i++) {
            clearDataSizes[i] = scratch.readUnsignedShort();
            encryptedDataSizes[i] = scratch.readUnsignedIntToInt();
        }
    } else {
        clearDataSizes[0] = 0;
        encryptedDataSizes[0] = extrasHolder.size - (int) (offset - extrasHolder.offset);
    }
    // Populate the cryptoInfo.
    CryptoData cryptoData = Util.castNonNull(extrasHolder.cryptoData);
    cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes, cryptoData.encryptionKey, cryptoInfo.iv, cryptoData.cryptoMode, cryptoData.encryptedBlocks, cryptoData.clearBlocks);
    // Adjust the offset and size to take into account the bytes read.
    int bytesRead = (int) (offset - extrasHolder.offset);
    extrasHolder.offset += bytesRead;
    extrasHolder.size -= bytesRead;
    return allocationNode;
}
Also used : CryptoData(com.google.android.exoplayer2.extractor.TrackOutput.CryptoData) CryptoInfo(com.google.android.exoplayer2.decoder.CryptoInfo) Nullable(androidx.annotation.Nullable)

Aggregations

Test (org.junit.Test)11 EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)9 DecoderInputBuffer (com.google.android.exoplayer2.decoder.DecoderInputBuffer)8 EventMessage (com.google.android.exoplayer2.metadata.emsg.EventMessage)8 Nullable (androidx.annotation.Nullable)7 Format (com.google.android.exoplayer2.Format)7 ByteBuffer (java.nio.ByteBuffer)6 FormatHolder (com.google.android.exoplayer2.FormatHolder)5 CryptoInfo (com.google.android.exoplayer2.decoder.CryptoInfo)5 ReadDataResult (com.google.android.exoplayer2.source.SampleStream.ReadDataResult)3 Before (org.junit.Before)3 CryptoException (com.google.android.exoplayer2.decoder.CryptoException)2 DecryptionException (com.google.android.exoplayer2.drm.DecryptionException)2 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)2 FixedTrackSelection (com.google.android.exoplayer2.trackselection.FixedTrackSelection)2 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)2 RequiresNonNull (org.checkerframework.checker.nullness.qual.RequiresNonNull)2 SurfaceTexture (android.graphics.SurfaceTexture)1 Handler (android.os.Handler)1 Surface (android.view.Surface)1