From 4ae29b00753550a266ca315f8daabc0349fbb42e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 11:52:08 -0800 Subject: [PATCH 01/14] 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" /> From d5b61309368546c825999c906deadf9e263ced4c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 12:09:32 -0800 Subject: [PATCH 02/14] Use 40% larger packets (1450 bytes) on local networks --- app/libs/limelight-common.jar | Bin 725184 -> 725347 bytes app/src/main/java/com/limelight/Game.java | 2 ++ 2 files changed, 2 insertions(+) diff --git a/app/libs/limelight-common.jar b/app/libs/limelight-common.jar index 34955aaa531d4da096832a62a97a824d07b7232f..a4d81de01e78372c5b44fa7f4ee1a4826557e6bf 100644 GIT binary patch delta 10455 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

i4LnSK%gA$6To)s}pPbgwko}SLf zt;P6j`XoMXb0(JZ>8JU)9T@jb=i%peV|+I~n4jB$Y4+RcQ~9}VnHF$QzrxS$!1!#s fr~tPGlg7vC{sP>-j4P+l72uX-`}CQMfq?-44^ZtE delta 10166 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 Date: Sun, 16 Nov 2014 14:23:58 -0800 Subject: [PATCH 03/14] Fix comment typo --- app/src/main/res/values-v21/styles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index 64631b04..aca590d2 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -3,7 +3,7 @@ + + + From afbe64f3ff1dd1ac71c4670fe847953cc261ad2b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:19:07 -0800 Subject: [PATCH 09/14] Remove an unused import --- .../com/limelight/binding/video/AndroidCpuDecoderRenderer.java | 1 - 1 file changed, 1 deletion(-) 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 acbda3c8..ed5c501f 100644 --- a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java @@ -5,7 +5,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.concurrent.locks.LockSupport; import android.graphics.PixelFormat; import android.os.Build; From 99e3b5f33b5aa84e8b417f7341192b5202dbf62e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:20:04 -0800 Subject: [PATCH 10/14] Rewrite a large portion of the computer manager service to fix some thread leaks and improve performance --- .../computers/ComputerManagerService.java | 109 +++++++++++------- 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index 227a9f67..20662c00 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -1,8 +1,7 @@ package com.limelight.computers; import java.net.InetAddress; -import java.util.HashMap; -import java.util.List; +import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; import com.limelight.LimeLog; @@ -30,7 +29,7 @@ public class ComputerManagerService extends Service { private AtomicInteger dbRefCount = new AtomicInteger(0); private IdentityManager idManager; - private final HashMap pollingThreads = new HashMap(); + private final LinkedList pollingTuples = new LinkedList(); private ComputerManagerListener listener = null; private AtomicInteger activePolls = new AtomicInteger(0); @@ -102,20 +101,8 @@ public class ComputerManagerService extends Service { @Override public void run() { while (!isInterrupted()) { - ComputerDetails originalDetails = new ComputerDetails(); - originalDetails.update(details); - // Check if this poll has modified the details - if (runPoll(details) && !originalDetails.equals(details)) { - // Replace our thread entry with the new one - synchronized (pollingThreads) { - if (pollingThreads.remove(originalDetails) != null) { - // This could have gone away in the meantime, so don't - // add it back if it has - pollingThreads.put(details, this); - } - } - } + runPoll(details); // Wait until the next polling interval try { @@ -137,24 +124,16 @@ public class ComputerManagerService extends Service { // Start mDNS autodiscovery too discoveryBinder.startDiscovery(MDNS_QUERY_PERIOD_MS); - - // Start polling known machines - if (!getLocalDatabaseReference()) { - return; - } - List computerList = dbManager.getAllComputers(); - releaseLocalDatabaseReference(); - synchronized (pollingThreads) { - for (ComputerDetails computer : computerList) { + synchronized (pollingTuples) { + for (PollingTuple tuple : pollingTuples) { // This polling thread might already be there - if (!pollingThreads.containsKey(computer)) { + if (tuple.thread == null) { // Report this computer initially - listener.notifyComputerUpdated(computer); + listener.notifyComputerUpdated(tuple.computer); - Thread t = createPollingThread(computer); - pollingThreads.put(computer, t); - t.start(); + tuple.thread = createPollingThread(tuple.computer); + tuple.thread.start(); } } } @@ -208,11 +187,14 @@ public class ComputerManagerService extends Service { discoveryBinder.stopDiscovery(); // Stop polling - synchronized (pollingThreads) { - for (Thread t : pollingThreads.values()) { - t.interrupt(); + synchronized (pollingTuples) { + for (PollingTuple tuple : pollingTuples) { + if (tuple.thread != null) { + // Interrupt and remove the thread + tuple.thread.interrupt(); + tuple.thread = null; + } } - pollingThreads.clear(); } // Remove the listener @@ -249,13 +231,26 @@ public class ComputerManagerService extends Service { fakeDetails.remoteIp = addr; // Spawn a thread for this computer - synchronized (pollingThreads) { + synchronized (pollingTuples) { // This polling thread might already be there - if (!pollingThreads.containsKey(fakeDetails)) { - Thread t = createPollingThread(fakeDetails); - pollingThreads.put(fakeDetails, t); - t.start(); + for (PollingTuple tuple : pollingTuples) { + if (tuple.computer.localIp.equals(addr) || + tuple.computer.remoteIp.equals(addr)) { + // This is the same computer + if (tuple.thread == null) { + tuple.thread = createPollingThread(fakeDetails); + tuple.thread.start(); + } + + // Found an entry so we're done + return; + } } + + // If we got here, we didn't find an entry + PollingTuple tuple = new PollingTuple(fakeDetails, createPollingThread(fakeDetails)); + pollingTuples.add(tuple); + tuple.thread.start(); } } @@ -279,6 +274,20 @@ public class ComputerManagerService extends Service { // Remove it from the database dbManager.deleteComputer(name); + + synchronized (pollingTuples) { + // Remove the computer from the computer list + for (PollingTuple tuple : pollingTuples) { + if (tuple.computer.name.equals(name)) { + if (tuple.thread != null) { + // Interrupt the thread on this entry + tuple.thread.interrupt(); + } + pollingTuples.remove(tuple); + break; + } + } + } releaseLocalDatabaseReference(); } @@ -376,6 +385,18 @@ public class ComputerManagerService extends Service { // Initialize the DB dbManager = new ComputerDatabaseManager(this); dbRefCount.set(1); + + // Grab known machines into our computer list + if (!getLocalDatabaseReference()) { + return; + } + + for (ComputerDetails computer : dbManager.getAllComputers()) { + // Add this computer without a thread + pollingTuples.add(new PollingTuple(computer, null)); + } + + releaseLocalDatabaseReference(); } @Override @@ -396,3 +417,13 @@ public class ComputerManagerService extends Service { return binder; } } + +class PollingTuple { + public Thread thread; + public ComputerDetails computer; + + public PollingTuple(ComputerDetails computer, Thread thread) { + this.computer = computer; + this.thread = thread; + } +} \ No newline at end of file From 79e8bef289627339657e42934b9ab0d9f0b2afac Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:20:11 -0800 Subject: [PATCH 11/14] Update common --- app/libs/limelight-common.jar | Bin 725347 -> 725230 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/libs/limelight-common.jar b/app/libs/limelight-common.jar index a4d81de01e78372c5b44fa7f4ee1a4826557e6bf..bb57e5a1fa9ae06f5f9c9fd3bc9212236442cb08 100644 GIT binary patch delta 1719 zcmaF7Nax)`9i9MhW)=|!4h{|m!I3_5o+?BXqy)3;xqD;3dtd;xsv0~+P>2rB`spJUG=)BZ%#$+&6|3{K4NwCw7IwMToKn z@U_)kwg(p_S6R;O-x+k$G~0C9k(kXfAAL@~Tp=}Wx7?eGPa*Z2R{K2JKArdY4b!`g zSIbL}bWiV1>R4BBZ>=?-u>9mbeqCPS8S^*FoUUGRVUpY}rJp~&PWCKj_2iv?@p9wq z9fGdw58XB19&?yIJ5aqqQSgax_Kt?`N3}~H3hi1c zx?ZTmZ=tnqNl;hd8O<0=xw??;ZzjDwX4sv=!@cC`{4hJ!iLSi;A6w@1W?e1OsGs=o zi|3um^SKO{vpx!Ltf*RJG~+?AR&vBLxyOcUG)m0om)MCOPFD$8kajeFx&C97e`;Uf z&M)$cpZYzwwK)6VpO(h-D}O%SsnMFlz*&2;+ks6*^qp1PdQrV~tj!ZAo%G<`@#abN z&6DL^do%xj(S4s$(a~?|B+}~i$-daLd~Z;FdH1tLs!4C`mdzGiscd_<(5L*KS(fSK zsH@lhmF8~!xo7bY$HYgq?^-lYan1Z6f3o_;2C=^(@!a~Qfr{)i=S}+fS@-Fi=&qaF zr)3_>nNYwh)ffYA4vK>3(XJVjOwyDu`V=%8z=UMX! z;?|cBoDp2wbAO@Zx36Nm%cR3SwOoxd*Y!*~Ao4Dt76k}HzEm*zF zdDr^?hu&-suh=rh_l*35$vivd9sG4J-an_t<(RQSbBk1qTjssiYfTp-g0Hy=%*x=( zWnFl3*@fqh8LK#7cPmWEKlMwCZn!LL3dV{m!9tT0yGBu{l$N$codcf4{q1xi=&7Mly5nFz5 zcz8zbKVyJ5JI9&Bsq%6x3=C&ECO^=Snf%^Y8eF)PvvbR~7xOZ<7xOZ;7xOZ=7xS{T z7xS{V7xS{U7xS{W7xQwo7xQv%FXrXye#T^2v+WBPrx2*DCmu zBJ7y{f{i<$c{vZ`pE^B&P3;WR#r7$F0TuDH$R# zCxuabdJIUUCI=#-mdhwPeHS0M7GvS`r+nQ0jIGm6`MJ%R`^y-oE0!~gPH*Ao)?)OW zzMh}kjj?k2H-2shMz!hY0^D|t+SAJfxE&b_r|%HpwqV};forv%D`PuEe0qQuBV2;NUN1Q(vAB3{Xmq%AsK`G*rWB6Lm)yKg zyZUNgQfy?=2=mH*s%9dkQM7vPbw$a^3nzP8&0O%+{>Ph7XZL*$n6CEr($<(?kDBdI zJ}vq=cP3-dhS*EfZ~lI>S^xgNxj#S8pI^^v(AX~6!ZK-Rk!J2p)x$>IuI9P#!(xwL z@P4`Ib=al)&rgGvK9f4v^zhZP(B1{E56<-MTfJQOuHKUT{Pz-;;S09DdbLimK((4F zz4`T}7rPp~rp5%`H`Bdbt6@;9q@L}&?aS4q*Q!jNsr-)XcK2n9KZ#wN_N?>%{?$8| zO}%&LjLrwOq^ZTbrmo~D`8|Ex!)3;Q&OH0v7q~XawXi4Xrse9a>fKX1L2i!MKR3q4Y^cT1PC zh4#)u(e(?uYft@7>^NT$a9Oq3@3h?9i@!OWLt_r6h+O_OEwk)z z`1Z*EpEfIt{CK)x`rSnjHzejHzx%f-j&s!-k*`^SWhb)3-PmS?8#YJA?M$s_s+aVY zwzHcqsKYtOUTfa!nPK+|7Dc%9H+`S6%iQ8}q2|d|5y!Z?7ldoIovoC-+V|U5PU}Nu z?5>EZdUh5`JLC5~kJ5@rFI>cB7J1{@+1Y*CJDeS~WfD%_SJgkQ`?KHT&ApUk#;ZU5 z>2x?gYr9Y51LJGOm1TBvQ{uZy_Hh+OKXR2`0J+g zVslO9l@<1U6t-U?D*MaWrbNHH7_s1Zta`5M@#%f{Kie$zY@MPu@4+Gd6sH$Yx1SYuyKsE{ zEA0jH>#OqO4!>^vsGQaAVchw|zvH^#^pXXAjGpYTC8m_D=u`CEYGvXnT&kiXyE573 zQi!ak=kZq()+`e~7<@OnZ1?P9KR1tDdPeWT<0pJK8W~H}AJC2YI=AN86$)-Pv<8hDqOU2ILhI|uz9!fIRji(Bly-NCgvM$_i2W)>C8OT^mU_?=Cus5;u{BSxX%2@e)fk~e!=^VE%KHe?a3cZRv2_Q9XHr` z_*6^5{m-2RV;rTrfdYx_SQw)THK?Ct+}INJa5aBly{!`1za zX=%dt?$2DDLen4o;bNISgOxi2!eU|LP6V^KkSr=@@WD!DU%&WD) zJh|!aoZNQIFLl8@lj(anxwV*InSgn6(>Itf3Qqs?gG*q#1{b#!(*$#n9V*kK%^3wC z!W|&txmFP26I|Rj%s*_wdNro&b937=t2i-E-e@8*otKxJbNU2sZVP57SGb7K^geG! zw&}mQxeb~3c%usQPQUS=OJI5#54RNKis=)1xD%OuBH&8Am^&gNoD00%tkZoX8AYad z^Kxr3r>DS$9hpDoKsY*l+|G>8rWf#W`!oKUet?hLoQb7;`cFP?2gZHVt@yd!7~f5A zVUTraKF8TQF;U Date: Sun, 16 Nov 2014 17:20:27 -0800 Subject: [PATCH 12/14] Increment version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c1d02b1b..72c5e489 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { minSdkVersion 16 targetSdkVersion 21 - versionName "3.0-beta1.01" - versionCode = 41 + versionName "3.0-beta2" + versionCode = 43 } productFlavors { From 94ba7f8e45b631d7b9cacd0dde36e1938fefe294 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 18:09:31 -0800 Subject: [PATCH 13/14] Fix a bunch of bugs in the new (and old) computer manager service --- .../computers/ComputerManagerService.java | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index 20662c00..dac2fe78 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -32,6 +32,7 @@ public class ComputerManagerService extends Service { private final LinkedList pollingTuples = new LinkedList(); private ComputerManagerListener listener = null; private AtomicInteger activePolls = new AtomicInteger(0); + private boolean pollingActive = false; private DiscoveryService.DiscoveryBinder discoveryBinder; private final ServiceConnection discoveryServiceConnection = new ServiceConnection() { @@ -100,7 +101,7 @@ public class ComputerManagerService extends Service { Thread t = new Thread() { @Override public void run() { - while (!isInterrupted()) { + while (!isInterrupted() && pollingActive) { // Check if this poll has modified the details runPoll(details); @@ -119,6 +120,9 @@ public class ComputerManagerService extends Service { public class ComputerManagerBinder extends Binder { public void startPolling(ComputerManagerListener listener) { + // Polling is active + pollingActive = true; + // Set the listener ComputerManagerService.this.listener = listener; @@ -187,6 +191,7 @@ public class ComputerManagerService extends Service { discoveryBinder.stopDiscovery(); // Stop polling + pollingActive = false; synchronized (pollingTuples) { for (PollingTuple tuple : pollingTuples) { if (tuple.thread != null) { @@ -230,15 +235,21 @@ public class ComputerManagerService extends Service { fakeDetails.localIp = addr; fakeDetails.remoteIp = addr; - // Spawn a thread for this computer + addTuple(fakeDetails); + } + + private void addTuple(ComputerDetails details) { synchronized (pollingTuples) { - // This polling thread might already be there for (PollingTuple tuple : pollingTuples) { - if (tuple.computer.localIp.equals(addr) || - tuple.computer.remoteIp.equals(addr)) { - // This is the same computer - if (tuple.thread == null) { - tuple.thread = createPollingThread(fakeDetails); + // Check if this is the same computer + if (tuple.computer == details || + tuple.computer.localIp.equals(details.localIp) || + tuple.computer.remoteIp.equals(details.remoteIp) || + tuple.computer.name.equals(details.name)) { + + // Start a polling thread if polling is active + if (pollingActive && tuple.thread == null) { + tuple.thread = createPollingThread(details); tuple.thread.start(); } @@ -248,11 +259,13 @@ public class ComputerManagerService extends Service { } // If we got here, we didn't find an entry - PollingTuple tuple = new PollingTuple(fakeDetails, createPollingThread(fakeDetails)); + PollingTuple tuple = new PollingTuple(details, pollingActive ? createPollingThread(details) : null); pollingTuples.add(tuple); - tuple.thread.start(); + if (tuple.thread != null) { + tuple.thread.start(); + } } - } + } public boolean addComputerBlocking(InetAddress addr) { // Setup a placeholder @@ -264,7 +277,14 @@ public class ComputerManagerService extends Service { runPoll(fakeDetails); // If the machine is reachable, it was successful - return fakeDetails.state == ComputerDetails.State.ONLINE; + if (fakeDetails.state == ComputerDetails.State.ONLINE) { + // Start a polling thread for this machine + addTuple(fakeDetails); + return true; + } + else { + return false; + } } public void removeComputer(String name) { From b2ba216cd1fee0fe101606ca4117d0bdde31a2d3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 18:14:50 -0800 Subject: [PATCH 14/14] Poll every 3 seconds instead of every 5 seconds --- .../java/com/limelight/computers/ComputerManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index dac2fe78..4b73d1f8 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -20,7 +20,7 @@ import android.os.Binder; import android.os.IBinder; public class ComputerManagerService extends Service { - private static final int POLLING_PERIOD_MS = 5000; + private static final int POLLING_PERIOD_MS = 3000; private static final int MDNS_QUERY_PERIOD_MS = 1000; private ComputerManagerBinder binder = new ComputerManagerBinder();