From 3df0103a8c9e858f242d7addec40e5d35eb97299 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 1 Sep 2026 20:58:38 -0500 Subject: [PATCH] Remove unused code paths for < API 21 --- .../video/MediaCodecDecoderRenderer.java | 128 +++++------------- 1 file changed, 37 insertions(+), 91 deletions(-) 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 cca41a468..d19aab17b 100644 --- a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -42,9 +42,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C private static final boolean USE_FRAME_RENDER_TIME = false; private static final boolean FRAME_RENDER_TIME_ONLY = USE_FRAME_RENDER_TIME && false; - // Used on versions < 5.0 - private ByteBuffer[] legacyInputBuffers; - private MediaCodecInfo avcDecoder; private MediaCodecInfo hevcDecoder; private MediaCodecInfo av1Decoder; @@ -137,7 +134,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C return decoder; } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) private boolean decoderCanMeetPerformancePoint(MediaCodecInfo.VideoCapabilities caps, PreferenceConfiguration prefs) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { MediaCodecInfo.VideoCapabilities.PerformancePoint targetPerfPoint = new MediaCodecInfo.VideoCapabilities.PerformancePoint(prefs.width, prefs.height, prefs.fps); @@ -180,42 +176,24 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C } private boolean decoderCanMeetPerformancePointWithHevcAndNotAvc(MediaCodecInfo hevcDecoderInfo, MediaCodecInfo avcDecoderInfo, PreferenceConfiguration prefs) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - MediaCodecInfo.VideoCapabilities avcCaps = avcDecoderInfo.getCapabilitiesForType("video/avc").getVideoCapabilities(); - MediaCodecInfo.VideoCapabilities hevcCaps = hevcDecoderInfo.getCapabilitiesForType("video/hevc").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities avcCaps = avcDecoderInfo.getCapabilitiesForType("video/avc").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities hevcCaps = hevcDecoderInfo.getCapabilitiesForType("video/hevc").getVideoCapabilities(); - return !decoderCanMeetPerformancePoint(avcCaps, prefs) && decoderCanMeetPerformancePoint(hevcCaps, prefs); - } - else { - // No performance data - return false; - } + return !decoderCanMeetPerformancePoint(avcCaps, prefs) && decoderCanMeetPerformancePoint(hevcCaps, prefs); } private boolean decoderCanMeetPerformancePointWithAv1AndNotHevc(MediaCodecInfo av1DecoderInfo, MediaCodecInfo hevcDecoderInfo, PreferenceConfiguration prefs) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - MediaCodecInfo.VideoCapabilities av1Caps = av1DecoderInfo.getCapabilitiesForType("video/av01").getVideoCapabilities(); - MediaCodecInfo.VideoCapabilities hevcCaps = hevcDecoderInfo.getCapabilitiesForType("video/hevc").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities av1Caps = av1DecoderInfo.getCapabilitiesForType("video/av01").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities hevcCaps = hevcDecoderInfo.getCapabilitiesForType("video/hevc").getVideoCapabilities(); - return !decoderCanMeetPerformancePoint(hevcCaps, prefs) && decoderCanMeetPerformancePoint(av1Caps, prefs); - } - else { - // No performance data - return false; - } + return !decoderCanMeetPerformancePoint(hevcCaps, prefs) && decoderCanMeetPerformancePoint(av1Caps, prefs); } private boolean decoderCanMeetPerformancePointWithAv1AndNotAvc(MediaCodecInfo av1DecoderInfo, MediaCodecInfo avcDecoderInfo, PreferenceConfiguration prefs) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - MediaCodecInfo.VideoCapabilities avcCaps = avcDecoderInfo.getCapabilitiesForType("video/avc").getVideoCapabilities(); - MediaCodecInfo.VideoCapabilities av1Caps = av1DecoderInfo.getCapabilitiesForType("video/av01").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities avcCaps = avcDecoderInfo.getCapabilitiesForType("video/avc").getVideoCapabilities(); + MediaCodecInfo.VideoCapabilities av1Caps = av1DecoderInfo.getCapabilitiesForType("video/av01").getVideoCapabilities(); - return !decoderCanMeetPerformancePoint(avcCaps, prefs) && decoderCanMeetPerformancePoint(av1Caps, prefs); - } - else { - // No performance data - return false; - } + return !decoderCanMeetPerformancePoint(avcCaps, prefs) && decoderCanMeetPerformancePoint(av1Caps, prefs); } private MediaCodecInfo findHevcDecoder(PreferenceConfiguration prefs, boolean meteredNetwork, boolean requestedHdr) { @@ -548,20 +526,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C spsBuffers.clear(); ppsBuffers.clear(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - // This will contain the actual accepted input format attributes - inputFormat = videoDecoder.getInputFormat(); - LimeLog.info("Input format: "+inputFormat); - } + // This will contain the actual accepted input format attributes + inputFormat = videoDecoder.getInputFormat(); + LimeLog.info("Input format: "+inputFormat); videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT); // Start the decoder videoDecoder.start(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - legacyInputBuffers = videoDecoder.getInputBuffers(); - } } private boolean tryConfigureDecoder(MediaCodecInfo selectedDecoderInfo, MediaFormat format, boolean throwOnCodecError) { @@ -781,7 +754,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C // For "non-recoverable" exceptions on L+, we can call reset() to recover // without having to recreate the entire decoder again. - if (codecRecoveryType.get() == CR_RECOVERY_TYPE_RESET && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (codecRecoveryType.get() == CR_RECOVERY_TYPE_RESET) { LimeLog.warning("Trying to reset decoder after CodecException"); try { videoDecoder.reset(); @@ -864,7 +837,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C return false; } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && e instanceof CodecException) { + if (e instanceof CodecException) { CodecException codecExc = (CodecException) e; if (codecExc.isTransient()) { @@ -978,9 +951,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C return; } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - frameTimeNanos -= activity.getWindowManager().getDefaultDisplay().getAppVsyncOffsetNanos(); - } + frameTimeNanos -= activity.getWindowManager().getDefaultDisplay().getAppVsyncOffsetNanos(); // Don't render unless a new frame is due. This prevents microstutter when streaming // at a frame rate that doesn't match the display (such as 60 FPS on 120 Hz). @@ -995,12 +966,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C Integer nextOutputBuffer = outputBufferQueue.poll(); if (nextOutputBuffer != null) { try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos); - } - else { - videoDecoder.releaseOutputBuffer(nextOutputBuffer, true); - } + videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos); lastRenderedFrameTimeNanos = frameTimeNanos; activeWindowVideoStats.totalFramesRendered++; @@ -1076,23 +1042,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS || prefs.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) { // In max smoothness or cap FPS mode, we want to never drop frames - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - // Use a PTS that will cause this frame to never be dropped - videoDecoder.releaseOutputBuffer(lastIndex, 0); - } - else { - videoDecoder.releaseOutputBuffer(lastIndex, true); - } + // Use a PTS that will cause this frame to never be dropped + videoDecoder.releaseOutputBuffer(lastIndex, 0); } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - // Use a PTS that will cause this frame to be dropped if another comes in within - // the same V-sync period - videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime()); - } - else { - videoDecoder.releaseOutputBuffer(lastIndex, true); - } + // Use a PTS that will cause this frame to be dropped if another comes in within + // the same V-sync period + videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime()); } activeWindowVideoStats.totalFramesRendered++; @@ -1175,20 +1131,12 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C if (nextInputBufferIndex >= 0) { // Using the new getInputBuffer() API on Lollipop allows // the framework to do some performance optimizations for us - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - nextInputBuffer = videoDecoder.getInputBuffer(nextInputBufferIndex); - if (nextInputBuffer == null) { - // According to the Android docs, getInputBuffer() can return null "if the - // index is not a dequeued input buffer". I don't think this ever should - // happen but if it does, let's try to get a new input buffer next time. - nextInputBufferIndex = -1; - } - } - else { - nextInputBuffer = legacyInputBuffers[nextInputBufferIndex]; - - // Clear old input data pre-Lollipop - nextInputBuffer.clear(); + nextInputBuffer = videoDecoder.getInputBuffer(nextInputBufferIndex); + if (nextInputBuffer == null) { + // According to the Android docs, getInputBuffer() can return null "if the + // index is not a dequeued input buffer". I don't think this ever should + // happen but if it does, let's try to get a new input buffer next time. + nextInputBufferIndex = -1; } } } catch (IllegalStateException e) { @@ -1883,7 +1831,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C str += "AVC Decoder: "+((renderer.avcDecoder != null) ? renderer.avcDecoder.getName():"(none)")+DELIMITER; str += "HEVC Decoder: "+((renderer.hevcDecoder != null) ? renderer.hevcDecoder.getName():"(none)")+DELIMITER; str += "AV1 Decoder: "+((renderer.av1Decoder != null) ? renderer.av1Decoder.getName():"(none)")+DELIMITER; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && renderer.avcDecoder != null) { + if (renderer.avcDecoder != null) { Range avcWidthRange = renderer.avcDecoder.getCapabilitiesForType("video/avc").getVideoCapabilities().getSupportedWidths(); str += "AVC supported width range: "+avcWidthRange+DELIMITER; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -1895,7 +1843,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C } } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && renderer.hevcDecoder != null) { + if (renderer.hevcDecoder != null) { Range hevcWidthRange = renderer.hevcDecoder.getCapabilitiesForType("video/hevc").getVideoCapabilities().getSupportedWidths(); str += "HEVC supported width range: "+hevcWidthRange+DELIMITER; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -1907,7 +1855,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C } } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && renderer.av1Decoder != null) { + if (renderer.av1Decoder != null) { Range av1WidthRange = renderer.av1Decoder.getCapabilitiesForType("video/av01").getVideoCapabilities().getSupportedWidths(); str += "AV1 supported width range: "+av1WidthRange+DELIMITER; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -1956,17 +1904,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C str += "Average hardware decoder latency: "+renderer.getAverageDecoderLatency()+"ms"+DELIMITER; str += "Frame pacing mode: "+renderer.prefs.framePacing+DELIMITER; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (originalException instanceof CodecException) { - CodecException ce = (CodecException) originalException; + if (originalException instanceof CodecException) { + CodecException ce = (CodecException) originalException; - str += "Diagnostic Info: "+ce.getDiagnosticInfo()+DELIMITER; - str += "Recoverable: "+ce.isRecoverable()+DELIMITER; - str += "Transient: "+ce.isTransient()+DELIMITER; + str += "Diagnostic Info: " + ce.getDiagnosticInfo() + DELIMITER; + str += "Recoverable: " + ce.isRecoverable() + DELIMITER; + str += "Transient: " + ce.isTransient() + DELIMITER; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - str += "Codec Error Code: "+ce.getErrorCode()+DELIMITER; - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + str += "Codec Error Code: " + ce.getErrorCode() + DELIMITER; } }