diff --git a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java index e9cde787..7cb7afe4 100644 --- a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -55,6 +55,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C private boolean adaptivePlayback, directSubmit, fusedIdrFrame; private boolean constrainedHighProfile; private boolean refFrameInvalidationAvc, refFrameInvalidationHevc; + private byte optimalSlicesPerFrame; private boolean refFrameInvalidationActive; private int initialWidth, initialHeight; private int videoFormat; @@ -249,6 +250,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C directSubmit = MediaCodecHelper.decoderCanDirectSubmit(avcDecoder.getName()); refFrameInvalidationAvc = MediaCodecHelper.decoderSupportsRefFrameInvalidationAvc(avcDecoder.getName(), prefs.height); refFrameInvalidationHevc = MediaCodecHelper.decoderSupportsRefFrameInvalidationHevc(avcDecoder.getName()); + optimalSlicesPerFrame = MediaCodecHelper.getDecoderOptimalSlicesPerFrame(avcDecoder.getName()); if (consecutiveCrashCount % 2 == 1) { refFrameInvalidationAvc = refFrameInvalidationHevc = false; @@ -264,6 +266,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C if (refFrameInvalidationHevc) { LimeLog.info("Decoder "+avcDecoder.getName()+" will use reference frame invalidation for HEVC"); } + LimeLog.info("Decoder "+avcDecoder.getName()+" will use "+optimalSlicesPerFrame+" slices per frame"); } } @@ -1199,8 +1202,8 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C public int getCapabilities() { int capabilities = 0; - // We always request 4 slices per frame to speed up decoding on some hardware - capabilities |= MoonBridge.CAPABILITY_SLICES_PER_FRAME((byte) 4); + // Request the optimal number of slices per frame for this decoder + capabilities |= MoonBridge.CAPABILITY_SLICES_PER_FRAME(optimalSlicesPerFrame); // Enable reference frame invalidation on supported hardware if (refFrameInvalidationAvc) { diff --git a/app/src/main/java/com/limelight/binding/video/MediaCodecHelper.java b/app/src/main/java/com/limelight/binding/video/MediaCodecHelper.java index 66f47717..e6e82794 100644 --- a/app/src/main/java/com/limelight/binding/video/MediaCodecHelper.java +++ b/app/src/main/java/com/limelight/binding/video/MediaCodecHelper.java @@ -38,6 +38,7 @@ public class MediaCodecHelper { private static final List whitelistedHevcDecoders; private static final List refFrameInvalidationAvcPrefixes; private static final List refFrameInvalidationHevcPrefixes; + private static final List useFourSlicesPrefixes; private static final List qualcommDecoderPrefixes; private static final List kirinDecoderPrefixes; private static final List exynosDecoderPrefixes; @@ -201,6 +202,12 @@ public class MediaCodecHelper { // Qualcomm is currently the only decoders in this group. } + static { + useFourSlicesPrefixes = new LinkedList<>(); + + // This decoders are decided at runtime + } + static { qualcommDecoderPrefixes = new LinkedList<>(); @@ -345,6 +352,9 @@ public class MediaCodecHelper { } else { blacklistedDecoderPrefixes.add("OMX.qcom.video.decoder.hevc"); + + // These older decoders need 4 slices per frame for best performance + useFourSlicesPrefixes.add("omx.qcom"); } // Older MediaTek SoCs have issues with HEVC rendering but the newer chips with @@ -569,6 +579,17 @@ public class MediaCodecHelper { return isDecoderInList(baselineProfileHackPrefixes, decoderName); } + public static byte getDecoderOptimalSlicesPerFrame(String decoderName) { + if (isDecoderInList(useFourSlicesPrefixes, decoderName)) { + // 4 slices per frame reduces decoding latency on older Qualcomm devices + return 4; + } + else { + // 1 slice per frame produces the optimal encoding efficiency + return 1; + } + } + public static boolean decoderSupportsRefFrameInvalidationAvc(String decoderName, int videoHeight) { // Reference frame invalidation is broken on low-end Snapdragon SoCs at 1080p. if (videoHeight > 720 && isLowEndSnapdragon) {