Only use 4 slices per frame on old Qualcomm devices that benefit from it

Using it everywhere decreases encoding efficiency for no gain in performance
This commit is contained in:
Cameron Gutman
2022-07-22 18:43:59 -05:00
parent fe322590cc
commit 2e442cb1d1
2 changed files with 26 additions and 2 deletions

View File

@@ -55,6 +55,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
private boolean adaptivePlayback, directSubmit, fusedIdrFrame; private boolean adaptivePlayback, directSubmit, fusedIdrFrame;
private boolean constrainedHighProfile; private boolean constrainedHighProfile;
private boolean refFrameInvalidationAvc, refFrameInvalidationHevc; private boolean refFrameInvalidationAvc, refFrameInvalidationHevc;
private byte optimalSlicesPerFrame;
private boolean refFrameInvalidationActive; private boolean refFrameInvalidationActive;
private int initialWidth, initialHeight; private int initialWidth, initialHeight;
private int videoFormat; private int videoFormat;
@@ -249,6 +250,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
directSubmit = MediaCodecHelper.decoderCanDirectSubmit(avcDecoder.getName()); directSubmit = MediaCodecHelper.decoderCanDirectSubmit(avcDecoder.getName());
refFrameInvalidationAvc = MediaCodecHelper.decoderSupportsRefFrameInvalidationAvc(avcDecoder.getName(), prefs.height); refFrameInvalidationAvc = MediaCodecHelper.decoderSupportsRefFrameInvalidationAvc(avcDecoder.getName(), prefs.height);
refFrameInvalidationHevc = MediaCodecHelper.decoderSupportsRefFrameInvalidationHevc(avcDecoder.getName()); refFrameInvalidationHevc = MediaCodecHelper.decoderSupportsRefFrameInvalidationHevc(avcDecoder.getName());
optimalSlicesPerFrame = MediaCodecHelper.getDecoderOptimalSlicesPerFrame(avcDecoder.getName());
if (consecutiveCrashCount % 2 == 1) { if (consecutiveCrashCount % 2 == 1) {
refFrameInvalidationAvc = refFrameInvalidationHevc = false; refFrameInvalidationAvc = refFrameInvalidationHevc = false;
@@ -264,6 +266,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
if (refFrameInvalidationHevc) { if (refFrameInvalidationHevc) {
LimeLog.info("Decoder "+avcDecoder.getName()+" will use reference frame invalidation for HEVC"); 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() { public int getCapabilities() {
int capabilities = 0; int capabilities = 0;
// We always request 4 slices per frame to speed up decoding on some hardware // Request the optimal number of slices per frame for this decoder
capabilities |= MoonBridge.CAPABILITY_SLICES_PER_FRAME((byte) 4); capabilities |= MoonBridge.CAPABILITY_SLICES_PER_FRAME(optimalSlicesPerFrame);
// Enable reference frame invalidation on supported hardware // Enable reference frame invalidation on supported hardware
if (refFrameInvalidationAvc) { if (refFrameInvalidationAvc) {

View File

@@ -38,6 +38,7 @@ public class MediaCodecHelper {
private static final List<String> whitelistedHevcDecoders; private static final List<String> whitelistedHevcDecoders;
private static final List<String> refFrameInvalidationAvcPrefixes; private static final List<String> refFrameInvalidationAvcPrefixes;
private static final List<String> refFrameInvalidationHevcPrefixes; private static final List<String> refFrameInvalidationHevcPrefixes;
private static final List<String> useFourSlicesPrefixes;
private static final List<String> qualcommDecoderPrefixes; private static final List<String> qualcommDecoderPrefixes;
private static final List<String> kirinDecoderPrefixes; private static final List<String> kirinDecoderPrefixes;
private static final List<String> exynosDecoderPrefixes; private static final List<String> exynosDecoderPrefixes;
@@ -201,6 +202,12 @@ public class MediaCodecHelper {
// Qualcomm is currently the only decoders in this group. // Qualcomm is currently the only decoders in this group.
} }
static {
useFourSlicesPrefixes = new LinkedList<>();
// This decoders are decided at runtime
}
static { static {
qualcommDecoderPrefixes = new LinkedList<>(); qualcommDecoderPrefixes = new LinkedList<>();
@@ -345,6 +352,9 @@ public class MediaCodecHelper {
} }
else { else {
blacklistedDecoderPrefixes.add("OMX.qcom.video.decoder.hevc"); 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 // Older MediaTek SoCs have issues with HEVC rendering but the newer chips with
@@ -569,6 +579,17 @@ public class MediaCodecHelper {
return isDecoderInList(baselineProfileHackPrefixes, decoderName); 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) { public static boolean decoderSupportsRefFrameInvalidationAvc(String decoderName, int videoHeight) {
// Reference frame invalidation is broken on low-end Snapdragon SoCs at 1080p. // Reference frame invalidation is broken on low-end Snapdragon SoCs at 1080p.
if (videoHeight > 720 && isLowEndSnapdragon) { if (videoHeight > 720 && isLowEndSnapdragon) {