Search in sources :

Example 1 with CryptoConfig

use of androidx.media3.decoder.CryptoConfig in project media by androidx.

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(androidx.media3.decoder.CryptoInfo) CryptoException(androidx.media3.decoder.CryptoException) ByteBuffer(java.nio.ByteBuffer) Nullable(androidx.annotation.Nullable)

Example 2 with CryptoConfig

use of androidx.media3.decoder.CryptoConfig in project media by androidx.

the class VpxDecoder method decode.

@Override
@Nullable
protected VpxDecoderException decode(DecoderInputBuffer inputBuffer, VideoDecoderOutputBuffer outputBuffer, boolean reset) {
    if (reset && lastSupplementalData != null) {
        // Don't propagate supplemental data across calls to flush the decoder.
        lastSupplementalData.clear();
    }
    ByteBuffer inputData = Util.castNonNull(inputBuffer.data);
    int inputSize = inputData.limit();
    CryptoInfo cryptoInfo = inputBuffer.cryptoInfo;
    final long result = inputBuffer.isEncrypted() ? vpxSecureDecode(vpxDecContext, inputData, inputSize, cryptoConfig, cryptoInfo.mode, Assertions.checkNotNull(cryptoInfo.key), Assertions.checkNotNull(cryptoInfo.iv), cryptoInfo.numSubSamples, cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData) : vpxDecode(vpxDecContext, inputData, inputSize);
    if (result != NO_ERROR) {
        if (result == DRM_ERROR) {
            String message = "Drm error: " + vpxGetErrorMessage(vpxDecContext);
            CryptoException cause = new CryptoException(vpxGetErrorCode(vpxDecContext), message);
            return new VpxDecoderException(message, cause);
        } else {
            return new VpxDecoderException("Decode error: " + vpxGetErrorMessage(vpxDecContext));
        }
    }
    if (inputBuffer.hasSupplementalData()) {
        ByteBuffer supplementalData = Assertions.checkNotNull(inputBuffer.supplementalData);
        int size = supplementalData.remaining();
        if (size > 0) {
            if (lastSupplementalData == null || lastSupplementalData.capacity() < size) {
                lastSupplementalData = ByteBuffer.allocate(size);
            } else {
                lastSupplementalData.clear();
            }
            lastSupplementalData.put(supplementalData);
            lastSupplementalData.flip();
        }
    }
    if (!inputBuffer.isDecodeOnly()) {
        outputBuffer.init(inputBuffer.timeUs, outputMode, lastSupplementalData);
        int getFrameResult = vpxGetFrame(vpxDecContext, outputBuffer);
        if (getFrameResult == 1) {
            outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
        } else if (getFrameResult == -1) {
            return new VpxDecoderException("Buffer initialization failed.");
        }
        outputBuffer.format = inputBuffer.format;
    }
    return null;
}
Also used : CryptoInfo(androidx.media3.decoder.CryptoInfo) CryptoException(androidx.media3.decoder.CryptoException) ByteBuffer(java.nio.ByteBuffer) Nullable(androidx.annotation.Nullable)

Example 3 with CryptoConfig

use of androidx.media3.decoder.CryptoConfig in project media by androidx.

the class DecoderAudioRenderer method maybeInitDecoder.

private void maybeInitDecoder() throws ExoPlaybackException {
    if (decoder != null) {
        return;
    }
    setDecoderDrmSession(sourceDrmSession);
    CryptoConfig cryptoConfig = null;
    if (decoderDrmSession != null) {
        cryptoConfig = decoderDrmSession.getCryptoConfig();
        if (cryptoConfig == null) {
            DrmSessionException drmError = decoderDrmSession.getError();
            if (drmError != null) {
            // Continue for now. We may be able to avoid failure if a new input format causes the
            // session to be replaced without it having been used.
            } else {
                // The drm session isn't open yet.
                return;
            }
        }
    }
    try {
        long codecInitializingTimestamp = SystemClock.elapsedRealtime();
        TraceUtil.beginSection("createAudioDecoder");
        decoder = createDecoder(inputFormat, cryptoConfig);
        TraceUtil.endSection();
        long codecInitializedTimestamp = SystemClock.elapsedRealtime();
        eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp);
        decoderCounters.decoderInitCount++;
    } catch (DecoderException e) {
        Log.e(TAG, "Audio codec error", e);
        eventDispatcher.audioCodecError(e);
        throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
    } catch (OutOfMemoryError e) {
        throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
    }
}
Also used : DecoderException(androidx.media3.decoder.DecoderException) DrmSessionException(androidx.media3.exoplayer.drm.DrmSession.DrmSessionException) CryptoConfig(androidx.media3.decoder.CryptoConfig)

Example 4 with CryptoConfig

use of androidx.media3.decoder.CryptoConfig in project media by androidx.

the class DecoderVideoRendererTest method setUp.

@Before
public void setUp() {
    surface = new Surface(new SurfaceTexture(/* texName= */
    0));
    renderer = new DecoderVideoRenderer(/* allowedJoiningTimeMs= */
    0, new Handler(), eventListener, /* maxDroppedFramesToNotify= */
    -1) {

        private final Phaser inputBuffersInCodecPhaser = new Phaser();

        @C.VideoOutputMode
        private int outputMode;

        @Override
        public String getName() {
            return "TestVideoRenderer";
        }

        @Override
        @Capabilities
        public int supportsFormat(Format format) {
            return RendererCapabilities.create(C.FORMAT_HANDLED);
        }

        @Override
        protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
            this.outputMode = outputMode;
        }

        @Override
        protected void renderOutputBufferToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface) {
        // Do nothing.
        }

        @Override
        protected void onQueueInputBuffer(DecoderInputBuffer buffer) {
            // Decoding is done on a background thread we have no control about from the test.
            // Ensure the background calls are predictably serialized by waiting for them to finish:
            // 1. Register queued input buffers here.
            // 2. Deregister the input buffer when it's cleared. If an input buffer is cleared it
            // will have been fully handled by the decoder.
            // 3. Send a message on the test thread to wait for all currently pending input buffers
            // to be cleared.
            // 4. The tests need to call ShadowLooper.idleMainThread() to execute the wait message
            // sent in step (3).
            int currentPhase = inputBuffersInCodecPhaser.register();
            new Handler().post(() -> inputBuffersInCodecPhaser.awaitAdvance(currentPhase));
            super.onQueueInputBuffer(buffer);
        }

        @Override
        protected SimpleDecoder<DecoderInputBuffer, ? extends VideoDecoderOutputBuffer, ? extends DecoderException> createDecoder(Format format, @Nullable CryptoConfig cryptoConfig) {
            return new SimpleDecoder<DecoderInputBuffer, VideoDecoderOutputBuffer, DecoderException>(new DecoderInputBuffer[10], new VideoDecoderOutputBuffer[10]) {

                @Override
                protected DecoderInputBuffer createInputBuffer() {
                    return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT) {

                        @Override
                        public void clear() {
                            super.clear();
                            inputBuffersInCodecPhaser.arriveAndDeregister();
                        }
                    };
                }

                @Override
                protected VideoDecoderOutputBuffer createOutputBuffer() {
                    return new VideoDecoderOutputBuffer(this::releaseOutputBuffer);
                }

                @Override
                protected DecoderException createUnexpectedDecodeException(Throwable error) {
                    return new DecoderException("error", error);
                }

                @Nullable
                @Override
                protected DecoderException decode(DecoderInputBuffer inputBuffer, VideoDecoderOutputBuffer outputBuffer, boolean reset) {
                    outputBuffer.init(inputBuffer.timeUs, outputMode, /* supplementalData= */
                    null);
                    return null;
                }

                @Override
                public String getName() {
                    return "TestDecoder";
                }
            };
        }
    };
    renderer.setOutput(surface);
}
Also used : SimpleDecoder(androidx.media3.decoder.SimpleDecoder) Handler(android.os.Handler) Surface(android.view.Surface) VideoDecoderOutputBuffer(androidx.media3.decoder.VideoDecoderOutputBuffer) DecoderException(androidx.media3.decoder.DecoderException) SurfaceTexture(android.graphics.SurfaceTexture) Format(androidx.media3.common.Format) DecoderInputBuffer(androidx.media3.decoder.DecoderInputBuffer) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities) Phaser(java.util.concurrent.Phaser) CryptoConfig(androidx.media3.decoder.CryptoConfig) Nullable(androidx.annotation.Nullable) Before(org.junit.Before)

Example 5 with CryptoConfig

use of androidx.media3.decoder.CryptoConfig in project ExoPlayer by google.

the class DecoderAudioRenderer method maybeInitDecoder.

private void maybeInitDecoder() throws ExoPlaybackException {
    if (decoder != null) {
        return;
    }
    setDecoderDrmSession(sourceDrmSession);
    CryptoConfig cryptoConfig = null;
    if (decoderDrmSession != null) {
        cryptoConfig = decoderDrmSession.getCryptoConfig();
        if (cryptoConfig == null) {
            DrmSessionException drmError = decoderDrmSession.getError();
            if (drmError != null) {
            // Continue for now. We may be able to avoid failure if a new input format causes the
            // session to be replaced without it having been used.
            } else {
                // The drm session isn't open yet.
                return;
            }
        }
    }
    try {
        long codecInitializingTimestamp = SystemClock.elapsedRealtime();
        TraceUtil.beginSection("createAudioDecoder");
        decoder = createDecoder(inputFormat, cryptoConfig);
        TraceUtil.endSection();
        long codecInitializedTimestamp = SystemClock.elapsedRealtime();
        eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp);
        decoderCounters.decoderInitCount++;
    } catch (DecoderException e) {
        Log.e(TAG, "Audio codec error", e);
        eventDispatcher.audioCodecError(e);
        throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
    } catch (OutOfMemoryError e) {
        throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
    }
}
Also used : DecoderException(com.google.android.exoplayer2.decoder.DecoderException) DrmSessionException(com.google.android.exoplayer2.drm.DrmSession.DrmSessionException) CryptoConfig(com.google.android.exoplayer2.decoder.CryptoConfig)

Aggregations

Nullable (androidx.annotation.Nullable)4 CryptoConfig (androidx.media3.decoder.CryptoConfig)3 DecoderException (androidx.media3.decoder.DecoderException)3 CryptoConfig (com.google.android.exoplayer2.decoder.CryptoConfig)3 DecoderException (com.google.android.exoplayer2.decoder.DecoderException)3 SurfaceTexture (android.graphics.SurfaceTexture)2 Handler (android.os.Handler)2 Surface (android.view.Surface)2 CryptoException (androidx.media3.decoder.CryptoException)2 CryptoInfo (androidx.media3.decoder.CryptoInfo)2 DrmSessionException (androidx.media3.exoplayer.drm.DrmSession.DrmSessionException)2 DrmSessionException (com.google.android.exoplayer2.drm.DrmSession.DrmSessionException)2 ByteBuffer (java.nio.ByteBuffer)2 Phaser (java.util.concurrent.Phaser)2 Before (org.junit.Before)2 Format (androidx.media3.common.Format)1 DecoderInputBuffer (androidx.media3.decoder.DecoderInputBuffer)1 SimpleDecoder (androidx.media3.decoder.SimpleDecoder)1 VideoDecoderOutputBuffer (androidx.media3.decoder.VideoDecoderOutputBuffer)1 RendererCapabilities (androidx.media3.exoplayer.RendererCapabilities)1