From 4ae29b00753550a266ca315f8daabc0349fbb42e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 11:52:08 -0800 Subject: [PATCH] Improve performance of the CPU decoder and add some details about changing decoders --- .../video/AndroidCpuDecoderRenderer.java | 53 +++++++++++++------ app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/preferences.xml | 1 + 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java index 26b11076..acbda3c8 100644 --- a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java @@ -21,14 +21,14 @@ import com.limelight.nvstream.av.video.cpu.AvcDecoder; @SuppressWarnings("EmptyCatchBlock") public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { - private Thread rendererThread; + private Thread rendererThread, decoderThread; private int targetFps; private static final int DECODER_BUFFER_SIZE = 92*1024; private ByteBuffer decoderBuffer; // Only sleep if the difference is above this value - private static final int WAIT_CEILING_MS = 8; + private static final int WAIT_CEILING_MS = 5; private static final int LOW_PERF = 1; private static final int MED_PERF = 2; @@ -108,9 +108,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { case LOW_PERF: // Disable the loop filter for performance reasons - avcFlags = AvcDecoder.DISABLE_LOOP_FILTER | - AvcDecoder.FAST_BILINEAR_FILTERING | - AvcDecoder.FAST_DECODE; + avcFlags = AvcDecoder.FAST_BILINEAR_FILTERING; // Use plenty of threads to try to utilize the CPU as best we can threadCount = cpuCount - 1; @@ -118,8 +116,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { default: case MED_PERF: - avcFlags = AvcDecoder.BILINEAR_FILTERING | - AvcDecoder.FAST_DECODE; + avcFlags = AvcDecoder.BILINEAR_FILTERING; // Only use 2 threads to minimize frame processing latency threadCount = 2; @@ -156,6 +153,26 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { @Override public boolean start(final VideoDepacketizer depacketizer) { + decoderThread = new Thread() { + @Override + public void run() { + DecodeUnit du; + while (!isInterrupted()) { + try { + du = depacketizer.takeNextDecodeUnit(); + } catch (InterruptedException e) { + break; + } + + submitDecodeUnit(du); + depacketizer.freeDecodeUnit(du); + } + } + }; + decoderThread.setName("Video - Decoder (CPU)"); + decoderThread.setPriority(Thread.MAX_PRIORITY - 1); + decoderThread.start(); + rendererThread = new Thread() { @Override public void run() { @@ -163,17 +180,15 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { DecodeUnit du; while (!isInterrupted()) { - du = depacketizer.pollNextDecodeUnit(); - if (du != null) { - submitDecodeUnit(du); - depacketizer.freeDecodeUnit(du); - } - long diff = nextFrameTime - System.currentTimeMillis(); if (diff > WAIT_CEILING_MS) { - LockSupport.parkNanos(1); - continue; + try { + Thread.sleep(diff - WAIT_CEILING_MS); + } catch (InterruptedException e) { + return; + } + continue; } nextFrameTime = computePresentationTimeMs(targetFps); @@ -194,10 +209,14 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { @Override public void stop() { rendererThread.interrupt(); + decoderThread.interrupt(); try { - rendererThread.join(); - } catch (InterruptedException e) { } + rendererThread.join(); + } catch (InterruptedException e) { } + try { + decoderThread.join(); + } catch (InterruptedException e) { } } @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 503be448..8ba430e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -106,4 +106,5 @@ Advanced Settings Change decoder + Software decoding may improve video latency at lower streaming settings diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 5a158cdd..c7780c06 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -52,6 +52,7 @@ android:title="@string/title_decoder_list" android:entries="@array/decoder_names" android:entryValues="@array/decoder_values" + android:summary="@string/summary_decoder_list" android:defaultValue="auto" />