From d6b60637986430620536c70bd65bbd848cd08e9f Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 12 Feb 2019 20:10:27 +0000 Subject: [PATCH] Allow specifying number of decoding threads to libvpx library. PiperOrigin-RevId: 233653857 --- .../ext/vp9/LibvpxVideoRenderer.java | 45 ++++++++++++++++++- .../exoplayer2/ext/vp9/VpxDecoder.java | 8 ++-- extensions/vp9/src/main/jni/vpx_jni.cc | 4 +- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java index 54ccbb40ad..7dda5d4200 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.ext.vp9; +import static java.lang.Runtime.getRuntime; + import android.os.Handler; import android.os.Looper; import android.os.SystemClock; @@ -116,6 +118,7 @@ public class LibvpxVideoRenderer extends BaseRenderer { private final TimedValueQueue formatQueue; private final DecoderInputBuffer flagsOnlyBuffer; private final DrmSessionManager drmSessionManager; + private final int threads; private Format format; private Format pendingFormat; @@ -209,12 +212,51 @@ public class LibvpxVideoRenderer extends BaseRenderer { DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys, boolean disableLoopFilter) { + this( + allowedJoiningTimeMs, + eventHandler, + eventListener, + maxDroppedFramesToNotify, + drmSessionManager, + playClearSamplesWithoutKeys, + disableLoopFilter, + getRuntime().availableProcessors()); + } + + /** + * @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer + * can attempt to seamlessly join an ongoing playback. + * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be + * null if delivery of events is not required. + * @param eventListener A listener of events. May be null if delivery of events is not required. + * @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between + * invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}. + * @param drmSessionManager For use with encrypted media. May be null if support for encrypted + * media is not required. + * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. + * For example a media file may start with a short clear region so as to allow playback to + * begin in parallel with key acquisition. This parameter specifies whether the renderer is + * permitted to play clear regions of encrypted media files before {@code drmSessionManager} + * has obtained the keys necessary to decrypt encrypted regions of the media. + * @param disableLoopFilter Disable the libvpx in-loop smoothing filter. + * @param threads Number of threads libvpx will use to decode. + */ + public LibvpxVideoRenderer( + long allowedJoiningTimeMs, + Handler eventHandler, + VideoRendererEventListener eventListener, + int maxDroppedFramesToNotify, + DrmSessionManager drmSessionManager, + boolean playClearSamplesWithoutKeys, + boolean disableLoopFilter, + int threads) { super(C.TRACK_TYPE_VIDEO); this.disableLoopFilter = disableLoopFilter; this.allowedJoiningTimeMs = allowedJoiningTimeMs; this.maxDroppedFramesToNotify = maxDroppedFramesToNotify; this.drmSessionManager = drmSessionManager; this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys; + this.threads = threads; joiningDeadlineMs = C.TIME_UNSET; clearReportedVideoSize(); formatHolder = new FormatHolder(); @@ -721,7 +763,8 @@ public class LibvpxVideoRenderer extends BaseRenderer { NUM_OUTPUT_BUFFERS, initialInputBufferSize, mediaCrypto, - disableLoopFilter); + disableLoopFilter, + threads); decoder.setOutputMode(outputMode); TraceUtil.endSection(); long decoderInitializedTimestamp = SystemClock.elapsedRealtime(); diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java index b157981487..33064af178 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java @@ -51,6 +51,7 @@ import java.nio.ByteBuffer; * @param exoMediaCrypto The {@link ExoMediaCrypto} object required for decoding encrypted * content. Maybe null and can be ignored if decoder does not handle encrypted content. * @param disableLoopFilter Disable the libvpx in-loop smoothing filter. + * @param threads Number of threads libvpx will use to decode. * @throws VpxDecoderException Thrown if an exception occurs when initializing the decoder. */ public VpxDecoder( @@ -58,7 +59,8 @@ import java.nio.ByteBuffer; int numOutputBuffers, int initialInputBufferSize, ExoMediaCrypto exoMediaCrypto, - boolean disableLoopFilter) + boolean disableLoopFilter, + int threads) throws VpxDecoderException { super(new VpxInputBuffer[numInputBuffers], new VpxOutputBuffer[numOutputBuffers]); if (!VpxLibrary.isAvailable()) { @@ -68,7 +70,7 @@ import java.nio.ByteBuffer; if (exoMediaCrypto != null && !VpxLibrary.vpxIsSecureDecodeSupported()) { throw new VpxDecoderException("Vpx decoder does not support secure decode."); } - vpxDecContext = vpxInit(disableLoopFilter); + vpxDecContext = vpxInit(disableLoopFilter, threads); if (vpxDecContext == 0) { throw new VpxDecoderException("Failed to initialize decoder"); } @@ -165,7 +167,7 @@ import java.nio.ByteBuffer; } } - private native long vpxInit(boolean disableLoopFilter); + private native long vpxInit(boolean disableLoopFilter, int threads); private native long vpxClose(long context); private native long vpxDecode(long context, ByteBuffer encoded, int length); diff --git a/extensions/vp9/src/main/jni/vpx_jni.cc b/extensions/vp9/src/main/jni/vpx_jni.cc index c37545190c..6ff86af355 100644 --- a/extensions/vp9/src/main/jni/vpx_jni.cc +++ b/extensions/vp9/src/main/jni/vpx_jni.cc @@ -433,11 +433,11 @@ int vpx_release_frame_buffer(void* priv, vpx_codec_frame_buffer_t* fb) { return buffer_manager->release(*(int*)fb->priv); } -DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter) { +DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter, jint threads) { JniCtx* context = new JniCtx(); context->decoder = new vpx_codec_ctx_t(); vpx_codec_dec_cfg_t cfg = {0, 0, 0}; - cfg.threads = android_getCpuCount(); + cfg.threads = threads; errorCode = 0; vpx_codec_err_t err = vpx_codec_dec_init(context->decoder, &vpx_codec_vp9_dx_algo, &cfg, 0);